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

Replace FixupPrecode with RelativeFixupPrecode for NGENed images #17642

Closed
Closed
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
3 changes: 3 additions & 0 deletions clrdefinitions.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,9 @@ add_definitions(-DFEATURE_STRONGNAME_MIGRATION)
if (CLR_CMAKE_PLATFORM_UNIX OR CLR_CMAKE_TARGET_ARCH_ARM64)
add_definitions(-DFEATURE_STUBS_AS_IL)
endif ()
if (FEATURE_FNV_MEM_OPTIMIZATIONS)
add_definitions(-DFEATURE_FNV_MEM_OPTIMIZATIONS)
endif(FEATURE_FNV_MEM_OPTIMIZATIONS)
add_definitions(-DFEATURE_SVR_GC)
add_definitions(-DFEATURE_SYMDIFF)
add_definitions(-DFEATURE_TIERED_COMPILATION)
Expand Down
56 changes: 56 additions & 0 deletions src/debug/daccess/nidump.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3526,6 +3526,10 @@ size_t NativeImageDumper::TranslateSymbol(IXCLRDisassemblySupport *dis,
#ifdef HAS_FIXUP_PRECODE
case PRECODE_FIXUP:
precodeName = "FixupPrecode"; break;
#if defined(FEATURE_FNV_MEM_OPTIMIZATIONS) && defined(HAS_RELATIVE_FIXUP_PRECODE)
case PRECODE_RELATIVE_FIXUP:
precodeName = "RelativeFixupPrecode"; break;
#endif
#endif // HAS_FIXUP_PRECODE
#ifdef HAS_THISPTR_RETBUF_PRECODE
case PRECODE_THISPTR_RETBUF:
Expand Down Expand Up @@ -7603,6 +7607,58 @@ void NativeImageDumper::DumpPrecode( PTR_Precode precode, PTR_Module module )
DisplayEndStructure( ALWAYS ); //FixupPrecode
}
break;
#if defined(FEATURE_FNV_MEM_OPTIMIZATIONS) && defined(HAS_RELATIVE_FIXUP_PRECODE)
case PRECODE_RELATIVE_FIXUP:
IF_OPT_AND(PRECODES, METHODDESCS)
{
PTR_RelativeFixupPrecode p( precode->AsRelativeFixupPrecode() );
DisplayStartStructure( "RelativeFixupPrecode",
DPtrToPreferredAddr(p),
sizeof(*p),
ALWAYS );
PTR_MethodDesc precodeMD(p->GetMethodDesc());
#ifdef HAS_FIXUP_PRECODE_CHUNKS
{
DisplayWriteFieldInt( m_MethodDescChunkIndex,
p->m_MethodDescChunkIndex, RelativeFixupPrecode,
ALWAYS );
DisplayWriteFieldInt( m_PrecodeChunkIndex,
p->m_PrecodeChunkIndex, RelativeFixupPrecode,
ALWAYS );
if( p->m_PrecodeChunkIndex == 0 )
{
//dump the location of the Base
DisplayWriteElementAddress( "PrecodeChunkBase",
DataPtrToDisplay(p->GetBase()),
sizeof(void*), ALWAYS );
}
//Make sure I align up if there is no code slot to make
//sure that I get the padding
TADDR mdPtrStart = p->GetBase()
+ (p->m_MethodDescChunkIndex * MethodDesc::ALIGNMENT);
TADDR mdPtrEnd = ALIGN_UP( mdPtrStart + sizeof(MethodDesc*),
8 );
CoverageRead( mdPtrStart, (ULONG32)(mdPtrEnd - mdPtrStart) );
TADDR precodeMDSlot = p->GetBase()
+ p->m_MethodDescChunkIndex * MethodDesc::ALIGNMENT;
DoWriteFieldMethodDesc( "MethodDesc",
(DWORD)(precodeMDSlot - PTR_TO_TADDR(p)),
sizeof(TADDR), precodeMD );
}
#else //HAS_FIXUP_PRECODE_CHUNKS
_ASSERTE( !"Unsupported precode without FixupPrecode chunks" );
#endif //HAS_FIXUP_PRECODE_CHUNKS
TADDR target = p->GetTarget();
DisplayWriteElementPointer("Target",
DataPtrToDisplay(target),
ALWAYS );
/* REVISIT_TODO Thu 01/05/2006
* dump slot with offset if it is here
*/
DisplayEndStructure( ALWAYS ); //RelativeFixupPrecode
}
break;
#endif
#endif
#ifdef HAS_THISPTR_RETBUF_PRECODE
case PRECODE_THISPTR_RETBUF:
Expand Down
3 changes: 3 additions & 0 deletions src/inc/daccess.h
Original file line number Diff line number Diff line change
Expand Up @@ -620,6 +620,9 @@ typedef struct _DacGlobals

ULONG fn__ThePreStubPatchLabel;
ULONG fn__PrecodeFixupThunk;
#ifdef FEATURE_FNV_MEM_OPTIMIZATIONS
ULONG fn__PrecodeRelativeFixupThunk;
#endif
ULONG fn__StubDispatchFixupStub;
ULONG fn__StubDispatchFixupPatchLabel;;
#ifdef FEATURE_COMINTEROP
Expand Down
6 changes: 5 additions & 1 deletion src/inc/jithelpers.h
Original file line number Diff line number Diff line change
Expand Up @@ -286,8 +286,12 @@

JITHELPER(CORINFO_HELP_EE_PRESTUB, ThePreStub, CORINFO_HELP_SIG_NO_ALIGN_STUB)

#if defined(HAS_FIXUP_PRECODE)
#if defined(HAS_FIXUP_PRECODE)
#if defined(FEATURE_FNV_MEM_OPTIMIZATIONS) && defined(HAS_RELATIVE_FIXUP_PRECODE)
JITHELPER(CORINFO_HELP_EE_PRECODE_FIXUP, PrecodeRelativeFixupThunk, CORINFO_HELP_SIG_NO_ALIGN_STUB)
#else
JITHELPER(CORINFO_HELP_EE_PRECODE_FIXUP, PrecodeFixupThunk, CORINFO_HELP_SIG_NO_ALIGN_STUB)
#endif
#else
JITHELPER(CORINFO_HELP_EE_PRECODE_FIXUP, NULL, CORINFO_HELP_SIG_NO_ALIGN_STUB)
#endif
Expand Down
25 changes: 25 additions & 0 deletions src/vm/arm/asmhelpers.S
Original file line number Diff line number Diff line change
Expand Up @@ -582,6 +582,31 @@ ThePreStubPatchLabel:

NESTED_END PrecodeFixupThunk, _TEXT

// ------------------------------------------------------------------
// The call in fixup precode initally points to this function.
// The pupose of this function is to load the MethodDesc and forward the call the prestub.
NESTED_ENTRY PrecodeRelativeFixupThunk, _TEXT, NoHandler

// r12 = RelativeFixupPrecode *

PROLOG_PUSH "{r0-r1}"

// Inline computation done by RelativeFixupPrecode::GetMethodDesc()
ldrb r0, [r12, #1] // m_PrecodeChunkIndex
ldrb r1, [r12, #0] // m_MethodDescChunkIndex

add r12,r12,r0,lsl #4
add r0,r12,r0,lsl #2 // r0 = addr in the last precode in chunk (closest to MethodDescOffset)
ldr r12, [r0,#6] // r12 = MethodDescOffset
add r0, r12
add r0, #6
add r12,r0,r1,lsl #2

EPILOG_POP "{r0-r1}"
b C_FUNC(ThePreStub)

NESTED_END PrecodeRelativeFixupThunk, _TEXT

// ------------------------------------------------------------------
// void ResolveWorkerAsmStub(r0, r1, r2, r3, r4:IndirectionCellAndFlags, r12:DispatchToken)
//
Expand Down
104 changes: 104 additions & 0 deletions src/vm/arm/cgencpu.h
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,8 @@ EXTERN_C void setFPReturn(int fpSize, INT64 retVal);
#define HAS_FIXUP_PRECODE 1
#define HAS_FIXUP_PRECODE_CHUNKS 1

#define HAS_RELATIVE_FIXUP_PRECODE 1

// ThisPtrRetBufPrecode one is necessary for closed delegates over static methods with return buffer
#define HAS_THISPTR_RETBUF_PRECODE 1

Expand Down Expand Up @@ -1080,6 +1082,7 @@ inline BOOL ClrFlushInstructionCache(LPCVOID pCodeAddr, size_t sizeOfCode)
// update PrecodeStubManager::CheckIsStub_Internal to account for it.

EXTERN_C VOID STDCALL PrecodeFixupThunk();
EXTERN_C VOID STDCALL PrecodeRelativeFixupThunk();

#define PRECODE_ALIGNMENT CODE_SIZE_ALIGN
#define SIZEOF_PRECODE_BASE CODE_SIZE_ALIGN
Expand Down Expand Up @@ -1273,6 +1276,107 @@ struct FixupPrecode {
typedef DPTR(FixupPrecode) PTR_FixupPrecode;


#if defined(FEATURE_FNV_MEM_OPTIMIZATIONS) && defined(HAS_RELATIVE_FIXUP_PRECODE)
struct RelativeFixupPrecode {

static const int Type = 0xe1;

// ldr r12, [pc, #12] ; =m_pTargetOffset
// add r12, pc
// push {r12}
// mov r12, pc
// pop {pc}
// dcb m_MethodDescChunkIndex
// dcb m_PrecodeChunkIndex
// dcd m_pTargetOffset
WORD m_InstrLdr[2];
WORD m_InstrAdd[1];
WORD m_InstrPush[2];
WORD m_InstrMov[1];
WORD m_InstrPop[1];

BYTE m_MethodDescChunkIndex;
BYTE m_PrecodeChunkIndex;
TADDR m_pTargetOffset;

TADDR GetBase()
{
LIMITED_METHOD_CONTRACT;
SUPPORTS_DAC;

return dac_cast<TADDR>(this) + (m_PrecodeChunkIndex + 1) * sizeof(RelativeFixupPrecode);
}

TADDR GetMethodDesc();

static TADDR GetTargetOffset()
{
LIMITED_METHOD_DAC_CONTRACT;
return offsetof(RelativeFixupPrecode, m_InstrPush) + 2;
}

PCODE GetTarget()
{
LIMITED_METHOD_DAC_CONTRACT;
return dac_cast<TADDR>(this) + GetTargetOffset() + m_pTargetOffset;
}

void ResetTargetInterlocked()
{
CONTRACTL
{
THROWS;
GC_TRIGGERS;
}
CONTRACTL_END;

EnsureWritableExecutablePages(&m_pTargetOffset);
TADDR addr = (TADDR)GetEEFuncEntryPoint(PrecodeRelativeFixupThunk) - (TADDR)(this) - GetTargetOffset();
InterlockedExchange((LONG*)&m_pTargetOffset, (LONG)addr);
}

BOOL SetTargetInterlocked(TADDR target, TADDR expected)
{
CONTRACTL
{
THROWS;
GC_TRIGGERS;
}
CONTRACTL_END;

EnsureWritableExecutablePages(&m_pTargetOffset);
TADDR addrExpected = expected - (TADDR)(this) - GetTargetOffset();
TADDR addrTarget = target - (TADDR)(this) - GetTargetOffset();
return (TADDR)InterlockedCompareExchange(
(LONG*)&m_pTargetOffset, (LONG)addrTarget, (LONG)addrExpected) == addrExpected;
}

static BOOL IsRelativeFixupPrecodeByASM(PCODE addr)
{
// Check for ldr and add
PTR_WORD pInstr = dac_cast<PTR_WORD>(PCODEToPINSTR(addr));

return
(pInstr[0] == 0xf8df) &&
(pInstr[1] == 0xc00c) &&
(pInstr[2] == 0x44fc);
}

#ifdef FEATURE_PREJIT
// Partial initialization. Used to save regrouped chunks.
void InitForSave(int iPrecodeChunkIndex);

void Fixup(DataImage *image, MethodDesc * pMD);
#endif

#ifdef DACCESS_COMPILE
void EnumMemoryRegions(CLRDataEnumMemoryFlags flags);
#endif
};
typedef DPTR(RelativeFixupPrecode) PTR_RelativeFixupPrecode;
#endif


// Precode to shuffle this and retbuf for closed delegates over static methods with return buffer
struct ThisPtrRetBufPrecode {

Expand Down
Loading