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:
André Bargull 2020-09-17 12:03:58 +00:00
Родитель 17b4754b7e
Коммит d931f42187
9 изменённых файлов: 76 добавлений и 1 удалений

Просмотреть файл

@ -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>;