Bug 1339535 - Set the hadElementsAccess flag less eagerly to avoid unnecessary Shape changes. r=evilpie
authorJan de Mooij <jdemooij@mozilla.com>
Mon, 27 Feb 2017 18:56:58 +0100
changeset 374151 4a9b7fb94f2c102e956c9efd5ad26c61bd77590a
parent 374150 8e98edd1c6d4a18239d043ec3df15449ab9e622e
child 374152 f9a4f73f014b633224ca4f48b7a75a1304b9ba02
push id10863
push userjlorenzo@mozilla.com
push dateMon, 06 Mar 2017 23:02:23 +0000
treeherdermozilla-aurora@0931190cd725 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersevilpie
bugs1339535
milestone54.0a1
Bug 1339535 - Set the hadElementsAccess flag less eagerly to avoid unnecessary Shape changes. r=evilpie
js/src/vm/Interpreter.cpp
--- a/js/src/vm/Interpreter.cpp
+++ b/js/src/vm/Interpreter.cpp
@@ -1495,18 +1495,29 @@ SetObjectElementOperation(JSContext* cx,
         int32_t i = JSID_TO_INT(id);
         if ((uint32_t)i >= length) {
             // Annotate script if provided with information (e.g. baseline)
             if (script && script->hasBaselineScript() && IsSetElemPC(pc))
                 script->baselineScript()->noteHasDenseAdd(script->pcToOffset(pc));
         }
     }
 
-    if (obj->isNative() && !JSID_IS_INT(id) && !JSObject::setHadElementsAccess(cx, obj))
-        return false;
+    // Set the HadElementsAccess flag on the object if needed. This flag is
+    // used to do more eager dictionary-mode conversion for objects that are
+    // used as hashmaps. Set this flag only for objects with many properties,
+    // to avoid unnecessary Shape changes.
+    if (obj->isNative() &&
+        JSID_IS_ATOM(id) &&
+        !obj->as<NativeObject>().inDictionaryMode() &&
+        !obj->hadElementsAccess() &&
+        obj->as<NativeObject>().slotSpan() > PropertyTree::MAX_HEIGHT_WITH_ELEMENTS_ACCESS / 3)
+    {
+        if (!JSObject::setHadElementsAccess(cx, obj))
+            return false;
+    }
 
     ObjectOpResult result;
     return SetProperty(cx, obj, id, value, receiver, result) &&
            result.checkStrictErrorOrWarning(cx, obj, id, strict);
 }
 
 /*
  * Get the innermost enclosing function that has a 'this' binding.