Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
Next Next commit
Support 32 byte alignment of code on xarch
Update jit and runtime to allow jit to ask for code to be 32 byte aligned.
Request 32 byte alignment for Tier1 methods on x86/x64.

Add minimal crossgen support; one can imagine requesting or choosing 32 byte
alignment for crossgenned code, but that is left as future work.

This should provide some measure of performance stability, in particular for
microbenchmarks or other code where performance depends crucially on a few
branches.

It may or may not improve performance. If/when there are regressions we can
contemplate updating the jit to add intra-method padding to address alignment
sensitive code layout (e.g. dotnet/coreclr#11607).

This will require a jit GUID update in addition to the changes here.
  • Loading branch information
AndyAyersMS committed Feb 14, 2020
commit 309e2ae582b6ad1ac6a415c6129f631eae24fe10
2 changes: 2 additions & 0 deletions src/coreclr/src/inc/corjit.h
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,8 @@ enum CorJitAllocMemFlag
CORJIT_ALLOCMEM_DEFAULT_CODE_ALIGN = 0x00000000, // The code will be use the normal alignment
CORJIT_ALLOCMEM_FLG_16BYTE_ALIGN = 0x00000001, // The code will be 16-byte aligned
CORJIT_ALLOCMEM_FLG_RODATA_16BYTE_ALIGN = 0x00000002, // The read-only data will be 16-byte aligned
CORJIT_ALLOCMEM_FLG_32BYTE_ALIGN = 0x00000004, // The code will be 32-byte aligned
CORJIT_ALLOCMEM_FLG_RODATA_32BYTE_ALIGN = 0x00000008, // The read-only data will be 32-byte aligned
};

inline CorJitAllocMemFlag operator |(CorJitAllocMemFlag a, CorJitAllocMemFlag b)
Expand Down
9 changes: 9 additions & 0 deletions src/coreclr/src/jit/emit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4615,6 +4615,15 @@ unsigned emitter::emitEndCodeGen(Compiler* comp,
}
#endif

#ifdef _TARGET_XARCH_
// For x64/x86, align Tier1 methods to 32 byte boundaries
//
if (emitComp->opts.jitFlags->IsSet(JitFlags::JIT_FLAG_TIER1))
{
allocMemFlag = CORJIT_ALLOCMEM_FLG_32BYTE_ALIGN;
}
#endif

if (emitConsDsc.align16)
{
allocMemFlag = static_cast<CorJitAllocMemFlag>(allocMemFlag | CORJIT_ALLOCMEM_FLG_RODATA_16BYTE_ALIGN);
Expand Down
2 changes: 2 additions & 0 deletions src/coreclr/src/tools/Common/JitInterface/CorInfoTypes.cs
Original file line number Diff line number Diff line change
Expand Up @@ -764,6 +764,8 @@ public enum CorJitAllocMemFlag
CORJIT_ALLOCMEM_DEFAULT_CODE_ALIGN = 0x00000000, // The code will be use the normal alignment
CORJIT_ALLOCMEM_FLG_16BYTE_ALIGN = 0x00000001, // The code will be 16-byte aligned
CORJIT_ALLOCMEM_FLG_RODATA_16BYTE_ALIGN = 0x00000002, // The read-only data will be 16-byte aligned
CORJIT_ALLOCMEM_FLG_32BYTE_ALIGN = 0x00000004, // The code will be 32-byte aligned
CORJIT_ALLOCMEM_FLG_RODATA_32BYTE_ALIGN = 0x00000008, // The read-only data will be 32-byte aligned
}

public enum CorJitFuncKind
Expand Down
6 changes: 5 additions & 1 deletion src/coreclr/src/vm/codeman.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2551,7 +2551,11 @@ CodeHeader* EEJitManager::allocCode(MethodDesc* pMD, size_t blockSize, size_t re

unsigned alignment = CODE_SIZE_ALIGN;

if ((flag & CORJIT_ALLOCMEM_FLG_16BYTE_ALIGN) != 0)
if ((flag & CORJIT_ALLOCMEM_FLG_32BYTE_ALIGN) != 0)
{
alignment = max(alignment, 32);
}
else if ((flag & CORJIT_ALLOCMEM_FLG_16BYTE_ALIGN) != 0)
{
alignment = max(alignment, 16);
}
Expand Down
19 changes: 16 additions & 3 deletions src/coreclr/src/vm/jitinterface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12065,7 +12065,11 @@ void CEEJitInfo::allocMem (
S_SIZE_T totalSize = S_SIZE_T(codeSize);

size_t roDataAlignment = sizeof(void*);
if ((flag & CORJIT_ALLOCMEM_FLG_RODATA_16BYTE_ALIGN)!= 0)
if ((flag & CORJIT_ALLOCMEM_FLG_RODATA_32BYTE_ALIGN)!= 0)
{
roDataAlignment = 32;
}
else if ((flag & CORJIT_ALLOCMEM_FLG_RODATA_16BYTE_ALIGN)!= 0)
{
roDataAlignment = 16;
}
Expand All @@ -12075,9 +12079,18 @@ void CEEJitInfo::allocMem (
}
if (roDataSize > 0)
{
size_t codeAlignment = ((flag & CORJIT_ALLOCMEM_FLG_16BYTE_ALIGN)!= 0)
? 16 : sizeof(void*);
size_t codeAlignment = sizeof(void*);

if ((flag & CORJIT_ALLOCMEM_FLG_32BYTE_ALIGN) != 0)
{
codeAlignment = 32;
}
else if ((flag & CORJIT_ALLOCMEM_FLG_16BYTE_ALIGN) != 0)
{
codeAlignment = 16;
}
totalSize.AlignUp(codeAlignment);

if (roDataAlignment > codeAlignment) {
// Add padding to align read-only data.
totalSize += (roDataAlignment - codeAlignment);
Expand Down
12 changes: 10 additions & 2 deletions src/coreclr/src/zap/zapinfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1085,7 +1085,11 @@ void ZapInfo::allocMem(

UINT align = DEFAULT_CODE_ALIGN;

if ((flag & CORJIT_ALLOCMEM_FLG_16BYTE_ALIGN) && !IsReadyToRunCompilation()) align = max(align, 16);
if (!IsReadyToRunCompilation())
{
if (flag & CORJIT_ALLOCMEM_FLG_32BYTE_ALIGN) align = max(align, 32);
else if (flag & CORJIT_ALLOCMEM_FLG_16BYTE_ALIGN) align = max(align, 16);
}

m_pCode = ZapCodeBlob::NewAlignedBlob(m_pImage, NULL, hotCodeSize, align);
*hotCodeBlock = m_pCode->GetData();
Expand All @@ -1104,7 +1108,11 @@ void ZapInfo::allocMem(

if (roDataSize > 0)
{
if (flag & CORJIT_ALLOCMEM_FLG_RODATA_16BYTE_ALIGN)
if (flag & CORJIT_ALLOCMEM_FLG_RODATA_32BYTE_ALIGN)
Copy link
Member

Choose a reason for hiding this comment

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

I would not bother changing anything for zapper. We are trying to churn the old crossgen and there are number of other changes to make it actually work (e.g. in NewAlignedBlob).

{
align = 32;
}
else if (flag & CORJIT_ALLOCMEM_FLG_RODATA_16BYTE_ALIGN)
{
align = 16;
}
Expand Down