зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1380344 - Add Ion support for IsPackedArray. r=jandem
--HG-- extra : rebase_source : 8599c33b39806d1580a3a5fd208f39150f6c2c3e extra : histedit_source : de214f94b5b5eb2d440519634555da3a0dc72b85
This commit is contained in:
Родитель
a32a33c30a
Коммит
ceca1e45b7
|
@ -124,6 +124,7 @@ GetObject(const MDefinition* ins)
|
|||
case MDefinition::Op_TypedArrayElements:
|
||||
case MDefinition::Op_TypedObjectElements:
|
||||
case MDefinition::Op_CopyLexicalEnvironmentObject:
|
||||
case MDefinition::Op_IsPackedArray:
|
||||
object = ins->getOperand(0);
|
||||
break;
|
||||
case MDefinition::Op_GetPropertyCache:
|
||||
|
|
|
@ -12842,5 +12842,30 @@ CodeGenerator::visitFinishBoundFunctionInit(LFinishBoundFunctionInit* lir)
|
|||
masm.bind(ool->rejoin());
|
||||
}
|
||||
|
||||
void
|
||||
CodeGenerator::visitIsPackedArray(LIsPackedArray* lir)
|
||||
{
|
||||
Register array = ToRegister(lir->array());
|
||||
Register output = ToRegister(lir->output());
|
||||
Register elementsTemp = ToRegister(lir->temp());
|
||||
|
||||
Label notPacked, done;
|
||||
|
||||
// Load elements and length.
|
||||
masm.loadPtr(Address(array, NativeObject::offsetOfElements()), elementsTemp);
|
||||
masm.load32(Address(elementsTemp, ObjectElements::offsetOfLength()), output);
|
||||
|
||||
// Test length == initializedLength.
|
||||
Address initLength(elementsTemp, ObjectElements::offsetOfInitializedLength());
|
||||
masm.branch32(Assembler::NotEqual, initLength, output, ¬Packed);
|
||||
|
||||
masm.move32(Imm32(1), output);
|
||||
masm.jump(&done);
|
||||
masm.bind(¬Packed);
|
||||
masm.move32(Imm32(0), output);
|
||||
|
||||
masm.bind(&done);
|
||||
}
|
||||
|
||||
} // namespace jit
|
||||
} // namespace js
|
||||
|
|
|
@ -411,6 +411,7 @@ class CodeGenerator final : public CodeGeneratorSpecific
|
|||
void visitNaNToZero(LNaNToZero* ins);
|
||||
void visitOutOfLineNaNToZero(OutOfLineNaNToZero* ool);
|
||||
void visitFinishBoundFunctionInit(LFinishBoundFunctionInit* lir);
|
||||
void visitIsPackedArray(LIsPackedArray* lir);
|
||||
|
||||
void visitCheckOverRecursed(LCheckOverRecursed* lir);
|
||||
void visitCheckOverRecursedFailure(CheckOverRecursedFailure* ool);
|
||||
|
|
|
@ -122,6 +122,7 @@
|
|||
_(IntrinsicSubstringKernel) \
|
||||
_(IntrinsicObjectHasPrototype) \
|
||||
_(IntrinsicFinishBoundFunctionInit) \
|
||||
_(IntrinsicIsPackedArray) \
|
||||
\
|
||||
_(IntrinsicIsArrayIterator) \
|
||||
_(IntrinsicIsMapIterator) \
|
||||
|
|
|
@ -781,6 +781,7 @@ class IonBuilder
|
|||
InliningResult inlineSubstringKernel(CallInfo& callInfo);
|
||||
InliningResult inlineObjectHasPrototype(CallInfo& callInfo);
|
||||
InliningResult inlineFinishBoundFunctionInit(CallInfo& callInfo);
|
||||
InliningResult inlineIsPackedArray(CallInfo& callInfo);
|
||||
|
||||
// Testing functions.
|
||||
InliningResult inlineBailout(CallInfo& callInfo);
|
||||
|
|
|
@ -4972,6 +4972,16 @@ LIRGenerator::visitFinishBoundFunctionInit(MFinishBoundFunctionInit* ins)
|
|||
assignSafepoint(lir, ins);
|
||||
}
|
||||
|
||||
void
|
||||
LIRGenerator::visitIsPackedArray(MIsPackedArray* ins)
|
||||
{
|
||||
MOZ_ASSERT(ins->array()->type() == MIRType::Object);
|
||||
MOZ_ASSERT(ins->type() == MIRType::Boolean);
|
||||
|
||||
auto lir = new(alloc()) LIsPackedArray(useRegister(ins->array()), temp());
|
||||
define(lir, ins);
|
||||
}
|
||||
|
||||
static void
|
||||
SpewResumePoint(MBasicBlock* block, MInstruction* ins, MResumePoint* resumePoint)
|
||||
{
|
||||
|
|
|
@ -343,6 +343,7 @@ class LIRGenerator : public LIRGeneratorSpecific
|
|||
void visitCheckObjCoercible(MCheckObjCoercible* ins);
|
||||
void visitDebugCheckSelfHosted(MDebugCheckSelfHosted* ins);
|
||||
void visitFinishBoundFunctionInit(MFinishBoundFunctionInit* ins);
|
||||
void visitIsPackedArray(MIsPackedArray* ins);
|
||||
};
|
||||
|
||||
} // namespace jit
|
||||
|
|
|
@ -312,6 +312,8 @@ IonBuilder::inlineNativeCall(CallInfo& callInfo, JSFunction* target)
|
|||
return inlineObjectHasPrototype(callInfo);
|
||||
case InlinableNative::IntrinsicFinishBoundFunctionInit:
|
||||
return inlineFinishBoundFunctionInit(callInfo);
|
||||
case InlinableNative::IntrinsicIsPackedArray:
|
||||
return inlineIsPackedArray(callInfo);
|
||||
|
||||
// Map intrinsics.
|
||||
case InlinableNative::IntrinsicIsMapObject:
|
||||
|
@ -1745,6 +1747,47 @@ IonBuilder::inlineFinishBoundFunctionInit(CallInfo& callInfo)
|
|||
return InliningStatus_Inlined;
|
||||
}
|
||||
|
||||
IonBuilder::InliningResult
|
||||
IonBuilder::inlineIsPackedArray(CallInfo& callInfo)
|
||||
{
|
||||
MOZ_ASSERT(!callInfo.constructing());
|
||||
MOZ_ASSERT(callInfo.argc() == 1);
|
||||
|
||||
if (getInlineReturnType() != MIRType::Boolean)
|
||||
return InliningStatus_NotInlined;
|
||||
|
||||
MDefinition* array = callInfo.getArg(0);
|
||||
|
||||
if (array->type() != MIRType::Object)
|
||||
return InliningStatus_NotInlined;
|
||||
|
||||
TemporaryTypeSet* arrayTypes = array->resultTypeSet();
|
||||
if (!arrayTypes)
|
||||
return InliningStatus_NotInlined;
|
||||
|
||||
const Class* clasp = arrayTypes->getKnownClass(constraints());
|
||||
if (clasp != &ArrayObject::class_)
|
||||
return InliningStatus_NotInlined;
|
||||
|
||||
// Only inline if the array uses dense storage.
|
||||
ObjectGroupFlags unhandledFlags = OBJECT_FLAG_SPARSE_INDEXES |
|
||||
OBJECT_FLAG_LENGTH_OVERFLOW |
|
||||
OBJECT_FLAG_NON_PACKED;
|
||||
|
||||
if (arrayTypes->hasObjectFlags(constraints(), unhandledFlags)) {
|
||||
trackOptimizationOutcome(TrackedOutcome::ArrayBadFlags);
|
||||
return InliningStatus_NotInlined;
|
||||
}
|
||||
|
||||
callInfo.setImplicitlyUsedUnchecked();
|
||||
|
||||
auto* ins = MIsPackedArray::New(alloc(), array);
|
||||
current->add(ins);
|
||||
current->push(ins);
|
||||
|
||||
return InliningStatus_Inlined;
|
||||
}
|
||||
|
||||
IonBuilder::InliningResult
|
||||
IonBuilder::inlineStrCharCodeAt(CallInfo& callInfo)
|
||||
{
|
||||
|
|
|
@ -13857,6 +13857,27 @@ class MFinishBoundFunctionInit
|
|||
NAMED_OPERANDS((0, bound), (1, target), (2, argCount))
|
||||
};
|
||||
|
||||
class MIsPackedArray
|
||||
: public MUnaryInstruction,
|
||||
public SingleObjectPolicy::Data
|
||||
{
|
||||
explicit MIsPackedArray(MDefinition* array)
|
||||
: MUnaryInstruction(array)
|
||||
{
|
||||
setResultType(MIRType::Boolean);
|
||||
setMovable();
|
||||
}
|
||||
|
||||
public:
|
||||
INSTRUCTION_HEADER(IsPackedArray)
|
||||
TRIVIAL_NEW_WRAPPERS
|
||||
NAMED_OPERANDS((0, array))
|
||||
|
||||
AliasSet getAliasSet() const override {
|
||||
return AliasSet::Load(AliasSet::ObjectFields);
|
||||
}
|
||||
};
|
||||
|
||||
// Flips the input's sign bit, independently of the rest of the number's
|
||||
// payload. Note this is different from multiplying by minus-one, which has
|
||||
// side-effects for e.g. NaNs.
|
||||
|
|
|
@ -298,6 +298,7 @@ namespace jit {
|
|||
_(CheckObjCoercible) \
|
||||
_(DebugCheckSelfHosted) \
|
||||
_(FinishBoundFunctionInit) \
|
||||
_(IsPackedArray) \
|
||||
_(AsmJSLoadHeap) \
|
||||
_(AsmJSStoreHeap) \
|
||||
_(AsmJSCompareExchangeHeap) \
|
||||
|
|
|
@ -9318,6 +9318,25 @@ class LFinishBoundFunctionInit : public LInstructionHelper<0, 3, 2>
|
|||
}
|
||||
};
|
||||
|
||||
class LIsPackedArray : public LInstructionHelper<1, 1, 1>
|
||||
{
|
||||
public:
|
||||
LIR_HEADER(IsPackedArray)
|
||||
|
||||
LIsPackedArray(const LAllocation& array, const LDefinition& temp)
|
||||
{
|
||||
setOperand(0, array);
|
||||
setTemp(0, temp);
|
||||
}
|
||||
|
||||
const LAllocation* array() {
|
||||
return getOperand(0);
|
||||
}
|
||||
const LDefinition* temp() {
|
||||
return getTemp(0);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace jit
|
||||
} // namespace js
|
||||
|
||||
|
|
|
@ -415,6 +415,7 @@
|
|||
_(CheckObjCoercible) \
|
||||
_(DebugCheckSelfHosted) \
|
||||
_(FinishBoundFunctionInit) \
|
||||
_(IsPackedArray) \
|
||||
_(AsmJSLoadHeap) \
|
||||
_(AsmJSStoreHeap) \
|
||||
_(AsmJSCompareExchangeHeap) \
|
||||
|
|
|
@ -2301,7 +2301,8 @@ static const JSFunctionSpec intrinsic_functions[] = {
|
|||
JS_INLINABLE_FN("UnsafeGetBooleanFromReservedSlot", intrinsic_UnsafeGetBooleanFromReservedSlot,2,0,
|
||||
IntrinsicUnsafeGetBooleanFromReservedSlot),
|
||||
|
||||
JS_FN("IsPackedArray", intrinsic_IsPackedArray, 1,0),
|
||||
JS_INLINABLE_FN("IsPackedArray", intrinsic_IsPackedArray, 1,0,
|
||||
IntrinsicIsPackedArray),
|
||||
|
||||
JS_FN("GetIteratorPrototype", intrinsic_GetIteratorPrototype, 0,0),
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче