[INFER] Reenable typed array ICs when inference is disabled, bug 643842.
authorBrian Hackett <bhackett1024@gmail.com>
Wed, 15 Jun 2011 08:29:33 -0700
changeset 75162 152b2b6e6fb9007a6d4199200703a8dc68a85554
parent 75161 f59a6cabfbd4aa07d23fd02320fa3348583556ea
child 75163 0767b119a1c8aa09216db8d347d06ae28cf87de8
push id2
push userbsmedberg@mozilla.com
push dateFri, 19 Aug 2011 14:38:13 +0000
bugs643842
milestone7.0a1
[INFER] Reenable typed array ICs when inference is disabled, bug 643842.
js/src/methodjit/PolyIC.cpp
js/src/methodjit/TypedArrayIC.h
--- a/js/src/methodjit/PolyIC.cpp
+++ b/js/src/methodjit/PolyIC.cpp
@@ -2502,19 +2502,28 @@ GetElementIC::attachTypedArray(JSContext
 #endif /* JS_POLYIC_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 0 // :FIXME: bug 643842
-//#if defined JS_POLYIC_TYPED_ARRAY
-    if (js_IsTypedArray(obj))
+#if defined JS_POLYIC_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
+     * arrays, just don't generate these ICs with inference enabled.
+     */
+    if (!cx->typeInferenceEnabled() && js_IsTypedArray(obj))
         return attachTypedArray(cx, obj, v, id, vp);
 #endif
 
     return disable(cx, "unhandled object and key type");
 }
 
 void JS_FASTCALL
 ic::CallElement(VMFrame &f, ic::GetElementIC *ic)
@@ -2864,19 +2873,19 @@ SetElementIC::update(JSContext *cx, cons
         return disable(cx, "non-int32 key");
 
     JSObject *obj = &objval.toObject();
     int32 key = idval.toInt32();
 
     if (obj->isDenseArray())
         return attachHoleStub(cx, obj, key);
 
-#if 0 // :FIXME: bug 643842
-//#if defined JS_POLYIC_TYPED_ARRAY
-    if (js_IsTypedArray(obj))
+#if defined JS_POLYIC_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");
 }
 
 template<JSBool strict>
 void JS_FASTCALL
--- a/js/src/methodjit/TypedArrayIC.h
+++ b/js/src/methodjit/TypedArrayIC.h
@@ -313,18 +313,17 @@ GenConversionForIntArray(Assembler &masm
     }
 }
 
 // Generate code that will ensure a dynamically typed value, pinned in |vr|,
 // can be stored in an integer typed array.  saveMask| is used to ensure that
 // |dataReg| (and volatile registers) are preserved across any conversion
 // process.
 //
-// Constants are left untouched. Any other value is placed into
-// Registers::FPConversionTemp.
+// Constants are left untouched. Any other value is placed into destReg.
 static void
 GenConversionForFloatArray(Assembler &masm, js::TypedArray *tarray, const ValueRemat &vr,
                            FPRegisterID destReg, uint32 saveMask)
 {
     if (vr.isConstant()) {
         // Constants are always folded to doubles up-front.
         JS_ASSERT(vr.knownType() == JSVAL_TYPE_DOUBLE);
         return;
@@ -518,25 +517,33 @@ StoreToTypedArray(JSContext *cx, Assembl
 
         // Note that this will finish restoring the damage from the
         // earlier register swap.
         saveRHS.restore();
         break;
       }
 
       case js::TypedArray::TYPE_FLOAT32:
-      case js::TypedArray::TYPE_FLOAT64:
+      case js::TypedArray::TYPE_FLOAT64: {
+        /*
+         * Use a temporary for conversion. Inference is disabled, so no FP
+         * registers are live.
+         */
+        Registers regs(Registers::TempFPRegs);
+        FPRegisterID temp = regs.takeAnyReg().fpreg();
+
         if (!ConstantFoldForFloatArray(cx, &vr))
             return false;
-        GenConversionForFloatArray(masm, tarray, vr, Registers::FPConversionTemp, saveMask);
+        GenConversionForFloatArray(masm, tarray, vr, temp, saveMask);
         if (vr.isConstant())
             StoreToFloatArray(masm, tarray, ImmDouble(vr.value().toDouble()), address);
         else
-            StoreToFloatArray(masm, tarray, Registers::FPConversionTemp, address);
+            StoreToFloatArray(masm, tarray, temp, address);
         break;
+      }
     }
 
     return true;
 }
 
 #endif // defined(JS_POLYIC) && (defined JS_CPU_X86 || defined JS_CPU_X64)
 
 } /* namespace mjit */