Bug 1346028 - Allow MCallInitElementArray to take dynamic index draft
authorTed Campbell <tcampbell@mozilla.com>
Mon, 20 Mar 2017 18:15:44 -0400
changeset 501881 c5dc73242e399545d80cb075490058cc3a630e14
parent 501569 05bfa2831c0ba4a26fa72328ffe6a99aba9c356a
child 501882 37a8ba6b04ad0753efea5f820ee14c8ca0d54639
child 504684 05794e48e2af77f59d5188956550f15aa30f73ee
push id50144
push userbmo:tcampbell@mozilla.com
push dateTue, 21 Mar 2017 03:36:33 +0000
bugs1346028
milestone55.0a1
Bug 1346028 - Allow MCallInitElementArray to take dynamic index MozReview-Commit-ID: L0UE9MtnxmS
js/src/jit/CodeGenerator.cpp
js/src/jit/IonBuilder.cpp
js/src/jit/Lowering.cpp
js/src/jit/MIR.h
js/src/jit/shared/LIR-shared.h
--- a/js/src/jit/CodeGenerator.cpp
+++ b/js/src/jit/CodeGenerator.cpp
@@ -10144,18 +10144,21 @@ CodeGenerator::visitCallSetElement(LCall
 typedef bool (*InitElementArrayFn)(JSContext*, jsbytecode*, HandleObject, uint32_t, HandleValue);
 static const VMFunction InitElementArrayInfo =
     FunctionInfo<InitElementArrayFn>(js::InitElementArray, "InitElementArray");
 
 void
 CodeGenerator::visitCallInitElementArray(LCallInitElementArray* lir)
 {
     pushArg(ToValue(lir, LCallInitElementArray::Value));
-    pushArg(Imm32(lir->mir()->index()));
-    pushArg(ToRegister(lir->getOperand(0)));
+    if (lir->index()->isConstant())
+        pushArg(Imm32(ToInt32(lir->index())));
+    else
+        pushArg(ToRegister(lir->index()));
+    pushArg(ToRegister(lir->object()));
     pushArg(ImmPtr(lir->mir()->resumePoint()->pc()));
     callVM(InitElementArrayInfo, lir);
 }
 
 void
 CodeGenerator::visitLoadFixedSlotV(LLoadFixedSlotV* ins)
 {
     const Register obj = ToRegister(ins->getOperand(0));
--- a/js/src/jit/IonBuilder.cpp
+++ b/js/src/jit/IonBuilder.cpp
@@ -6137,17 +6137,22 @@ IonBuilder::jsop_initelem_array()
                 elemTypes.freeze(constraints());
                 needStub = true;
             }
         }
     }
 
     uint32_t index = GET_UINT32(pc);
     if (needStub) {
-        MCallInitElementArray* store = MCallInitElementArray::New(alloc(), obj, index, value);
+        MOZ_ASSERT(index <= INT32_MAX,
+                   "the bytecode emitter must fail to compile code that would "
+                   "produce JSOP_INITELEM_ARRAY with an index exceeding "
+                   "int32_t range");
+        MCallInitElementArray* store = MCallInitElementArray::New(alloc(), obj,
+                                                                  constantInt(index), value);
         current->add(store);
         return resumeAfter(store);
     }
 
     return initializeArrayElement(obj, index, value, unboxedType, /* addResumePoint = */ true);
 }
 
 AbortReasonOr<Ok>
--- a/js/src/jit/Lowering.cpp
+++ b/js/src/jit/Lowering.cpp
@@ -4011,18 +4011,20 @@ LIRGenerator::visitCallSetElement(MCallS
                                                         useBoxAtStart(ins->value()));
     add(lir, ins);
     assignSafepoint(lir, ins);
 }
 
 void
 LIRGenerator::visitCallInitElementArray(MCallInitElementArray* ins)
 {
-    LCallInitElementArray* lir = new(alloc()) LCallInitElementArray(useRegisterAtStart(ins->object()),
-                                                                    useBoxAtStart(ins->value()));
+    LCallInitElementArray* lir =
+        new(alloc()) LCallInitElementArray(useRegisterAtStart(ins->object()),
+                                           useRegisterOrConstantAtStart(ins->index()),
+                                           useBoxAtStart(ins->value()));
     add(lir, ins);
     assignSafepoint(lir, ins);
 }
 
 void
 LIRGenerator::visitIteratorStart(MIteratorStart* ins)
 {
     if (ins->object()->type() == MIRType::Value) {
--- a/js/src/jit/MIR.h
+++ b/js/src/jit/MIR.h
@@ -11935,36 +11935,29 @@ class MCallSetElement
     TRIVIAL_NEW_WRAPPERS
 
     bool possiblyCalls() const override {
         return true;
     }
 };
 
 class MCallInitElementArray
-  : public MAryInstruction<2>,
-    public MixPolicy<ObjectPolicy<0>, BoxPolicy<1> >::Data
-{
-    uint32_t index_;
-
-    MCallInitElementArray(MDefinition* obj, uint32_t index, MDefinition* val)
-      : index_(index)
-    {
-        initOperand(0, obj);
-        initOperand(1, val);
+  : public MTernaryInstruction,
+    public Mix3Policy<ObjectPolicy<0>, IntPolicy<1>, BoxPolicy<2> >::Data
+{
+    MCallInitElementArray(MDefinition* obj, MDefinition* index, MDefinition* val)
+      : MTernaryInstruction(obj, index, val)
+    {
+        MOZ_ASSERT(index->type() == MIRType::Int32);
     }
 
   public:
     INSTRUCTION_HEADER(CallInitElementArray)
     TRIVIAL_NEW_WRAPPERS
-    NAMED_OPERANDS((0, object), (1, value))
-
-    uint32_t index() const {
-        return index_;
-    }
+    NAMED_OPERANDS((0, object), (1, index), (2, value))
 
     bool possiblyCalls() const override {
         return true;
     }
 };
 
 class MSetDOMProperty
   : public MAryInstruction<2>,
--- a/js/src/jit/shared/LIR-shared.h
+++ b/js/src/jit/shared/LIR-shared.h
@@ -7149,28 +7149,35 @@ class LCallSetElement : public LCallInst
     }
 
     const MCallSetElement* mir() const {
         return mir_->toCallSetElement();
     }
 };
 
 // Call js::InitElementArray.
-class LCallInitElementArray : public LCallInstructionHelper<0, 1 + BOX_PIECES, 0>
+class LCallInitElementArray : public LCallInstructionHelper<0, 2 + BOX_PIECES, 0>
 {
 public:
     LIR_HEADER(CallInitElementArray)
 
-    static const size_t Value = 1;
-
-    LCallInitElementArray(const LAllocation& obj, const LBoxAllocation& value) {
+    static const size_t Value = 2;
+
+    LCallInitElementArray(const LAllocation& obj, const LAllocation& index,
+                          const LBoxAllocation& value) {
         setOperand(0, obj);
+        setOperand(1, index);
         setBoxOperand(Value, value);
     }
-
+    const LAllocation* object() {
+        return getOperand(0);
+    }
+    const LAllocation* index() {
+        return getOperand(1);
+    }
     const MCallInitElementArray* mir() const {
         return mir_->toCallInitElementArray();
     }
 };
 
 // Call a VM function to perform a property or name assignment of a generic value.
 class LCallSetProperty : public LCallInstructionHelper<0, 1 + BOX_PIECES, 0>
 {