@@ -4057,6 +4057,8 @@ LinearScan::InsertSecondChanceCompensation(Lifetime ** branchRegContent, Lifetim
40574057 continue ;
40584058 }
40594059
4060+ // Allow us to properly insert compensation code for symbols whose lifetimes start after the generator jump table
4061+ // The GeneratorBailInLabel will have 2 edges in: one from the normal flow, one straight from the generator jump table
40604062 if (!branchLifetime && lifetime && lifetime->start > branchInstr->GetNumber () && labelInstr->m_opcode == Js::OpCode::GeneratorBailInLabel)
40614063 {
40624064 continue ;
@@ -4977,14 +4979,12 @@ void LinearScan::GeneratorBailIn::SpillRegsForBailIn()
49774979 }
49784980}
49794981
4982+ // Note: Comments refer to rax/rcx for x64. For x86, we use their equivalence: eax/ecx
49804983// Restores the live stack locations followed by the live registers from
49814984// the interpreter's register slots.
49824985// RecordDefs each live register that is restored.
49834986//
49844987// Generates the following code:
4985- //
4986- // PUSH rax ; if needed
4987- // PUSH rcx ; if needed
49884988//
49894989// MOV rax, param0
49904990// MOV rax, [rax + JavascriptGenerator::GetFrameOffset()]
@@ -4998,8 +4998,6 @@ void LinearScan::GeneratorBailIn::SpillRegsForBailIn()
49984998//
49994999// MOV sym(register), [rax + regslot offset]
50005000//
5001- // POP rax; if needed
5002- // POP rcx; if needed
50035001IR::Instr* LinearScan::GeneratorBailIn::GenerateBailIn (IR::Instr* resumeLabelInstr, BailOutInfo* bailOutInfo)
50045002{
50055003 Assert (!bailOutInfo->capturedValues || bailOutInfo->capturedValues ->constantValues .Empty ());
@@ -5138,10 +5136,20 @@ bool LinearScan::GeneratorBailIn::NeedsReloadingValueWhenBailIn(StackSym* sym, L
51385136 {
51395137 if (this ->func ->GetJITFunctionBody ()->RegIsConstant (sym->GetByteCodeRegSlot ()))
51405138 {
5139+ // Resume jump table is inserted after we load symbols in the constant table,
5140+ // so at bail-in point, we can have two scenarios:
5141+ // 1) the symbols are still in registers
5142+ // 2) the symbols have already been "spilled"
5143+ // Since we don't save/restore constant symbols and simply insert loads of their
5144+ // values before use, in either case, there is no need to reload the values
51415145 return false ;
51425146 }
51435147 else
51445148 {
5149+ // Again, for all other constant symbols, if they are bytecodeUpwardExposed and they have
5150+ // already been "spilled", which means that the register allocator will automatically
5151+ // insert the load of their values later before use, we don't need to restore.
5152+ // Only restore symbols that are still in registers
51455153 return !lifetime->isSpilled ;
51465154 }
51475155 }
@@ -5159,6 +5167,8 @@ bool LinearScan::GeneratorBailIn::NeedsReloadingValueWhenBailIn(StackSym* sym, L
51595167
51605168IR::SymOpnd* LinearScan::GeneratorBailIn::CreateGeneratorObjectOpnd () const
51615169{
5170+ // First parameter passed to the jit'd frame
5171+ // See `CallGenerator` method
51625172 StackSym* sym = StackSym::NewParamSlotSym (1 , this ->func );
51635173 this ->func ->SetArgOffset (sym, LowererMD::GetFormalParamOffset () * MachPtr);
51645174 return IR::SymOpnd::New (sym, TyMachPtr, this ->func );
0 commit comments