[INFER] Disable inline paths for typed arrays on ARM and fix a regalloc problem, bug 663485. r=bhackett
authorJan de Mooij <jandemooij@gmail.com>
Tue, 12 Jul 2011 18:50:04 +0200
changeset 77345 b67c4240345870b7f65ba403a29468ab81ec59a5
parent 77344 0a10e83c2b3ac3376b20935c5fd7289712c6fa55
child 77346 8e009db2de15ed820e4a7c45346eeae3fb0f1a07
push id78
push userclegnitto@mozilla.com
push dateFri, 16 Dec 2011 17:32:24 +0000
treeherdermozilla-release@79d24e644fdd [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbhackett
bugs663485
milestone8.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
[INFER] Disable inline paths for typed arrays on ARM and fix a regalloc problem, bug 663485. r=bhackett
js/src/configure.in
js/src/jit-test/tests/basic/testTypedArrayByteRegs.js
js/src/methodjit/BaseAssembler.h
js/src/methodjit/Compiler.h
js/src/methodjit/FastOps.cpp
js/src/methodjit/PolyIC.cpp
js/src/methodjit/TypedArrayIC.h
--- a/js/src/configure.in
+++ b/js/src/configure.in
@@ -2731,27 +2731,27 @@ dnl Configure JIT support
 
 case "$target" in
 i?86-*)
     ENABLE_TRACEJIT=1
     NANOJIT_ARCH=i386
     ENABLE_METHODJIT=1
     ENABLE_MONOIC=1
     ENABLE_POLYIC=1
-    ENABLE_POLYIC_TYPED_ARRAY=1
+    ENABLE_METHODJIT_TYPED_ARRAY=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_TYPED_ARRAY=1
+    ENABLE_METHODJIT_TYPED_ARRAY=1
     AC_DEFINE(JS_CPU_X64)
     AC_DEFINE(JS_PUNBOX64)
     ;;
 arm*-*)
     ENABLE_TRACEJIT=1
     NANOJIT_ARCH=ARM
     ENABLE_METHODJIT=1
     ENABLE_MONOIC=1
@@ -2760,17 +2760,17 @@ arm*-*)
     AC_DEFINE(JS_NUNBOX32)
     ;;
 sparc*-*)
     ENABLE_TRACEJIT=1
     NANOJIT_ARCH=Sparc
     ENABLE_METHODJIT=1
     ENABLE_MONOIC=1
     ENABLE_POLYIC=1
-    ENABLE_POLYIC_TYPED_ARRAY=1
+    ENABLE_METHODJIT_TYPED_ARRAY=1
     AC_DEFINE(JS_CPU_SPARC)
     AC_DEFINE(JS_NUNBOX32)
     ;;
 esac
 
 MOZ_ARG_DISABLE_BOOL(methodjit,
 [  --disable-methodjit           Disable method JIT support],
   ENABLE_METHODJIT= )
@@ -2801,18 +2801,18 @@ fi
 if test "$ENABLE_MONOIC"; then
     AC_DEFINE(JS_MONOIC)
 fi
 
 if test "$ENABLE_POLYIC"; then
     AC_DEFINE(JS_POLYIC)
 fi
 
-if test "$ENABLE_POLYIC_TYPED_ARRAY"; then
-    AC_DEFINE(JS_POLYIC_TYPED_ARRAY)
+if test "$ENABLE_METHODJIT_TYPED_ARRAY"; then
+    AC_DEFINE(JS_METHODJIT_TYPED_ARRAY)
 fi
 
 if test "$ENABLE_METHODJIT_SPEW"; then
     AC_DEFINE(JS_METHODJIT_SPEW)
 fi
 
 if test "$ENABLE_TRACEJIT"; then
 
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/basic/testTypedArrayByteRegs.js
@@ -0,0 +1,30 @@
+// Uint8Array and Int8Array need single byte registers.
+// Test for id and value having the same backing.
+function f() {
+    var x = new Uint8Array(30);
+    for (var i=0; i<x.length; i++) {
+        x[i] = i;
+    }
+
+    var res = 0;
+    for (var i=0; i<x.length; i++) {
+        res += x[i];
+    }
+    assertEq(res, 435);
+}
+f();
+
+// Test for id and value having a different backing.
+function g() {
+    var x = new Int8Array(30);
+    for (var i=1; i<x.length; i++) {
+        x[i-1] = i;
+    }
+
+    var res = 0;
+    for (var i=0; i<x.length; i++) {
+        res += x[i];
+    }
+    assertEq(res, 435);
+}
+g();
--- a/js/src/methodjit/BaseAssembler.h
+++ b/js/src/methodjit/BaseAssembler.h
@@ -859,16 +859,17 @@ static const JSC::MacroAssembler::Regist
         if (shape->isMethod())
             loadValueAsComponents(ObjectValue(shape->methodObject()), typeReg, dataReg);
         else if (obj->isFixedSlot(shape->slot))
             loadInlineSlot(objReg, shape->slot, typeReg, dataReg);
         else
             loadDynamicSlot(objReg, obj->dynamicSlotIndex(shape->slot), typeReg, dataReg);
     }
 
+#ifdef JS_METHODJIT_TYPED_ARRAY
     // Load a value from a typed array's packed data vector into dataReg.
     // This function expects the following combinations of typeReg, dataReg and tempReg:
     // 1) for all INT arrays other than UINT32:
     //    - dataReg is a GP-register
     //    - typeReg is optional
     //    - tempReg is not set
     // 2) for UINT32:
     //    - dataReg is either a FP-register or a GP-register
@@ -1100,16 +1101,17 @@ static const JSC::MacroAssembler::Regist
         // It was a tie. Mask out the ones bit to get an even value.
         // See js_TypedArray_uint8_clamp_double for the reasoning behind this.
         and32(Imm32(~1), reg);
 
         done1.linkTo(label(), this);
         done2.linkTo(label(), this);
         done3.linkTo(label(), this);
     }
+#endif /* JS_METHODJIT_TYPED_ARRAY */
 
     Address objPropAddress(JSObject *obj, RegisterID objReg, uint32 slot)
     {
         if (obj->isFixedSlot(slot))
             return Address(objReg, JSObject::getFixedSlotOffset(slot));
         loadPtr(Address(objReg, JSObject::offsetOfSlots()), objReg);
         return Address(objReg, obj->dynamicSlotIndex(slot) * sizeof(Value));
     }
--- a/js/src/methodjit/Compiler.h
+++ b/js/src/methodjit/Compiler.h
@@ -700,23 +700,27 @@ class Compiler : public BaseCompiler
     bool jsop_andor(JSOp op, jsbytecode *target);
     bool jsop_arginc(JSOp op, uint32 slot);
     bool jsop_localinc(JSOp op, uint32 slot);
     bool jsop_newinit();
     void jsop_initmethod();
     void jsop_initprop();
     void jsop_initelem();
     void jsop_setelem_dense();
+#ifdef JS_METHODJIT_TYPED_ARRAY
     void jsop_setelem_typed(int atype);
     void convertForTypedArray(int atype, ValueRemat *vr, bool *allocated);
+#endif
     bool jsop_setelem(bool popGuaranteed);
     bool jsop_getelem(bool isCall);
     void jsop_getelem_dense(bool isPacked);
     void jsop_getelem_args();
+#ifdef JS_METHODJIT_TYPED_ARRAY
     void jsop_getelem_typed(int atype);
+#endif
     bool isCacheableBaseAndIndex(FrameEntry *obj, FrameEntry *id);
     void jsop_stricteq(JSOp op);
     bool jsop_equality(JSOp op, BoolStub stub, jsbytecode *target, JSOp fused);
     bool jsop_equality_int_string(JSOp op, BoolStub stub, jsbytecode *target, JSOp fused);
     void jsop_pos();
 
     static inline Assembler::Condition
     GetCompareCondition(JSOp op, JSOp fused)
--- a/js/src/methodjit/FastOps.cpp
+++ b/js/src/methodjit/FastOps.cpp
@@ -1189,16 +1189,17 @@ mjit::Compiler::jsop_setelem_dense()
     OOL_STUBCALL(STRICT_VARIANT(stubs::SetElem), REJOIN_FALLTHROUGH);
 
     if (!hoisted)
         frame.freeReg(slotsReg);
     frame.shimmy(2);
     stubcc.rejoin(Changes(2));
 }
 
+#ifdef JS_METHODJIT_TYPED_ARRAY
 void
 mjit::Compiler::convertForTypedArray(int atype, ValueRemat *vr, bool *allocated)
 {
     FrameEntry *value = frame.peek(-1);
     bool floatArray = (atype == TypedArray::TYPE_FLOAT32 ||
                        atype == TypedArray::TYPE_FLOAT64);
     *allocated = false;
 
@@ -1242,30 +1243,45 @@ mjit::Compiler::convertForTypedArray(int
             *vr = ValueRemat::FromFPRegister(fpReg);
         } else {
             /*
              * Allocate a register with the following properties:
              * 1) For byte arrays the value must be in a byte register.
              * 2) For Uint8ClampedArray the register must be writable.
              * 3) If the value is definitely int32 (and the array is not
              *    Uint8ClampedArray) we don't have to allocate a new register.
+             * 4) If id and value have the same backing (e.g. arr[i] = i) and
+             *    we need a byte register, we have to allocate a new register
+             *    because we've already pinned a key register and can't use
+             *    tempRegInMaskForData.
              */
             MaybeRegisterID reg;
             bool needsByteReg = (atype == TypedArray::TYPE_INT8 ||
                                  atype == TypedArray::TYPE_UINT8 ||
                                  atype == TypedArray::TYPE_UINT8_CLAMPED);
-            if (!value->isType(JSVAL_TYPE_INT32) || atype == TypedArray::TYPE_UINT8_CLAMPED) {
+            FrameEntry *id = frame.peek(-2);
+            if (!value->isType(JSVAL_TYPE_INT32) || atype == TypedArray::TYPE_UINT8_CLAMPED ||
+                (needsByteReg && frame.haveSameBacking(id, value))) {
+                // Pin value so that we don't evict it.
+                MaybeRegisterID dataReg;
+                if (value->mightBeType(JSVAL_TYPE_INT32) && !frame.haveSameBacking(id, value)) {
+                    dataReg = frame.tempRegForData(value);
+                    frame.pinReg(dataReg.reg());
+                }
+
                 // x86 has 4 single byte registers. Worst case we've pinned 3
                 // registers, one for each of object, key and value. This means
                 // there must be at least one single byte register available.
                 if (needsByteReg)
                     reg = frame.allocReg(Registers::SingleByteRegs).reg();
                 else
                     reg = frame.allocReg();
                 *allocated = true;
+                if (dataReg.isSet())
+                    frame.unpinReg(dataReg.reg());
             } else {
                 if (needsByteReg)
                     reg = frame.tempRegInMaskForData(value, Registers::SingleByteRegs).reg();
                 else
                     reg = frame.tempRegForData(value);
             }
 
             MaybeJump intDone;
@@ -1321,16 +1337,17 @@ mjit::Compiler::convertForTypedArray(int
                     frame.freeReg(fpReg);
             }
             if (intDone.isSet())
                 intDone.get().linkTo(masm.label(), &masm);
             *vr = ValueRemat::FromKnownType(JSVAL_TYPE_INT32, reg.reg());
         }
     }
 }
+
 void
 mjit::Compiler::jsop_setelem_typed(int atype)
 {
     FrameEntry *obj = frame.peek(-3);
     FrameEntry *id = frame.peek(-2);
     FrameEntry *value = frame.peek(-1);
 
     // We might not know whether this is an object, but if it is an object we
@@ -1341,53 +1358,54 @@ mjit::Compiler::jsop_setelem_typed(int a
     }
 
     // Test for integer index.
     if (!id->isTypeKnown()) {
         Jump guard = frame.testInt32(Assembler::NotEqual, id);
         stubcc.linkExit(guard, Uses(3));
     }
 
-    // Pin value. We don't use pinEntry here because it may also
-    // pin a type register and convertForTypedArray assumes we've
-    // pinned at most 3 registers (object, key and value).
-    MaybeRegisterID dataReg;
-    if (value->mightBeType(JSVAL_TYPE_INT32) && !value->isConstant()) {
-        dataReg = frame.tempRegForData(value);
-        frame.pinReg(dataReg.reg());
-    }
+    // Pin value.
+    ValueRemat vr;
+    frame.pinEntry(value, vr, /* breakDouble = */ false);
 
     // Allocate and pin object and key regs.
     Int32Key key = id->isConstant()
                  ? Int32Key::FromConstant(id->getValue().toInt32())
                  : Int32Key::FromRegister(frame.tempRegForData(id));
 
-    JS_ASSERT_IF(frame.haveSameBacking(id, value), dataReg.isSet());
     bool pinKey = !key.isConstant() && !frame.haveSameBacking(id, value);
     if (pinKey)
         frame.pinReg(key.reg());
     RegisterID objReg = frame.copyDataIntoReg(obj);
 
     // Get the internal typed array.
     masm.loadPtr(Address(objReg, offsetof(JSObject, privateData)), objReg);
 
     // Bounds check.
     Jump lengthGuard = masm.guardArrayExtent(TypedArray::lengthOffset(),
                                              objReg, key, Assembler::BelowOrEqual);
     stubcc.linkExit(lengthGuard, Uses(3));
 
     // Load the array's packed data vector.
     masm.loadPtr(Address(objReg, js::TypedArray::dataOffset()), objReg);
 
-    // Convert the value.
+    // Unpin value so that convertForTypedArray can assign a new data
+    // register using tempRegInMaskForData.
+    frame.unpinEntry(vr);
+
+    // Make sure key is pinned.
+    if (frame.haveSameBacking(id, value)) {
+        frame.pinReg(key.reg());
+        pinKey = true;
+    }
+    JS_ASSERT(pinKey == !id->isConstant());
+
     bool allocated;
-    ValueRemat vr;
     convertForTypedArray(atype, &vr, &allocated);
-    if (dataReg.isSet())
-        frame.unpinReg(dataReg.reg());
 
     // Store the value.
     masm.storeToTypedArray(atype, objReg, key, vr);
     if (allocated) {
         if (vr.isFPRegister())
             frame.freeReg(vr.fpReg());
         else
             frame.freeReg(vr.dataReg());
@@ -1397,16 +1415,17 @@ mjit::Compiler::jsop_setelem_typed(int a
     frame.freeReg(objReg);
 
     stubcc.leave();
     OOL_STUBCALL(STRICT_VARIANT(stubs::SetElem), REJOIN_FALLTHROUGH);
 
     frame.shimmy(2);
     stubcc.rejoin(Changes(2));
 }
+#endif /* JS_METHODJIT_TYPED_ARRAY */
 
 bool
 mjit::Compiler::jsop_setelem(bool popGuaranteed)
 {
     FrameEntry *obj = frame.peek(-3);
     FrameEntry *id = frame.peek(-2);
     FrameEntry *value = frame.peek(-1);
 
@@ -1423,26 +1442,29 @@ mjit::Compiler::jsop_setelem(bool popGua
         types::TypeSet *types = analysis->poppedTypes(PC, 2);
 
         if (!types->hasObjectFlags(cx, types::OBJECT_FLAG_NON_DENSE_ARRAY) &&
             !arrayPrototypeHasIndexedProperty()) {
             // Inline dense array path.
             jsop_setelem_dense();
             return true;
         }
+
+#ifdef JS_METHODJIT_TYPED_ARRAY
         if (!types->hasObjectFlags(cx, types::OBJECT_FLAG_NON_TYPED_ARRAY) &&
             (value->mightBeType(JSVAL_TYPE_INT32) || value->mightBeType(JSVAL_TYPE_DOUBLE))) {
             // Inline typed array path. Look at the proto to determine the typed array type.
             if (types::TypeObject *objType = types->getSingleObject()) {
                 int atype = objType->proto->getClass() - TypedArray::slowClasses;
                 JS_ASSERT(atype >= 0 && atype < TypedArray::TYPE_MAX);
                 jsop_setelem_typed(atype);
                 return true;
             }
         }
+#endif
     }
 
     SetElementICInfo ic = SetElementICInfo(JSOp(*PC));
 
     // One by one, check if the most important stack entries have registers,
     // and if so, pin them. This is to avoid spilling and reloading from the
     // stack as we incrementally allocate other registers.
     MaybeRegisterID pinnedValueType = frame.maybePinType(value);
@@ -1809,16 +1831,17 @@ mjit::Compiler::jsop_getelem_args()
     frame.pushRegs(typeReg, dataReg, knownPushedType(0));
     BarrierState barrier = testBarrier(typeReg, dataReg, false);
 
     stubcc.rejoin(Changes(2));
 
     finishBarrier(barrier, REJOIN_FALLTHROUGH, 0);
 }
 
+#ifdef JS_METHODJIT_TYPED_ARRAY
 void
 mjit::Compiler::jsop_getelem_typed(int atype)
 {
     FrameEntry *obj = frame.peek(-2);
     FrameEntry *id = frame.peek(-1);
 
     // We might not know whether this is an object, but if it's an object we
     // know it is a typed array.
@@ -1905,16 +1928,17 @@ mjit::Compiler::jsop_getelem_typed(int a
     } else {
         JS_ASSERT(type == JSVAL_TYPE_INT32);
         frame.pushTypedPayload(JSVAL_TYPE_INT32, dataReg.reg());
     }
     stubcc.rejoin(Changes(2));
 
     finishBarrier(barrier, REJOIN_FALLTHROUGH, 0);
 }
+#endif /* JS_METHODJIT_TYPED_ARRAY */
 
 bool
 mjit::Compiler::jsop_getelem(bool isCall)
 {
     FrameEntry *obj = frame.peek(-2);
     FrameEntry *id = frame.peek(-1);
 
     if (!IsCacheableGetElem(obj, id)) {
@@ -1929,34 +1953,38 @@ mjit::Compiler::jsop_getelem(bool isCall
     // we can generate code directly without using an inline cache.
     if (cx->typeInferenceEnabled() && id->mightBeType(JSVAL_TYPE_INT32) && !isCall) {
         types::TypeSet *types = analysis->poppedTypes(PC, 1);
         if (types->isLazyArguments(cx) && !outerScript->analysis(cx)->modifiesArguments()) {
             // Inline arguments path.
             jsop_getelem_args();
             return true;
         }
+
         if (obj->mightBeType(JSVAL_TYPE_OBJECT) &&
             !types->hasObjectFlags(cx, types::OBJECT_FLAG_NON_DENSE_ARRAY) &&
             !arrayPrototypeHasIndexedProperty()) {
             // Inline dense array path.
             bool packed = !types->hasObjectFlags(cx, types::OBJECT_FLAG_NON_PACKED_ARRAY);
             jsop_getelem_dense(packed);
             return true;
         }
+
+#ifdef JS_METHODJIT_TYPED_ARRAY
         if (obj->mightBeType(JSVAL_TYPE_OBJECT) &&
             !types->hasObjectFlags(cx, types::OBJECT_FLAG_NON_TYPED_ARRAY)) {
             // Inline typed array path. Look at the proto to determine the typed array type.
             if (types::TypeObject *objType = types->getSingleObject()) {
                 int atype = objType->proto->getClass() - TypedArray::slowClasses;
                 JS_ASSERT(atype >= 0 && atype < TypedArray::TYPE_MAX);
                 jsop_getelem_typed(atype);
                 return true;
             }
         }
+#endif
     }
 
     frame.forgetMismatchedObject(obj);
 
     GetElementICInfo ic = GetElementICInfo(JSOp(*PC));
 
     // Pin the top of the stack to avoid spills, before allocating registers.
     MaybeRegisterID pinnedIdData = frame.maybePinData(id);
--- a/js/src/methodjit/PolyIC.cpp
+++ b/js/src/methodjit/PolyIC.cpp
@@ -2420,17 +2420,17 @@ GetElementIC::attachGetProp(VMFrame &f, 
     if (shape->isMethod())
         *vp = ObjectValue(shape->methodObject());
     else
         *vp = holder->getSlot(shape->slot);
 
     return Lookup_Cacheable;
 }
 
-#if defined JS_POLYIC_TYPED_ARRAY
+#if defined JS_METHODJIT_TYPED_ARRAY
 LookupStatus
 GetElementIC::attachTypedArray(JSContext *cx, JSObject *obj, const Value &v, jsid id, Value *vp)
 {
     if (!v.isInt32())
         return disable(cx, "typed array with string key");
 
     if (op == JSOP_CALLELEM)
         return disable(cx, "typed array with call");
@@ -2503,25 +2503,25 @@ GetElementIC::attachTypedArray(JSContext
     disable(cx, "generated typed array stub");
 
     // Fetch the value as expected of Lookup_Cacheable for GetElement.
     if (!obj->getProperty(cx, id, vp))
         return Lookup_Error;
 
     return Lookup_Cacheable;
 }
-#endif /* JS_POLYIC_TYPED_ARRAY */
+#endif /* JS_METHODJIT_TYPED_ARRAY */
 
 LookupStatus
 GetElementIC::update(VMFrame &f, JSContext *cx, JSObject *obj, const Value &v, jsid id, Value *vp)
 {
     if (v.isString())
         return attachGetProp(f, cx, obj, v, id, vp);
 
-#if defined JS_POLYIC_TYPED_ARRAY
+#if defined JS_METHODJIT_TYPED_ARRAY
     /*
      * Typed array ICs can make stub calls, and need to know which registers
      * are in use and need to be restored after the call. If type inference is
      * enabled then we don't necessarily know the full set of such registers
      * when generating the IC (loop-carried registers may be allocated later),
      * and additionally the push/pop instructions used to save/restore in the
      * IC are not compatible with carrying entries in floating point registers.
      * Since we can use type information to generate inline paths for typed
@@ -2778,17 +2778,17 @@ SetElementIC::attachHoleStub(JSContext *
     repatcher.relink(fastPathStart.jumpAtOffset(inlineHoleGuard), cs);
     inlineHoleGuardPatched = true;
 
     disable(cx, "generated dense array hole stub");
 
     return Lookup_Cacheable;
 }
 
-#if defined JS_POLYIC_TYPED_ARRAY
+#if defined JS_METHODJIT_TYPED_ARRAY
 LookupStatus
 SetElementIC::attachTypedArray(JSContext *cx, JSObject *obj, int32 key)
 {
     // Right now, only one clasp guard extension is supported.
     JS_ASSERT(!inlineClaspGuardPatched);
 
     Assembler masm;
 
@@ -2866,33 +2866,33 @@ SetElementIC::attachTypedArray(JSContext
     // For simplicitly, they are currently monomorphic.
     if (stubsGenerated == MAX_GETELEM_IC_STUBS)
         disable(cx, "max stubs reached");
 
     disable(cx, "generated typed array stub");
 
     return Lookup_Cacheable;
 }
-#endif /* JS_POLYIC_TYPED_ARRAY */
+#endif /* JS_METHODJIT_TYPED_ARRAY */
 
 LookupStatus
 SetElementIC::update(JSContext *cx, const Value &objval, const Value &idval)
 {
     if (!objval.isObject())
         return disable(cx, "primitive lval");
     if (!idval.isInt32())
         return disable(cx, "non-int32 key");
 
     JSObject *obj = &objval.toObject();
     int32 key = idval.toInt32();
 
     if (obj->isDenseArray())
         return attachHoleStub(cx, obj, key);
 
-#if defined JS_POLYIC_TYPED_ARRAY
+#if defined JS_METHODJIT_TYPED_ARRAY
     /* Not attaching typed array stubs with linear scan allocator, see GetElementIC. */
     if (!cx->typeInferenceEnabled() && js_IsTypedArray(obj))
         return attachTypedArray(cx, obj, key);
 #endif
 
     return disable(cx, "unsupported object type");
 }
 
--- a/js/src/methodjit/TypedArrayIC.h
+++ b/js/src/methodjit/TypedArrayIC.h
@@ -44,17 +44,17 @@
 #include "jstypedarray.h"
 #include "jstypedarrayinlines.h"
 
 #include "jsnuminlines.h"
 
 namespace js {
 namespace mjit {
 
-#ifdef JS_POLYIC_TYPED_ARRAY
+#ifdef JS_METHODJIT_TYPED_ARRAY
 
 typedef JSC::MacroAssembler::RegisterID RegisterID;
 typedef JSC::MacroAssembler::FPRegisterID FPRegisterID;
 typedef JSC::MacroAssembler::Jump Jump;
 typedef JSC::MacroAssembler::Imm32 Imm32;
 typedef JSC::MacroAssembler::ImmDouble ImmDouble;
 
 static inline bool
@@ -425,15 +425,15 @@ StoreToTypedArray(JSContext *cx, Assembl
             masm.storeToTypedFloatArray(tarray->type, temp, address);
         break;
       }
     }
 
     return true;
 }
 
-#endif // defined(JS_POLYIC) && (defined JS_CPU_X86 || defined JS_CPU_X64)
+#endif /* JS_METHODJIT_TYPED_ARRAY */
 
 } /* namespace mjit */
 } /* namespace js */
 
 #endif /* js_typedarray_ic_h___ */