Bug 1317936 part 2 - Use atom hash code for jsid hashing. r=jonco
authorJan de Mooij <jdemooij@mozilla.com>
Thu, 24 Nov 2016 13:39:06 +0100
changeset 324178 b92dcbb89ffcf96216a9cfdacfc3b2d652606028
parent 324177 be48744b160459666cbf97f065a97cdad695092f
child 324179 43b2fafc68f489d42956e6ca661066d7480b419f
push id24
push usermaklebus@msu.edu
push dateTue, 20 Dec 2016 03:11:33 +0000
reviewersjonco
bugs1317936
milestone53.0a1
Bug 1317936 part 2 - Use atom hash code for jsid hashing. r=jonco
js/public/Id.h
js/src/jsatom.h
js/src/jsiter.cpp
js/src/vm/ObjectGroup.cpp
js/src/vm/Shape.h
js/src/vm/String.h
--- a/js/public/Id.h
+++ b/js/public/Id.h
@@ -171,28 +171,16 @@ struct GCPolicy<jsid>
     }
 };
 
 } // namespace JS
 
 namespace js {
 
 template <>
-struct DefaultHasher<jsid>
-{
-    typedef jsid Lookup;
-    static HashNumber hash(jsid id) {
-        return JSID_BITS(id);
-    }
-    static bool match(jsid id1, jsid id2) {
-        return id1 == id2;
-    }
-};
-
-template <>
 struct BarrierMethods<jsid>
 {
     static void postBarrier(jsid* idp, jsid prev, jsid next) {}
     static void exposeToJS(jsid id) {
         if (JSID_IS_GCTHING(id))
             js::gc::ExposeGCThingToActiveJS(JSID_TO_GCTHING(id));
     }
 };
--- a/js/src/jsatom.h
+++ b/js/src/jsatom.h
@@ -18,24 +18,16 @@
 #include "js/GCHashTable.h"
 #include "vm/CommonPropertyNames.h"
 
 class JSAtom;
 class JSAutoByteString;
 
 namespace js {
 
-JS_STATIC_ASSERT(sizeof(HashNumber) == 4);
-
-static MOZ_ALWAYS_INLINE js::HashNumber
-HashId(jsid id)
-{
-    return mozilla::HashGeneric(JSID_BITS(id));
-}
-
 /*
  * Return a printable, lossless char[] representation of a string-type atom.
  * The lifetime of the result matches the lifetime of bytes.
  */
 extern const char*
 AtomToPrintableString(ExclusiveContext* cx, JSAtom* atom, JSAutoByteString* bytes);
 
 class AtomStateEntry
--- a/js/src/jsiter.cpp
+++ b/js/src/jsiter.cpp
@@ -63,27 +63,17 @@ NativeIterator::trace(JSTracer* trc)
         guard_array[i].trace(trc);
 
     // The SuppressDeletedPropertyHelper loop can GC, so make sure that if the
     // GC removes any elements from the list, it won't remove this one.
     if (iterObj_)
         TraceManuallyBarrieredEdge(trc, &iterObj_, "iterObj");
 }
 
-struct IdHashPolicy {
-    typedef jsid Lookup;
-    static HashNumber hash(jsid id) {
-        return JSID_BITS(id);
-    }
-    static bool match(jsid id1, jsid id2) {
-        return id1 == id2;
-    }
-};
-
-typedef HashSet<jsid, IdHashPolicy> IdSet;
+typedef HashSet<jsid, DefaultHasher<jsid>> IdSet;
 
 static inline bool
 NewKeyValuePair(JSContext* cx, jsid id, const Value& val, MutableHandleValue rval)
 {
     return NewValuePair(cx, IdToValue(id), val, rval);
 }
 
 static inline bool
--- a/js/src/vm/ObjectGroup.cpp
+++ b/js/src/vm/ObjectGroup.cpp
@@ -1118,17 +1118,17 @@ struct ObjectGroupCompartment::PlainObje
         uint32_t nproperties;
 
         Lookup(IdValuePair* properties, uint32_t nproperties)
           : properties(properties), nproperties(nproperties)
         {}
     };
 
     static inline HashNumber hash(const Lookup& lookup) {
-        return (HashNumber) (JSID_BITS(lookup.properties[lookup.nproperties - 1].id) ^
+        return (HashNumber) (HashId(lookup.properties[lookup.nproperties - 1].id) ^
                              lookup.nproperties);
     }
 
     static inline bool match(const PlainObjectKey& v, const Lookup& lookup) {
         if (lookup.nproperties != v.nproperties)
             return false;
         for (size_t i = 0; i < lookup.nproperties; i++) {
             if (lookup.properties[i].id != v.properties[i])
--- a/js/src/vm/Shape.h
+++ b/js/src/vm/Shape.h
@@ -1318,17 +1318,17 @@ struct StackShape
     }
 
     HashNumber hash() const {
         HashNumber hash = uintptr_t(base);
 
         /* Accumulate from least to most random so the low bits are most random. */
         hash = mozilla::RotateLeft(hash, 4) ^ attrs;
         hash = mozilla::RotateLeft(hash, 4) ^ slot_;
-        hash = mozilla::RotateLeft(hash, 4) ^ JSID_BITS(propid);
+        hash = mozilla::RotateLeft(hash, 4) ^ HashId(propid);
         hash = mozilla::RotateLeft(hash, 4) ^ uintptr_t(rawGetter);
         hash = mozilla::RotateLeft(hash, 4) ^ uintptr_t(rawSetter);
         return hash;
     }
 
     // Traceable implementation.
     static void trace(StackShape* stackShape, JSTracer* trc) { stackShape->trace(trc); }
     void trace(JSTracer* trc);
--- a/js/src/vm/String.h
+++ b/js/src/vm/String.h
@@ -1293,16 +1293,38 @@ NewStringCopyUTF8N(JSContext* cx, const 
 
 template <js::AllowGC allowGC>
 inline JSFlatString*
 NewStringCopyUTF8Z(JSContext* cx, const JS::ConstUTF8CharsZ utf8)
 {
     return NewStringCopyUTF8N<allowGC>(cx, JS::UTF8Chars(utf8.c_str(), strlen(utf8.c_str())));
 }
 
+JS_STATIC_ASSERT(sizeof(HashNumber) == 4);
+
+static MOZ_ALWAYS_INLINE js::HashNumber
+HashId(jsid id)
+{
+    if (MOZ_LIKELY(JSID_IS_ATOM(id)))
+        return JSID_TO_ATOM(id)->hash();
+    return mozilla::HashGeneric(JSID_BITS(id));
+}
+
+template <>
+struct DefaultHasher<jsid>
+{
+    typedef jsid Lookup;
+    static HashNumber hash(jsid id) {
+        return HashId(id);
+    }
+    static bool match(jsid id1, jsid id2) {
+        return id1 == id2;
+    }
+};
+
 } /* namespace js */
 
 // Addon IDs are interned atoms which are never destroyed. This detail is
 // not exposed outside the API.
 class JSAddonId : public JSAtom
 {};
 
 MOZ_ALWAYS_INLINE bool