Bug 1543055 - Fix AllocationSiteKey hashing to not have quadratic behavior when many scripts share bytecode. r=jonco
authorJan de Mooij <jdemooij@mozilla.com>
Fri, 12 Apr 2019 08:54:08 +0000
changeset 469259 21ee37c5b888931751bc0a2429eb15ecdf74f57f
parent 469258 e4b6aa9c2fc4281c677a9f1eb35eb70500cbc64e
child 469260 a34e5dcf0fe8277176fb505348fdf85a1f22e1fb
push id112776
push usershindli@mozilla.com
push dateFri, 12 Apr 2019 16:20:17 +0000
treeherdermozilla-inbound@b4501ced5619 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjonco
bugs1543055
milestone68.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1543055 - Fix AllocationSiteKey hashing to not have quadratic behavior when many scripts share bytecode. r=jonco This also uses HashGeneric/AddToHash instead of manual XOR'ing. Differential Revision: https://phabricator.services.mozilla.com/D26696
js/src/vm/ObjectGroup.cpp
--- a/js/src/vm/ObjectGroup.cpp
+++ b/js/src/vm/ObjectGroup.cpp
@@ -1341,27 +1341,30 @@ struct ObjectGroupRealm::AllocationSiteK
 
   void operator=(AllocationSiteKey&& key) {
     script = std::move(key.script);
     offset = key.offset;
     kind = key.kind;
     proto = std::move(key.proto);
   }
 
-  static inline uint32_t hash(AllocationSiteKey key) {
-    return uint32_t(
-        size_t(key.script.unbarrieredGet()->offsetToPC(key.offset)) ^ key.kind ^
-        MovableCellHasher<JSObject*>::hash(key.proto.unbarrieredGet()));
+  static inline HashNumber hash(const AllocationSiteKey& key) {
+    JSScript* script = key.script.unbarrieredGet();
+    JSObject* proto = key.proto.unbarrieredGet();
+    HashNumber hash = mozilla::HashGeneric(key.offset, key.kind);
+    hash = mozilla::AddToHash(hash, MovableCellHasher<JSScript*>::hash(script));
+    hash = mozilla::AddToHash(hash, MovableCellHasher<JSObject*>::hash(proto));
+    return hash;
   }
 
   static inline bool match(const AllocationSiteKey& a,
                            const AllocationSiteKey& b) {
-    return DefaultHasher<JSScript*>::match(a.script.unbarrieredGet(),
-                                           b.script.unbarrieredGet()) &&
-           a.offset == b.offset && a.kind == b.kind &&
+    return a.offset == b.offset && a.kind == b.kind &&
+           MovableCellHasher<JSScript*>::match(a.script.unbarrieredGet(),
+                                               b.script.unbarrieredGet()) &&
            MovableCellHasher<JSObject*>::match(a.proto, b.proto);
   }
 
   void trace(JSTracer* trc) {
     TraceRoot(trc, &script, "AllocationSiteKey script");
     TraceNullableRoot(trc, &proto, "AllocationSiteKey proto");
   }