Skip to content

Commit dfd11cd

Browse files
committed
[MERGE #5250 @Cellule] Post-Op bailout with unconditional branches
Merge pull request #5250 from Cellule:post_op_bailout When searching for new bytecode instr for a post-op bailout, follow unconditional branches. OS#17449647
2 parents 83efad9 + cc811b1 commit dfd11cd

File tree

6 files changed

+60
-17
lines changed

6 files changed

+60
-17
lines changed

lib/Backend/FlowGraph.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -317,7 +317,9 @@ FlowGraph::Build(void)
317317

318318
Assert(leaveTarget->labelRefs.HasOne());
319319
IR::BranchInstr * brOnException = IR::BranchInstr::New(Js::OpCode::BrOnException, finallyLabel, instr->m_func);
320-
leaveTarget->labelRefs.Head()->InsertBefore(brOnException);
320+
IR::BranchInstr * leaveInstr = leaveTarget->labelRefs.Head();
321+
brOnException->SetByteCodeOffset(leaveInstr);
322+
leaveInstr->InsertBefore(brOnException);
321323

322324
instrPrev = instr->m_prev;
323325
}

lib/Backend/GlobOptBailOut.cpp

Lines changed: 2 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1372,24 +1372,10 @@ GlobOpt::MayNeedBailOnImplicitCall(IR::Instr const * instr, Value const * src1Va
13721372
void
13731373
GlobOpt::GenerateBailAfterOperation(IR::Instr * *const pInstr, IR::BailOutKind kind)
13741374
{
1375-
Assert(pInstr);
1375+
Assert(pInstr && *pInstr);
13761376

13771377
IR::Instr* instr = *pInstr;
1378-
Assert(instr);
1379-
1380-
IR::Instr * nextInstr = instr->GetNextRealInstrOrLabel();
1381-
uint32 currentOffset = instr->GetByteCodeOffset();
1382-
while (nextInstr->GetByteCodeOffset() == Js::Constants::NoByteCodeOffset ||
1383-
nextInstr->GetByteCodeOffset() == currentOffset)
1384-
{
1385-
nextInstr = nextInstr->GetNextRealInstrOrLabel();
1386-
}
1387-
// This can happen due to break block removal
1388-
while (nextInstr->GetByteCodeOffset() == Js::Constants::NoByteCodeOffset ||
1389-
nextInstr->GetByteCodeOffset() < currentOffset)
1390-
{
1391-
nextInstr = nextInstr->GetNextRealInstrOrLabel();
1392-
}
1378+
IR::Instr * nextInstr = instr->GetNextByteCodeInstr();
13931379
IR::Instr * bailOutInstr = instr->ConvertToBailOutInstr(nextInstr, kind);
13941380
if (this->currentBlock->GetLastInstr() == instr)
13951381
{

lib/Backend/IR.cpp

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2704,6 +2704,38 @@ Instr::GetNextBranchOrLabel() const
27042704
return instr;
27052705
}
27062706

2707+
IR::Instr *
2708+
Instr::GetNextByteCodeInstr() const
2709+
{
2710+
IR::Instr * nextInstr = GetNextRealInstrOrLabel();
2711+
uint32 currentOffset = GetByteCodeOffset();
2712+
const auto getNext = [](IR::Instr* nextInstr) -> IR::Instr*
2713+
{
2714+
if (nextInstr->IsBranchInstr())
2715+
{
2716+
IR::BranchInstr* branchInstr = nextInstr->AsBranchInstr();
2717+
AssertMsg(branchInstr->IsUnconditional(), "We can't know which branch to take on a conditionnal branch");
2718+
if (branchInstr->IsUnconditional())
2719+
{
2720+
return branchInstr->GetTarget();
2721+
}
2722+
}
2723+
return nextInstr->GetNextRealInstrOrLabel();
2724+
};
2725+
while (nextInstr->GetByteCodeOffset() == Js::Constants::NoByteCodeOffset ||
2726+
nextInstr->GetByteCodeOffset() == currentOffset)
2727+
{
2728+
nextInstr = getNext(nextInstr);
2729+
}
2730+
// This can happen due to break block removal
2731+
while (nextInstr->GetByteCodeOffset() == Js::Constants::NoByteCodeOffset ||
2732+
nextInstr->GetByteCodeOffset() < currentOffset)
2733+
{
2734+
nextInstr = getNext(nextInstr);
2735+
}
2736+
return nextInstr;
2737+
}
2738+
27072739
///----------------------------------------------------------------------------
27082740
///
27092741
/// Instr::GetPrevRealInstr

lib/Backend/IR.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -288,6 +288,7 @@ class Instr
288288
IR::Instr * GetNextRealInstr() const;
289289
IR::Instr * GetNextRealInstrOrLabel() const;
290290
IR::Instr * GetNextBranchOrLabel() const;
291+
IR::Instr * GetNextByteCodeInstr() const;
291292
IR::Instr * GetPrevRealInstr() const;
292293
IR::Instr * GetPrevRealInstrOrLabel() const;
293294
IR::LabelInstr *GetPrevLabelInstr() const;

test/bailout/bug17449647.js

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
//-------------------------------------------------------------------------------------------------------
2+
// Copyright (C) Microsoft. All rights reserved.
3+
// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
4+
//-------------------------------------------------------------------------------------------------------
5+
6+
var strvar1 = "";
7+
function foo() {
8+
switch (strvar1) {
9+
case 1:
10+
this();
11+
case "":
12+
}
13+
}
14+
for (let i = 0; i < 1000; ++i) {
15+
foo();
16+
}
17+
console.log("pass");

test/bailout/rlexe.xml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -270,4 +270,9 @@
270270
<files>bug13674598.js</files>
271271
</default>
272272
</test>
273+
<test>
274+
<default>
275+
<files>bug17449647.js</files>
276+
</default>
277+
</test>
273278
</regress-exe>

0 commit comments

Comments
 (0)