From 5ee844f71001af821244696414bd92973f78fc09 Mon Sep 17 00:00:00 2001 From: wolfbeast Date: Sat, 22 Feb 2020 21:09:32 +0100 Subject: Revert #1142 - Remove unboxed objects - accounting for removal of watch()/unwatch() --- js/src/jit/MCallOptimize.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'js/src/jit/MCallOptimize.cpp') diff --git a/js/src/jit/MCallOptimize.cpp b/js/src/jit/MCallOptimize.cpp index 236354530..a1c336391 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; -- cgit v1.2.3 From dd57b9273c7c95a7cdabc94854c8dc63b0653f02 Mon Sep 17 00:00:00 2001 From: wolfbeast Date: Sun, 23 Feb 2020 14:41:40 +0100 Subject: Revert #1137 - Remove unboxed arrays - accounting for removal of watch()/unwatch() - updated for intermediate code changes. --- js/src/jit/MCallOptimize.cpp | 81 +++++++++++++++++++++++++++++++++----------- 1 file changed, 62 insertions(+), 19 deletions(-) (limited to 'js/src/jit/MCallOptimize.cpp') diff --git a/js/src/jit/MCallOptimize.cpp b/js/src/jit/MCallOptimize.cpp index a1c336391..276b5eba5 100644 --- a/js/src/jit/MCallOptimize.cpp +++ b/js/src/jit/MCallOptimize.cpp @@ -471,6 +471,11 @@ IonBuilder::inlineArray(CallInfo& callInfo) return InliningStatus_NotInlined; } + if (templateObject->is()) { + if (templateObject->group()->unboxedLayout().nativeGroup()) + return InliningStatus_NotInlined; + } + // Multiple arguments imply array initialization, not just construction. if (callInfo.argc() >= 2) { initLength = callInfo.argc(); @@ -518,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().length()) + if (initLength != GetAnyBoxedOrUnboxedArrayLength(templateObject)) return InliningStatus_NotInlined; // Don't inline large allocations. @@ -533,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; } @@ -574,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)); @@ -610,7 +616,7 @@ IonBuilder::inlineArrayPopShift(CallInfo& callInfo, MArrayPopShift::Mode mode) 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); @@ -623,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); @@ -636,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); @@ -718,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 || @@ -728,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); @@ -774,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); @@ -797,8 +827,15 @@ IonBuilder::inlineArraySlice(CallInfo& callInfo) if (!templateObj) return InliningStatus_NotInlined; - if (!templateObj->is()) - return InliningStatus_NotInlined; + if (unboxedType == JSVAL_TYPE_MAGIC) { + if (!templateObj->is()) + return InliningStatus_NotInlined; + } else { + if (!templateObj->is()) + return InliningStatus_NotInlined; + if (templateObj->as().elementType() != unboxedType) + return InliningStatus_NotInlined; + } callInfo.setImplicitlyUsedUnchecked(); @@ -817,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); @@ -1341,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; @@ -1367,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 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) @@ -1404,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. @@ -1414,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; -- cgit v1.2.3 From ecdeefc4dd5624e824e696ac1c492c0b103f4acd Mon Sep 17 00:00:00 2001 From: wolfbeast Date: Sun, 23 Feb 2020 19:43:47 +0100 Subject: Revert #1091 Remove unboxed object code phase 1 + extras. This should be the last code backout for this. merging this branch should get us back to the way we were (+ additional code changes for later changes) as fasr as the unused unboxed code is concerned. --- js/src/jit/MCallOptimize.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'js/src/jit/MCallOptimize.cpp') diff --git a/js/src/jit/MCallOptimize.cpp b/js/src/jit/MCallOptimize.cpp index 276b5eba5..f2071dc6a 100644 --- a/js/src/jit/MCallOptimize.cpp +++ b/js/src/jit/MCallOptimize.cpp @@ -611,7 +611,7 @@ 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; @@ -700,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)) @@ -773,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) @@ -2097,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); -- cgit v1.2.3