Skip to content

Commit

Permalink
[1.2>master] [MERGE #958] Fixing bug with shared bailouts
Browse files Browse the repository at this point in the history
Merge pull request #958 from rajatd:bailoutArmBug
Shared bailouts for InlineMathFloor/Ceil/Round were bypassing the code on the bailout path that sets up data specific to a bailout (bailout kind, polymorphic inline cache index etc.) on the bailout record and were jumping directly to the bailout label. Fixed that.
  • Loading branch information
rajatd committed May 11, 2016
2 parents 5a79092 + 22d2fb0 commit 7f3a8f6
Show file tree
Hide file tree
Showing 4 changed files with 32 additions and 52 deletions.
19 changes: 9 additions & 10 deletions lib/Backend/Lower.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12162,11 +12162,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);
Expand All @@ -12179,14 +12178,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(
Expand Down Expand Up @@ -12234,10 +12237,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)
{
Expand Down
2 changes: 1 addition & 1 deletion lib/Backend/Lower.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
14 changes: 5 additions & 9 deletions lib/Backend/LowerMDShared.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8874,14 +8874,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;
Expand Down Expand Up @@ -9096,7 +9089,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
{
Expand Down
49 changes: 17 additions & 32 deletions lib/Backend/arm/LowerMD.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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);
Expand All @@ -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);
Expand Down Expand Up @@ -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);
Expand All @@ -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);
Expand Down Expand Up @@ -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);
Expand Down

0 comments on commit 7f3a8f6

Please sign in to comment.