Skip to content

Commit a7c2341

Browse files
Add an assert to trigger earlier on improper insertion of bytecodeuses instructions.
1 parent 054dde1 commit a7c2341

File tree

5 files changed

+29
-26
lines changed

5 files changed

+29
-26
lines changed

lib/Backend/BackwardPass.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6894,7 +6894,7 @@ BackwardPass::ProcessInlineeStart(IR::Instr* inlineeStart)
68946894
if (!opnd->GetIsJITOptimizedReg() && sym && sym->HasByteCodeRegSlot())
68956895
{
68966896
// Replace instrs with bytecodeUses
6897-
IR::ByteCodeUsesInstr *bytecodeUse = IR::ByteCodeUsesInstr::New(argInstr, sym->m_id);
6897+
IR::ByteCodeUsesInstr *bytecodeUse = IR::ByteCodeUsesInstr::New(argInstr, opnd, sym->m_id);
68986898
argInstr->InsertBefore(bytecodeUse);
68996899
}
69006900
startCallInstr = argInstr->GetSrc2()->GetStackSym()->m_instrDef;
@@ -6961,7 +6961,7 @@ BackwardPass::ProcessInlineeStart(IR::Instr* inlineeStart)
69616961
if (!src1->GetIsJITOptimizedReg() && sym && sym->HasByteCodeRegSlot())
69626962
{
69636963
// Replace instrs with bytecodeUses
6964-
IR::ByteCodeUsesInstr *bytecodeUse = IR::ByteCodeUsesInstr::New(inlineeStart, sym->m_id);
6964+
IR::ByteCodeUsesInstr *bytecodeUse = IR::ByteCodeUsesInstr::New(inlineeStart, src1, sym->m_id);
69656965
inlineeStart->InsertBefore(bytecodeUse);
69666966
}
69676967

lib/Backend/IR.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -880,20 +880,22 @@ ByteCodeUsesInstr::New(Func * func)
880880
}
881881

882882
ByteCodeUsesInstr *
883-
ByteCodeUsesInstr::New(IR::Instr* originalBytecodeInstr, SymID symid)
883+
ByteCodeUsesInstr::New(IR::Instr* originalBytecodeInstr, IR::Opnd* srcopnd, SymID symid)
884884
{
885885
Func* func = originalBytecodeInstr->m_func;
886886
ByteCodeUsesInstr * byteCodeUses = JitAnew(func->m_alloc, IR::ByteCodeUsesInstr);
887887
byteCodeUses->Init(Js::OpCode::ByteCodeUses, InstrKindByteCodeUses, func);
888+
Assert(!srcopnd == nullptr && !srcopnd->GetIsJITOptimizedReg());
888889
byteCodeUses->byteCodeUpwardExposedUsed = JitAnew(func->m_alloc, BVSparse<JitArenaAllocator>, func->m_alloc);
889890
byteCodeUses->byteCodeUpwardExposedUsed->Set(symid);
890891
byteCodeUses->SetByteCodeOffset(originalBytecodeInstr);
891892
byteCodeUses->propertySymUse = nullptr;
892893
return byteCodeUses;
893894
}
894895

895-
void ByteCodeUsesInstr::Set(uint symId)
896+
void ByteCodeUsesInstr::Set(IR::Opnd* srcopnd, uint symId)
896897
{
898+
Assert(!srcopnd == nullptr && !srcopnd->GetIsJITOptimizedReg());
897899
if(!byteCodeUpwardExposedUsed)
898900
{
899901
byteCodeUpwardExposedUsed = JitAnew(m_func->m_alloc, BVSparse<JitArenaAllocator>, m_func->m_alloc);

lib/Backend/IR.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -507,11 +507,11 @@ class ByteCodeUsesInstr : public Instr
507507
{
508508
public:
509509
static ByteCodeUsesInstr * New(Func * func);
510-
static ByteCodeUsesInstr* New(IR::Instr* originalBytecodeInstr, SymID symid);
510+
static ByteCodeUsesInstr* New(IR::Instr* originalBytecodeInstr, Opnd* srcopnd, SymID symid);
511511
BVSparse<JitArenaAllocator> * byteCodeUpwardExposedUsed;
512512
PropertySym * propertySymUse;
513513

514-
void Set(uint symId);
514+
void Set(Opnd* srcopnd, uint symId);
515515
};
516516

517517
class JitProfilingInstr : public Instr

lib/Backend/Inline.cpp

Lines changed: 19 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -476,7 +476,7 @@ Inline::Optimize(Func *func, __in_ecount_opt(callerArgOutCount) IR::Instr *calle
476476

477477
// Insert a ByteCodeUsesInstr to make sure the methodValueDstOpnd's constant value is captured by any
478478
// bailout that occurs between CheckFixedMethodField and CallI.
479-
IR::ByteCodeUsesInstr * useCallTargetInstr = IR::ByteCodeUsesInstr::New(instr, originalCallTargetStackSym->m_id);
479+
IR::ByteCodeUsesInstr * useCallTargetInstr = IR::ByteCodeUsesInstr::New(instr, instr->GetSrc1(), originalCallTargetStackSym->m_id);
480480
instr->InsertBefore(useCallTargetInstr);
481481

482482
// Split NewScObject into NewScObjectNoCtor and CallI, but don't touch NewScObjectArray.
@@ -1070,7 +1070,7 @@ void Inline::CompletePolymorphicInlining(IR::Instr* callInstr, IR::RegOpnd* retu
10701070
return false;
10711071
});
10721072

1073-
callInstr->InsertBefore(IR::ByteCodeUsesInstr::New(callInstr, callInstr->GetSrc1()->GetStackSym()->m_id));
1073+
callInstr->InsertBefore(IR::ByteCodeUsesInstr::New(callInstr, callInstr->GetSrc1(), callInstr->GetSrc1()->GetStackSym()->m_id));
10741074

10751075
IR::Instr* endCallInstr = IR::Instr::New(Js::OpCode::EndCallForPolymorphicInlinee, callInstr->m_func);
10761076
endCallInstr->SetSrc1(IR::IntConstOpnd::New(actualsCount + Js::Constants::InlineeMetaArgCount, TyInt32, callInstr->m_func, /*dontEncode*/ true));
@@ -2025,7 +2025,7 @@ Inline::InlineBuiltInFunction(IR::Instr *callInstr, const FunctionJITTimeInfo *
20252025
// Insert a byteCodeUsesInstr to make sure the function object's lifetime is extended beyond the last bailout point
20262026
// at which we may need to call the inlinee again in the interpreter.
20272027
{
2028-
IR::ByteCodeUsesInstr * useCallTargetInstr = IR::ByteCodeUsesInstr::New(callInstr, originalCallTargetStackSym->m_id);
2028+
IR::ByteCodeUsesInstr * useCallTargetInstr = IR::ByteCodeUsesInstr::New(callInstr, callInstr->GetSrc1(), originalCallTargetStackSym->m_id);
20292029
callInstr->InsertBefore(useCallTargetInstr);
20302030
}
20312031

@@ -2061,7 +2061,7 @@ Inline::InlineBuiltInFunction(IR::Instr *callInstr, const FunctionJITTimeInfo *
20612061

20622062
// Insert a byteCodeUsesInstr to make sure the function object's lifetime is extended beyond the last bailout point
20632063
// at which we may need to call the inlinee again in the interpreter.
2064-
IR::ByteCodeUsesInstr * useCallTargetInstr = IR::ByteCodeUsesInstr::New(callInstr->GetPrevRealInstrOrLabel(), originalCallTargetStackSym->m_id);
2064+
IR::ByteCodeUsesInstr * useCallTargetInstr = IR::ByteCodeUsesInstr::New(callInstr->GetPrevRealInstrOrLabel(), callInstr->GetSrc1(), originalCallTargetStackSym->m_id);
20652065

20662066
if(inlineCallOpCode == Js::OpCode::InlineArrayPop)
20672067
{
@@ -2423,7 +2423,7 @@ IR::Instr * Inline::InlineApplyWithArgumentsObject(IR::Instr * callInstr, IR::In
24232423
// the bailout on non-stack arguments.
24242424
if (callInstr->m_opcode == Js::OpCode::CallIFixed)
24252425
{
2426-
IR::ByteCodeUsesInstr * useCallTargetInstr = IR::ByteCodeUsesInstr::New(callInstr, originalCallTargetStackSym->m_id);
2426+
IR::ByteCodeUsesInstr * useCallTargetInstr = IR::ByteCodeUsesInstr::New(callInstr, callInstr->GetSrc1(), originalCallTargetStackSym->m_id);
24272427
callInstr->InsertBefore(useCallTargetInstr);
24282428
}
24292429

@@ -2559,7 +2559,7 @@ IR::Instr * Inline::InlineApplyWithoutArrayArgument(IR::Instr *callInstr, const
25592559
if (TryOptimizeCallInstrWithFixedMethod(callInstr, applyTargetInfo, false /*isPolymorphic*/, false /*isBuiltIn*/, false /*isCtor*/, true /*isInlined*/, safeThis /*unused here*/))
25602560
{
25612561
Assert(callInstr->m_opcode == Js::OpCode::CallIFixed);
2562-
callInstr->InsertBefore(IR::ByteCodeUsesInstr::New(callInstr, callTargetStackSym->m_id));
2562+
callInstr->InsertBefore(IR::ByteCodeUsesInstr::New(callInstr, callInstr->GetSrc1(), callTargetStackSym->m_id));
25632563
}
25642564

25652565
return callInstr;
@@ -2723,13 +2723,13 @@ bool Inline::InlineApplyScriptTarget(IR::Instr *callInstr, const FunctionJITTime
27232723
startCall->SetSrc2(IR::IntConstOpnd::New(startCall->GetArgOutCount(/*getInterpreterArgOutCount*/ false), TyUint32, startCall->m_func));
27242724
startCall->GetSrc1()->AsIntConstOpnd()->IncrValue(-1); // update the count of argouts as seen by JIT, in the start call instruction
27252725

2726-
*returnInstr = InlineCallApplyTarget_Shared(callInstr, originalCallTargetStackSym, inlineeData, inlineCacheIndex,
2726+
*returnInstr = InlineCallApplyTarget_Shared(callInstr, callInstr->GetSrc1(), originalCallTargetStackSym, inlineeData, inlineCacheIndex,
27272727
safeThis, /*isApplyTarget*/ true, /*isCallTarget*/ false, recursiveInlineDepth);
27282728
return true;
27292729
}
27302730

27312731
IR::Instr *
2732-
Inline::InlineCallApplyTarget_Shared(IR::Instr *callInstr, StackSym* originalCallTargetStackSym, const FunctionJITTimeInfo *const inlineeData,
2732+
Inline::InlineCallApplyTarget_Shared(IR::Instr *callInstr, IR::Opnd* originalCallTargetOpnd, StackSym* originalCallTargetStackSym, const FunctionJITTimeInfo *const inlineeData,
27332733
uint inlineCacheIndex, bool safeThis, bool isApplyTarget, bool isCallTarget, uint recursiveInlineDepth)
27342734
{
27352735
Assert(isApplyTarget ^ isCallTarget);
@@ -2810,7 +2810,7 @@ Inline::InlineCallApplyTarget_Shared(IR::Instr *callInstr, StackSym* originalCal
28102810
// instrNext
28112811
IR::Instr* instrNext = callInstr->m_next;
28122812

2813-
return InlineFunctionCommon(callInstr, originalCallTargetStackSym, inlineeData, inlinee, instrNext, returnValueOpnd, callInstr, nullptr, recursiveInlineDepth, safeThis, isApplyTarget);
2813+
return InlineFunctionCommon(callInstr, originalCallTargetOpnd, originalCallTargetStackSym, inlineeData, inlinee, instrNext, returnValueOpnd, callInstr, nullptr, recursiveInlineDepth, safeThis, isApplyTarget);
28142814
}
28152815

28162816
IR::Opnd *
@@ -3007,7 +3007,7 @@ Inline::InlineCallTarget(IR::Instr *callInstr, const FunctionJITTimeInfo* inline
30073007
startCall->SetSrc2(IR::IntConstOpnd::New(startCall->GetArgOutCount(/*getInterpreterArgOutCount*/ false), TyUint32, startCall->m_func));
30083008
startCall->GetSrc1()->AsIntConstOpnd()->SetValue(startCall->GetSrc1()->AsIntConstOpnd()->GetValue() - 1);
30093009

3010-
*returnInstr = InlineCallApplyTarget_Shared(callInstr, originalCallTargetStackSym, inlineeData, inlineCacheIndex,
3010+
*returnInstr = InlineCallApplyTarget_Shared(callInstr, callInstr->GetSrc1(), originalCallTargetStackSym, inlineeData, inlineCacheIndex,
30113011
safeThis, /*isApplyTarget*/ false, /*isCallTarget*/ true, recursiveInlineDepth);
30123012

30133013
return true;
@@ -3575,11 +3575,11 @@ Inline::InlineGetterSetterFunction(IR::Instr *accessorInstr, const FunctionJITTi
35753575
bool safeThis = false;
35763576
TryOptimizeCallInstrWithFixedMethod(accessorInstr, inlineeData, false, false, false, true, safeThis);
35773577

3578-
return InlineFunctionCommon(accessorInstr, nullptr, inlineeData, inlinee, instrNext, returnValueOpnd, inlineBailoutChecksBeforeInstr, symCallerThis, recursiveInlineDepth, safeThis);
3578+
return InlineFunctionCommon(accessorInstr, nullptr, nullptr, inlineeData, inlinee, instrNext, returnValueOpnd, inlineBailoutChecksBeforeInstr, symCallerThis, recursiveInlineDepth, safeThis);
35793579
}
35803580

35813581
IR::Instr *
3582-
Inline::InlineFunctionCommon(IR::Instr *callInstr, StackSym* originalCallTargetStackSym, const FunctionJITTimeInfo *funcInfo, Func *inlinee, IR::Instr *instrNext,
3582+
Inline::InlineFunctionCommon(IR::Instr *callInstr, IR::Opnd* originalCallTargetOpnd, StackSym* originalCallTargetStackSym, const FunctionJITTimeInfo *funcInfo, Func *inlinee, IR::Instr *instrNext,
35833583
IR::RegOpnd * returnValueOpnd, IR::Instr *inlineBailoutChecksBeforeInstr, const StackSym *symCallerThis, uint recursiveInlineDepth, bool safeThis, bool isApplyTarget)
35843584
{
35853585
BuildIRForInlinee(inlinee, funcInfo->GetBody(), callInstr, isApplyTarget, recursiveInlineDepth);
@@ -3623,11 +3623,12 @@ Inline::InlineFunctionCommon(IR::Instr *callInstr, StackSym* originalCallTargetS
36233623
if (callInstr->m_opcode == Js::OpCode::CallIFixed && !inlinee->isGetterSetter)
36243624
{
36253625
Assert(originalCallTargetStackSym != nullptr);
3626+
Assert(opnd != nullptr);
36263627

36273628
// Insert a ByteCodeUsesInstr to make sure the function object's lifetimes is extended beyond the last bailout point
36283629
// at which we may have to call the function again in the interpreter.
36293630
// Don't need to do this for a getter/setter inlinee as, upon bailout, the execution will start in the interpreter at the LdFld/StFld itself.
3630-
callInstr->InsertBefore(IR::ByteCodeUsesInstr::New(callInstr, originalCallTargetStackSym->m_id));
3631+
callInstr->InsertBefore(IR::ByteCodeUsesInstr::New(callInstr, originalCallTargetOpnd, originalCallTargetStackSym->m_id));
36313632
}
36323633

36333634
// InlineeStart indicate the beginning of the inlinee, and we need the stack arg for the inlinee until InlineeEnd
@@ -3887,7 +3888,7 @@ Inline::InlineScriptFunction(IR::Instr *callInstr, const FunctionJITTimeInfo *co
38873888
false);
38883889
#endif
38893890

3890-
return InlineFunctionCommon(callInstr, originalCallTargetStackSym, inlineeData, inlinee, instrNext, returnValueOpnd, inlineBailoutChecksBeforeInstr, symCallerThis, recursiveInlineDepth, safeThis);
3891+
return InlineFunctionCommon(callInstr, callInstr->GetSrc1(), originalCallTargetStackSym, inlineeData, inlinee, instrNext, returnValueOpnd, inlineBailoutChecksBeforeInstr, symCallerThis, recursiveInlineDepth, safeThis);
38913892
}
38923893

38933894
bool
@@ -4190,7 +4191,7 @@ Inline::TryFixedMethodAndPrepareInsertionPoint(IR::Instr *callInstr, const Funct
41904191
Assert(callInstr->m_opcode == Js::OpCode::CallIFixed);
41914192

41924193
// If we optimized the call instruction for a fixed function, we must extend the function object's lifetime until after the last bailout before the call.
4193-
IR::ByteCodeUsesInstr * useCallTargetInstr = IR::ByteCodeUsesInstr::New(callInstr, originalCallTargetStackSym->m_id);
4194+
IR::ByteCodeUsesInstr * useCallTargetInstr = IR::ByteCodeUsesInstr::New(callInstr, callInstr->GetSrc1(), originalCallTargetStackSym->m_id);
41944195
callInstr->InsertBefore(useCallTargetInstr);
41954196
}
41964197
else
@@ -4387,11 +4388,11 @@ bool Inline::InlConstFold(IR::Instr *instr, IntConstType *pValue, __in_ecount_op
43874388
{
43884389
if (src1Sym->HasByteCodeRegSlot())
43894390
{
4390-
byteCodeInstr->Set(src1Sym->m_id);
4391+
byteCodeInstr->Set(src1->AsRegOpnd(), src1Sym->m_id);
43914392
}
43924393
if (src2Sym->HasByteCodeRegSlot())
43934394
{
4394-
byteCodeInstr->Set(src2Sym->m_id);
4395+
byteCodeInstr->Set(src2->AsRegOpnd(), src2Sym->m_id);
43954396
}
43964397
instr->InsertBefore(byteCodeInstr);
43974398
}
@@ -4426,7 +4427,7 @@ bool Inline::InlConstFold(IR::Instr *instr, IntConstType *pValue, __in_ecount_op
44264427
{
44274428
IR::ByteCodeUsesInstr * byteCodeInstr = IR::ByteCodeUsesInstr::New(instr->m_func);
44284429
byteCodeInstr->SetByteCodeOffset(instr);
4429-
byteCodeInstr->Set(src1Sym->m_id);
4430+
byteCodeInstr->Set(src1->AsRegOpnd(), src1Sym->m_id);
44304431
instr->InsertBefore(byteCodeInstr);
44314432
}
44324433

lib/Backend/Inline.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ class Inline
4242
IR::Instr * InlineDOMGetterSetterFunction(IR::Instr *ldFldInstr, const FunctionJITTimeInfo *const inlineeData, const FunctionJITTimeInfo *const inlinerData);
4343
#endif
4444
IR::Instr * InlineGetterSetterFunction(IR::Instr *accessorInstr, const FunctionJITTimeInfo *const inlineeData, const StackSym *symCallerThis, const uint inlineCacheIndex, bool isGetter, bool *pIsInlined, uint recursiveInlineDepth);
45-
IR::Instr * InlineFunctionCommon(IR::Instr *callInstr, StackSym* originalCallTargetStackSym, const FunctionJITTimeInfo *funcInfo, Func *inlinee, IR::Instr *instrNext,
45+
IR::Instr * InlineFunctionCommon(IR::Instr *callInstr, IR::Opnd* originalCallTargetOpnd, StackSym* originalCallTargetStackSym, const FunctionJITTimeInfo *funcInfo, Func *inlinee, IR::Instr *instrNext,
4646
IR::RegOpnd * returnValueOpnd, IR::Instr *inlineBailoutChecksBeforeInstr, const StackSym *symCallerThis, uint recursiveInlineDepth, bool safeThis = false, bool isApplyTarget = false);
4747
IR::Instr * SimulateCallForGetterSetter(IR::Instr *accessorInstr, IR::Instr* insertInstr, IR::PropertySymOpnd* methodOpnd, bool isGetter);
4848

@@ -61,7 +61,7 @@ class Inline
6161
bool InlConstFoldArg(IR::Instr *instr, __in_ecount_opt(callerArgOutCount) IR::Instr *callerArgOuts[], Js::ArgSlot callerArgOutCount);
6262
bool InlConstFold(IR::Instr *instr, IntConstType *pValue, __in_ecount_opt(callerArgOutCount) IR::Instr *callerArgOuts[], Js::ArgSlot callerArgOutCount);
6363

64-
IR::Instr * InlineCallApplyTarget_Shared(IR::Instr *callInstr, StackSym* originalCallTargetStackSym, const FunctionJITTimeInfo*const inlineeData,
64+
IR::Instr * InlineCallApplyTarget_Shared(IR::Instr *callInstr, IR::Opnd* originalCallTargetOpnd, StackSym* originalCallTargetStackSym, const FunctionJITTimeInfo*const inlineeData,
6565
uint inlineCacheIndex, bool safeThis, bool isApplyTarget, bool isCallTarget, uint recursiveInlineDepth);
6666
bool SkipCallApplyScriptTargetInlining_Shared(IR::Instr *callInstr, const FunctionJITTimeInfo* inlinerData, const FunctionJITTimeInfo* inlineeData, bool isApplyTarget, bool isCallTarget);
6767
bool TryGetFixedMethodsForBuiltInAndTarget(IR::Instr *callInstr, const FunctionJITTimeInfo* inlinerData, const FunctionJITTimeInfo* inlineeData, const FunctionJITTimeInfo *builtInFuncInfo,

0 commit comments

Comments
 (0)