[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 76034 b67c4240345870b7f65ba403a29468ab81ec59a5
parent 76033 0a10e83c2b3ac3376b20935c5fd7289712c6fa55
child 76035 8e009db2de15ed820e4a7c45346eeae3fb0f1a07
push id3
push userfelipc@gmail.com
push dateFri, 30 Sep 2011 20:09:13 +0000
reviewersbhackett
bugs663485
milestone8.0a1
[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___ */