@@ -517,35 +517,21 @@ IR::Instr* LinearScanMD::GeneratorBailIn::GenerateBailIn(IR::Instr* resumeLabelI
517517 instrAfter /* instrInsertRegSym */
518518 };
519519
520- SaveInitializedRegister saveInitializedReg { false /* rax */ , false /* rcx */ };
521-
522520 // 4) Restore symbols
523521 // - We don't need to restore argObjSyms because StackArgs is currently not enabled
524522 // Commented out here in case we do want to enable it in the future:
525523 // this->InsertRestoreSymbols(bailOutInfo->capturedValues->argObjSyms, insertionPoint, saveInitializedReg);
526524 //
527525 // - We move all argout symbols right before the call so we don't need to restore argouts either
528- this ->InsertRestoreSymbols (bailOutInfo->byteCodeUpwardExposedUsed , insertionPoint, saveInitializedReg );
526+ this ->InsertRestoreSymbols (bailOutInfo->byteCodeUpwardExposedUsed , insertionPoint);
529527 Assert (!this ->func ->IsStackArgsEnabled ());
530528
531- // 5) Save/restore rax/rcx if needed
532- if (saveInitializedReg.rax )
533- {
534- this ->InsertSaveAndRestore (resumeLabelInstr, instrAfter, raxRegOpnd);
535- }
536-
537- if (saveInitializedReg.rcx )
538- {
539- this ->InsertSaveAndRestore (resumeLabelInstr, instrAfter, rcxRegOpnd);
540- }
541-
542529 return instrAfter;
543530}
544531
545532void LinearScanMD::GeneratorBailIn::InsertRestoreSymbols (
546533 BVSparse<JitArenaAllocator>* symbols,
547- BailInInsertionPoint& insertionPoint,
548- SaveInitializedRegister& saveInitializedReg
534+ BailInInsertionPoint& insertionPoint
549535)
550536{
551537 if (symbols == nullptr )
@@ -558,89 +544,77 @@ void LinearScanMD::GeneratorBailIn::InsertRestoreSymbols(
558544 StackSym* stackSym = this ->func ->m_symTable ->FindStackSym (symId);
559545 Lifetime* lifetime = stackSym->scratch .linearScan .lifetime ;
560546
561- if (this ->NeedsReloadingValueWhenBailIn (stackSym, lifetime))
547+ if (! this ->NeedsReloadingValueWhenBailIn (stackSym, lifetime))
562548 {
563- Js::RegSlot regSlot = stackSym->GetByteCodeRegSlot ();
564- IR::Opnd* srcOpnd = IR::IndirOpnd::New (
565- this ->raxRegOpnd ,
566- this ->GetOffsetFromInterpreterStackFrame (regSlot),
567- stackSym->GetType (),
568- this ->func
569- );
570-
571- if (lifetime->isSpilled )
549+ continue ;
550+ }
551+
552+ Js::RegSlot regSlot = stackSym->GetByteCodeRegSlot ();
553+ IR::Opnd* srcOpnd = IR::IndirOpnd::New (
554+ this ->raxRegOpnd ,
555+ this ->GetOffsetFromInterpreterStackFrame (regSlot),
556+ stackSym->GetType (),
557+ this ->func
558+ );
559+
560+ if (lifetime->isSpilled )
561+ {
562+ Assert (!stackSym->IsConst ());
563+ // Stack restores require an extra register since we can't move an indir directly to an indir on amd64
564+ IR::SymOpnd* dstOpnd = IR::SymOpnd::New (stackSym, stackSym->GetType (), this ->func );
565+ LinearScan::InsertMove (this ->rcxRegOpnd , srcOpnd, insertionPoint.instrInsertStackSym );
566+ LinearScan::InsertMove (dstOpnd, this ->rcxRegOpnd , insertionPoint.instrInsertStackSym );
567+ }
568+ else
569+ {
570+ // Register restores must come after stack restores so that we have RAX and RCX free to
571+ // use for stack restores and further RAX must be restored last since it holds the
572+ // pointer to the InterpreterStackFrame from which we are restoring values.
573+ // We must also track these restores using RecordDef in case the symbols are spilled.
574+
575+ IR::Instr* instr;
576+
577+ if (stackSym->IsConst ())
572578 {
573- Assert (!stackSym->IsConst ());
574- // Stack restores require an extra register since we can't move an indir directly to an indir on amd64
575- IR::SymOpnd* dstOpnd = IR::SymOpnd::New (stackSym, stackSym->GetType (), this ->func );
576- LinearScan::InsertMove (this ->rcxRegOpnd , srcOpnd, insertionPoint.instrInsertStackSym );
577- LinearScan::InsertMove (dstOpnd, this ->rcxRegOpnd , insertionPoint.instrInsertStackSym );
579+ instr = this ->linearScanMD ->linearScan ->InsertLoad (insertionPoint.instrInsertRegSym , stackSym, lifetime->reg );
578580 }
579581 else
580582 {
581- // Register restores must come after stack restores so that we have RAX and RCX free to
582- // use for stack restores and further RAX must be restored last since it holds the
583- // pointer to the InterpreterStackFrame from which we are restoring values.
584- // We must also track these restores using RecordDef in case the symbols are spilled.
583+ IR::RegOpnd* dstRegOpnd = IR::RegOpnd::New (stackSym, stackSym-> GetType (), this -> func );
584+ dstRegOpnd-> SetReg (lifetime-> reg );
585+ instr = LinearScan::InsertMove (dstRegOpnd, srcOpnd, insertionPoint. instrInsertRegSym );
586+ }
585587
586- IR::Instr* instr;
587-
588- if (stackSym->IsConst ())
589- {
590- instr = this ->linearScanMD ->linearScan ->InsertLoad (insertionPoint.instrInsertRegSym , stackSym, lifetime->reg );
591- }
592- else
593- {
594- IR::RegOpnd* dstRegOpnd = IR::RegOpnd::New (stackSym, stackSym->GetType (), this ->func );
595- dstRegOpnd->SetReg (lifetime->reg );
596- instr = LinearScan::InsertMove (dstRegOpnd, srcOpnd, insertionPoint.instrInsertRegSym );
597- }
588+ if (insertionPoint.instrInsertRegSym == insertionPoint.instrInsertStackSym )
589+ {
590+ // This is the first register sym, make sure we don't insert stack stores
591+ // after this instruction so we can ensure rax and rcx remain free to use
592+ // for restoring spilled stack syms.
593+ insertionPoint.instrInsertStackSym = instr;
594+ }
598595
599- if (insertionPoint.instrInsertRegSym == insertionPoint.instrInsertStackSym )
600- {
601- // This is the first register sym, make sure we don't insert stack stores
602- // after this instruction so we can ensure rax and rcx remain free to use
603- // for restoring spilled stack syms.
604- insertionPoint.instrInsertStackSym = instr;
605- }
596+ if (lifetime->reg == RegRAX)
597+ {
598+ // Ensure rax is restored last
599+ Assert (insertionPoint.instrInsertRegSym != insertionPoint.instrInsertStackSym );
606600
607- if (lifetime->reg == RegRAX)
601+ insertionPoint.instrInsertRegSym = instr;
602+
603+ if (insertionPoint.raxRestoreInstr != nullptr )
608604 {
609- // Ensure rax is restored last
610- Assert (insertionPoint.instrInsertRegSym != insertionPoint.instrInsertStackSym );
611-
612- insertionPoint.instrInsertRegSym = instr;
613-
614- if (insertionPoint.raxRestoreInstr != nullptr )
615- {
616- AssertMsg (false , " this is unexpected until copy prop is enabled" );
617- // rax was mapped to multiple bytecode registers. Obviously only the first
618- // restore we do will work so change all following stores to `mov rax, rax`.
619- // We still need to keep them around for RecordDef in case the corresponding
620- // dst sym is spilled later on.
621- insertionPoint.raxRestoreInstr ->FreeSrc1 ();
622- insertionPoint.raxRestoreInstr ->SetSrc1 (this ->raxRegOpnd );
623- }
624-
625- insertionPoint.raxRestoreInstr = instr;
605+ AssertMsg (false , " this is unexpected until copy prop is enabled" );
606+ // rax was mapped to multiple bytecode registers. Obviously only the first
607+ // restore we do will work so change all following stores to `mov rax, rax`.
608+ // We still need to keep them around for RecordDef in case the corresponding
609+ // dst sym is spilled later on.
610+ insertionPoint.raxRestoreInstr ->FreeSrc1 ();
611+ insertionPoint.raxRestoreInstr ->SetSrc1 (this ->raxRegOpnd );
626612 }
627613
628- this ->linearScanMD ->linearScan ->RecordDef (lifetime, instr, 0 );
629- }
630- }
631- else
632- {
633- if (lifetime->reg == RegRAX)
634- {
635- Assert (!saveInitializedReg.rax );
636- saveInitializedReg.rax = true ;
614+ insertionPoint.raxRestoreInstr = instr;
637615 }
638616
639- if (lifetime->reg == RegRCX)
640- {
641- Assert (!saveInitializedReg.rcx );
642- saveInitializedReg.rcx = true ;
643- }
617+ this ->linearScanMD ->linearScan ->RecordDef (lifetime, instr, 0 );
644618 }
645619 }
646620 NEXT_BITSET_IN_SPARSEBV;
@@ -699,11 +673,3 @@ uint32 LinearScanMD::GeneratorBailIn::GetOffsetFromInterpreterStackFrame(Js::Reg
699673 return regSlot * sizeof (Js::Var) + Js::InterpreterStackFrame::GetOffsetOfLocals ();
700674 }
701675}
702-
703- void LinearScanMD::GeneratorBailIn::InsertSaveAndRestore (IR::Instr* start, IR::Instr* end, IR::RegOpnd* reg)
704- {
705- IR::Instr* push = IR::Instr::New (Js::OpCode::PUSH, nullptr /* dst */ , reg /* src1 */ , this ->func );
706- IR::Instr* pop = IR::Instr::New (Js::OpCode::POP, reg /* dst */ , this ->func );
707- start->InsertAfter (push);
708- end->InsertBefore (pop);
709- }
0 commit comments