Bug 588021: Port CALLPROP PIC for ARM. (r=dmandelin)
authorChris Leary <cdleary@mozilla.com>
Thu, 13 Jan 2011 22:42:07 -0800
changeset 60596 d3ca3ea64e570e0bd7c1d230e996b0857b431a99
parent 60595 151a8a6ce36bb7793b70729f32cc001cb92d5a43
child 60597 a08bbc16b665b9c755ad0aab242aea4558855a6f
push idunknown
push userunknown
push dateunknown
reviewersdmandelin
bugs588021
milestone2.0b10pre
Bug 588021: Port CALLPROP PIC for ARM. (r=dmandelin)
js/src/configure.in
js/src/methodjit/Compiler.cpp
--- a/js/src/configure.in
+++ b/js/src/configure.in
@@ -2910,42 +2910,45 @@ case "$target" in
 i?86-*)
     ENABLE_TRACEJIT=1
     NANOJIT_ARCH=i386
     ENABLE_METHODJIT=1
     ENABLE_MONOIC=1
     ENABLE_POLYIC=1
     ENABLE_POLYIC_GETPROP=1
     ENABLE_POLYIC_SETPROP=1
+    ENABLE_POLYIC_CALLPROP=1
     ENABLE_POLYIC_BIND=1
     ENABLE_POLYIC_NAME=1
     AC_DEFINE(JS_CPU_X86)
     AC_DEFINE(JS_NUNBOX32)
     ;;
 x86_64*-*)
     ENABLE_TRACEJIT=1
     NANOJIT_ARCH=X64
     ENABLE_METHODJIT=1
     ENABLE_MONOIC=1
     ENABLE_POLYIC=1
     ENABLE_POLYIC_GETPROP=1
     ENABLE_POLYIC_SETPROP=1
+    ENABLE_POLYIC_CALLPROP=1
     ENABLE_POLYIC_BIND=1
     ENABLE_POLYIC_NAME=1
     AC_DEFINE(JS_CPU_X64)
     AC_DEFINE(JS_PUNBOX64)
     ;;
 arm*-*)
     ENABLE_TRACEJIT=1
     NANOJIT_ARCH=ARM
     ENABLE_METHODJIT=1
     ENABLE_MONOIC=1
     ENABLE_POLYIC=1
     ENABLE_POLYIC_GETPROP=1
     ENABLE_POLYIC_SETPROP=1
+    ENABLE_POLYIC_CALLPROP=1
     ENABLE_POLYIC_BIND=1
     ENABLE_POLYIC_NAME=1
     AC_DEFINE(JS_CPU_ARM)
     AC_DEFINE(JS_NUNBOX32)
     ;;
 sparc*-*)
     ENABLE_TRACEJIT=1
     NANOJIT_ARCH=Sparc
@@ -2991,16 +2994,20 @@ fi
 if test "$ENABLE_POLYIC_GETPROP"; then
     AC_DEFINE(JS_POLYIC_GETPROP)
 fi
 
 if test "$ENABLE_POLYIC_SETPROP"; then
     AC_DEFINE(JS_POLYIC_SETPROP)
 fi
 
+if test "$ENABLE_POLYIC_CALLPROP"; then
+    AC_DEFINE(JS_POLYIC_CALLPROP)
+fi
+
 if test "$ENABLE_POLYIC_NAME"; then
     AC_DEFINE(JS_POLYIC_NAME)
 fi
 
 if test "$ENABLE_POLYIC_BIND"; then
     AC_DEFINE(JS_POLYIC_BIND)
 fi
 
--- a/js/src/methodjit/Compiler.cpp
+++ b/js/src/methodjit/Compiler.cpp
@@ -3100,92 +3100,101 @@ mjit::Compiler::jsop_callprop_generic(JS
 
     PICGenInfo pic(ic::PICInfo::CALL, JSOp(*PC), true);
 
     pic.pc = PC;
 
     /* Guard that the type is an object. */
     pic.typeReg = frame.copyTypeIntoReg(top);
 
+    RESERVE_IC_SPACE(masm);
+
     /* Start the hot path where it's easy to patch it. */
     pic.fastPathStart = masm.label();
 
     /*
      * Guard that the value is an object. This part needs some extra gunk
      * because the leave() after the shape guard will emit a jump from this
      * path to the final call. We need a label in between that jump, which
      * will be the target of patched jumps in the PIC.
      */
-    Jump typeCheck = masm.testObject(Assembler::NotEqual, pic.typeReg);
-    DBGLABEL(dbgInlineTypeGuard);
-
-    pic.typeCheck = stubcc.linkExit(typeCheck, Uses(1));
+    Jump typeCheckJump = masm.testObject(Assembler::NotEqual, pic.typeReg);
+    Label typeCheck = masm.label();
+    RETURN_IF_OOM(false);
+
+    pic.typeCheck = stubcc.linkExit(typeCheckJump, Uses(1));
     pic.hasTypeCheck = true;
     pic.objReg = objReg;
     pic.shapeReg = shapeReg;
     pic.atom = atom;
 
     /*
      * Store the type and object back. Don't bother keeping them in registers,
      * since a sync will be needed for the upcoming call.
      */
     uint32 thisvSlot = frame.localSlots();
     Address thisv = Address(JSFrameReg, sizeof(JSStackFrame) + thisvSlot * sizeof(Value));
+
 #if defined JS_NUNBOX32
     masm.storeValueFromComponents(pic.typeReg, pic.objReg, thisv);
 #elif defined JS_PUNBOX64
     masm.orPtr(pic.objReg, pic.typeReg);
     masm.storePtr(pic.typeReg, thisv);
 #endif
+
     frame.freeReg(pic.typeReg);
 
     /* Guard on shape. */
     masm.loadShape(objReg, shapeReg);
     pic.shapeGuard = masm.label();
 
     DataLabel32 inlineShapeLabel;
     Jump j = masm.branch32WithPatch(Assembler::NotEqual, shapeReg,
                            Imm32(int32(JSObjectMap::INVALID_SHAPE)),
                            inlineShapeLabel);
-    DBGLABEL(dbgInlineShapeJump);
-
-    pic.slowPathStart = stubcc.linkExit(j, Uses(1));
+    Label inlineShapeJump = masm.label();
 
     /* Slow path. */
+    RESERVE_OOL_SPACE(stubcc.masm);
+    pic.slowPathStart = stubcc.linkExit(j, Uses(1));
     stubcc.leave();
     passICAddress(&pic);
     pic.slowPathCall = OOL_STUBCALL(ic::CallProp);
+    CHECK_OOL_SPACE();
 
     /* Adjust the frame. None of this will generate code. */
     frame.pop();
     frame.pushRegs(shapeReg, objReg);
     frame.pushSynced();
 
-    /* Load dslots. */
-    Label dslotsLoadLabel = masm.label();
-    masm.loadPtr(Address(objReg, offsetof(JSObject, slots)), objReg);
+    /* Load the base slot address. */
+    Label dslotsLoadLabel = masm.loadPtrWithPatchToLEA(Address(objReg, offsetof(JSObject, slots)),
+                                                               objReg);
 
     /* Copy the slot value to the expression stack. */
     Address slot(objReg, 1 << 24);
 
     Label fastValueLoad = masm.loadValueWithAddressOffsetPatch(slot, shapeReg, objReg);
     pic.fastPathRejoin = masm.label();
 
-    /* Assert correctness of hardcoded offsets. */
     RETURN_IF_OOM(false);
-    JS_ASSERT(masm.differenceBetween(pic.fastPathStart, dbgInlineTypeGuard) == GETPROP_INLINE_TYPE_GUARD);
-
+
+    /* 
+     * Initialize op labels. We use GetPropLabels here because we have the same patching
+     * requirements for CallProp.
+     */
     GetPropLabels &labels = pic.getPropLabels();
     labels.setDslotsLoadOffset(masm.differenceBetween(pic.fastPathRejoin, dslotsLoadLabel));
     labels.setInlineShapeOffset(masm.differenceBetween(pic.shapeGuard, inlineShapeLabel));
     labels.setValueLoad(masm, pic.fastPathRejoin, fastValueLoad);
-#if defined JS_NUNBOX32
-    JS_ASSERT(masm.differenceBetween(pic.shapeGuard, dbgInlineShapeJump) == GETPROP_INLINE_SHAPE_JUMP);
-#elif defined JS_PUNBOX64
-    JS_ASSERT(masm.differenceBetween(inlineShapeLabel, dbgInlineShapeJump) == GETPROP_INLINE_SHAPE_JUMP);
+    labels.setInlineTypeJump(masm, pic.fastPathStart, typeCheck);
+#ifdef JS_CPU_X64
+    labels.setInlineShapeJump(masm, inlineShapeLabel, inlineShapeJump);
+#else
+    labels.setInlineShapeJump(masm, pic.shapeGuard, inlineShapeJump);
 #endif
 
     stubcc.rejoin(Changes(2));
     pics.append(pic);
 
     return true;
 }
 
@@ -3252,16 +3261,18 @@ bool
 mjit::Compiler::jsop_callprop_obj(JSAtom *atom)
 {
     FrameEntry *top = frame.peek(-1);
 
     PICGenInfo pic(ic::PICInfo::CALL, JSOp(*PC), true);
 
     JS_ASSERT(top->isTypeKnown());
     JS_ASSERT(top->getKnownType() == JSVAL_TYPE_OBJECT);
+    
+    RESERVE_IC_SPACE(masm);
 
     pic.pc = PC;
     pic.fastPathStart = masm.label();
     pic.hasTypeCheck = false;
     pic.typeReg = Registers::ReturnReg;
 
     RegisterID objReg = frame.copyDataIntoReg(top);
     RegisterID shapeReg = frame.allocReg();
@@ -3272,27 +3283,29 @@ mjit::Compiler::jsop_callprop_obj(JSAtom
     /* Guard on shape. */
     masm.loadShape(objReg, shapeReg);
     pic.shapeGuard = masm.label();
 
     DataLabel32 inlineShapeLabel;
     Jump j = masm.branch32WithPatch(Assembler::NotEqual, shapeReg,
                            Imm32(int32(JSObjectMap::INVALID_SHAPE)),
                            inlineShapeLabel);
-    DBGLABEL(dbgInlineShapeJump);
-
+    Label inlineShapeJump = masm.label();
+
+    /* Slow path. */
+    RESERVE_OOL_SPACE(stubcc.masm);
     pic.slowPathStart = stubcc.linkExit(j, Uses(1));
-
     stubcc.leave();
     passICAddress(&pic);
     pic.slowPathCall = OOL_STUBCALL(ic::CallProp);
-
-    /* Load dslots. */
-    Label dslotsLoadLabel = masm.label();
-    masm.loadPtr(Address(objReg, offsetof(JSObject, slots)), objReg);
+    CHECK_OOL_SPACE();
+
+    /* Load the base slot address. */
+    Label dslotsLoadLabel = masm.loadPtrWithPatchToLEA(Address(objReg, offsetof(JSObject, slots)),
+                                                               objReg);
 
     /* Copy the slot value to the expression stack. */
     Address slot(objReg, 1 << 24);
 
     Label fastValueLoad = masm.loadValueWithAddressOffsetPatch(slot, shapeReg, objReg);
 
     pic.fastPathRejoin = masm.label();
     pic.objReg = objReg;
@@ -3315,21 +3328,20 @@ mjit::Compiler::jsop_callprop_obj(JSAtom
      * No type guard: type is asserted.
      */
     RETURN_IF_OOM(false);
 
     GetPropLabels &labels = pic.getPropLabels();
     labels.setDslotsLoadOffset(masm.differenceBetween(pic.fastPathRejoin, dslotsLoadLabel));
     labels.setInlineShapeOffset(masm.differenceBetween(pic.shapeGuard, inlineShapeLabel));
     labels.setValueLoad(masm, pic.fastPathRejoin, fastValueLoad);
-
-#if defined JS_NUNBOX32
-    JS_ASSERT(masm.differenceBetween(pic.shapeGuard, dbgInlineShapeJump) == GETPROP_INLINE_SHAPE_JUMP);
-#elif defined JS_PUNBOX64
-    JS_ASSERT(masm.differenceBetween(inlineShapeLabel, dbgInlineShapeJump) == GETPROP_INLINE_SHAPE_JUMP);
+#ifdef JS_CPU_X64
+    labels.setInlineShapeJump(masm, inlineShapeLabel, inlineShapeJump);
+#else
+    labels.setInlineShapeJump(masm, pic.shapeGuard, inlineShapeJump);
 #endif
 
     stubcc.rejoin(Changes(2));
     pics.append(pic);
 
     return true;
 }