@@ -3010,7 +3010,6 @@ Lowerer::LowerRange(IR::Instr *instrStart, IR::Instr *instrEnd, bool defaultDoFa
3010
3010
3011
3011
case Js::OpCode::GeneratorResumeJumpTable:
3012
3012
{
3013
- this->m_lowerGeneratorHelper.InsertBailOutForElidedYield();
3014
3013
this->m_lowerGeneratorHelper.LowerGeneratorResumeJumpTable(instr);
3015
3014
break;
3016
3015
}
@@ -29079,49 +29078,6 @@ void Lowerer::LowerGeneratorHelper::InsertNullOutGeneratorFrameInEpilogue(IR::La
29079
29078
InsertMove(indirOpnd, addrOpnd, insertionPoint);
29080
29079
}
29081
29080
29082
- void
29083
- Lowerer::LowerGeneratorHelper::InsertBailOutForElidedYield()
29084
- {
29085
- IR::LabelInstr* bailOutNoSaveLabel = nullptr;
29086
-
29087
- this->func->MapUntilYieldOffsetResumeLabels([this, &bailOutNoSaveLabel](int, const YieldOffsetResumeLabel& yorl)
29088
- {
29089
- if (yorl.Second() == nullptr)
29090
- {
29091
- if (bailOutNoSaveLabel == nullptr)
29092
- {
29093
- bailOutNoSaveLabel = IR::LabelInstr::New(Js::OpCode::Label, this->func);
29094
- }
29095
-
29096
- return true;
29097
- }
29098
-
29099
- return false;
29100
- });
29101
-
29102
- // Insert the bailoutnosave label somewhere along with a call to BailOutNoSave helper
29103
- if (bailOutNoSaveLabel != nullptr)
29104
- {
29105
- bailOutNoSaveLabel->m_hasNonBranchRef = true;
29106
- bailOutNoSaveLabel->isOpHelper = true;
29107
-
29108
- IR::Instr* exitPrevInstr = this->GetEpilogueForReturnStatements()->m_prev;
29109
- IR::Instr* bailOutCall = IR::Instr::New(Js::OpCode::Call, this->func);
29110
- IR::Instr* branchToEpilogue = IR::BranchInstr::New(LowererMD::MDUncondBranchOpcode, this->GetEpilogueForBailOut(), this->func);
29111
-
29112
- exitPrevInstr->InsertBefore(bailOutNoSaveLabel);
29113
- exitPrevInstr->InsertBefore(bailOutCall);
29114
- exitPrevInstr->InsertBefore(branchToEpilogue);
29115
-
29116
- IR::RegOpnd* frameRegOpnd = IR::RegOpnd::New(nullptr, LowererMD::GetRegFramePointer(), TyMachPtr, this->func);
29117
- this->lowererMD.LoadHelperArgument(bailOutCall, frameRegOpnd);
29118
- this->lowererMD.ChangeToHelperCall(bailOutCall, IR::HelperNoSaveRegistersBailOutForElidedYield);
29119
-
29120
- this->func->m_bailOutNoSaveLabel = bailOutNoSaveLabel;
29121
- LABELNAMESET(bailOutNoSaveLabel, "GeneratorBailOutForElidedYield");
29122
- }
29123
- }
29124
-
29125
29081
void
29126
29082
Lowerer::LowerGeneratorHelper::EnsureEpilogueLabels()
29127
29083
{
@@ -29165,30 +29121,76 @@ Lowerer::LowerGeneratorHelper::LowerGeneratorResumeJumpTable(IR::Instr* jumpTabl
29165
29121
Assert(this->func->GetJITFunctionBody()->IsCoroutine());
29166
29122
Assert(jumpTableInstr->m_opcode == Js::OpCode::GeneratorResumeJumpTable);
29167
29123
29124
+ IR::LabelInstr* bailOutForElidedYield = this->InsertBailOutForElidedYield();
29125
+
29168
29126
IR::Opnd* srcOpnd = jumpTableInstr->UnlinkSrc1();
29169
29127
29170
- this->func->MapYieldOffsetResumeLabels([this, &srcOpnd, &jumpTableInstr](int i, const YieldOffsetResumeLabel& yorl)
29128
+ this->func->MapYieldOffsetResumeLabels([this, &srcOpnd, &jumpTableInstr, &bailOutForElidedYield ](int i, const YieldOffsetResumeLabel& yorl)
29171
29129
{
29172
29130
uint32 offset = yorl.First();
29173
- IR::LabelInstr* label = yorl.Second();
29131
+ IR::LabelInstr* resumeLabel = yorl.Second();
29174
29132
29175
- if (label != nullptr && label->m_hasNonBranchRef )
29133
+ if (resumeLabel != nullptr)
29176
29134
{
29135
+ Assert(resumeLabel->IsGeneratorBailInInstr());
29177
29136
// Also fix up the bailout at the label with the jump to epilog that was not emitted in GenerateBailOut()
29178
- this->lowerer->GenerateJumpToEpilogForBailOut(label ->m_prev->GetBailOutInfo(), label ->m_prev, this->GetEpilogueForBailOut());
29137
+ this->lowerer->GenerateJumpToEpilogForBailOut(resumeLabel ->m_prev->GetBailOutInfo(), resumeLabel ->m_prev, this->GetEpilogueForBailOut());
29179
29138
}
29180
- else if (label == nullptr)
29139
+ else if (resumeLabel == nullptr)
29181
29140
{
29182
- label = this->func->m_bailOutNoSaveLabel ;
29141
+ resumeLabel = bailOutForElidedYield ;
29183
29142
}
29184
29143
29185
29144
// For each offset label pair, insert a compare of the offset and branch if equal to the label
29186
- this->lowerer->InsertCompareBranch(srcOpnd, IR::IntConstOpnd::New(offset, TyUint32, this->func), Js::OpCode::BrSrEq_A, label , jumpTableInstr);
29145
+ this->lowerer->InsertCompareBranch(srcOpnd, IR::IntConstOpnd::New(offset, TyUint32, this->func), Js::OpCode::BrSrEq_A, resumeLabel , jumpTableInstr);
29187
29146
});
29188
29147
29189
29148
jumpTableInstr->Remove();
29190
29149
}
29191
29150
29151
+ IR::LabelInstr*
29152
+ Lowerer::LowerGeneratorHelper::InsertBailOutForElidedYield()
29153
+ {
29154
+ IR::LabelInstr* bailOutNoSaveLabel = nullptr;
29155
+
29156
+ this->func->MapUntilYieldOffsetResumeLabels([this, &bailOutNoSaveLabel](int, const YieldOffsetResumeLabel& yorl)
29157
+ {
29158
+ if (yorl.Second() == nullptr)
29159
+ {
29160
+ if (bailOutNoSaveLabel == nullptr)
29161
+ {
29162
+ bailOutNoSaveLabel = IR::LabelInstr::New(Js::OpCode::Label, this->func);
29163
+ }
29164
+
29165
+ return true;
29166
+ }
29167
+
29168
+ return false;
29169
+ });
29170
+
29171
+ // Insert the bailoutnosave label somewhere along with a call to BailOutNoSave helper
29172
+ if (bailOutNoSaveLabel != nullptr)
29173
+ {
29174
+ bailOutNoSaveLabel->m_hasNonBranchRef = true;
29175
+
29176
+ IR::Instr* insertionPoint = this->func->m_bailOutForElidedYieldInsertionPoint->m_next;
29177
+ IR::Instr* bailOutCall = IR::Instr::New(Js::OpCode::Call, this->func);
29178
+ IR::Instr* branchToEpilogue = IR::BranchInstr::New(LowererMD::MDUncondBranchOpcode, this->GetEpilogueForBailOut(), this->func);
29179
+
29180
+ insertionPoint->InsertBefore(bailOutNoSaveLabel);
29181
+ insertionPoint->InsertBefore(bailOutCall);
29182
+ insertionPoint->InsertBefore(branchToEpilogue);
29183
+
29184
+ IR::RegOpnd* frameRegOpnd = IR::RegOpnd::New(nullptr, LowererMD::GetRegFramePointer(), TyMachPtr, this->func);
29185
+ this->lowererMD.LoadHelperArgument(bailOutCall, frameRegOpnd);
29186
+ this->lowererMD.ChangeToHelperCall(bailOutCall, IR::HelperNoSaveRegistersBailOutForElidedYield);
29187
+
29188
+ LABELNAMESET(bailOutNoSaveLabel, "GeneratorBailOutForElidedYield");
29189
+ }
29190
+
29191
+ return bailOutNoSaveLabel;
29192
+ }
29193
+
29192
29194
void
29193
29195
Lowerer::LowerGeneratorHelper::LowerCreateInterpreterStackFrameForGenerator(IR::Instr* instr)
29194
29196
{
0 commit comments