зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1664990: Transpile LoadWrapperTarget CacheIR op. r=jandem
`LoadWrapperTarget` is used when reading properties from the global object. The alias set can't be `AliasSet::None()`, because the target changes when the `document` is moved. Differential Revision: https://phabricator.services.mozilla.com/D90220
This commit is contained in:
Родитель
17b4754b7e
Коммит
d931f42187
|
@ -179,6 +179,7 @@ static inline const MDefinition* GetObject(const MDefinition* ins) {
|
||||||
case MDefinition::Opcode::CompareExchangeTypedArrayElement:
|
case MDefinition::Opcode::CompareExchangeTypedArrayElement:
|
||||||
case MDefinition::Opcode::AtomicExchangeTypedArrayElement:
|
case MDefinition::Opcode::AtomicExchangeTypedArrayElement:
|
||||||
case MDefinition::Opcode::AtomicTypedArrayElementBinop:
|
case MDefinition::Opcode::AtomicTypedArrayElementBinop:
|
||||||
|
case MDefinition::Opcode::LoadWrapperTarget:
|
||||||
case MDefinition::Opcode::AsmJSLoadHeap:
|
case MDefinition::Opcode::AsmJSLoadHeap:
|
||||||
case MDefinition::Opcode::AsmJSStoreHeap:
|
case MDefinition::Opcode::AsmJSStoreHeap:
|
||||||
case MDefinition::Opcode::WasmHeapBase:
|
case MDefinition::Opcode::WasmHeapBase:
|
||||||
|
|
|
@ -682,7 +682,7 @@
|
||||||
|
|
||||||
- name: LoadWrapperTarget
|
- name: LoadWrapperTarget
|
||||||
shared: true
|
shared: true
|
||||||
transpile: false
|
transpile: true
|
||||||
cost_estimate: 1
|
cost_estimate: 1
|
||||||
args:
|
args:
|
||||||
obj: ObjId
|
obj: ObjId
|
||||||
|
|
|
@ -15063,6 +15063,16 @@ void CodeGenerator::visitGuardTagNotEqual(LGuardTagNotEqual* lir) {
|
||||||
masm.bind(&done);
|
masm.bind(&done);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CodeGenerator::visitLoadWrapperTarget(LLoadWrapperTarget* lir) {
|
||||||
|
Register object = ToRegister(lir->object());
|
||||||
|
Register output = ToRegister(lir->output());
|
||||||
|
|
||||||
|
masm.loadPtr(Address(object, ProxyObject::offsetOfReservedSlots()), output);
|
||||||
|
masm.unboxObject(
|
||||||
|
Address(output, js::detail::ProxyReservedSlots::offsetOfPrivateSlot()),
|
||||||
|
output);
|
||||||
|
}
|
||||||
|
|
||||||
template <size_t NumDefs>
|
template <size_t NumDefs>
|
||||||
void CodeGenerator::emitIonToWasmCallBase(LIonToWasmCallBase<NumDefs>* lir) {
|
void CodeGenerator::emitIonToWasmCallBase(LIonToWasmCallBase<NumDefs>* lir) {
|
||||||
wasm::JitCallStackArgVector stackArgs;
|
wasm::JitCallStackArgVector stackArgs;
|
||||||
|
|
|
@ -57,6 +57,10 @@ const WellKnownSymbols& CompileRuntime::wellKnownSymbols() {
|
||||||
return *runtime()->wellKnownSymbols;
|
return *runtime()->wellKnownSymbols;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const JSClass* CompileRuntime::maybeWindowProxyClass() {
|
||||||
|
return runtime()->maybeWindowProxyClass();
|
||||||
|
}
|
||||||
|
|
||||||
const void* CompileRuntime::mainContextPtr() {
|
const void* CompileRuntime::mainContextPtr() {
|
||||||
return runtime()->mainContextFromAnyThread();
|
return runtime()->mainContextFromAnyThread();
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,6 +42,7 @@ class CompileRuntime {
|
||||||
const PropertyName* emptyString();
|
const PropertyName* emptyString();
|
||||||
const StaticStrings& staticStrings();
|
const StaticStrings& staticStrings();
|
||||||
const WellKnownSymbols& wellKnownSymbols();
|
const WellKnownSymbols& wellKnownSymbols();
|
||||||
|
const JSClass* maybeWindowProxyClass();
|
||||||
|
|
||||||
const void* mainContextPtr();
|
const void* mainContextPtr();
|
||||||
uint32_t* addressOfTenuredAllocCount();
|
uint32_t* addressOfTenuredAllocCount();
|
||||||
|
|
|
@ -5537,6 +5537,13 @@ void LIRGenerator::visitGuardTagNotEqual(MGuardTagNotEqual* ins) {
|
||||||
add(guard, ins);
|
add(guard, ins);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void LIRGenerator::visitLoadWrapperTarget(MLoadWrapperTarget* ins) {
|
||||||
|
MDefinition* object = ins->object();
|
||||||
|
MOZ_ASSERT(object->type() == MIRType::Object);
|
||||||
|
|
||||||
|
define(new (alloc()) LLoadWrapperTarget(useRegisterAtStart(object)), ins);
|
||||||
|
}
|
||||||
|
|
||||||
void LIRGenerator::visitConstant(MConstant* ins) {
|
void LIRGenerator::visitConstant(MConstant* ins) {
|
||||||
if (!IsFloatingPointType(ins->type()) && ins->canEmitAtUses()) {
|
if (!IsFloatingPointType(ins->type()) && ins->canEmitAtUses()) {
|
||||||
emitAtUses(ins);
|
emitAtUses(ins);
|
||||||
|
|
|
@ -12746,6 +12746,32 @@ class MLoadValueTag : public MUnaryInstruction, public BoxInputsPolicy::Data {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Load the target object from a proxy wrapper. The target is stored in the
|
||||||
|
// proxy object's private slot.
|
||||||
|
class MLoadWrapperTarget : public MUnaryInstruction,
|
||||||
|
public SingleObjectPolicy::Data {
|
||||||
|
explicit MLoadWrapperTarget(MDefinition* obj)
|
||||||
|
: MUnaryInstruction(classOpcode, obj) {
|
||||||
|
setResultType(MIRType::Object);
|
||||||
|
setMovable();
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
INSTRUCTION_HEADER(LoadWrapperTarget)
|
||||||
|
TRIVIAL_NEW_WRAPPERS
|
||||||
|
NAMED_OPERANDS((0, object))
|
||||||
|
|
||||||
|
AliasSet getAliasSet() const override {
|
||||||
|
// Can't use |AliasSet::None| because the target changes on navigation.
|
||||||
|
// TODO: Investigate using a narrower or a custom alias set.
|
||||||
|
return AliasSet::Load(AliasSet::Any);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool congruentTo(const MDefinition* ins) const override {
|
||||||
|
return congruentIfOperandsEqual(ins);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
// Flips the input's sign bit, independently of the rest of the number's
|
// 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
|
// payload. Note this is different from multiplying by minus-one, which has
|
||||||
// side-effects for e.g. NaNs.
|
// side-effects for e.g. NaNs.
|
||||||
|
|
|
@ -276,12 +276,16 @@ bool WarpCacheIRTranspiler::emitGuardClass(ObjOperandId objId,
|
||||||
case GuardClassKind::DataView:
|
case GuardClassKind::DataView:
|
||||||
classp = &DataViewObject::class_;
|
classp = &DataViewObject::class_;
|
||||||
break;
|
break;
|
||||||
|
case GuardClassKind::WindowProxy:
|
||||||
|
classp = mirGen().runtime->maybeWindowProxyClass();
|
||||||
|
break;
|
||||||
case GuardClassKind::JSFunction:
|
case GuardClassKind::JSFunction:
|
||||||
classp = &JSFunction::class_;
|
classp = &JSFunction::class_;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
MOZ_CRASH("not yet supported");
|
MOZ_CRASH("not yet supported");
|
||||||
}
|
}
|
||||||
|
MOZ_ASSERT(classp);
|
||||||
|
|
||||||
auto* ins = MGuardToClass::New(alloc(), def, classp);
|
auto* ins = MGuardToClass::New(alloc(), def, classp);
|
||||||
add(ins);
|
add(ins);
|
||||||
|
@ -3128,6 +3132,16 @@ bool WarpCacheIRTranspiler::emitLoadValueTruthyResult(ValOperandId inputId) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool WarpCacheIRTranspiler::emitLoadWrapperTarget(ObjOperandId objId,
|
||||||
|
ObjOperandId resultId) {
|
||||||
|
MDefinition* obj = getOperand(objId);
|
||||||
|
|
||||||
|
auto* ins = MLoadWrapperTarget::New(alloc(), obj);
|
||||||
|
add(ins);
|
||||||
|
|
||||||
|
return defineOperand(resultId, ins);
|
||||||
|
}
|
||||||
|
|
||||||
bool WarpCacheIRTranspiler::emitLoadArgumentSlot(ValOperandId resultId,
|
bool WarpCacheIRTranspiler::emitLoadArgumentSlot(ValOperandId resultId,
|
||||||
uint32_t slotIndex) {
|
uint32_t slotIndex) {
|
||||||
// Reverse of GetIndexOfArgument.
|
// Reverse of GetIndexOfArgument.
|
||||||
|
|
|
@ -8299,6 +8299,18 @@ class LGuardTagNotEqual : public LInstructionHelper<0, 2, 0> {
|
||||||
const LAllocation* rhs() { return getOperand(1); }
|
const LAllocation* rhs() { return getOperand(1); }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class LLoadWrapperTarget : public LInstructionHelper<1, 1, 0> {
|
||||||
|
public:
|
||||||
|
LIR_HEADER(LoadWrapperTarget)
|
||||||
|
|
||||||
|
explicit LLoadWrapperTarget(const LAllocation& object)
|
||||||
|
: LInstructionHelper(classOpcode) {
|
||||||
|
setOperand(0, object);
|
||||||
|
}
|
||||||
|
|
||||||
|
const LAllocation* object() { return getOperand(0); }
|
||||||
|
};
|
||||||
|
|
||||||
template <size_t NumDefs>
|
template <size_t NumDefs>
|
||||||
class LIonToWasmCallBase : public LVariadicInstruction<NumDefs, 2> {
|
class LIonToWasmCallBase : public LVariadicInstruction<NumDefs, 2> {
|
||||||
using Base = LVariadicInstruction<NumDefs, 2>;
|
using Base = LVariadicInstruction<NumDefs, 2>;
|
||||||
|
|
Загрузка…
Ссылка в новой задаче