Bug 1383591 - Don't use |current| block in OutOfLineStoreElementHole code. r=nbp
authorJan de Mooij <jdemooij@mozilla.com>
Tue, 25 Jul 2017 17:09:08 +0200
changeset 419586 2bb6be91be3978952ba4b12272afa251b6e6a3d7
parent 419585 53accdb19e4f336d10a3a93a377b25f89f343826
child 419587 979cc414d80a9964cb62ff03b72859e5fcb20a40
push id7566
push usermtabara@mozilla.com
push dateWed, 02 Aug 2017 08:25:16 +0000
treeherdermozilla-beta@86913f512c3c [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersnbp
bugs1383591
milestone56.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 1383591 - Don't use |current| block in OutOfLineStoreElementHole code. r=nbp
js/src/jit-test/tests/ion/bug1383591.js
js/src/jit/CodeGenerator.cpp
js/src/jit/shared/CodeGenerator-shared.cpp
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/ion/bug1383591.js
@@ -0,0 +1,20 @@
+function test() {
+    var count = 0;
+    function f(x) {
+        "use strict";
+        if (x) {
+            Object.seal(this);
+        }
+        this[0] = 1;
+    }
+    for (var y of [1, 0, arguments, 1]) {
+        try {
+            var o = new f(y);
+        } catch (e) {
+            count++;
+        }
+    }
+    assertEq(count, 3);
+}
+test();
+test();
--- a/js/src/jit/CodeGenerator.cpp
+++ b/js/src/jit/CodeGenerator.cpp
@@ -8468,34 +8468,38 @@ CodeGenerator::visitBoundsCheckLower(LBo
     bailoutCmp32(Assembler::LessThan, ToRegister(lir->index()), Imm32(min),
                  lir->snapshot());
 }
 
 class OutOfLineStoreElementHole : public OutOfLineCodeBase<CodeGenerator>
 {
     LInstruction* ins_;
     Label rejoinStore_;
+    bool strict_;
 
   public:
-    explicit OutOfLineStoreElementHole(LInstruction* ins)
-      : ins_(ins)
+    explicit OutOfLineStoreElementHole(LInstruction* ins, bool strict)
+      : ins_(ins), strict_(strict)
     {
         MOZ_ASSERT(ins->isStoreElementHoleV() || ins->isStoreElementHoleT() ||
                    ins->isFallibleStoreElementV() || ins->isFallibleStoreElementT());
     }
 
     void accept(CodeGenerator* codegen) {
         codegen->visitOutOfLineStoreElementHole(this);
     }
     LInstruction* ins() const {
         return ins_;
     }
     Label* rejoinStore() {
         return &rejoinStore_;
     }
+    bool strict() const {
+        return strict_;
+    }
 };
 
 void
 CodeGenerator::emitStoreHoleCheck(Register elements, const LAllocation* index,
                                   int32_t offsetAdjustment, LSnapshot* snapshot)
 {
     Label bail;
     if (index->isConstant()) {
@@ -8574,17 +8578,18 @@ CodeGenerator::visitStoreElementV(LStore
 }
 
 template <typename T> void
 CodeGenerator::emitStoreElementHoleT(T* lir)
 {
     static_assert(std::is_same<T, LStoreElementHoleT>::value || std::is_same<T, LFallibleStoreElementT>::value,
                   "emitStoreElementHoleT called with unexpected argument type");
 
-    OutOfLineStoreElementHole* ool = new(alloc()) OutOfLineStoreElementHole(lir);
+    OutOfLineStoreElementHole* ool =
+        new(alloc()) OutOfLineStoreElementHole(lir, current->mir()->strict());
     addOutOfLineCode(ool, lir->mir());
 
     Register obj = ToRegister(lir->object());
     Register elements = ToRegister(lir->elements());
     const LAllocation* index = lir->index();
     RegisterOrInt32Constant key = ToRegisterOrInt32Constant(index);
 
     JSValueType unboxedType = lir->mir()->unboxedType();
@@ -8633,17 +8638,18 @@ CodeGenerator::visitStoreElementHoleT(LS
 }
 
 template <typename T> void
 CodeGenerator::emitStoreElementHoleV(T* lir)
 {
     static_assert(std::is_same<T, LStoreElementHoleV>::value || std::is_same<T, LFallibleStoreElementV>::value,
                   "emitStoreElementHoleV called with unexpected parameter type");
 
-    OutOfLineStoreElementHole* ool = new(alloc()) OutOfLineStoreElementHole(lir);
+    OutOfLineStoreElementHole* ool =
+        new(alloc()) OutOfLineStoreElementHole(lir, current->mir()->strict());
     addOutOfLineCode(ool, lir->mir());
 
     Register obj = ToRegister(lir->object());
     Register elements = ToRegister(lir->elements());
     const LAllocation* index = lir->index();
     const ValueOperand value = ToValue(lir, T::Value);
     RegisterOrInt32Constant key = ToRegisterOrInt32Constant(index);
 
@@ -8893,17 +8899,17 @@ CodeGenerator::visitOutOfLineStoreElemen
     } else {
         // Jump to the inline path where we will store the value.
         masm.jump(ool->rejoinStore());
     }
 
     masm.bind(&callStub);
     saveLive(ins);
 
-    pushArg(Imm32(current->mir()->strict()));
+    pushArg(Imm32(ool->strict()));
     pushArg(value);
     if (index->isConstant())
         pushArg(Imm32(ToInt32(index)));
     else
         pushArg(ToRegister(index));
     pushArg(object);
     callVM(SetDenseOrUnboxedArrayElementInfo, ins);
 
--- a/js/src/jit/shared/CodeGenerator-shared.cpp
+++ b/js/src/jit/shared/CodeGenerator-shared.cpp
@@ -158,16 +158,20 @@ CodeGeneratorShared::generateEpilogue()
     // On systems that use a constant pool, this is a good time to emit.
     masm.flushBuffer();
     return true;
 }
 
 bool
 CodeGeneratorShared::generateOutOfLineCode()
 {
+    // OOL paths should not attempt to use |current| as it's the last block
+    // instead of the block corresponding to the OOL path.
+    current = nullptr;
+
     for (size_t i = 0; i < outOfLineCode_.length(); i++) {
         // Add native => bytecode mapping entries for OOL sites.
         // Not enabled on wasm yet since it doesn't contain bytecode mappings.
         if (!gen->compilingWasm()) {
             if (!addNativeToBytecodeEntry(outOfLineCode_[i]->bytecodeSite()))
                 return false;
         }