Skip to content

Commit 073e35e

Browse files
authored
Simplify "secret stub arg" handling between JIT and EE (#100823)
When a pinvoke/reverse pinvoke needs marshalling the VM creates an IL stub to perform this marshalling. These IL stubs have a non-standard parameter called the "secret stub parameter". The VM uses this parameter to map the IL stub back to the user defined function that caused the IL stub to be required (multiple user functions can share the same IL stubs, so the mapping cannot be done by other means). To facilitate the access of this value the JIT must make the parameter's value available to the VM somehow. Previously this was done in two separate ways for 32-bit and 64-bit target: - For 32-bit targets the parameter was marked as do-not-enregister and always spilled to the stack frame at a location that was known by the VM. - For 64-bit targets the parameter was saved in the `InlinedCallFrame` as part of a VM helper call. We still marked it as do-not-enregister, probably because parameter homing did not handle it. For 64-bit targets this introduces a bit of inefficiency: the secret stub parameter is only needed for the IL stubs case, but `InlinedCallFrame` is used for all inlined pinvokes. So we ended up with a larger frame than necessary and with an additional store to the frame, even outside IL stubs. This change removes that inefficiency by unifying how 32-bit and 64-bit targets work: - Switch all platforms to only allocate space in `InlinedCallFrame` for the secret stub parameter when necessary - Move responsibility of storing the secret stub parameter out of `CORINFO_HELP_INIT_PINVOKE_FRAME` and to the JIT generated code - Remove special casing of frame layout around the secret stub parameter and frame structures within the JIT - Enable enregistration for the secret stub parameter Fix #100662
1 parent 3de068c commit 073e35e

33 files changed

+191
-281
lines changed

eng/native/sanitizer-ignorelist.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,5 +10,5 @@ fun:_ZN11CMiniMdBase19UsesAllocatedMemoryEP11CMiniColDef
1010
# 2 0x4e8051 in __ubsan_handle_dynamic_type_cache_miss
1111
# 3 0x7f02ce676cd8 in JIT_InitPInvokeFrame(InlinedCallFrame*, void*) /home/steveharter/git/dotnet_coreclr/vm/jithelpers.cpp:6491:9
1212
# 4 0x7f0252bbceb2 (<unknown module>)
13-
fun:_Z20JIT_InitPInvokeFrameP16InlinedCallFramePv
13+
fun:_Z20JIT_InitPInvokeFrameP16InlinedCallFrame
1414

src/coreclr/inc/corinfo.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1754,13 +1754,17 @@ struct CORINFO_EE_INFO
17541754
// Size of the Frame structure
17551755
unsigned size;
17561756

1757+
// Size of the Frame structure when it also contains the secret stub arg
1758+
unsigned sizeWithSecretStubArg;
1759+
17571760
unsigned offsetOfGSCookie;
17581761
unsigned offsetOfFrameVptr;
17591762
unsigned offsetOfFrameLink;
17601763
unsigned offsetOfCallSiteSP;
17611764
unsigned offsetOfCalleeSavedFP;
17621765
unsigned offsetOfCallTarget;
17631766
unsigned offsetOfReturnAddress;
1767+
unsigned offsetOfSecretStubArg;
17641768
// This offset is used only for ARM
17651769
unsigned offsetOfSPAfterProlog;
17661770
}

src/coreclr/inc/jiteeversionguid.h

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -43,11 +43,11 @@ typedef const GUID *LPCGUID;
4343
#define GUID_DEFINED
4444
#endif // !GUID_DEFINED
4545

46-
constexpr GUID JITEEVersionIdentifier = { /* 43854594-cd60-45df-a89f-5b7697586f46 */
47-
0x43854594,
48-
0xcd60,
49-
0x45df,
50-
{0xa8, 0x9f, 0x5b, 0x76, 0x97, 0x58, 0x6f, 0x46}
46+
constexpr GUID JITEEVersionIdentifier = { /* 227e46fa-1be3-4770-b613-4a239e7c28aa */
47+
0x227e46fa,
48+
0x1be3,
49+
0x4770,
50+
{0xb6, 0x13, 0x4a, 0x23, 0x9e, 0x7c, 0x28, 0xaa}
5151
};
5252

5353
//////////////////////////////////////////////////////////////////////////////////////////////////////////

src/coreclr/jit/codegen.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -277,6 +277,7 @@ class CodeGen final : public CodeGenInterface
277277

278278
var_types genParamStackStoreType(LclVarDsc* dsc, const ABIPassingSegment& seg);
279279
void genSpillOrAddRegisterParam(unsigned lclNum, class RegGraph* graph);
280+
void genSpillOrAddNonStandardRegisterParam(unsigned lclNum, regNumber sourceReg, class RegGraph* graph);
280281
void genEnregisterIncomingStackArgs();
281282
#if defined(TARGET_ARM64) || defined(TARGET_LOONGARCH64) || defined(TARGET_RISCV64)
282283
void genEnregisterOSRArgsAndLocals(regNumber initReg, bool* pInitRegZeroed);

src/coreclr/jit/codegencommon.cpp

Lines changed: 36 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -3246,6 +3246,31 @@ void CodeGen::genSpillOrAddRegisterParam(unsigned lclNum, RegGraph* graph)
32463246
}
32473247
}
32483248

3249+
// -----------------------------------------------------------------------------
3250+
// genSpillOrAddNonStandardRegisterParam: Handle a non-standard register parameter either
3251+
// by homing it to stack immediately, or by adding it to the register graph.
3252+
//
3253+
// Parameters:
3254+
// lclNum - Local that represents the non-standard parameter
3255+
// sourceReg - Register that the non-standard parameter is in on entry to the function
3256+
// graph - The register graph to add to
3257+
//
3258+
void CodeGen::genSpillOrAddNonStandardRegisterParam(unsigned lclNum, regNumber sourceReg, RegGraph* graph)
3259+
{
3260+
LclVarDsc* varDsc = compiler->lvaGetDesc(lclNum);
3261+
if (varDsc->lvOnFrame && (!varDsc->lvIsInReg() || varDsc->lvLiveInOutOfHndlr))
3262+
{
3263+
GetEmitter()->emitIns_S_R(ins_Store(varDsc->TypeGet()), emitActualTypeSize(varDsc), sourceReg, lclNum, 0);
3264+
}
3265+
3266+
if (varDsc->lvIsInReg())
3267+
{
3268+
RegNode* sourceRegNode = graph->GetOrAdd(sourceReg);
3269+
RegNode* destRegNode = graph->GetOrAdd(varDsc->GetRegNum());
3270+
graph->AddEdge(sourceRegNode, destRegNode, TYP_I_IMPL, 0);
3271+
}
3272+
}
3273+
32493274
// -----------------------------------------------------------------------------
32503275
// genHomeRegisterParams: Move all register parameters to their initial
32513276
// assigned location.
@@ -3289,6 +3314,12 @@ void CodeGen::genHomeRegisterParams(regNumber initReg, bool* initRegStillZeroed)
32893314
}
32903315
}
32913316

3317+
if (compiler->info.compPublishStubParam && ((paramRegs & RBM_SECRET_STUB_PARAM) != RBM_NONE))
3318+
{
3319+
GetEmitter()->emitIns_S_R(ins_Store(TYP_I_IMPL), EA_PTRSIZE, REG_SECRET_STUB_PARAM,
3320+
compiler->lvaStubArgumentVar, 0);
3321+
}
3322+
32923323
return;
32933324
}
32943325

@@ -3321,6 +3352,11 @@ void CodeGen::genHomeRegisterParams(regNumber initReg, bool* initRegStillZeroed)
33213352
}
33223353
}
33233354

3355+
if (compiler->info.compPublishStubParam && ((paramRegs & RBM_SECRET_STUB_PARAM) != RBM_NONE))
3356+
{
3357+
genSpillOrAddNonStandardRegisterParam(compiler->lvaStubArgumentVar, REG_SECRET_STUB_PARAM, &graph);
3358+
}
3359+
33243360
DBEXEC(VERBOSE, graph.Dump());
33253361

33263362
regMaskTP busyRegs = intRegState.rsCalleeRegArgMaskLiveIn | floatRegState.rsCalleeRegArgMaskLiveIn;
@@ -3784,13 +3820,6 @@ void CodeGen::genCheckUseBlockInit()
37843820
{
37853821
regMaskTP maskCalleeRegArgMask = intRegState.rsCalleeRegArgMaskLiveIn;
37863822

3787-
// If there is a secret stub param, don't count it, as it will no longer
3788-
// be live when we do block init.
3789-
if (compiler->info.compPublishStubParam)
3790-
{
3791-
maskCalleeRegArgMask &= ~RBM_SECRET_STUB_PARAM;
3792-
}
3793-
37943823
#ifdef TARGET_ARM
37953824
//
37963825
// On the Arm if we are using a block init to initialize, then we
@@ -5572,16 +5601,6 @@ void CodeGen::genFnProlog()
55725601
}
55735602
#endif // TARGET_ARM
55745603

5575-
if (compiler->info.compPublishStubParam)
5576-
{
5577-
GetEmitter()->emitIns_S_R(ins_Store(TYP_I_IMPL), EA_PTRSIZE, REG_SECRET_STUB_PARAM,
5578-
compiler->lvaStubArgumentVar, 0);
5579-
assert(intRegState.rsCalleeRegArgMaskLiveIn & RBM_SECRET_STUB_PARAM);
5580-
5581-
// It's no longer live; clear it out so it can be used after this in the prolog
5582-
intRegState.rsCalleeRegArgMaskLiveIn &= ~RBM_SECRET_STUB_PARAM;
5583-
}
5584-
55855604
//
55865605
// Zero out the frame as needed
55875606
//

src/coreclr/jit/compiler.cpp

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4602,11 +4602,6 @@ void Compiler::compCompile(void** methodCodePtr, uint32_t* methodCodeSize, JitFl
46024602
assert(lvaStubArgumentVar == BAD_VAR_NUM);
46034603
lvaStubArgumentVar = lvaGrabTempWithImplicitUse(false DEBUGARG("stub argument"));
46044604
lvaGetDesc(lvaStubArgumentVar)->lvType = TYP_I_IMPL;
4605-
// TODO-CQ: there is no need to mark it as doNotEnreg. There are no stores for this local
4606-
// before codegen so liveness and LSRA mark it as "liveIn" and always allocate a stack slot for it.
4607-
// However, it would be better to process it like other argument locals and keep it in
4608-
// a reg for the whole method without spilling to the stack when possible.
4609-
lvaSetVarDoNotEnregister(lvaStubArgumentVar DEBUGARG(DoNotEnregisterReason::VMNeedsStackAddr));
46104605
}
46114606
};
46124607
DoPhase(this, PHASE_PRE_IMPORT, preImportPhase);

src/coreclr/jit/compiler.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4243,7 +4243,7 @@ class Compiler
42434243
return lvaGetDesc(lclNum)->lvInSsa;
42444244
}
42454245

4246-
unsigned lvaStubArgumentVar; // variable representing the secret stub argument coming in EAX
4246+
unsigned lvaStubArgumentVar; // variable representing the secret stub argument
42474247

42484248
unsigned lvaPSPSym; // variable representing the PSPSym
42494249

src/coreclr/jit/flowgraph.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2438,7 +2438,10 @@ PhaseStatus Compiler::fgAddInternal()
24382438

24392439
LclVarDsc* varDsc = lvaGetDesc(lvaInlinedPInvokeFrameVar);
24402440
// Make room for the inlined frame.
2441-
lvaSetStruct(lvaInlinedPInvokeFrameVar, typGetBlkLayout(eeGetEEInfo()->inlinedCallFrameInfo.size), false);
2441+
const CORINFO_EE_INFO* eeInfo = eeGetEEInfo();
2442+
unsigned frameSize = info.compPublishStubParam ? eeInfo->inlinedCallFrameInfo.sizeWithSecretStubArg
2443+
: eeInfo->inlinedCallFrameInfo.size;
2444+
lvaSetStruct(lvaInlinedPInvokeFrameVar, typGetBlkLayout(frameSize), false);
24422445
}
24432446

24442447
// Do we need to insert a "JustMyCode" callback?

src/coreclr/jit/gentree.cpp

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13136,8 +13136,6 @@ const char* Compiler::gtGetWellKnownArgNameForArgMsg(WellKnownArg arg)
1313613136
return "retbuf";
1313713137
case WellKnownArg::PInvokeFrame:
1313813138
return "pinv frame";
13139-
case WellKnownArg::SecretStubParam:
13140-
return "stub param";
1314113139
case WellKnownArg::WrapperDelegateCell:
1314213140
return "wrap cell";
1314313141
case WellKnownArg::ShiftLow:

src/coreclr/jit/gentree.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4465,7 +4465,6 @@ enum class WellKnownArg : unsigned
44654465
InstParam,
44664466
RetBuffer,
44674467
PInvokeFrame,
4468-
SecretStubParam,
44694468
WrapperDelegateCell,
44704469
ShiftLow,
44714470
ShiftHigh,

src/coreclr/jit/lclvars.cpp

Lines changed: 0 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -6694,22 +6694,6 @@ void Compiler::lvaAssignVirtualFrameOffsetsToLocals()
66946694
continue;
66956695
}
66966696

6697-
// This should be low on the stack. Hence, it will be assigned later.
6698-
if (lclNum == lvaStubArgumentVar)
6699-
{
6700-
#ifdef JIT32_GCENCODER
6701-
noway_assert(codeGen->isFramePointerUsed());
6702-
#endif
6703-
continue;
6704-
}
6705-
6706-
// This should be low on the stack. Hence, it will be assigned later.
6707-
if (lclNum == lvaInlinedPInvokeFrameVar)
6708-
{
6709-
noway_assert(codeGen->isFramePointerUsed());
6710-
continue;
6711-
}
6712-
67136697
if (varDsc->lvIsParam)
67146698
{
67156699
#ifdef TARGET_ARM64
@@ -6852,25 +6836,6 @@ void Compiler::lvaAssignVirtualFrameOffsetsToLocals()
68526836
*-------------------------------------------------------------------------
68536837
*/
68546838

6855-
// lvaInlinedPInvokeFrameVar and lvaStubArgumentVar need to be assigned last
6856-
// Important: The stack walker depends on lvaStubArgumentVar immediately
6857-
// following lvaInlinedPInvokeFrameVar in the frame.
6858-
6859-
if (lvaStubArgumentVar != BAD_VAR_NUM)
6860-
{
6861-
#ifdef JIT32_GCENCODER
6862-
noway_assert(codeGen->isFramePointerUsed());
6863-
#endif
6864-
stkOffs = lvaAllocLocalAndSetVirtualOffset(lvaStubArgumentVar, lvaLclSize(lvaStubArgumentVar), stkOffs);
6865-
}
6866-
6867-
if (lvaInlinedPInvokeFrameVar != BAD_VAR_NUM)
6868-
{
6869-
noway_assert(codeGen->isFramePointerUsed());
6870-
stkOffs =
6871-
lvaAllocLocalAndSetVirtualOffset(lvaInlinedPInvokeFrameVar, lvaLclSize(lvaInlinedPInvokeFrameVar), stkOffs);
6872-
}
6873-
68746839
#ifdef JIT32_GCENCODER
68756840
// JIT32 encoder cannot handle GS cookie at fp+0 since NO_GS_COOKIE == 0.
68766841
// Add some padding if it is the last allocated local.

src/coreclr/jit/lower.cpp

Lines changed: 30 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -5515,7 +5515,7 @@ GenTree* Lowering::CreateFrameLinkUpdate(FrameLinkAction action)
55155515
const CORINFO_EE_INFO* pInfo = comp->eeGetEEInfo();
55165516
const CORINFO_EE_INFO::InlinedCallFrameInfo& callFrameInfo = pInfo->inlinedCallFrameInfo;
55175517

5518-
GenTree* TCB = new (comp, GT_LCL_VAR) GenTreeLclVar(GT_LCL_VAR, TYP_I_IMPL, comp->info.compLvFrameListRoot);
5518+
GenTree* TCB = comp->gtNewLclVarNode(comp->info.compLvFrameListRoot, TYP_I_IMPL);
55195519

55205520
// Thread->m_pFrame
55215521
GenTree* addr = new (comp, GT_LEA) GenTreeAddrMode(TYP_I_IMPL, TCB, nullptr, 1, pInfo->offsetOfThreadFrame);
@@ -5525,18 +5525,17 @@ GenTree* Lowering::CreateFrameLinkUpdate(FrameLinkAction action)
55255525
if (action == PushFrame)
55265526
{
55275527
// Thread->m_pFrame = &inlinedCallFrame;
5528-
data = new (comp, GT_LCL_ADDR)
5529-
GenTreeLclFld(GT_LCL_ADDR, TYP_BYREF, comp->lvaInlinedPInvokeFrameVar, callFrameInfo.offsetOfFrameVptr);
5528+
data = comp->gtNewLclAddrNode(comp->lvaInlinedPInvokeFrameVar, callFrameInfo.offsetOfFrameVptr);
55305529
}
55315530
else
55325531
{
55335532
assert(action == PopFrame);
55345533
// Thread->m_pFrame = inlinedCallFrame.m_pNext;
55355534

5536-
data = new (comp, GT_LCL_FLD) GenTreeLclFld(GT_LCL_FLD, TYP_BYREF, comp->lvaInlinedPInvokeFrameVar,
5537-
pInfo->inlinedCallFrameInfo.offsetOfFrameLink);
5535+
data = comp->gtNewLclFldNode(comp->lvaInlinedPInvokeFrameVar, TYP_I_IMPL,
5536+
pInfo->inlinedCallFrameInfo.offsetOfFrameLink);
55385537
}
5539-
GenTree* storeInd = new (comp, GT_STOREIND) GenTreeStoreInd(TYP_I_IMPL, addr, data);
5538+
GenTree* storeInd = comp->gtNewStoreIndNode(TYP_I_IMPL, addr, data);
55405539
return storeInd;
55415540
}
55425541

@@ -5558,28 +5557,22 @@ GenTree* Lowering::CreateFrameLinkUpdate(FrameLinkAction action)
55585557
// +08h +04h vptr for class InlinedCallFrame offsetOfFrameVptr method prolog
55595558
// +10h +08h m_Next offsetOfFrameLink method prolog
55605559
// +18h +0Ch m_Datum offsetOfCallTarget call site
5561-
// +20h n/a m_StubSecretArg not set by JIT
5562-
// +28h +10h m_pCallSiteSP offsetOfCallSiteSP x86: call site, and zeroed in method
5560+
// +20h +10h m_pCallSiteSP offsetOfCallSiteSP x86: call site, and zeroed in method
55635561
// prolog;
55645562
// non-x86: method prolog (SP remains
55655563
// constant in function, after prolog: no
55665564
// localloc and PInvoke in same function)
5567-
// +30h +14h m_pCallerReturnAddress offsetOfReturnAddress call site
5568-
// +38h +18h m_pCalleeSavedFP offsetOfCalleeSavedFP not set by JIT
5569-
// +1Ch m_pThread
5565+
// +28h +14h m_pCallerReturnAddress offsetOfReturnAddress call site
5566+
// +30h +18h m_pCalleeSavedFP offsetOfCalleeSavedFP not set by JIT
5567+
// +38h +1Ch m_pThread
55705568
// +20h m_pSPAfterProlog offsetOfSPAfterProlog arm only
5571-
// +20/24h JIT retval spill area (int) before call_gc ???
5572-
// +24/28h JIT retval spill area (long) before call_gc ???
5573-
// +28/2Ch Saved value of EBP method prolog ???
5569+
// +40h +20/24h m_StubSecretArg offsetOfSecretStubArg method prolog of IL stubs with secret arg
55745570
//
55755571
// Note that in the VM, InlinedCallFrame is a C++ class whose objects have a 'this' pointer that points
55765572
// to the InlinedCallFrame vptr (the 2nd field listed above), and the GS cookie is stored *before*
55775573
// the object. When we link the InlinedCallFrame onto the Frame chain, we must point at this location,
55785574
// and not at the beginning of the InlinedCallFrame local, which is actually the GS cookie.
55795575
//
5580-
// Return Value:
5581-
// none
5582-
//
55835576
// See the usages for USE_PER_FRAME_PINVOKE_INIT for more information.
55845577
void Lowering::InsertPInvokeMethodProlog()
55855578
{
@@ -5601,47 +5594,38 @@ void Lowering::InsertPInvokeMethodProlog()
56015594
const CORINFO_EE_INFO* pInfo = comp->eeGetEEInfo();
56025595
const CORINFO_EE_INFO::InlinedCallFrameInfo& callFrameInfo = pInfo->inlinedCallFrameInfo;
56035596

5604-
// First arg: &compiler->lvaInlinedPInvokeFrameVar + callFrameInfo.offsetOfFrameVptr
5605-
#if defined(DEBUG)
5606-
const LclVarDsc* inlinedPInvokeDsc = comp->lvaGetDesc(comp->lvaInlinedPInvokeFrameVar);
5607-
assert(inlinedPInvokeDsc->IsAddressExposed());
5608-
#endif // DEBUG
5609-
GenTree* frameAddr = new (comp, GT_LCL_ADDR)
5610-
GenTreeLclFld(GT_LCL_ADDR, TYP_BYREF, comp->lvaInlinedPInvokeFrameVar, callFrameInfo.offsetOfFrameVptr);
5597+
assert(comp->lvaGetDesc(comp->lvaInlinedPInvokeFrameVar)->IsAddressExposed());
56115598

5612-
// Call runtime helper to fill in our InlinedCallFrame and push it on the Frame list:
5613-
// TCB = CORINFO_HELP_INIT_PINVOKE_FRAME(&symFrameStart, secretArg);
5614-
GenTreeCall* call = comp->gtNewHelperCallNode(CORINFO_HELP_INIT_PINVOKE_FRAME, TYP_I_IMPL);
5599+
GenTree* const insertionPoint = firstBlockRange.FirstNonCatchArgNode();
56155600

5616-
NewCallArg frameAddrArg = NewCallArg::Primitive(frameAddr).WellKnown(WellKnownArg::PInvokeFrame);
5617-
call->gtArgs.PushBack(comp, frameAddrArg);
5618-
// for x86/arm32 don't pass the secretArg.
5619-
#if !defined(TARGET_X86) && !defined(TARGET_ARM)
5620-
GenTree* argNode;
5601+
// Store the stub secret arg if necessary. This has to be done before the
5602+
// call to the init helper below, which links the frame into the thread
5603+
// list on 32-bit platforms.
5604+
// InlinedCallFrame.m_StubSecretArg = stubSecretArg;
56215605
if (comp->info.compPublishStubParam)
56225606
{
5623-
argNode = comp->gtNewLclvNode(comp->lvaStubArgumentVar, TYP_I_IMPL);
5607+
GenTree* value = comp->gtNewLclvNode(comp->lvaStubArgumentVar, TYP_I_IMPL);
5608+
GenTree* store = comp->gtNewStoreLclFldNode(comp->lvaInlinedPInvokeFrameVar, TYP_I_IMPL,
5609+
callFrameInfo.offsetOfSecretStubArg, value);
5610+
firstBlockRange.InsertBefore(insertionPoint, LIR::SeqTree(comp, store));
5611+
DISPTREERANGE(firstBlockRange, store);
56245612
}
5625-
else
5626-
{
5627-
argNode = comp->gtNewIconNode(0, TYP_I_IMPL);
5628-
}
5629-
NewCallArg stubParamArg = NewCallArg::Primitive(argNode).WellKnown(WellKnownArg::SecretStubParam);
5630-
call->gtArgs.PushBack(comp, stubParamArg);
5631-
#endif
5613+
5614+
// Call runtime helper to fill in our InlinedCallFrame and push it on the Frame list:
5615+
// TCB = CORINFO_HELP_INIT_PINVOKE_FRAME(&symFrameStart);
5616+
GenTree* frameAddr = comp->gtNewLclAddrNode(comp->lvaInlinedPInvokeFrameVar, callFrameInfo.offsetOfFrameVptr);
5617+
NewCallArg frameAddrArg = NewCallArg::Primitive(frameAddr).WellKnown(WellKnownArg::PInvokeFrame);
5618+
5619+
GenTreeCall* call = comp->gtNewHelperCallNode(CORINFO_HELP_INIT_PINVOKE_FRAME, TYP_I_IMPL);
5620+
call->gtArgs.PushBack(comp, frameAddrArg);
56325621

56335622
// some sanity checks on the frame list root vardsc
56345623
const unsigned lclNum = comp->info.compLvFrameListRoot;
56355624
const LclVarDsc* varDsc = comp->lvaGetDesc(lclNum);
56365625
noway_assert(!varDsc->lvIsParam);
56375626
noway_assert(varDsc->lvType == TYP_I_IMPL);
56385627

5639-
GenTree* store = new (comp, GT_STORE_LCL_VAR) GenTreeLclVar(GT_STORE_LCL_VAR, TYP_I_IMPL, lclNum);
5640-
store->AsOp()->gtOp1 = call;
5641-
store->gtFlags |= GTF_VAR_DEF;
5642-
5643-
GenTree* const insertionPoint = firstBlockRange.FirstNonCatchArgNode();
5644-
5628+
GenTree* store = comp->gtNewStoreLclVarNode(lclNum, call);
56455629
comp->fgMorphTree(store);
56465630
firstBlockRange.InsertBefore(insertionPoint, LIR::SeqTree(comp, store));
56475631
DISPTREERANGE(firstBlockRange, store);
@@ -5656,7 +5640,6 @@ void Lowering::InsertPInvokeMethodProlog()
56565640
GenTree* spValue = PhysReg(REG_SPBASE);
56575641
GenTreeLclFld* storeSP = comp->gtNewStoreLclFldNode(comp->lvaInlinedPInvokeFrameVar, TYP_I_IMPL,
56585642
callFrameInfo.offsetOfCallSiteSP, spValue);
5659-
assert(inlinedPInvokeDsc->lvDoNotEnregister);
56605643

56615644
firstBlockRange.InsertBefore(insertionPoint, LIR::SeqTree(comp, storeSP));
56625645
DISPTREERANGE(firstBlockRange, storeSP);
@@ -5672,7 +5655,6 @@ void Lowering::InsertPInvokeMethodProlog()
56725655
GenTree* fpValue = PhysReg(REG_FPBASE);
56735656
GenTreeLclFld* storeFP = comp->gtNewStoreLclFldNode(comp->lvaInlinedPInvokeFrameVar, TYP_I_IMPL,
56745657
callFrameInfo.offsetOfCalleeSavedFP, fpValue);
5675-
assert(inlinedPInvokeDsc->lvDoNotEnregister);
56765658

56775659
firstBlockRange.InsertBefore(insertionPoint, LIR::SeqTree(comp, storeFP));
56785660
DISPTREERANGE(firstBlockRange, storeFP);

src/coreclr/jit/lsra.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -644,6 +644,8 @@ class LinearScan : public LinearScanInterface
644644
template <bool localVarsEnregistered>
645645
void buildIntervals();
646646

647+
void buildInitialParamDef(const LclVarDsc* varDsc, regNumber paramReg);
648+
647649
// This is where the actual assignment is done for scenarios where
648650
// no local var enregistration is done.
649651
void allocateRegistersMinimal();

0 commit comments

Comments
 (0)