diff options
author | Moonchild <git-repo@palemoon.org> | 2020-02-26 02:38:18 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-02-26 02:38:18 +0100 |
commit | cce2bc96771613f51659e9209181e0d54a3fee96 (patch) | |
tree | cbeec2384bd44bab37cd787215ec830fa8b356cd /js/src/jit/MCallOptimize.cpp | |
parent | 35c26c6c19e66fabcb230fb074e76e243df04d2b (diff) | |
parent | ecdeefc4dd5624e824e696ac1c492c0b103f4acd (diff) | |
download | UXP-cce2bc96771613f51659e9209181e0d54a3fee96.tar UXP-cce2bc96771613f51659e9209181e0d54a3fee96.tar.gz UXP-cce2bc96771613f51659e9209181e0d54a3fee96.tar.lz UXP-cce2bc96771613f51659e9209181e0d54a3fee96.tar.xz UXP-cce2bc96771613f51659e9209181e0d54a3fee96.zip |
Merge pull request #1461 from MoonchildProductions/ubbo
Back out unboxed array/object removals
Diffstat (limited to 'js/src/jit/MCallOptimize.cpp')
-rw-r--r-- | js/src/jit/MCallOptimize.cpp | 90 |
1 files changed, 67 insertions, 23 deletions
diff --git a/js/src/jit/MCallOptimize.cpp b/js/src/jit/MCallOptimize.cpp index 236354530..f2071dc6a 100644 --- a/js/src/jit/MCallOptimize.cpp +++ b/js/src/jit/MCallOptimize.cpp @@ -30,6 +30,7 @@ #include "jit/shared/Lowering-shared-inl.h" #include "vm/NativeObject-inl.h" #include "vm/StringObject-inl.h" +#include "vm/UnboxedObject-inl.h" using mozilla::ArrayLength; using mozilla::AssertedCast; @@ -470,6 +471,11 @@ IonBuilder::inlineArray(CallInfo& callInfo) return InliningStatus_NotInlined; } + if (templateObject->is<UnboxedArrayObject>()) { + if (templateObject->group()->unboxedLayout().nativeGroup()) + return InliningStatus_NotInlined; + } + // Multiple arguments imply array initialization, not just construction. if (callInfo.argc() >= 2) { initLength = callInfo.argc(); @@ -517,7 +523,7 @@ IonBuilder::inlineArray(CallInfo& callInfo) // Make sure initLength matches the template object's length. This is // not guaranteed to be the case, for instance if we're inlining the // MConstant may come from an outer script. - if (initLength != templateObject->as<ArrayObject>().length()) + if (initLength != GetAnyBoxedOrUnboxedArrayLength(templateObject)) return InliningStatus_NotInlined; // Don't inline large allocations. @@ -532,15 +538,16 @@ IonBuilder::inlineArray(CallInfo& callInfo) MDefinition* array = current->peek(-1); if (callInfo.argc() >= 2) { + JSValueType unboxedType = GetBoxedOrUnboxedType(templateObject); for (uint32_t i = 0; i < initLength; i++) { if (!alloc().ensureBallast()) return InliningStatus_Error; MDefinition* value = callInfo.getArg(i); - if (!initializeArrayElement(array, i, value, /* addResumePoint = */ false)) + if (!initializeArrayElement(array, i, value, unboxedType, /* addResumePoint = */ false)) return InliningStatus_Error; } - MInstruction* setLength = setInitializedLength(array, initLength); + MInstruction* setLength = setInitializedLength(array, unboxedType, initLength); if (!resumeAfter(setLength)) return InliningStatus_Error; } @@ -573,7 +580,7 @@ IonBuilder::inlineArrayIsArray(CallInfo& callInfo) if (!clasp || clasp->isProxy()) return InliningStatus_NotInlined; - isArray = (clasp == &ArrayObject::class_); + isArray = (clasp == &ArrayObject::class_ || clasp == &UnboxedArrayObject::class_); } pushConstant(BooleanValue(isArray)); @@ -604,12 +611,12 @@ IonBuilder::inlineArrayPopShift(CallInfo& callInfo, MArrayPopShift::Mode mode) OBJECT_FLAG_LENGTH_OVERFLOW | OBJECT_FLAG_ITERATED; - MDefinition* obj = callInfo.thisArg(); + MDefinition* obj = convertUnboxedObjects(callInfo.thisArg()); TemporaryTypeSet* thisTypes = obj->resultTypeSet(); if (!thisTypes) return InliningStatus_NotInlined; const Class* clasp = thisTypes->getKnownClass(constraints()); - if (clasp != &ArrayObject::class_) + if (clasp != &ArrayObject::class_ && clasp != &UnboxedArrayObject::class_) return InliningStatus_NotInlined; if (thisTypes->hasObjectFlags(constraints(), unhandledFlags)) { trackOptimizationOutcome(TrackedOutcome::ArrayBadFlags); @@ -622,9 +629,17 @@ IonBuilder::inlineArrayPopShift(CallInfo& callInfo, MArrayPopShift::Mode mode) return InliningStatus_NotInlined; } + JSValueType unboxedType = JSVAL_TYPE_MAGIC; + if (clasp == &UnboxedArrayObject::class_) { + unboxedType = UnboxedArrayElementType(constraints(), obj, nullptr); + if (unboxedType == JSVAL_TYPE_MAGIC) + return InliningStatus_NotInlined; + } + callInfo.setImplicitlyUsedUnchecked(); - obj = addMaybeCopyElementsForWrite(obj, /* checkNative = */ false); + if (clasp == &ArrayObject::class_) + obj = addMaybeCopyElementsForWrite(obj, /* checkNative = */ false); TemporaryTypeSet* returnTypes = getInlineReturnTypeSet(); bool needsHoleCheck = thisTypes->hasObjectFlags(constraints(), OBJECT_FLAG_NON_PACKED); @@ -635,7 +650,8 @@ IonBuilder::inlineArrayPopShift(CallInfo& callInfo, MArrayPopShift::Mode mode) if (barrier != BarrierKind::NoBarrier) returnType = MIRType::Value; - MArrayPopShift* ins = MArrayPopShift::New(alloc(), obj, mode, needsHoleCheck, maybeUndefined); + MArrayPopShift* ins = MArrayPopShift::New(alloc(), obj, mode, + unboxedType, needsHoleCheck, maybeUndefined); current->add(ins); current->push(ins); ins->setResultType(returnType); @@ -684,7 +700,7 @@ IonBuilder::inlineArrayPush(CallInfo& callInfo) return InliningStatus_NotInlined; } - MDefinition* obj = callInfo.thisArg(); + MDefinition* obj = convertUnboxedObjects(callInfo.thisArg()); MDefinition* value = callInfo.getArg(0); if (PropertyWriteNeedsTypeBarrier(alloc(), constraints(), current, &obj, nullptr, &value, /* canModify = */ false)) @@ -717,6 +733,13 @@ IonBuilder::inlineArrayPush(CallInfo& callInfo) return InliningStatus_NotInlined; } + JSValueType unboxedType = JSVAL_TYPE_MAGIC; + if (clasp == &UnboxedArrayObject::class_) { + unboxedType = UnboxedArrayElementType(constraints(), obj, nullptr); + if (unboxedType == JSVAL_TYPE_MAGIC) + return InliningStatus_NotInlined; + } + callInfo.setImplicitlyUsedUnchecked(); if (conversion == TemporaryTypeSet::AlwaysConvertToDoubles || @@ -727,12 +750,13 @@ IonBuilder::inlineArrayPush(CallInfo& callInfo) value = valueDouble; } - obj = addMaybeCopyElementsForWrite(obj, /* checkNative = */ false); + if (unboxedType == JSVAL_TYPE_MAGIC) + obj = addMaybeCopyElementsForWrite(obj, /* checkNative = */ false); if (NeedsPostBarrier(value)) current->add(MPostWriteBarrier::New(alloc(), obj, value)); - MArrayPush* ins = MArrayPush::New(alloc(), obj, value); + MArrayPush* ins = MArrayPush::New(alloc(), obj, value, unboxedType); current->add(ins); current->push(ins); @@ -749,7 +773,7 @@ IonBuilder::inlineArraySlice(CallInfo& callInfo) return InliningStatus_NotInlined; } - MDefinition* obj = callInfo.thisArg(); + MDefinition* obj = convertUnboxedObjects(callInfo.thisArg()); // Ensure |this| and result are objects. if (getInlineReturnType() != MIRType::Object) @@ -773,9 +797,16 @@ IonBuilder::inlineArraySlice(CallInfo& callInfo) return InliningStatus_NotInlined; const Class* clasp = thisTypes->getKnownClass(constraints()); - if (clasp != &ArrayObject::class_) + if (clasp != &ArrayObject::class_ && clasp != &UnboxedArrayObject::class_) return InliningStatus_NotInlined; + JSValueType unboxedType = JSVAL_TYPE_MAGIC; + if (clasp == &UnboxedArrayObject::class_) { + unboxedType = UnboxedArrayElementType(constraints(), obj, nullptr); + if (unboxedType == JSVAL_TYPE_MAGIC) + return InliningStatus_NotInlined; + } + // Watch out for indexed properties on the object or its prototype. if (ElementAccessHasExtraIndexedProperty(this, obj)) { trackOptimizationOutcome(TrackedOutcome::ProtoIndexedProps); @@ -796,8 +827,15 @@ IonBuilder::inlineArraySlice(CallInfo& callInfo) if (!templateObj) return InliningStatus_NotInlined; - if (!templateObj->is<ArrayObject>()) - return InliningStatus_NotInlined; + if (unboxedType == JSVAL_TYPE_MAGIC) { + if (!templateObj->is<ArrayObject>()) + return InliningStatus_NotInlined; + } else { + if (!templateObj->is<UnboxedArrayObject>()) + return InliningStatus_NotInlined; + if (templateObj->as<UnboxedArrayObject>().elementType() != unboxedType) + return InliningStatus_NotInlined; + } callInfo.setImplicitlyUsedUnchecked(); @@ -816,12 +854,16 @@ IonBuilder::inlineArraySlice(CallInfo& callInfo) end = MArrayLength::New(alloc(), elements); current->add(end->toInstruction()); + } else { + end = MUnboxedArrayLength::New(alloc(), obj); + current->add(end->toInstruction()); } MArraySlice* ins = MArraySlice::New(alloc(), constraints(), obj, begin, end, templateObj, - templateObj->group()->initialHeap(constraints())); + templateObj->group()->initialHeap(constraints()), + unboxedType); current->add(ins); current->push(ins); @@ -1340,7 +1382,7 @@ IonBuilder::inlineConstantStringSplitString(CallInfo& callInfo) // Check if exist a template object in stub. JSString* stringStr = nullptr; JSString* stringSep = nullptr; - ArrayObject* templateObject = nullptr; + JSObject* templateObject = nullptr; if (!inspector->isOptimizableCallStringSplit(pc, &stringStr, &stringSep, &templateObject)) return InliningStatus_NotInlined; @@ -1366,13 +1408,13 @@ IonBuilder::inlineConstantStringSplitString(CallInfo& callInfo) if (!key.maybeTypes()->hasType(TypeSet::StringType())) return InliningStatus_NotInlined; - uint32_t initLength = templateObject->length(); - if (templateObject->getDenseInitializedLength() != initLength) + uint32_t initLength = GetAnyBoxedOrUnboxedArrayLength(templateObject); + if (GetAnyBoxedOrUnboxedInitializedLength(templateObject) != initLength) return InliningStatus_NotInlined; Vector<MConstant*, 0, SystemAllocPolicy> arrayValues; for (uint32_t i = 0; i < initLength; i++) { - Value str = templateObject->getDenseElement(i); + Value str = GetAnyBoxedOrUnboxedDenseElement(templateObject, i); MOZ_ASSERT(str.toString()->isAtom()); MConstant* value = MConstant::New(alloc().fallible(), str, constraints()); if (!value) @@ -1403,6 +1445,8 @@ IonBuilder::inlineConstantStringSplitString(CallInfo& callInfo) return InliningStatus_Inlined; } + JSValueType unboxedType = GetBoxedOrUnboxedType(templateObject); + // Store all values, no need to initialize the length after each as // jsop_initelem_array is doing because we do not expect to bailout // because the memory is supposed to be allocated by now. @@ -1413,11 +1457,11 @@ IonBuilder::inlineConstantStringSplitString(CallInfo& callInfo) MConstant* value = arrayValues[i]; current->add(value); - if (!initializeArrayElement(array, i, value, /* addResumePoint = */ false)) + if (!initializeArrayElement(array, i, value, unboxedType, /* addResumePoint = */ false)) return InliningStatus_Error; } - MInstruction* setLength = setInitializedLength(array, initLength); + MInstruction* setLength = setInitializedLength(array, unboxedType, initLength); if (!resumeAfter(setLength)) return InliningStatus_Error; @@ -2053,7 +2097,7 @@ IonBuilder::inlineDefineDataProperty(CallInfo& callInfo) if (callInfo.argc() != 3) return InliningStatus_NotInlined; - MDefinition* obj = callInfo.getArg(0); + MDefinition* obj = convertUnboxedObjects(callInfo.getArg(0)); MDefinition* id = callInfo.getArg(1); MDefinition* value = callInfo.getArg(2); |