Skip to content

Commit 00184d7

Browse files
committed
fix bailouts from inlined callback.call
1 parent 59407fd commit 00184d7

File tree

6 files changed

+64
-13
lines changed

6 files changed

+64
-13
lines changed

lib/Backend/Inline.cpp

Lines changed: 20 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1010,6 +1010,13 @@ Inline::InlinePolymorphicFunctionUsingFixedMethods(IR::Instr *callInstr, const F
10101010
return instrNext;
10111011
}
10121012

1013+
IR::RegOpnd * Inline::GetCallbackFunctionOpnd(IR::Instr * callInstr)
1014+
{
1015+
IR::Instr * callApplyLdInstr = callInstr->GetSrc1()->GetStackSym()->GetInstrDef();
1016+
IR::Instr * targetDefInstr = callApplyLdInstr->GetSrc1()->AsPropertySymOpnd()->GetObjectSym()->GetInstrDef();
1017+
return targetDefInstr->GetDst()->AsRegOpnd();
1018+
}
1019+
10131020
IR::Instr * Inline::TryGetCallbackDefInstrForCallInstr(IR::Instr * callInstr)
10141021
{
10151022
// Try to find a function argument that could be inlined.
@@ -2891,7 +2898,12 @@ bool Inline::InlineApplyScriptTarget(IR::Instr *callInstr, const FunctionJITTime
28912898
StackSym* originalCallTargetStackSym = callInstr->GetSrc1()->GetStackSym();
28922899
bool originalCallTargetOpndIsJITOpt = callInstr->GetSrc1()->GetIsJITOptimizedReg();
28932900
bool safeThis = false;
2894-
if (!targetIsCallback && !TryGetFixedMethodsForBuiltInAndTarget(callInstr, inlinerData, inlineeData, applyFuncInfo, applyLdInstr, applyTargetLdInstr, safeThis, /*isApplyTarget*/ true))
2901+
2902+
if (targetIsCallback)
2903+
{
2904+
callInstr->ReplaceSrc1(GetCallbackFunctionOpnd(callInstr));
2905+
}
2906+
else if (!TryGetFixedMethodsForBuiltInAndTarget(callInstr, inlinerData, inlineeData, applyFuncInfo, applyLdInstr, applyTargetLdInstr, safeThis, /*isApplyTarget*/ true))
28952907
{
28962908
return false;
28972909
}
@@ -3216,7 +3228,12 @@ Inline::InlineCallTarget(IR::Instr *callInstr, const FunctionJITTimeInfo* inline
32163228
StackSym* originalCallTargetStackSym = callInstr->GetSrc1()->GetStackSym();
32173229
bool originalCallTargetOpndIsJITOpt = callInstr->GetSrc1()->GetIsJITOptimizedReg();
32183230
bool safeThis = false;
3219-
if (!targetIsCallback && !TryGetFixedMethodsForBuiltInAndTarget(callInstr, inlinerData, inlineeData, callFuncInfo, callLdInstr, callTargetLdInstr, safeThis, /*isApplyTarget*/ false))
3231+
3232+
if (targetIsCallback)
3233+
{
3234+
callInstr->ReplaceSrc1(GetCallbackFunctionOpnd(callInstr));
3235+
}
3236+
else if (!TryGetFixedMethodsForBuiltInAndTarget(callInstr, inlinerData, inlineeData, callFuncInfo, callLdInstr, callTargetLdInstr, safeThis, /*isApplyTarget*/ false))
32203237
{
32213238
return false;
32223239
}
@@ -4433,17 +4450,7 @@ Inline::PrepareInsertionPoint(IR::Instr *callInstr, const FunctionJITTimeInfo *f
44334450
Assert(insertBeforeInstr->m_func == callInstr->m_func);
44344451
IR::BailOutKind bailOutKind = IR::BailOutOnInlineFunction;
44354452

4436-
IR::RegOpnd * funcOpnd;
4437-
if (isCallbackCallApplyTarget)
4438-
{
4439-
IR::Instr * callApplyLdInstr = callInstr->GetSrc1()->GetStackSym()->GetInstrDef();
4440-
IR::Instr * targetDefInstr = callApplyLdInstr->GetSrc1()->AsPropertySymOpnd()->GetObjectSym()->GetInstrDef();
4441-
funcOpnd = targetDefInstr->GetDst()->AsRegOpnd();
4442-
}
4443-
else
4444-
{
4445-
funcOpnd = callInstr->GetSrc1()->AsRegOpnd();
4446-
}
4453+
IR::RegOpnd * funcOpnd = callInstr->GetSrc1()->AsRegOpnd();
44474454

44484455
// FunctionBody check is the primary bailout instruction, create it first
44494456
IR::BailOutInstr* primaryBailOutInstr = IR::BailOutInstr::New(Js::OpCode::BailOnNotEqual, bailOutKind, insertBeforeInstr, callInstr->m_func);

lib/Backend/Inline.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,8 @@ class Inline
9595
const bool isInlined, const bool doneFixedMethodFld, IR::Instr** createObjInstrOut, IR::Instr** callCtorInstrOut) const;
9696
IR::Instr * InlinePolymorphicFunction(IR::Instr *callInstr, const FunctionJITTimeInfo * inlinerData, const StackSym *symCallerThis, const Js::ProfileId profileId, bool* pIsInlined, uint recursiveInlineDepth, bool triedUsingFixedMethods = false);
9797
IR::Instr * InlinePolymorphicFunctionUsingFixedMethods(IR::Instr *callInstr, const FunctionJITTimeInfo * inlinerData, const StackSym *symCallerThis, const Js::ProfileId profileId, IR::PropertySymOpnd* methodValueOpnd, bool* pIsInlined, uint recursiveInlineDepth);
98+
99+
IR::RegOpnd * GetCallbackFunctionOpnd(IR::Instr * callInstr);
98100
IR::Instr * TryGetCallbackDefInstr(StackSym * callbackSym);
99101
IR::Instr * TryGetCallbackDefInstrForCallInstr(IR::Instr * callInstr);
100102
IR::Instr * TryGetCallbackDefInstrForCallApplyTarget(IR::Instr * callApplyLdInstr);
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
INLINING : Found callback def instr for call/apply target callback at CallSite: 0 Caller: DispatchCallWithThis ( (#1.2), #3)
2+
INLINING CALLBACK : Inlining callback for call/apply target : BailOut ( (#1.1), #2)
3+
BailOut: function BailOut, Opcode: BoundCheck Kind: BailOutOnNotNativeArray
4+
BailOut: function DispatchCallWithThis, Opcode: InlineeEnd Kind: BailOutOnNotNativeArray
5+
BailOut: function DispatchBailout, Opcode: InlineeEnd Kind: BailOutOnNotNativeArray
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
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+
// test bailout from inlined callback.call
7+
function BailOut(ary)
8+
{
9+
ary[0] = 1;
10+
}
11+
12+
function DispatchCallWithThis(callback, arg)
13+
{
14+
callback.call(this, arg);
15+
}
16+
17+
function DispatchBailout(arg)
18+
{
19+
DispatchCallWithThis(BailOut, arg);
20+
}
21+
22+
DispatchBailout([1]);
23+
DispatchBailout([1]);
24+
DispatchBailout([1.1]);

test/inlining/InlineCallbacks.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
44
//-------------------------------------------------------------------------------------------------------
55

6+
// Test inlining of callback.
67
function Dispatch(f) { f(); }
78
function Foo() { WScript.Echo("foo"); }
89
function DispatchFoo() { Dispatch(Foo); }
@@ -17,13 +18,15 @@ DispatchFoo();
1718
DispatchFoo();
1819
DispatchFoo();
1920

21+
// Test inlining of a callback function with a callback.
2022
function Bar() { WScript.Echo("bar"); }
2123
function DispatchBar() { Dispatch(Bar); }
2224
function NestedDispatch() { Dispatch(DispatchBar) };
2325
NestedDispatch();
2426
NestedDispatch();
2527
NestedDispatch();
2628

29+
// Test inlining of callback with argument
2730
function Dispatch2(f, arg) { f(arg); }
2831
function Blah(arg) { WScript.Echo(arg); }
2932
function DispatchBlah(arg) { Dispatch2(Blah, arg) }
@@ -44,6 +47,7 @@ DispatchFooBar();
4447
DispatchFooBar();
4548
DispatchFooBar();
4649

50+
// test inlining of callback.call
4751
function DispatchCall(callback, thisArg) { callback.call(thisArg); }
4852
function DispatchFooCall() { DispatchCall(Foo, {}); }
4953
DispatchCall(function(){});
@@ -52,6 +56,7 @@ DispatchFooCall();
5256
DispatchFooCall();
5357
DispatchFooCall();
5458

59+
// test inlining of callback.apply
5560
function DispatchApply(callback, thisArg) { callback.apply(thisArg); }
5661
function DispatchBarApply() { DispatchApply(Bar, {}); }
5762
DispatchApply(function(){});

test/inlining/rlexe.xml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -304,6 +304,14 @@
304304
<tags>exclude_dynapogo,exclude_nonative,exclude_forceserialized,require_backend</tags>
305305
</default>
306306
</test>
307+
<test>
308+
<default>
309+
<files>InlineCallbackCallBailout.js</files>
310+
<compile-flags>-testtrace:InlineCallbacks -testtrace:Bailout</compile-flags>
311+
<baseline>InlineCallbackCallBailout.baseline</baseline>
312+
<tags>exclude_dynapogo,exclude_nonative,exclude_forceserialized,require_backend</tags>
313+
</default>
314+
</test>
307315
<test>
308316
<default>
309317
<files>recursiveCallbacks.js</files>

0 commit comments

Comments
 (0)