Bug 1536228 - Part 2: Don't emit megamorphic store slot stub for JSOP_INITELEM. r=jandem
authorAndré Bargull <andre.bargull@gmail.com>
Tue, 26 Mar 2019 10:12:30 +0000
changeset 466192 d3e9985fd713ebf98c02799b5634639c23f99ed5
parent 466191 0afcf25330d97fa7d7d15b4c0c9beef4b2eb6cd0
child 466193 ebbe8a58525ed960cd9615258b6c33b1e4297d08
push id35762
push usercsabou@mozilla.com
push dateWed, 27 Mar 2019 04:44:00 +0000
treeherdermozilla-central@bc572aee49b6 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjandem
bugs1536228
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 1536228 - Part 2: Don't emit megamorphic store slot stub for JSOP_INITELEM. r=jandem Depends on D24493 Differential Revision: https://phabricator.services.mozilla.com/D24495
js/src/jit-test/tests/cacheir/bug1536228.js
js/src/jit/CacheIR.cpp
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/cacheir/bug1536228.js
@@ -0,0 +1,40 @@
+load(libdir + "asserts.js");
+
+function test() {
+    var plainDataProperty = {
+        value: 0, enumerable: true, configurable: true, writable: true
+    };
+    var nonEnumerableProperty = {
+        value: 0, enumerable: false, configurable: true, writable: true
+    };
+    var nonConfigurableProperty = {
+        value: 0, enumerable: true, configurable: false, writable: true
+    };
+    var n = 5000;
+    for (var i = 0; i < n; ++i) {
+        var obj = {};
+
+        // Create a different shape for each object to ensure JSOP_INITELEM
+        // below can get into the megamorphic state.
+        Object.defineProperty(obj, "bar" + i, nonEnumerableProperty);
+
+        // Plain data property, will be created through _DefineDataProperty,
+        // which is emitted as JSOP_INITELEM. The object doesn't have a "foo"
+        // property, so JSOP_INITELEM can simply create a new property.
+        Object.defineProperty(obj, "foo", plainDataProperty);
+
+        // Redefine as a non-data property for the last object.
+        var desc = (i + 1 !== n) ? plainDataProperty : nonConfigurableProperty;
+        Object.defineProperty(obj, "foo", desc);
+
+        // Again JSOP_INITELEM, but this time JSOP_INITELEM can't simply add a
+        // property, because "foo" is already present. And for the last object,
+        // which has a non-configurable "foo" property, this call must throw a
+        // TypeError exception.
+        Object.defineProperty(obj, "foo", plainDataProperty);
+    }
+}
+
+for (var i = 0; i < 2; ++i) {
+    assertThrowsInstanceOf(test, TypeError);
+}
--- a/js/src/jit/CacheIR.cpp
+++ b/js/src/jit/CacheIR.cpp
@@ -3382,17 +3382,19 @@ bool SetPropIRGenerator::tryAttachNative
                                                 ObjOperandId objId, HandleId id,
                                                 ValOperandId rhsId) {
   RootedShape propShape(cx_);
   if (!CanAttachNativeSetSlot(cx_, JSOp(*pc_), obj, id,
                               isTemporarilyUnoptimizable_, &propShape)) {
     return false;
   }
 
-  if (mode_ == ICState::Mode::Megamorphic && cacheKind_ == CacheKind::SetProp) {
+  // Don't attach a megamorphic store slot stub for ops like JSOP_INITELEM.
+  if (mode_ == ICState::Mode::Megamorphic && cacheKind_ == CacheKind::SetProp &&
+      IsPropertySetOp(JSOp(*pc_))) {
     writer.megamorphicStoreSlot(objId, JSID_TO_ATOM(id)->asPropertyName(),
                                 rhsId, typeCheckInfo_.needsTypeBarrier());
     writer.returnFromIC();
     trackAttached("MegamorphicNativeSlot");
     return true;
   }
 
   maybeEmitIdGuard(id);