Bug 1659424 - Transpile AllocateAndStoreDynamicSlot. r=jandem

Differential Revision: https://phabricator.services.mozilla.com/D87269
This commit is contained in:
Tom Schuster 2020-08-18 18:34:56 +00:00
parent f0910370b4
commit c3ccd2a7fa
8 changed files with 127 additions and 1 deletions

View File

@ -116,6 +116,7 @@ static inline const MDefinition* GetObject(const MDefinition* ins) {
case MDefinition::Opcode::StoreDataViewElement:
case MDefinition::Opcode::SetInitializedLength:
case MDefinition::Opcode::AddAndStoreSlot:
case MDefinition::Opcode::AllocateAndStoreSlot:
case MDefinition::Opcode::ArrayLength:
case MDefinition::Opcode::SetArrayLength:
case MDefinition::Opcode::Slots:

View File

@ -4686,6 +4686,7 @@ AttachDecision SetPropIRGenerator::tryAttachAddSlotStub(
// shape guard below) to ensure class is unchanged. This group guard may also
// imply maybeInterpretedFunction() for the special-case of function
// prototype property set.
// TODO(Warp): Figure out if this can be removed without TI.
writer.guardGroup(objId, oldGroup);
// If we are adding a property to an object for which the new script

View File

@ -841,7 +841,7 @@
- name: AllocateAndStoreDynamicSlot
shared: false
transpile: false
transpile: true
cost_estimate: 6
args:
obj: ObjId

View File

@ -11757,6 +11757,43 @@ void CodeGenerator::visitAddAndStoreSlot(LAddAndStoreSlot* ins) {
}
}
void CodeGenerator::visitAllocateAndStoreSlot(LAllocateAndStoreSlot* ins) {
const Register obj = ToRegister(ins->getOperand(0));
const ValueOperand value = ToValue(ins, LAllocateAndStoreSlot::Value);
const Register temp1 = ToRegister(ins->getTemp(0));
const Register temp2 = ToRegister(ins->getTemp(1));
masm.push(obj);
masm.pushValue(value);
masm.setupUnalignedABICall(temp1);
masm.loadJSContext(temp1);
masm.passABIArg(temp1);
masm.passABIArg(obj);
masm.move32(Imm32(ins->mir()->numNewSlots()), temp2);
masm.passABIArg(temp2);
masm.callWithABI(JS_FUNC_TO_DATA_PTR(void*, NativeObject::growSlotsPure));
masm.storeCallBoolResult(temp1);
masm.popValue(value);
masm.pop(obj);
Label bail;
masm.branchIfFalseBool(temp1, &bail);
bailoutFrom(&bail, ins->snapshot());
masm.storeObjShape(ins->mir()->shape(), obj,
[](MacroAssembler& masm, const Address& addr) {
EmitPreBarrier(masm, addr, MIRType::Shape);
});
// Perform the store. No pre-barrier required since this is a new
// initialization.
masm.loadPtr(Address(obj, NativeObject::offsetOfSlots()), temp1);
Address slot(temp1, ins->mir()->slotOffset());
masm.storeValue(value, slot);
}
void CodeGenerator::visitStoreFixedSlotV(LStoreFixedSlotV* ins) {
const Register obj = ToRegister(ins->getOperand(0));
size_t slot = ins->mir()->slot();

View File

@ -3922,6 +3922,16 @@ void LIRGenerator::visitAddAndStoreSlot(MAddAndStoreSlot* ins) {
add(lir, ins);
}
void LIRGenerator::visitAllocateAndStoreSlot(MAllocateAndStoreSlot* ins) {
MOZ_ASSERT(ins->object()->type() == MIRType::Object);
auto* lir = new (alloc()) LAllocateAndStoreSlot(
useRegisterAtStart(ins->object()), useBoxAtStart(ins->value()),
tempFixed(CallTempReg0), tempFixed(CallTempReg1));
assignSnapshot(lir, BailoutKind::DuringVMCall);
add(lir, ins);
}
void LIRGenerator::visitStoreFixedSlot(MStoreFixedSlot* ins) {
MOZ_ASSERT(ins->object()->type() == MIRType::Object);

View File

@ -10003,6 +10003,39 @@ class MAddAndStoreSlot
}
};
class MAllocateAndStoreSlot
: public MBinaryInstruction,
public MixPolicy<SingleObjectPolicy, BoxPolicy<1>>::Data {
private:
CompilerShape shape_;
uint32_t slotOffset_;
uint32_t numNewSlots_;
MAllocateAndStoreSlot(MDefinition* obj, MDefinition* value,
uint32_t slotOffset, Shape* shape, uint32_t numNewSlots)
: MBinaryInstruction(classOpcode, obj, value),
shape_(shape),
slotOffset_(slotOffset),
numNewSlots_(numNewSlots) {}
public:
INSTRUCTION_HEADER(AllocateAndStoreSlot)
TRIVIAL_NEW_WRAPPERS
NAMED_OPERANDS((0, object), (1, value))
Shape* shape() const { return shape_; }
uint32_t slotOffset() const { return slotOffset_; }
uint32_t numNewSlots() const { return numNewSlots_; }
AliasSet getAliasSet() const override {
return AliasSet::Store(AliasSet::ObjectFields | AliasSet::DynamicSlot);
}
bool possiblyCalls() const override { return true; }
bool appendRoots(MRootList& roots) const override {
return roots.append(shape_);
}
};
// Store to vp[slot] (slots that are not inline in an object).
class MStoreDynamicSlot : public MBinaryInstruction,
public NoFloatPolicy<1>::Data {

View File

@ -1386,6 +1386,29 @@ bool WarpCacheIRTranspiler::emitAddAndStoreDynamicSlot(
offsetOffset, rhsId, newShapeOffset);
}
bool WarpCacheIRTranspiler::emitAllocateAndStoreDynamicSlot(
ObjOperandId objId, uint32_t offsetOffset, ValOperandId rhsId,
bool changeGroup, uint32_t newGroupOffset, uint32_t newShapeOffset,
uint32_t numNewSlotsOffset) {
MOZ_ASSERT(!changeGroup);
int32_t offset = int32StubField(offsetOffset);
Shape* shape = shapeStubField(newShapeOffset);
uint32_t numNewSlots = uint32StubField(numNewSlotsOffset);
MDefinition* obj = getOperand(objId);
MDefinition* rhs = getOperand(rhsId);
auto* barrier = MPostWriteBarrier::New(alloc(), obj, rhs);
add(barrier);
auto* allocateAndStore =
MAllocateAndStoreSlot::New(alloc(), obj, rhs, offset, shape, numNewSlots);
addEffectful(allocateAndStore);
return resumeAfter(allocateAndStore);
}
bool WarpCacheIRTranspiler::emitStoreDenseElement(ObjOperandId objId,
Int32OperandId indexId,
ValOperandId rhsId) {

View File

@ -4999,6 +4999,27 @@ class LAddAndStoreSlot : public LInstructionHelper<0, 1 + BOX_PIECES, 1> {
const MAddAndStoreSlot* mir() const { return mir_->toAddAndStoreSlot(); }
};
class LAllocateAndStoreSlot
: public LCallInstructionHelper<0, 1 + BOX_PIECES, 2> {
public:
LIR_HEADER(AllocateAndStoreSlot)
LAllocateAndStoreSlot(const LAllocation& obj, const LBoxAllocation& value,
const LDefinition& temp1, const LDefinition& temp2)
: LCallInstructionHelper(classOpcode) {
setOperand(0, obj);
setBoxOperand(Value, value);
setTemp(0, temp1);
setTemp(1, temp2);
}
static const size_t Value = 1;
const MAllocateAndStoreSlot* mir() const {
return mir_->toAllocateAndStoreSlot();
}
};
// Store a boxed value to an object's fixed slot.
class LStoreFixedSlotV : public LInstructionHelper<0, 1 + BOX_PIECES, 0> {
public: