зеркало из 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::AtomicExchangeTypedArrayElement:
|
||||
case MDefinition::Opcode::AtomicTypedArrayElementBinop:
|
||||
case MDefinition::Opcode::LoadWrapperTarget:
|
||||
case MDefinition::Opcode::AsmJSLoadHeap:
|
||||
case MDefinition::Opcode::AsmJSStoreHeap:
|
||||
case MDefinition::Opcode::WasmHeapBase:
|
||||
|
|
|
@ -682,7 +682,7 @@
|
|||
|
||||
- name: LoadWrapperTarget
|
||||
shared: true
|
||||
transpile: false
|
||||
transpile: true
|
||||
cost_estimate: 1
|
||||
args:
|
||||
obj: ObjId
|
||||
|
|
|
@ -15063,6 +15063,16 @@ void CodeGenerator::visitGuardTagNotEqual(LGuardTagNotEqual* lir) {
|
|||
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>
|
||||
void CodeGenerator::emitIonToWasmCallBase(LIonToWasmCallBase<NumDefs>* lir) {
|
||||
wasm::JitCallStackArgVector stackArgs;
|
||||
|
|
|
@ -57,6 +57,10 @@ const WellKnownSymbols& CompileRuntime::wellKnownSymbols() {
|
|||
return *runtime()->wellKnownSymbols;
|
||||
}
|
||||
|
||||
const JSClass* CompileRuntime::maybeWindowProxyClass() {
|
||||
return runtime()->maybeWindowProxyClass();
|
||||
}
|
||||
|
||||
const void* CompileRuntime::mainContextPtr() {
|
||||
return runtime()->mainContextFromAnyThread();
|
||||
}
|
||||
|
|
|
@ -42,6 +42,7 @@ class CompileRuntime {
|
|||
const PropertyName* emptyString();
|
||||
const StaticStrings& staticStrings();
|
||||
const WellKnownSymbols& wellKnownSymbols();
|
||||
const JSClass* maybeWindowProxyClass();
|
||||
|
||||
const void* mainContextPtr();
|
||||
uint32_t* addressOfTenuredAllocCount();
|
||||
|
|
|
@ -5537,6 +5537,13 @@ void LIRGenerator::visitGuardTagNotEqual(MGuardTagNotEqual* 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) {
|
||||
if (!IsFloatingPointType(ins->type()) && ins->canEmitAtUses()) {
|
||||
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
|
||||
// payload. Note this is different from multiplying by minus-one, which has
|
||||
// side-effects for e.g. NaNs.
|
||||
|
|
|
@ -276,12 +276,16 @@ bool WarpCacheIRTranspiler::emitGuardClass(ObjOperandId objId,
|
|||
case GuardClassKind::DataView:
|
||||
classp = &DataViewObject::class_;
|
||||
break;
|
||||
case GuardClassKind::WindowProxy:
|
||||
classp = mirGen().runtime->maybeWindowProxyClass();
|
||||
break;
|
||||
case GuardClassKind::JSFunction:
|
||||
classp = &JSFunction::class_;
|
||||
break;
|
||||
default:
|
||||
MOZ_CRASH("not yet supported");
|
||||
}
|
||||
MOZ_ASSERT(classp);
|
||||
|
||||
auto* ins = MGuardToClass::New(alloc(), def, classp);
|
||||
add(ins);
|
||||
|
@ -3128,6 +3132,16 @@ bool WarpCacheIRTranspiler::emitLoadValueTruthyResult(ValOperandId inputId) {
|
|||
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,
|
||||
uint32_t slotIndex) {
|
||||
// Reverse of GetIndexOfArgument.
|
||||
|
|
|
@ -8299,6 +8299,18 @@ class LGuardTagNotEqual : public LInstructionHelper<0, 2, 0> {
|
|||
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>
|
||||
class LIonToWasmCallBase : public LVariadicInstruction<NumDefs, 2> {
|
||||
using Base = LVariadicInstruction<NumDefs, 2>;
|
||||
|
|
Загрузка…
Ссылка в новой задаче