forked from mirrors/gecko-dev
		
	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:
		
							parent
							
								
									90636aeb84
								
							
						
					
					
						commit
						1260414bfd
					
				
					 5 changed files with 93 additions and 0 deletions
				
			
		|  | @ -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); | ||||
|  |  | |||
|  | @ -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: | ||||
|  |  | |||
|  | @ -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())); | ||||
|  |  | |||
|  | @ -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* | ||||
|  |  | |||
|  | @ -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( | ||||
|  |  | |||
		Loading…
	
		Reference in a new issue
	
	 André Bargull
						André Bargull