diff --git a/js/src/ion/MCallOptimize.cpp b/js/src/ion/MCallOptimize.cpp index 581603541d1..8f2e33843c5 100644 --- a/js/src/ion/MCallOptimize.cpp +++ b/js/src/ion/MCallOptimize.cpp @@ -880,15 +880,15 @@ IonBuilder::inlineUnsafeSetElement(CallInfo &callInfo) */ for (uint32_t base = 0; base < argc; base += 3) { - uint32_t arri = base + 1; - uint32_t idxi = base + 2; + uint32_t arri = base + 0; + uint32_t idxi = base + 1; types::StackTypeSet *obj = getInlineArgTypeSet(callInfo, arri); types::StackTypeSet *id = getInlineArgTypeSet(callInfo, idxi); int arrayType; - if (!oracle->elementAccessIsDenseNative(obj, id) && - !oracle->elementAccessIsTypedArray(obj, id, &arrayType)) + if (!oracle->elementWriteIsDenseNative(obj, id) && + !oracle->elementWriteIsTypedArray(obj, id, &arrayType)) { return InliningStatus_NotInlined; } @@ -903,20 +903,20 @@ IonBuilder::inlineUnsafeSetElement(CallInfo &callInfo) current->push(udef); for (uint32_t base = 0; base < argc; base += 3) { - uint32_t arri = base + 1; - uint32_t idxi = base + 2; + uint32_t arri = base + 0; + uint32_t idxi = base + 1; types::StackTypeSet *obj = getInlineArgTypeSet(callInfo, arri); types::StackTypeSet *id = getInlineArgTypeSet(callInfo, idxi); - if (oracle->elementAccessIsDenseNative(obj, id)) { + if (oracle->elementWriteIsDenseNative(obj, id)) { if (!inlineUnsafeSetDenseArrayElement(callInfo, base)) return InliningStatus_Error; continue; } int arrayType; - if (oracle->elementAccessIsTypedArray(obj, id, &arrayType)) { + if (oracle->elementWriteIsTypedArray(obj, id, &arrayType)) { if (!inlineUnsafeSetTypedArrayElement(callInfo, base, arrayType)) return InliningStatus_Error; continue; @@ -938,9 +938,9 @@ IonBuilder::inlineUnsafeSetDenseArrayElement(CallInfo &callInfo, uint32_t base) // Furthermore, note that inference should be propagating // the type of the value to the JSID_VOID property of the array. - uint32_t arri = base + 1; - uint32_t idxi = base + 2; - uint32_t elemi = base + 3; + uint32_t arri = base + 0; + uint32_t idxi = base + 1; + uint32_t elemi = base + 2; MElements *elements = MElements::New(callInfo.getArg(arri)); current->add(elements); @@ -1073,8 +1073,10 @@ IonBuilder::inlineNewDenseArrayForParallelExecution(CallInfo &callInfo) return InliningStatus_Error; templateObject->setType(typeObject); + callInfo.unwrapArgs(); + MParNewDenseArray *newObject = new MParNewDenseArray(graph().parSlice(), - callInfo.getArg(1), + callInfo.getArg(0), templateObject); current->add(newObject); current->push(newObject); diff --git a/js/src/ion/TypeOracle.cpp b/js/src/ion/TypeOracle.cpp index 82671c55852..aaa2ad3cb19 100644 --- a/js/src/ion/TypeOracle.cpp +++ b/js/src/ion/TypeOracle.cpp @@ -290,19 +290,32 @@ TypeInferenceOracle::inArrayIsPacked(UnrootedScript script, jsbytecode *pc) bool TypeInferenceOracle::elementReadIsDenseNative(RawScript script, jsbytecode *pc) { - return elementAccessIsDenseNative(script->analysis()->poppedTypes(pc, 1), - script->analysis()->poppedTypes(pc, 0)); + // Check whether the object is a dense array and index is int32 or double. + StackTypeSet *obj = script->analysis()->poppedTypes(pc, 1); + StackTypeSet *id = script->analysis()->poppedTypes(pc, 0); + + JSValueType idType = id->getKnownTypeTag(); + if (idType != JSVAL_TYPE_INT32 && idType != JSVAL_TYPE_DOUBLE) + return false; + + Class *clasp = obj->getKnownClass(); + return clasp && clasp->isNative(); } bool TypeInferenceOracle::elementReadIsTypedArray(RawScript script, jsbytecode *pc, int *arrayType) { - if (!elementAccessIsTypedArray(script->analysis()->poppedTypes(pc, 1), - script->analysis()->poppedTypes(pc, 0), - arrayType)) - { + // Check whether the object is a typed array and index is int32 or double. + StackTypeSet *obj = script->analysis()->poppedTypes(pc, 1); + StackTypeSet *id = DropUnrooted(script)->analysis()->poppedTypes(pc, 0); + + JSValueType idType = id->getKnownTypeTag(); + if (idType != JSVAL_TYPE_INT32 && idType != JSVAL_TYPE_DOUBLE) + return false; + + *arrayType = obj->getTypedArrayType(); + if (*arrayType == TypedArray::TYPE_MAX) return false; - } JS_ASSERT(*arrayType >= 0 && *arrayType < TypedArray::TYPE_MAX); @@ -393,13 +406,14 @@ TypeInferenceOracle::elementReadGeneric(UnrootedScript script, jsbytecode *pc, b bool TypeInferenceOracle::elementWriteIsDenseNative(HandleScript script, jsbytecode *pc) { - return elementAccessIsDenseNative(script->analysis()->poppedTypes(pc, 2), + return elementWriteIsDenseNative(script->analysis()->poppedTypes(pc, 2), script->analysis()->poppedTypes(pc, 1)); } bool -TypeInferenceOracle::elementAccessIsDenseNative(StackTypeSet *obj, StackTypeSet *id) +TypeInferenceOracle::elementWriteIsDenseNative(StackTypeSet *obj, StackTypeSet *id) { + // Check whether the object is a dense array and index is int32 or double. JSValueType idType = id->getKnownTypeTag(); if (idType != JSVAL_TYPE_INT32 && idType != JSVAL_TYPE_DOUBLE) return false; @@ -414,16 +428,15 @@ TypeInferenceOracle::elementAccessIsDenseNative(StackTypeSet *obj, StackTypeSet bool TypeInferenceOracle::elementWriteIsTypedArray(RawScript script, jsbytecode *pc, int *arrayType) { - return elementAccessIsTypedArray(script->analysis()->poppedTypes(pc, 2), - script->analysis()->poppedTypes(pc, 1), - arrayType); + return elementWriteIsTypedArray(script->analysis()->poppedTypes(pc, 2), + script->analysis()->poppedTypes(pc, 1), + arrayType); } bool -TypeInferenceOracle::elementAccessIsTypedArray(StackTypeSet *obj, StackTypeSet *id, int *arrayType) +TypeInferenceOracle::elementWriteIsTypedArray(StackTypeSet *obj, StackTypeSet *id, int *arrayType) { // Check whether the object is a typed array and index is int32 or double. - JSValueType idType = id->getKnownTypeTag(); if (idType != JSVAL_TYPE_INT32 && idType != JSVAL_TYPE_DOUBLE) return false; diff --git a/js/src/ion/TypeOracle.h b/js/src/ion/TypeOracle.h index 7a57b33cc01..380b2ce9525 100644 --- a/js/src/ion/TypeOracle.h +++ b/js/src/ion/TypeOracle.h @@ -111,9 +111,15 @@ class TypeOracle virtual bool elementWriteIsDenseNative(HandleScript script, jsbytecode *pc) { return false; } + virtual bool elementWriteIsDenseNative(types::StackTypeSet *obj, types::StackTypeSet *id) { + return false; + } virtual bool elementWriteIsTypedArray(RawScript script, jsbytecode *pc, int *arrayType) { return false; } + virtual bool elementWriteIsTypedArray(types::StackTypeSet *obj, types::StackTypeSet *id, int *arrayType) { + return false; + } virtual bool elementWriteNeedsDoubleConversion(UnrootedScript script, jsbytecode *pc) { return false; } @@ -123,12 +129,6 @@ class TypeOracle virtual bool elementWriteIsPacked(RawScript script, jsbytecode *pc) { return false; } - virtual bool elementAccessIsDenseNative(types::StackTypeSet *obj, types::StackTypeSet *id) { - return false; - } - virtual bool elementAccessIsTypedArray(types::StackTypeSet *obj, types::StackTypeSet *id, int *arrayType) { - return false; - } virtual bool arrayResultShouldHaveDoubleConversion(UnrootedScript script, jsbytecode *pc) { return false; } @@ -259,9 +259,9 @@ class TypeInferenceOracle : public TypeOracle bool elementReadIsPacked(UnrootedScript script, jsbytecode *pc); void elementReadGeneric(UnrootedScript script, jsbytecode *pc, bool *cacheable, bool *monitorResult, bool *intIndex); bool elementWriteIsDenseNative(HandleScript script, jsbytecode *pc); - bool elementAccessIsDenseNative(types::StackTypeSet *obj, types::StackTypeSet *id); + bool elementWriteIsDenseNative(types::StackTypeSet *obj, types::StackTypeSet *id); bool elementWriteIsTypedArray(RawScript script, jsbytecode *pc, int *arrayType); - bool elementAccessIsTypedArray(types::StackTypeSet *obj, types::StackTypeSet *id, int *arrayType); + bool elementWriteIsTypedArray(types::StackTypeSet *obj, types::StackTypeSet *id, int *arrayType); bool elementWriteNeedsDoubleConversion(UnrootedScript script, jsbytecode *pc); bool elementWriteHasExtraIndexedProperty(RawScript script, jsbytecode *pc); bool elementWriteIsPacked(RawScript script, jsbytecode *pc);