Skip to content
This repository has been archived by the owner on Jan 23, 2023. It is now read-only.

Commit

Permalink
[x86/Linux] Stack align 16 bytes for JIT code
Browse files Browse the repository at this point in the history
Change JIT code to align stack in 16 byte used in modern compiler
  • Loading branch information
seanshpark committed Jan 10, 2017
1 parent 01f8e7d commit a6a7403
Show file tree
Hide file tree
Showing 4 changed files with 59 additions and 11 deletions.
18 changes: 8 additions & 10 deletions src/jit/codegenxarch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2631,16 +2631,14 @@ void CodeGen::genLclHeap(GenTreePtr tree)
// Loop:
genDefineTempLabel(loop);

#if defined(_TARGET_AMD64_)
// Push two 8-byte zeros. This matches the 16-byte STACK_ALIGN value.
static_assert_no_msg(STACK_ALIGN == (REGSIZE_BYTES * 2));
inst_IV(INS_push_hide, 0); // --- push 8-byte 0
inst_IV(INS_push_hide, 0); // --- push 8-byte 0
#elif defined(_TARGET_X86_)
// Push a single 4-byte zero. This matches the 4-byte STACK_ALIGN value.
static_assert_no_msg(STACK_ALIGN == REGSIZE_BYTES);
inst_IV(INS_push_hide, 0); // --- push 4-byte 0
#endif // _TARGET_X86_
static_assert_no_msg((STACK_ALIGN % REGSIZE_BYTES) == 0);
unsigned const count = (STACK_ALIGN / REGSIZE_BYTES);

for (unsigned i=0; i<count; i++)
{
inst_IV(INS_push_hide, 0); // --- push REG_SIZE bytes of 0
}
// Note that the stack must always be aligned to STACK_ALIGN bytes

// Decrement the loop counter and loop if not done.
inst_RV(INS_dec, regCnt, TYP_I_IMPL);
Expand Down
19 changes: 19 additions & 0 deletions src/jit/lclvars.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5750,6 +5750,7 @@ void Compiler::lvaAlignFrame()

#elif defined(_TARGET_X86_)

#if DOUBLE_ALIGN
if (genDoubleAlign())
{
// Double Frame Alignement for x86 is handled in Compiler::lvaAssignVirtualFrameOffsetsToLocals()
Expand All @@ -5760,6 +5761,24 @@ void Compiler::lvaAlignFrame()
lvaIncrementFrameSize(sizeof(void*));
}
}
#endif

if (STACK_ALIGN > REGSIZE_BYTES)
{
if (lvaDoneFrameLayout != FINAL_FRAME_LAYOUT)
{
// If we are not doing final layout, we don't know the exact value of compLclFrameSize
// and thus do not know how much we will need to add in order to be aligned.
// We add the maximum pad that we could ever have (which is 12)
lvaIncrementFrameSize(STACK_ALIGN - REGSIZE_BYTES);
}

// The stack must always be 16 byte aligned.
if ((compLclFrameSize % STACK_ALIGN) != 0)
{
lvaIncrementFrameSize(STACK_ALIGN - (compLclFrameSize % STACK_ALIGN));
}
}

#else
NYI("TARGET specific lvaAlignFrame");
Expand Down
6 changes: 6 additions & 0 deletions src/jit/target.h
Original file line number Diff line number Diff line change
Expand Up @@ -484,9 +484,15 @@ typedef unsigned short regPairNoSmall; // arm: need 12 bits
#define MIN_ARG_AREA_FOR_CALL 0 // Minimum required outgoing argument space for a call.

#define CODE_ALIGN 1 // code alignment requirement
#if !defined(FEATURE_PAL)
#define STACK_ALIGN 4 // stack alignment requirement
#define STACK_ALIGN_SHIFT 2 // Shift-right amount to convert stack size in bytes to size in DWORD_PTRs
#define STACK_ALIGN_SHIFT_ALL 2 // Shift-right amount to convert stack size in bytes to size in STACK_ALIGN units
#else
#define STACK_ALIGN 16 // stack alignment requirement
#define STACK_ALIGN_SHIFT 4 // Shift-right amount to convert stack size in bytes to size in DWORD_PTRs
#define STACK_ALIGN_SHIFT_ALL 4 // Shift-right amount to convert stack size in bytes to size in STACK_ALIGN units
#endif // !FEATURE_PAL

#define RBM_INT_CALLEE_SAVED (RBM_EBX|RBM_ESI|RBM_EDI)
#define RBM_INT_CALLEE_TRASH (RBM_EAX|RBM_ECX|RBM_EDX)
Expand Down
27 changes: 26 additions & 1 deletion src/vm/i386/asmhelpers.S
Original file line number Diff line number Diff line change
Expand Up @@ -497,13 +497,14 @@ LEAF_ENTRY HelperMethodFrameRestoreState, _TEXT

cmp dword ptr [eax+MachState__pRetAddr], 0

#ifdef _DEBUG
#ifdef _DEBUG_XX
jnz LOCAL_LABEL(noConfirm)
push ebp
push ebx
push edi
push esi
push ecx // HelperFrame*
CHECK_STACK_ALIGNMENT
call C_FUNC(HelperMethodFrameConfirmState)
// on return, eax = MachState*
cmp DWORD PTR [eax + MachState__pRetAddr], 0
Expand Down Expand Up @@ -561,6 +562,7 @@ NESTED_ENTRY OnHijackTripThread, _TEXT, NoHandler
sub esp,12

push esp
CHECK_STACK_ALIGNMENT
call C_FUNC(OnHijackWorker)

// unused space for floating point state
Expand Down Expand Up @@ -596,6 +598,7 @@ NESTED_ENTRY OnHijackFPTripThread, _TEXT, NoHandler
fstp QWORD PTR [esp]

push esp
CHECK_STACK_ALIGNMENT
call C_FUNC(OnHijackWorker)

// restore top of the floating point stack
Expand Down Expand Up @@ -641,10 +644,20 @@ LEAF_ENTRY NDirectImportThunk, _TEXT
push ecx
push edx

// Compute padding size and adjust
mov esi, esp
lea ebx, [esp - 4] // for one push
and ebx, 15
sub esp, ebx

// Invoke the function that does the real work.
push eax
CHECK_STACK_ALIGNMENT
call C_FUNC(NDirectImportWorker)

// Restore stack pointer
mov esp, esi

// Restore argument registers
pop edx
pop ecx
Expand Down Expand Up @@ -686,6 +699,7 @@ NESTED_ENTRY UM2MThunk_WrapperHelper, _TEXT, NoHandler
mov eax, [esp + 20] // pEntryThunk
mov ecx, [esp + 24] // pThread
mov ebx, [esp + 8] // pThunkArgs
CHECK_STACK_ALIGNMENT
call [esp + 16] // pAddr

pop ebx
Expand All @@ -699,6 +713,7 @@ NESTED_ENTRY UMThunkStubRareDisable, _TEXT, NoHandler

push eax // Push the UMEntryThunk
push ecx // Push thread
CHECK_STACK_ALIGNMENT
call C_FUNC(UMThunkStubRareDisableWorker)

pop ecx
Expand Down Expand Up @@ -756,6 +771,7 @@ LOCAL_LABEL(GoCallVarargWorker):
push dword ptr [esi + 4*7] // pVaSigCookie
push esi // pTransitionBlock

CHECK_STACK_ALIGNMENT
call C_FUNC(VarargPInvokeStubWorker)

// restore pMD
Expand Down Expand Up @@ -847,6 +863,7 @@ LOCAL_LABEL(GoCallCalliWorker):
push dword ptr [esi + 4*7] // pVaSigCookie (first stack argument)
push esi // pTransitionBlock

CHECK_STACK_ALIGNMENT
call C_FUNC(GenericPInvokeCalliStubWorker)

// restore target
Expand All @@ -872,6 +889,7 @@ NESTED_ENTRY StubDispatchFixupStub, _TEXT, NoHandler
push eax // siteAddrForRegisterIndirect (for tailcalls)
push esi // pTransitionBlock

CHECK_STACK_ALIGNMENT
call C_FUNC(StubDispatchFixupWorker)

STUB_EPILOG
Expand Down Expand Up @@ -906,6 +924,7 @@ NESTED_ENTRY ExternalMethodFixupStub, _TEXT_ NoHandler
// pTransitionBlock
push esi

CHECK_STACK_ALIGNMENT
call C_FUNC(ExternalMethodFixupWorker)

// eax now contains replacement stub. PreStubWorker will never return
Expand Down Expand Up @@ -939,6 +958,7 @@ NESTED_ENTRY DelayLoad_MethodCall, _TEXT, NoHandler
// pTransitionBlock
push esi

CHECK_STACK_ALIGNMENT
call C_FUNC(ExternalMethodFixupWorker)

// eax now contains replacement stub. PreStubWorker will never return
Expand Down Expand Up @@ -981,6 +1001,8 @@ NESTED_ENTRY VirtualMethodFixupStub, _TEXT, NoHandler

push eax // address of the thunk
push ecx // this ptr

CHECK_STACK_ALIGNMENT
call C_FUNC(VirtualMethodFixupWorker)

// Restore stack pointer
Expand Down Expand Up @@ -1070,6 +1092,7 @@ NESTED_ENTRY DelayLoad_Helper\suffix, _TEXT, NoHandler
push eax // indirection cell address.
push esi // pTransitionBlock

CHECK_STACK_ALIGNMENT
call C_FUNC(DynamicHelperWorker)
test eax,eax
jnz LOCAL_LABEL(TailCallDelayLoad_Helper\suffix)
Expand Down Expand Up @@ -1121,6 +1144,7 @@ NESTED_ENTRY ResolveWorkerAsmStub, _TEXT, NoHandler
lea ebp, [esi + 5*4]

// Make the call
//CHECK_STACK_ALIGNMENT
call C_FUNC(VSD_ResolveWorker)

// From here on, mustn't trash eax
Expand Down Expand Up @@ -1228,6 +1252,7 @@ LOCAL_LABEL(main_loop):
// promote the entry to the beginning of the chain
mov ecx, eax
// call C_FUNC(VirtualCallStubManager::PromoteChainEntry)
CHECK_STACK_ALIGNMENT
call C_FUNC(_ZN22VirtualCallStubManager17PromoteChainEntryEP16ResolveCacheElem)

LOCAL_LABEL(nopromote):
Expand Down

0 comments on commit a6a7403

Please sign in to comment.