Skip to content
This repository was archived by the owner on Jan 23, 2023. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 16 additions & 10 deletions src/inc/corjit.h
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ enum CorJitFlag
CORJIT_FLG_GCPOLL_CALLS = 0x00000040, // Emit calls to JIT_POLLGC for thread suspension.
CORJIT_FLG_MCJIT_BACKGROUND = 0x00000080, // Calling from multicore JIT background thread, do not call JitComplete

#ifdef FEATURE_LEGACYNETCF
#if defined(FEATURE_LEGACYNETCF)

CORJIT_FLG_NETCF_QUIRKS = 0x00000100, // Mimic .NetCF JIT's quirks for generated code (currently just inlining heuristics)

Expand Down Expand Up @@ -121,27 +121,33 @@ enum CorJitFlag

#endif // !defined(_TARGET_X86_) && !defined(_TARGET_AMD64_)

#ifdef MDIL
#if defined(MDIL)

CORJIT_FLG_MDIL = 0x00004000, // Generate MDIL code instead of machine code
#else // MDIL
CORJIT_FLG_CFI_UNWIND = 0x00004000, // Emit CFI unwind info
#endif // MDIL

#ifdef MDIL
// Safe to overlap with CORJIT_FLG_MAKEFINALCODE below. Not used by the JIT, used internally by NGen only.
CORJIT_FLG_MINIMAL_MDIL = 0x00008000, // Generate MDIL code suitable for use to bind other assemblies.

// Safe to overlap with CORJIT_FLG_READYTORUN below. Not used by the JIT, used internally by NGen only.
CORJIT_FLG_NO_MDIL = 0x00010000, // Generate an MDIL section but no code or CTL. Not used by the JIT, used internally by NGen only.
#endif // MDIL

#else // defined(MDIL)

CORJIT_FLG_CFI_UNWIND = 0x00004000, // Emit CFI unwind info

#if defined(FEATURE_INTERPRETER)

CORJIT_FLG_MAKEFINALCODE = 0x00008000, // Use the final code generator, i.e., not the interpreter.
#endif // FEATURE_INTERPRETER

#ifdef FEATURE_READYTORUN_COMPILER
#endif // defined(FEATURE_INTERPRETER)

#if defined(FEATURE_READYTORUN_COMPILER)

CORJIT_FLG_READYTORUN = 0x00010000, // Use version-resilient code generation
#endif

#endif // defined(FEATURE_READYTORUN_COMPILER)

#endif // !defined(MDIL)

CORJIT_FLG_PROF_ENTERLEAVE = 0x00020000, // Instrument prologues/epilogues
CORJIT_FLG_PROF_REJIT_NOPS = 0x00040000, // Insert NOPs to ensure code is re-jitable
Expand Down
24 changes: 18 additions & 6 deletions src/jit/codegencommon.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7558,6 +7558,7 @@ void CodeGen::genPrologPadForReJit()
regMaskTP CodeGen::genPInvokeMethodProlog(regMaskTP initRegs)
{
assert(compiler->compGeneratingProlog);
noway_assert(!compiler->opts.ShouldUsePInvokeHelpers());
noway_assert(compiler->info.compCallUnmanaged);

CORINFO_EE_INFO * pInfo = compiler->eeGetEEInfo();
Expand Down Expand Up @@ -7777,6 +7778,7 @@ regMaskTP CodeGen::genPInvokeMethodProlog(regMaskTP initRegs)
void CodeGen::genPInvokeMethodEpilog()
{
noway_assert(compiler->info.compCallUnmanaged);
noway_assert(!compiler->opts.ShouldUsePInvokeHelpers());
noway_assert(compiler->compCurBB == compiler->genReturnBB ||
(compiler->compTailCallUsed && (compiler->compCurBB->bbJumpKind == BBJ_THROW)) ||
(compiler->compJmpOpUsed && (compiler->compCurBB->bbFlags & BBF_HAS_JMP)));
Expand Down Expand Up @@ -8518,13 +8520,23 @@ void CodeGen::genFnProlog()
// since they are trashed by the jithelper call to setup the PINVOKE frame
if (compiler->info.compCallUnmanaged)
{
excludeMask |= (RBM_PINVOKE_FRAME | RBM_PINVOKE_TCB | RBM_PINVOKE_SCRATCH);
excludeMask |= RBM_PINVOKE_FRAME;

// We also must exclude the register used by compLvFrameListRoot when it is enregistered
//
LclVarDsc * varDsc = &compiler->lvaTable[compiler->info.compLvFrameListRoot];
if (varDsc->lvRegister)
excludeMask |= genRegMask(varDsc->lvRegNum);
assert((!compiler->opts.ShouldUsePInvokeHelpers()) || (compiler->info.compLvFrameListRoot == BAD_VAR_NUM));
if (!compiler->opts.ShouldUsePInvokeHelpers())
{
noway_assert(compiler->info.compLvFrameListRoot < compiler->lvaCount);

excludeMask |= (RBM_PINVOKE_TCB | RBM_PINVOKE_SCRATCH);

// We also must exclude the register used by compLvFrameListRoot when it is enregistered
//
LclVarDsc * varDsc = &compiler->lvaTable[compiler->info.compLvFrameListRoot];
if (varDsc->lvRegister)
{
excludeMask |= genRegMask(varDsc->lvRegNum);
}
}
}
#endif // INLINE_NDIRECT

Expand Down
4 changes: 4 additions & 0 deletions src/jit/compiler.h
Original file line number Diff line number Diff line change
Expand Up @@ -7707,6 +7707,10 @@ public :
inline bool IsReadyToRun() { return false; }
#endif

// true if we should use the PINVOKE_{BEGIN,END} helpers instead of generating
// PInvoke transitions inline (e.g. when targeting CoreRT).
inline bool ShouldUsePInvokeHelpers() { return (jitFlags->corJitFlags2 & CORJIT_FLG2_USE_PINVOKE_HELPERS) != 0; }

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please put the {, body, and }, on separate lines from the declaration.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The method as written is consistent with the various accessors immediately above it.

Also, I cannot find any guidance re: braces for methods in the CC.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd prefer to remain consistent with the other accessors in the case. If we believe that it is important that these methods have braces on the next line, we should change them together.


// true if we must generate compatible code with Jit64 quirks
inline bool IsJit64Compat()
{
Expand Down
12 changes: 9 additions & 3 deletions src/jit/flowgraph.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8215,7 +8215,12 @@ void Compiler::fgAddInternal()
#if INLINE_NDIRECT
if (info.compCallUnmanaged != 0)
{
info.compLvFrameListRoot = lvaGrabTemp(false DEBUGARG("Pinvoke FrameListRoot"));
// The P/Invoke helpers only require a frame variable, so only allocate the
// TCB variable if we're not using them.
if (!opts.ShouldUsePInvokeHelpers())
{
info.compLvFrameListRoot = lvaGrabTemp(false DEBUGARG("Pinvoke FrameListRoot"));
}

lvaInlinedPInvokeFrameVar = lvaGrabTempWithImplicitUse(false DEBUGARG("Pinvoke FrameVar"));

Expand All @@ -8226,8 +8231,9 @@ void Compiler::fgAddInternal()
varDsc->lvExactSize = eeGetEEInfo()->inlinedCallFrameInfo.size;
#if FEATURE_FIXED_OUT_ARGS
// Grab and reserve space for TCB, Frame regs used in PInvoke epilog to pop the inlined frame.
// See genPInvokeMethodEpilog() for use of the grabbed var.
if (compJmpOpUsed)
// See genPInvokeMethodEpilog() for use of the grabbed var. This is only necessary if we are
// not using the P/Invoke helpers.
if (!opts.ShouldUsePInvokeHelpers() && compJmpOpUsed)
{
lvaPInvokeFrameRegSaveVar = lvaGrabTempWithImplicitUse(false DEBUGARG("PInvokeFrameRegSave Var"));
varDsc = &lvaTable[lvaPInvokeFrameRegSaveVar];
Expand Down
2 changes: 1 addition & 1 deletion src/jit/gentree.h
Original file line number Diff line number Diff line change
Expand Up @@ -2107,7 +2107,7 @@ struct GenTreeLclVar: public GenTreeLclVarCommon
DEBUG_ARG(largeNode)),
gtLclILoffs(ilOffs)
{
assert(OperIsLocal(oper));
assert(OperIsLocal(oper) || OperIsLocalAddr(oper));

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems like a fundamental change: GT_LCL_var can now take a local addr? why?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

GT_LCL_var can already be a local addr, just not at the time it is constructed (i.e. it is legal to create an lcl_var node and then change its type to a lcl_addr).

}

#if DEBUGGABLE_GENTREE
Expand Down
80 changes: 48 additions & 32 deletions src/jit/lclvars.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2170,17 +2170,21 @@ void Compiler::lvaDecRefCnts(GenTreePtr tree)

if ((tree->gtOper == GT_CALL) && (tree->gtFlags & GTF_CALL_UNMANAGED))
{
/* Get the special variable descriptor */
assert((!opts.ShouldUsePInvokeHelpers()) || (info.compLvFrameListRoot == BAD_VAR_NUM));
if (!opts.ShouldUsePInvokeHelpers())
{
/* Get the special variable descriptor */

lclNum = info.compLvFrameListRoot;

noway_assert(lclNum <= lvaCount);
varDsc = lvaTable + lclNum;

/* Decrement the reference counts twice */
lclNum = info.compLvFrameListRoot;

varDsc->decRefCnts(compCurBB->getBBWeight(this), this);
varDsc->decRefCnts(compCurBB->getBBWeight(this), this);
noway_assert(lclNum <= lvaCount);
varDsc = lvaTable + lclNum;

/* Decrement the reference counts twice */

varDsc->decRefCnts(compCurBB->getBBWeight(this), this);
varDsc->decRefCnts(compCurBB->getBBWeight(this), this);
}
}
else
{
Expand Down Expand Up @@ -2225,17 +2229,21 @@ void Compiler::lvaIncRefCnts(GenTreePtr tree)

if ((tree->gtOper == GT_CALL) && (tree->gtFlags & GTF_CALL_UNMANAGED))
{
/* Get the special variable descriptor */
assert((!opts.ShouldUsePInvokeHelpers()) || (info.compLvFrameListRoot == BAD_VAR_NUM));
if (!opts.ShouldUsePInvokeHelpers())
{
/* Get the special variable descriptor */

lclNum = info.compLvFrameListRoot;

noway_assert(lclNum <= lvaCount);
varDsc = lvaTable + lclNum;

/* Increment the reference counts twice */
lclNum = info.compLvFrameListRoot;

varDsc->incRefCnts(compCurBB->getBBWeight(this), this);
varDsc->incRefCnts(compCurBB->getBBWeight(this), this);
noway_assert(lclNum <= lvaCount);
varDsc = lvaTable + lclNum;

/* Increment the reference counts twice */

varDsc->incRefCnts(compCurBB->getBBWeight(this), this);
varDsc->incRefCnts(compCurBB->getBBWeight(this), this);
}
}
else
{
Expand Down Expand Up @@ -2811,16 +2819,20 @@ void Compiler::lvaMarkLclRefs(GenTreePtr tree)
/* Is this a call to unmanaged code ? */
if (tree->gtOper == GT_CALL && tree->gtFlags & GTF_CALL_UNMANAGED)
{
/* Get the special variable descriptor */
assert((!opts.ShouldUsePInvokeHelpers()) || (info.compLvFrameListRoot == BAD_VAR_NUM));
if (!opts.ShouldUsePInvokeHelpers())
{
/* Get the special variable descriptor */

unsigned lclNum = info.compLvFrameListRoot;
noway_assert(lclNum <= lvaCount);
LclVarDsc * varDsc = lvaTable + lclNum;
unsigned lclNum = info.compLvFrameListRoot;

noway_assert(lclNum <= lvaCount);
LclVarDsc * varDsc = lvaTable + lclNum;

/* Increment the ref counts twice */
varDsc->incRefCnts(lvaMarkRefsWeight, this);
varDsc->incRefCnts(lvaMarkRefsWeight, this);
/* Increment the ref counts twice */
varDsc->incRefCnts(lvaMarkRefsWeight, this);
varDsc->incRefCnts(lvaMarkRefsWeight, this);
}
}
#endif

Expand Down Expand Up @@ -3177,15 +3189,19 @@ void Compiler::lvaMarkLocalVars()

if (info.compCallUnmanaged != 0)
{
noway_assert(info.compLvFrameListRoot >= info.compLocalsCount &&
info.compLvFrameListRoot < lvaCount);
assert((!opts.ShouldUsePInvokeHelpers()) || (info.compLvFrameListRoot == BAD_VAR_NUM));
if (!opts.ShouldUsePInvokeHelpers())
{
noway_assert(info.compLvFrameListRoot >= info.compLocalsCount &&
info.compLvFrameListRoot < lvaCount);

lvaTable[info.compLvFrameListRoot].lvType = TYP_I_IMPL;
lvaTable[info.compLvFrameListRoot].lvType = TYP_I_IMPL;

/* Set the refCnt, it is used in the prolog and return block(s) */
/* Set the refCnt, it is used in the prolog and return block(s) */

lvaTable[info.compLvFrameListRoot].lvRefCnt = 2;
lvaTable[info.compLvFrameListRoot].lvRefCntWtd = 2 * BB_UNITY_WEIGHT;
lvaTable[info.compLvFrameListRoot].lvRefCnt = 2;
lvaTable[info.compLvFrameListRoot].lvRefCntWtd = 2 * BB_UNITY_WEIGHT;
}
}
#endif

Expand Down
Loading