//
unsigned genStackLevel;
+ void SubtractStackLevel(unsigned adjustment)
+ {
+ assert(genStackLevel >= adjustment);
+ unsigned newStackLevel = genStackLevel - adjustment;
+ if (genStackLevel != newStackLevel)
+ {
+ JITDUMP("Adjusting stack level from %d to %d\n", genStackLevel, newStackLevel);
+ }
+ genStackLevel = newStackLevel;
+ }
+
+ void AddStackLevel(unsigned adjustment)
+ {
+ unsigned newStackLevel = genStackLevel + adjustment;
+ if (genStackLevel != newStackLevel)
+ {
+ JITDUMP("Adjusting stack level from %d to %d\n", genStackLevel, newStackLevel);
+ }
+ genStackLevel = newStackLevel;
+ }
+
+ void SetStackLevel(unsigned newStackLevel)
+ {
+ if (genStackLevel != newStackLevel)
+ {
+ JITDUMP("Setting stack level from %d to %d\n", genStackLevel, newStackLevel);
+ }
+ genStackLevel = newStackLevel;
+ }
+
#if STACK_PROBES
// Stack Probes
bool genNeedPrologStackProbe;
{
noway_assert(block->bbFlags & BBF_JMP_TARGET);
- genStackLevel = compiler->fgThrowHlpBlkStkLevel(block) * sizeof(int);
+ SetStackLevel(compiler->fgThrowHlpBlkStkLevel(block) * sizeof(int));
if (genStackLevel != 0)
{
#ifdef _TARGET_X86_
getEmitter()->emitMarkStackLvl(genStackLevel);
inst_RV_IV(INS_add, REG_SPBASE, genStackLevel, EA_PTRSIZE);
- genStackLevel = 0;
+ SetStackLevel(0);
#else // _TARGET_X86_
NYI("Need emitMarkStackLvl()");
#endif // _TARGET_X86_
}
#endif // DEBUG
#endif // 0
- genStackLevel += 4;
+ AddStackLevel(4);
inst_IV(INS_push, wbKind);
genEmitHelperCall(helper,
4, // argSize
EA_PTRSIZE); // retSize
- genStackLevel -= 4;
+ SubtractStackLevel(4);
}
else
{
/* Restore the stack level */
- genStackLevel = saveStackLvl2;
+ SetStackLevel(saveStackLvl2);
#else // target
NYI("Emit Profiler Enter callback");
#endif // target
/* Restore the stack level */
- genStackLevel = saveStackLvl2;
+ SetStackLevel(saveStackLvl2);
}
#endif // PROFILING_SUPPORTED
//
void CodeGen::genSinglePush()
{
- genStackLevel += sizeof(void*);
+ AddStackLevel(REGSIZE_BYTES);
}
//------------------------------------------------------------------------
//
void CodeGen::genSinglePop()
{
- genStackLevel -= sizeof(void*);
+ SubtractStackLevel(REGSIZE_BYTES);
}
//------------------------------------------------------------------------
#endif //_TARGET_X86_
/* Restore the stack level */
- genStackLevel = saveStackLvl2;
+ SetStackLevel(saveStackLvl2);
}
#endif // PROFILING_SUPPORTED
/* Both stacks are always empty on entry to a basic block */
- genStackLevel = 0;
+ SetStackLevel(0);
#if FEATURE_STACK_FP_X87
genResetFPstkLevel();
#endif // FEATURE_STACK_FP_X87
}
}
- genStackLevel -= savedStkLvl;
+ SubtractStackLevel(savedStkLvl);
gcInfo.gcMarkRegSetNpt(gcrefRegs | byrefRegs);
}
inst_RV_IV(INS_sub, REG_SPBASE, stkDisp, EA_PTRSIZE);
- genStackLevel += stkDisp;
+ AddStackLevel(stkDisp);
while (curDisp < stkDisp)
{
#endif //_TARGET_X86_
/* Restore the stack level */
- genStackLevel = saveStackLvl2;
+ SetStackLevel(saveStackLvl2);
}
#endif // PROFILING_SUPPORTED
/* The function will pop all arguments before returning */
- genStackLevel = saveStackLvl;
+ SetStackLevel(saveStackLvl);
/* No trashed registers may possibly hold a pointer at this point */
CLANG_FORMAT_COMMENT_ANCHOR;
/* Both stacks are always empty on entry to a basic block */
- genStackLevel = 0;
+ SetStackLevel(0);
genAdjustStackLevel(block);
savedStkLvl = genStackLevel;
}
}
- genStackLevel -= savedStkLvl;
+ SubtractStackLevel(savedStkLvl);
#ifdef DEBUG
// compCurLife should be equal to the liveOut set, except that we don't keep
#if defined(_TARGET_X86_)
// The call will pop its arguments.
- genStackLevel -= stackArgBytes;
+ SubtractStackLevel(stackArgBytes);
#endif // defined(_TARGET_X86_)
// Update GC info:
{
const unsigned argSize = genTypeSize(putArgStk);
inst_RV_IV(INS_sub, REG_SPBASE, argSize, EA_PTRSIZE);
- genStackLevel += argSize;
+ AddStackLevel(argSize);
m_pushStkArg = false;
return true;
}
{
m_pushStkArg = false;
inst_RV_IV(INS_sub, REG_SPBASE, argSize, EA_PTRSIZE);
- genStackLevel += argSize;
+ AddStackLevel(argSize);
return true;
}
}
{
inst_IV(INS_push, 0);
currentOffset -= pushSize;
- genStackLevel += pushSize;
+ AddStackLevel(pushSize);
adjustment -= pushSize;
}
m_pushStkArg = true;
// Adjust the stack pointer to the next slot boundary.
inst_RV_IV(INS_sub, REG_SPBASE, adjustment, EA_PTRSIZE);
currentOffset -= adjustment;
- genStackLevel += adjustment;
+ AddStackLevel(adjustment);
}
// Does it need to be in a byte register?
}
}
currentOffset -= TARGET_POINTER_SIZE;
- genStackLevel += TARGET_POINTER_SIZE;
+ AddStackLevel(TARGET_POINTER_SIZE);
}
else
{
{
// We don't expect padding at the beginning of a struct, but it could happen with explicit layout.
inst_RV_IV(INS_sub, REG_SPBASE, currentOffset, EA_PTRSIZE);
- genStackLevel += currentOffset;
+ AddStackLevel(currentOffset);
}
}
#endif // _TARGET_X86_
{
inst_IV(INS_push, data->gtIntCon.gtIconVal);
}
- genStackLevel += argSize;
+ AddStackLevel(argSize);
}
else if (data->OperGet() == GT_FIELD_LIST)
{
inst_RV_IV(INS_sub, REG_SPBASE, size, EA_PTRSIZE);
getEmitter()->emitIns_AR_R(ins, attr, srcReg, REG_SPBASE, 0);
}
- genStackLevel += size;
+ AddStackLevel(size);
}
#endif // _TARGET_X86_
{
getEmitter()->emitIns_S(INS_push, slotAttr, srcLclNum, srcLclOffset + offset);
}
- genStackLevel += TARGET_POINTER_SIZE;
+ AddStackLevel(TARGET_POINTER_SIZE);
}
#else // !defined(_TARGET_X86_)