Bug 1341937 - Part 13: Check eliding post write barriers is correct. r=jandem

Add a debug-only check that it's okay to elide the post write barriers.

Differential Revision: https://phabricator.services.mozilla.com/D156789
This commit is contained in:
André Bargull 2022-09-08 13:47:02 +00:00
parent 90636aeb84
commit 1260414bfd
5 changed files with 93 additions and 0 deletions

View File

@ -5084,6 +5084,22 @@ void CodeGenerator::visitPostWriteElementBarrierV(
visitPostWriteBarrierCommonV(lir, ool);
}
void CodeGenerator::visitAssertCanElidePostWriteBarrier(
LAssertCanElidePostWriteBarrier* lir) {
Register object = ToRegister(lir->object());
ValueOperand value =
ToValue(lir, LAssertCanElidePostWriteBarrier::ValueIndex);
Register temp = ToRegister(lir->temp0());
Label ok;
masm.branchPtrInNurseryChunk(Assembler::Equal, object, temp, &ok);
masm.branchValueIsNurseryCell(Assembler::NotEqual, value, temp, &ok);
masm.assumeUnreachable("Unexpected missing post write barrier");
masm.bind(&ok);
}
void CodeGenerator::visitCallNative(LCallNative* call) {
WrappedFunction* target = call->getSingleTarget();
MOZ_ASSERT(target);

View File

@ -2359,6 +2359,13 @@
num_temps: 1
mir_op: PostWriteElementBarrier
# Assert in debug mode that a post write barrier can be elided.
- name: AssertCanElidePostWriteBarrier
operands:
object: WordSized
value: BoxedValue
num_temps: 1
# Guard against an object's identity.
- name: GuardObjectIdentity
operands:

View File

@ -3389,6 +3389,13 @@ void LIRGenerator::visitPostWriteElementBarrier(MPostWriteElementBarrier* ins) {
}
}
void LIRGenerator::visitAssertCanElidePostWriteBarrier(
MAssertCanElidePostWriteBarrier* ins) {
auto* lir = new (alloc()) LAssertCanElidePostWriteBarrier(
useRegister(ins->object()), useBox(ins->value()), temp());
add(lir, ins);
}
void LIRGenerator::visitArrayLength(MArrayLength* ins) {
MOZ_ASSERT(ins->elements()->type() == MIRType::Elements);
auto* lir = new (alloc()) LArrayLength(useRegisterAtStart(ins->elements()));

View File

@ -1985,6 +1985,14 @@
- name: PostWriteElementBarrier
gen_boilerplate: false
- name: AssertCanElidePostWriteBarrier
operands:
object: Object
value: Value
result_type: None
guard: true
alias_set: none
- name: NewNamedLambdaObject
arguments:
templateObj: NamedLambdaObject*

View File

@ -327,6 +327,13 @@ MInstruction* WarpBuilder::buildNamedLambdaEnv(MDefinition* callee,
MInstruction* namedLambda = MNewNamedLambdaObject::New(alloc(), templateObj);
current->add(namedLambda);
#ifdef DEBUG
// Assert in debug mode we can elide the post write barriers.
current->add(MAssertCanElidePostWriteBarrier::New(alloc(), namedLambda, env));
current->add(
MAssertCanElidePostWriteBarrier::New(alloc(), namedLambda, callee));
#endif
// Initialize the object's reserved slots. No post barrier is needed here:
// the object will be allocated in the nursery if possible, and if the
// tenured heap is used instead, a minor collection will have been performed
@ -349,6 +356,12 @@ MInstruction* WarpBuilder::buildCallObject(MDefinition* callee,
MNewCallObject* callObj = MNewCallObject::New(alloc(), templateCst);
current->add(callObj);
#ifdef DEBUG
// Assert in debug mode we can elide the post write barriers.
current->add(MAssertCanElidePostWriteBarrier::New(alloc(), callObj, env));
current->add(MAssertCanElidePostWriteBarrier::New(alloc(), callObj, callee));
#endif
// Initialize the object's reserved slots. No post barrier is needed here,
// for the same reason as in buildNamedLambdaEnv.
size_t enclosingSlot = CallObject::enclosingEnvironmentSlot();
@ -379,6 +392,11 @@ MInstruction* WarpBuilder::buildCallObject(MDefinition* callee,
param = current->getSlot(info().argSlotUnchecked(formal));
}
#ifdef DEBUG
// Assert in debug mode we can elide the post write barrier.
current->add(MAssertCanElidePostWriteBarrier::New(alloc(), callObj, param));
#endif
if (slot >= numFixedSlots) {
if (!slots) {
slots = MSlots::New(alloc(), callObj);
@ -1989,6 +2007,11 @@ bool WarpBuilder::build_PushLexicalEnv(BytecodeLocation loc) {
auto* ins = MNewLexicalEnvironmentObject::New(alloc(), templateCst);
current->add(ins);
#ifdef DEBUG
// Assert in debug mode we can elide the post write barrier.
current->add(MAssertCanElidePostWriteBarrier::New(alloc(), ins, env));
#endif
// Initialize the object's reserved slots. No post barrier is needed here,
// for the same reason as in buildNamedLambdaEnv.
current->add(MStoreFixedSlot::NewUnbarriered(
@ -2010,6 +2033,11 @@ bool WarpBuilder::build_PushClassBodyEnv(BytecodeLocation loc) {
auto* ins = MNewClassBodyEnvironmentObject::New(alloc(), templateCst);
current->add(ins);
#ifdef DEBUG
// Assert in debug mode we can elide the post write barrier.
current->add(MAssertCanElidePostWriteBarrier::New(alloc(), ins, env));
#endif
// Initialize the object's reserved slots. No post barrier is needed here,
// for the same reason as in buildNamedLambdaEnv.
current->add(MStoreFixedSlot::NewUnbarriered(
@ -2045,6 +2073,12 @@ bool WarpBuilder::build_FreshenLexicalEnv(BytecodeLocation loc) {
auto* ins = MNewLexicalEnvironmentObject::New(alloc(), templateCst);
current->add(ins);
#ifdef DEBUG
// Assert in debug mode we can elide the post write barrier.
current->add(
MAssertCanElidePostWriteBarrier::New(alloc(), ins, enclosingEnv));
#endif
// Initialize the object's reserved slots. No post barrier is needed here,
// for the same reason as in buildNamedLambdaEnv.
current->add(MStoreFixedSlot::NewUnbarriered(
@ -2082,12 +2116,22 @@ bool WarpBuilder::build_FreshenLexicalEnv(BytecodeLocation loc) {
auto* load = MLoadDynamicSlot::New(alloc(), envSlots, dynamicSlot);
current->add(load);
#ifdef DEBUG
// Assert in debug mode we can elide the post write barrier.
current->add(MAssertCanElidePostWriteBarrier::New(alloc(), ins, load));
#endif
current->add(
MStoreDynamicSlot::NewUnbarriered(alloc(), slots, dynamicSlot, load));
} else {
auto* load = MLoadFixedSlot::New(alloc(), env, slot);
current->add(load);
#ifdef DEBUG
// Assert in debug mode we can elide the post write barrier.
current->add(MAssertCanElidePostWriteBarrier::New(alloc(), ins, load));
#endif
current->add(MStoreFixedSlot::NewUnbarriered(alloc(), ins, slot, load));
}
}
@ -2108,6 +2152,12 @@ bool WarpBuilder::build_RecreateLexicalEnv(BytecodeLocation loc) {
auto* ins = MNewLexicalEnvironmentObject::New(alloc(), templateCst);
current->add(ins);
#ifdef DEBUG
// Assert in debug mode we can elide the post write barrier.
current->add(
MAssertCanElidePostWriteBarrier::New(alloc(), ins, enclosingEnv));
#endif
// Initialize the object's reserved slots. No post barrier is needed here,
// for the same reason as in buildNamedLambdaEnv.
current->add(MStoreFixedSlot::NewUnbarriered(
@ -2130,6 +2180,11 @@ bool WarpBuilder::build_PushVarEnv(BytecodeLocation loc) {
auto* ins = MNewVarEnvironmentObject::New(alloc(), templateCst);
current->add(ins);
#ifdef DEBUG
// Assert in debug mode we can elide the post write barrier.
current->add(MAssertCanElidePostWriteBarrier::New(alloc(), ins, env));
#endif
// Initialize the object's reserved slots. No post barrier is needed here,
// for the same reason as in buildNamedLambdaEnv.
current->add(MStoreFixedSlot::NewUnbarriered(