From dc20aef28b417b84465bbeb02bac80f95d00a10a Mon Sep 17 00:00:00 2001 From: Rajat Dua Date: Tue, 10 May 2016 18:24:50 -0700 Subject: [PATCH] Fixing bug with shared bailouts --- lib/Backend/Lower.cpp | 19 +++++++------- lib/Backend/Lower.h | 2 +- lib/Backend/LowerMDShared.cpp | 14 ++++------ lib/Backend/arm/LowerMD.cpp | 49 ++++++++++++----------------------- 4 files changed, 32 insertions(+), 52 deletions(-) diff --git a/lib/Backend/Lower.cpp b/lib/Backend/Lower.cpp index 090cba84b92..dc494347ee7 100644 --- a/lib/Backend/Lower.cpp +++ b/lib/Backend/Lower.cpp @@ -12157,11 +12157,10 @@ Lowerer::GenerateObjectTestAndTypeLoad(IR::Instr *instrLdSt, IR::RegOpnd *opndBa } IR::LabelInstr * -Lowerer::GenerateBailOut(IR::Instr * instr, IR::BranchInstr * branchInstr, IR::LabelInstr *bailOutLabel) +Lowerer::GenerateBailOut(IR::Instr * instr, IR::BranchInstr * branchInstr, IR::LabelInstr *bailOutLabel, IR::LabelInstr * collectRuntimeStatsLabel) { BailOutInfo * bailOutInfo = instr->GetBailOutInfo(); IR::Instr * bailOutInstr = bailOutInfo->bailOutInstr; - IR::LabelInstr *collectRuntimeStatsLabel = nullptr; if (instr->IsCloned()) { Assert(bailOutInstr != instr); @@ -12174,14 +12173,18 @@ Lowerer::GenerateBailOut(IR::Instr * instr, IR::BranchInstr * branchInstr, IR::L return bailOutLabel; } + // Add helper label to trigger layout. + if (!collectRuntimeStatsLabel) + { + collectRuntimeStatsLabel = IR::LabelInstr::New(Js::OpCode::Label, this->m_func, true); + } + Assert(!collectRuntimeStatsLabel->IsLinked()); + instr->InsertBefore(collectRuntimeStatsLabel); + if (bailOutInstr != instr) { // this bailOutInfo is shared, just jump to the bailout target - // Add helper label to trigger layout. - collectRuntimeStatsLabel = IR::LabelInstr::New(Js::OpCode::Label, this->m_func, true); - instr->InsertBefore(collectRuntimeStatsLabel); - IR::MemRefOpnd *pIndexOpndForBailOutKind = IR::MemRefOpnd::New((BYTE*)bailOutInfo->bailOutRecord + BailOutRecord::GetOffsetOfBailOutKind(), TyUint32, this->m_func, IR::AddrOpndKindDynamicBailOutKindRef); m_lowererMD.CreateAssign( @@ -12229,10 +12232,6 @@ Lowerer::GenerateBailOut(IR::Instr * instr, IR::BranchInstr * branchInstr, IR::L // The bailout hasn't be generated yet. Assert(!bailOutInstr->IsLabelInstr()); - // Add helper label to trigger layout. - collectRuntimeStatsLabel = IR::LabelInstr::New(Js::OpCode::Label, this->m_func, true); - instr->InsertBefore(collectRuntimeStatsLabel); - // capture the condition for this bailout if (bailOutLabel == nullptr) { diff --git a/lib/Backend/Lower.h b/lib/Backend/Lower.h index 31d872d0c34..57d4ea2bb49 100644 --- a/lib/Backend/Lower.h +++ b/lib/Backend/Lower.h @@ -408,7 +408,7 @@ class Lowerer void PreserveSourcesForBailOnResultCondition(IR::Instr *const instr, IR::LabelInstr *const skipBailOutLabel) const; void LowerInstrWithBailOnResultCondition(IR::Instr *const instr, const IR::BailOutKind bailOutKind, IR::LabelInstr *const bailOutLabel, IR::LabelInstr *const skipBailOutLabel) const; void GenerateObjectTestAndTypeLoad(IR::Instr *instrLdSt, IR::RegOpnd *opndBase, IR::RegOpnd *opndType, IR::LabelInstr *labelHelper); - IR::LabelInstr *GenerateBailOut(IR::Instr * instr, IR::BranchInstr * branchInstr = nullptr, IR::LabelInstr * labelBailOut = nullptr); + IR::LabelInstr *GenerateBailOut(IR::Instr * instr, IR::BranchInstr * branchInstr = nullptr, IR::LabelInstr * labelBailOut = nullptr, IR::LabelInstr * collectRuntimeStatsLabel = nullptr); void GenerateJumpToEpilogForBailOut(BailOutInfo * bailOutInfo, IR::Instr *instrAfter); void LowerDivI4(IR::Instr * const instr); diff --git a/lib/Backend/LowerMDShared.cpp b/lib/Backend/LowerMDShared.cpp index df7b136841a..156b3427101 100644 --- a/lib/Backend/LowerMDShared.cpp +++ b/lib/Backend/LowerMDShared.cpp @@ -8849,14 +8849,7 @@ void LowererMD::GenerateFastInlineBuiltInCall(IR::Instr* instr, IR::JnHelperMeth if (instr->GetDst()->IsInt32()) { sharedBailout = (instr->GetBailOutInfo()->bailOutInstr != instr) ? true : false; - if (sharedBailout) - { - bailoutLabel = instr->GetBailOutInfo()->bailOutInstr->AsLabelInstr(); - } - else - { - bailoutLabel = IR::LabelInstr::New(Js::OpCode::Label, this->m_func, /*helperLabel*/true); - } + bailoutLabel = IR::LabelInstr::New(Js::OpCode::Label, this->m_func, /*helperLabel*/true); } IR::Opnd * zero; @@ -9071,7 +9064,10 @@ void LowererMD::GenerateFastInlineBuiltInCall(IR::Instr* instr, IR::JnHelperMeth { instr->InsertBefore(bailoutLabel); } - this->m_lowerer->GenerateBailOut(instr); + + // In case of a shared bailout, we should jump to the code that sets some data on the bailout record which is specific + // to this bailout. Pass the bailoutLabel to GenerateFunction so that it may use the label as the collectRuntimeStatsLabel. + this->m_lowerer->GenerateBailOut(instr, nullptr, nullptr, sharedBailout ? bailoutLabel : nullptr); } else { diff --git a/lib/Backend/arm/LowerMD.cpp b/lib/Backend/arm/LowerMD.cpp index f972729f51e..821911c726d 100644 --- a/lib/Backend/arm/LowerMD.cpp +++ b/lib/Backend/arm/LowerMD.cpp @@ -8399,17 +8399,9 @@ LowererMD::GenerateFastInlineBuiltInMathFloor(IR::Instr* instr) IR::RegOpnd* floatOpnd = IR::RegOpnd::New(TyFloat64, this->m_func); this->m_lowerer->InsertMove(floatOpnd, src, instr); - IR::LabelInstr * bailoutLabel; + IR::LabelInstr * bailoutLabel = IR::LabelInstr::New(Js::OpCode::Label, this->m_func, /*helperLabel*/true);; bool sharedBailout = (instr->GetBailOutInfo()->bailOutInstr != instr) ? true : false; - if(sharedBailout) - { - bailoutLabel = instr->GetBailOutInfo()->bailOutInstr->AsLabelInstr(); - } - else - { - bailoutLabel = IR::LabelInstr::New(Js::OpCode::Label, this->m_func, true); - } - + // NaN check IR::Instr *instrCmp = IR::Instr::New(Js::OpCode::VCMPF64, this->m_func); instrCmp->SetSrc1(floatOpnd); @@ -8481,7 +8473,10 @@ LowererMD::GenerateFastInlineBuiltInMathFloor(IR::Instr* instr) { instr->InsertBefore(bailoutLabel); } - this->m_lowerer->GenerateBailOut(instr); + + // In case of a shared bailout, we should jump to the code that sets some data on the bailout record which is specific + // to this bailout. Pass the bailoutLabel to GenerateFunction so that it may use the label as the collectRuntimeStatsLabel. + this->m_lowerer->GenerateBailOut(instr, nullptr, nullptr, sharedBailout ? bailoutLabel : nullptr); // MOV dst, intOpnd IR::Instr* movInstr = IR::Instr::New(Js::OpCode::MOV, dst, intOpnd, this->m_func); @@ -8502,16 +8497,8 @@ LowererMD::GenerateFastInlineBuiltInMathCeil(IR::Instr* instr) IR::RegOpnd* floatOpnd = IR::RegOpnd::New(TyFloat64, this->m_func); this->m_lowerer->InsertMove(floatOpnd, src, instr); - IR::LabelInstr * bailoutLabel; + IR::LabelInstr * bailoutLabel = IR::LabelInstr::New(Js::OpCode::Label, this->m_func, /*helperLabel*/true);; bool sharedBailout = (instr->GetBailOutInfo()->bailOutInstr != instr) ? true : false; - if(sharedBailout) - { - bailoutLabel = instr->GetBailOutInfo()->bailOutInstr->AsLabelInstr(); - } - else - { - bailoutLabel = IR::LabelInstr::New(Js::OpCode::Label, this->m_func, true); - } // NaN check IR::Instr *instrCmp = IR::Instr::New(Js::OpCode::VCMPF64, this->m_func); @@ -8589,7 +8576,10 @@ LowererMD::GenerateFastInlineBuiltInMathCeil(IR::Instr* instr) { instr->InsertBefore(bailoutLabel); } - this->m_lowerer->GenerateBailOut(instr); + + // In case of a shared bailout, we should jump to the code that sets some data on the bailout record which is specific + // to this bailout. Pass the bailoutLabel to GenerateFunction so that it may use the label as the collectRuntimeStatsLabel. + this->m_lowerer->GenerateBailOut(instr, nullptr, nullptr, sharedBailout ? bailoutLabel : nullptr); // MOV dst, intOpnd IR::Instr* movInstr = IR::Instr::New(Js::OpCode::MOV, dst, intOpnd, this->m_func); @@ -8610,17 +8600,9 @@ LowererMD::GenerateFastInlineBuiltInMathRound(IR::Instr* instr) IR::RegOpnd* floatOpnd = IR::RegOpnd::New(TyFloat64, this->m_func); this->m_lowerer->InsertMove(floatOpnd, src, instr); - IR::LabelInstr * bailoutLabel; + IR::LabelInstr * bailoutLabel = IR::LabelInstr::New(Js::OpCode::Label, this->m_func, /*helperLabel*/true);; bool sharedBailout = (instr->GetBailOutInfo()->bailOutInstr != instr) ? true : false; - if(sharedBailout) - { - bailoutLabel = instr->GetBailOutInfo()->bailOutInstr->AsLabelInstr(); - } - else - { - bailoutLabel = IR::LabelInstr::New(Js::OpCode::Label, this->m_func, true); - } - + // NaN check IR::Instr *instrCmp = IR::Instr::New(Js::OpCode::VCMPF64, this->m_func); instrCmp->SetSrc1(floatOpnd); @@ -8701,7 +8683,10 @@ LowererMD::GenerateFastInlineBuiltInMathRound(IR::Instr* instr) { instr->InsertBefore(bailoutLabel); } - this->m_lowerer->GenerateBailOut(instr); + + // In case of a shared bailout, we should jump to the code that sets some data on the bailout record which is specific + // to this bailout. Pass the bailoutLabel to GenerateFunction so that it may use the label as the collectRuntimeStatsLabel. + this->m_lowerer->GenerateBailOut(instr, nullptr, nullptr, sharedBailout ? bailoutLabel : nullptr); // MOV dst, intOpnd IR::Instr* movInstr = IR::Instr::New(Js::OpCode::MOV, dst, intOpnd, this->m_func);