Skip to content

Commit 3dab094

Browse files
committed
Fixing bug with hoisting a type check bailout
1 parent 838b864 commit 3dab094

File tree

7 files changed

+72
-15
lines changed

7 files changed

+72
-15
lines changed

lib/Backend/BailOut.cpp

+12-4
Original file line numberDiff line numberDiff line change
@@ -292,7 +292,7 @@ BailOutRecord::BailOutRecord(uint32 bailOutOffset, uint bailOutCacheIndex, IR::B
292292
argOutOffsetInfo(nullptr), bailOutOffset(bailOutOffset),
293293
bailOutCount(0), polymorphicCacheIndex(bailOutCacheIndex), bailOutKind(kind),
294294
branchValueRegSlot(Js::Constants::NoRegister),
295-
ehBailoutData(nullptr), m_bailOutRecordId(0)
295+
ehBailoutData(nullptr), m_bailOutRecordId(0), type(Normal)
296296
#if DBG
297297
, inlineDepth(0)
298298
#endif
@@ -1279,9 +1279,9 @@ BailOutRecord::BailOutFromLoopBodyHelper(Js::JavascriptCallStackLayout * layout,
12791279
return bailOutOffset;
12801280
}
12811281

1282-
void BailOutRecord::UpdatePolymorphicFieldAccess(Js::JavascriptFunction * function, BailOutRecord const * bailOutRecord)
1282+
void BailOutRecord::UpdatePolymorphicFieldAccess(Js::JavascriptFunction * function, BailOutRecord const * bailOutRecord)
12831283
{
1284-
Js::FunctionBody * executeFunction = function->GetFunctionBody();
1284+
Js::FunctionBody * executeFunction = bailOutRecord->type == Shared ? ((SharedBailOutRecord*)bailOutRecord)->functionBody : function->GetFunctionBody();
12851285
Js::DynamicProfileInfo *dynamicProfileInfo = nullptr;
12861286
if (executeFunction->HasDynamicProfileInfo())
12871287
{
@@ -1290,7 +1290,7 @@ void BailOutRecord::UpdatePolymorphicFieldAccess(Js::JavascriptFunction * funct
12901290

12911291
if (bailOutRecord->polymorphicCacheIndex != (uint)-1)
12921292
{
1293-
dynamicProfileInfo->RecordPolymorphicFieldAccess(function->GetFunctionBody(), bailOutRecord->polymorphicCacheIndex);
1293+
dynamicProfileInfo->RecordPolymorphicFieldAccess(executeFunction, bailOutRecord->polymorphicCacheIndex);
12941294
if (IR::IsEquivalentTypeCheckBailOutKind(bailOutRecord->bailOutKind))
12951295
{
12961296
// If we've already got a polymorphic inline cache, and if we've got an equivalent type check
@@ -2546,6 +2546,7 @@ BranchBailOutRecord::BranchBailOutRecord(uint32 trueBailOutOffset, uint32 falseB
25462546
: BailOutRecord(trueBailOutOffset, (uint)-1, kind, bailOutFunc), falseBailOutOffset(falseBailOutOffset)
25472547
{
25482548
branchValueRegSlot = resultByteCodeReg;
2549+
type = BailoutRecordType::Branch;
25492550
};
25502551

25512552
Js::Var BranchBailOutRecord::BailOut(BranchBailOutRecord const * bailOutRecord, BOOL cond)
@@ -2633,6 +2634,13 @@ BranchBailOutRecord::BailOutFromLoopBodyInlined(Js::JavascriptCallStackLayout *
26332634
return __super::BailOutFromLoopBodyInlinedCommon(layout, bailOutRecord, bailOutOffset, returnAddress, bailOutRecord->bailOutKind, branchValue);
26342635
}
26352636

2637+
SharedBailOutRecord::SharedBailOutRecord(uint32 bailOutOffset, uint bailOutCacheIndex, IR::BailOutKind kind, Func *bailOutFunc)
2638+
: BailOutRecord(bailOutOffset, bailOutCacheIndex, kind, bailOutFunc)
2639+
{
2640+
this->functionBody = nullptr;
2641+
this->type = BailoutRecordType::Shared;
2642+
}
2643+
26362644
void LazyBailOutRecord::SetBailOutKind()
26372645
{
26382646
this->bailoutRecord->SetBailOutKind(IR::BailOutKind::LazyBailOut);

lib/Backend/BailOut.h

+12-4
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,13 @@ class BailOutRecord
200200
template <typename Fn>
201201
void MapArgOutOffsets(Fn fn);
202202

203+
enum BailoutRecordType : byte
204+
{
205+
Normal = 0,
206+
Branch = 1,
207+
Shared = 2
208+
};
209+
BailoutRecordType GetType() { return type; }
203210
protected:
204211
struct BailOutReturnValue
205212
{
@@ -308,6 +315,7 @@ class BailOutRecord
308315
void DumpLocalOffsets(uint count, int argOutSlotStart);
309316
void DumpValue(int offset, bool isFloat64);
310317
#endif
318+
BailoutRecordType type;
311319
ushort bailOutCount;
312320
uint32 m_bailOutRecordId;
313321

@@ -338,13 +346,13 @@ class BranchBailOutRecord : public BailOutRecord
338346
uint falseBailOutOffset;
339347
};
340348

341-
class FunctionBailOutRecord
349+
class SharedBailOutRecord : public BailOutRecord
342350
{
343351
public:
344-
FunctionBailOutRecord() : constantCount(0), constants(nullptr) {}
352+
Js::FunctionBody* functionBody; // function body in which the bailout originally was before possible hoisting
345353

346-
uint constantCount;
347-
Js::Var * constants;
354+
SharedBailOutRecord(uint32 bailOutOffset, uint bailOutCacheIndex, IR::BailOutKind kind, Func *bailOutFunc);
355+
static size_t GetOffsetOfFunctionBody() { return offsetof(SharedBailOutRecord, functionBody); }
348356
};
349357

350358
template <typename Fn>

lib/Backend/Lower.cpp

+18-3
Original file line numberDiff line numberDiff line change
@@ -12195,13 +12195,20 @@ Lowerer::GenerateBailOut(IR::Instr * instr, IR::BranchInstr * branchInstr, IR::L
1219512195
// Generate code to write the cache index into the bailout record before we jump to the call site.
1219612196
Assert(bailOutInfo->polymorphicCacheIndex != (uint)-1);
1219712197
Assert(bailOutInfo->bailOutRecord);
12198-
1219912198
IR::MemRefOpnd *pIndexOpnd =
1220012199
IR::MemRefOpnd::New((BYTE*)bailOutInfo->bailOutRecord + BailOutRecord::GetOffsetOfPolymorphicCacheIndex(), TyUint32, this->m_func);
1220112200
m_lowererMD.CreateAssign(
1220212201
pIndexOpnd, IR::IntConstOpnd::New(bailOutInfo->polymorphicCacheIndex, TyUint32, this->m_func), instr);
1220312202
}
1220412203

12204+
if (bailOutInfo->bailOutRecord->GetType() == BailOutRecord::BailoutRecordType::Shared)
12205+
{
12206+
IR::MemRefOpnd *functionBodyOpnd =
12207+
IR::MemRefOpnd::New((BYTE*)bailOutInfo->bailOutRecord + SharedBailOutRecord::GetOffsetOfFunctionBody(), TyMachPtr, this->m_func);
12208+
m_lowererMD.CreateAssign(
12209+
functionBodyOpnd, CreateFunctionBodyOpnd(instr->m_func), instr);
12210+
}
12211+
1220512212
// GenerateBailOut should have replaced this as a label as we should have already lowered
1220612213
// the main bailOutInstr.
1220712214
IR::LabelInstr * bailOutTargetLabel = bailOutInstr->AsLabelInstr();
@@ -12313,8 +12320,16 @@ Lowerer::GenerateBailOut(IR::Instr * instr, IR::BranchInstr * branchInstr, IR::L
1231312320
}
1231412321
else
1231512322
{
12316-
bailOutRecord = NativeCodeDataNewZ(this->m_func->GetNativeCodeDataAllocator(),
12317-
BailOutRecord, bailOutInfo->bailOutOffset, bailOutInfo->polymorphicCacheIndex, instr->GetBailOutKind(), bailOutInfo->bailOutFunc);
12323+
if (bailOutInstr->GetBailOutKind() == IR::BailOutShared)
12324+
{
12325+
bailOutRecord = NativeCodeDataNewZ(this->m_func->GetNativeCodeDataAllocator(),
12326+
SharedBailOutRecord, bailOutInfo->bailOutOffset, bailOutInfo->polymorphicCacheIndex, instr->GetBailOutKind(), bailOutInfo->bailOutFunc);
12327+
}
12328+
else
12329+
{
12330+
bailOutRecord = NativeCodeDataNewZ(this->m_func->GetNativeCodeDataAllocator(),
12331+
BailOutRecord, bailOutInfo->bailOutOffset, bailOutInfo->polymorphicCacheIndex, instr->GetBailOutKind(), bailOutInfo->bailOutFunc);
12332+
}
1231812333

1231912334
helperMethod = IR::HelperSaveAllRegistersAndBailOut;
1232012335
#ifdef _M_IX86

lib/Runtime/Base/FunctionBody.h

-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99

1010
struct CodeGenWorkItem;
1111
class SourceContextInfo;
12-
class FunctionBailOutRecord;
1312
struct DeferredFunctionStub;
1413
#ifdef DYNAMIC_PROFILE_MUTATOR
1514
class DynamicProfileMutator;

test/Optimizer/bug7100343.js renamed to test/Optimizer/forceRejitBugs.js

+28-1
Original file line numberDiff line numberDiff line change
@@ -10,4 +10,31 @@ function foo(i1)
1010
}
1111
print(foo());
1212
print(foo());
13-
print(foo());
13+
print(foo());
14+
15+
function test0() {
16+
}
17+
var arrObj0 = {};
18+
var func2 = function () {
19+
Object;
20+
function v0() {
21+
for (var v1 = 0; v1 < 8; v1++) {
22+
function func9() {
23+
Object.prototype;
24+
}
25+
obj7 = func9();
26+
}
27+
}
28+
v0();
29+
};
30+
31+
var ary = Array(2);
32+
var VarArr0 = [];
33+
var __loopvar0 = 4;
34+
func2()
35+
func2()
36+
37+
for (var _strvar65 of ary) {
38+
prop5 = test0;
39+
litObj9 = { prop7: VarArr0.unshift(func2(), func2()) };
40+
}

test/Optimizer/rlexe.xml

+2-2
Original file line numberDiff line numberDiff line change
@@ -1361,9 +1361,9 @@
13611361
</test>
13621362
<test>
13631363
<default>
1364-
<files>bug7100343.js</files>
1364+
<files>forceRejitBugs.js</files>
13651365
<compile-flags>-mic:1 -off:simplejit -force:rejit</compile-flags>
1366-
<baseline>bug7100343.baseline</baseline>
1366+
<baseline>forceRejitBugs.baseline</baseline>
13671367
</default>
13681368
</test>
13691369
</regress-exe>

0 commit comments

Comments
 (0)