Skip to content

Commit 79adb49

Browse files
committed
[MERGE #6142 @pleath] OSG:20015601 Do not clear inlinee callinfo prior to a bailout, as we need the callinfo to help us box stack args and set up the interpreter instance
Merge pull request #6142 from pleath:20015601
2 parents 0fc5e95 + 660bcf9 commit 79adb49

File tree

5 files changed

+37
-3
lines changed

5 files changed

+37
-3
lines changed

lib/Backend/BailOut.cpp

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1258,6 +1258,8 @@ BailOutRecord::BailOutInlinedHelper(Js::JavascriptCallStackLayout * layout, Bail
12581258
}
12591259

12601260
// Let's restore the inline stack - so that in case of a stack walk we have it available
1261+
InlinedFrameLayout *inlinedFrameToRestore = nullptr;
1262+
Js::ArgSlot clearedCallInfoCount = 0;
12611263
if (entryPointInfo->HasInlinees())
12621264
{
12631265
InlineeFrameRecord* inlineeFrameRecord = entryPointInfo->FindInlineeFrame(returnAddress);
@@ -1267,14 +1269,20 @@ BailOutRecord::BailOutInlinedHelper(Js::JavascriptCallStackLayout * layout, Bail
12671269
// object, the cached version (that was previously boxed) will be reused to maintain pointer identity and correctness
12681270
// after the transition to the interpreter.
12691271
InlinedFrameLayout* outerMostFrame = (InlinedFrameLayout *)(((uint8 *)Js::JavascriptCallStackLayout::ToFramePointer(layout)) - entryPointInfo->GetFrameHeight());
1270-
inlineeFrameRecord->RestoreFrames(functionBody, outerMostFrame, layout, true /* boxArgs */);
1272+
inlineeFrameRecord->RestoreFrames(functionBody, outerMostFrame, layout, true /*boxArgs*/, &inlinedFrameToRestore, &clearedCallInfoCount);
12711273
}
12721274
}
12731275

12741276
do
12751277
{
12761278
InlinedFrameLayout *inlinedFrame = (InlinedFrameLayout *)(((char *)layout) + currentBailOutRecord->globalBailOutRecordTable->firstActualStackOffset);
12771279
Js::InlineeCallInfo inlineeCallInfo = inlinedFrame->callInfo;
1280+
if (inlinedFrameToRestore == inlinedFrame)
1281+
{
1282+
// Restore the frame's callinfo count prior to using it to create an interpreter instance
1283+
Assert(inlineeCallInfo.Count == 0);
1284+
inlineeCallInfo.Count = clearedCallInfoCount;
1285+
}
12781286
Assert((Js::ArgSlot)inlineeCallInfo.Count == currentBailOutRecord->actualCount);
12791287

12801288
Js::CallFlags callFlags = Js::CallFlags_Value;

lib/Backend/InlineeFrameInfo.cpp

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -243,7 +243,7 @@ void InlineeFrameRecord::Restore(Js::FunctionBody* functionBody, InlinedFrameLay
243243
// Note: the boxValues parameter should be true when this is called from a Bailout codepath to ensure that multiple vars to
244244
// the same object reuse the cached value during the transition to the interpreter.
245245
// Otherwise, this parameter should be false as the values are not required to be moved to the heap to restore the frame.
246-
void InlineeFrameRecord::RestoreFrames(Js::FunctionBody* functionBody, InlinedFrameLayout* outerMostFrame, Js::JavascriptCallStackLayout* callstack, bool boxValues)
246+
void InlineeFrameRecord::RestoreFrames(Js::FunctionBody* functionBody, InlinedFrameLayout* outerMostFrame, Js::JavascriptCallStackLayout* callstack, bool boxValues, InlinedFrameLayout **ppInlinedFrameToRestore, Js::ArgSlot *pClearedCallInfoCount)
247247
{
248248
InlineeFrameRecord* innerMostRecord = this;
249249
class AutoReverse
@@ -287,6 +287,12 @@ void InlineeFrameRecord::RestoreFrames(Js::FunctionBody* functionBody, InlinedFr
287287
}
288288

289289
// Terminate the inlined stack
290+
if (ppInlinedFrameToRestore)
291+
{
292+
// Tell the caller that we need to restore this frame's callinfo count before using it to create an interpreter instance
293+
*ppInlinedFrameToRestore = currentFrame;
294+
*pClearedCallInfoCount = currentFrame->callInfo.Count;
295+
}
290296
currentFrame->callInfo.Count = 0;
291297
}
292298

lib/Backend/InlineeFrameInfo.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ struct InlineeFrameRecord
110110
}
111111

112112
void PopulateParent(Func* func);
113-
void RestoreFrames(Js::FunctionBody* functionBody, InlinedFrameLayout* outerMostInlinee, Js::JavascriptCallStackLayout* callstack, bool boxValues);
113+
void RestoreFrames(Js::FunctionBody* functionBody, InlinedFrameLayout* outerMostInlinee, Js::JavascriptCallStackLayout* callstack, bool boxValues, InlinedFrameLayout ** ppInlinedFrameToRestore = nullptr, Js::ArgSlot *pClearedCallInfoCount = nullptr);
114114
void Finalize(Func* inlinee, uint currentOffset);
115115
#if DBG_DUMP
116116
void Dump() const;

test/Function/rlexe.xml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -453,6 +453,11 @@
453453
<baseline>stackArgsLenConstOpt.baseline</baseline>
454454
</default>
455455
</test>
456+
<test>
457+
<default>
458+
<files>stackArgsWithInlineeBailOut.js</files>
459+
</default>
460+
</test>
456461
<test>
457462
<default>
458463
<files>childCallsEvalJitLoopBody.js</files>
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
var gi = 3;
2+
var bigArray = new Array(50);
3+
bigArray.fill(42);
4+
function foo() {
5+
return arguments[gi];
6+
}
7+
function bar() {
8+
bigArray.every(function (x) {
9+
foo();
10+
});
11+
}
12+
for (var i = 0; i < 3; ++i) {
13+
bar();
14+
}
15+
WScript.Echo('pass');

0 commit comments

Comments
 (0)