Skip to content

Commit ac760bf

Browse files
Create a single copy of stub templates (#114462)
Instead of generating stub templates by running the code page generation function for each stub code region that is generated, map a single file into memory in multiple locations instead. This logic is architected so that it can fall back to the previous model of using the double mapping logic to generate the stubs. We implement 3 schemes for finding the to use as mapping data. 1. On apple platforms, we compile the stubs into the coreclr Mach-O file, and use the virtual memory manager support for mapping memory from the coreclr binary into various locations on the heap. 3. On Unix platforms that are not Apple derived we use an anonymous in memory file just like our normal executable allocation path. 3. On Linux platforms, we *can* compile the stubs into the coreclr ELF file, and then use the `dladdr` and `dl_iterate_phdr` functionality to find the file name of the coreclr binary and the section that contains it, and then we can use mmap to map from the file directly into memory. This mode is disabled by default as it doesn't support all scenarios, but it does allow for testing of the majority of the logic used on Apple platforms on a Linux machine. 4. On Windows platforms, we currently do not yet support this mode.
1 parent fadf883 commit ac760bf

File tree

16 files changed

+904
-50
lines changed

16 files changed

+904
-50
lines changed

src/coreclr/clrdefinitions.cmake

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -218,6 +218,10 @@ if (FEATURE_STUBPRECODE_DYNAMIC_HELPERS)
218218
add_definitions(-DFEATURE_STUBPRECODE_DYNAMIC_HELPERS)
219219
endif()
220220

221+
if (CLR_CMAKE_TARGET_APPLE)
222+
add_definitions(-DFEATURE_MAP_THUNKS_FROM_IMAGE)
223+
endif()
224+
221225
# Use this function to enable building with a specific target OS and architecture set of defines
222226
# This is known to work for the set of defines used by the JIT and gcinfo, it is not likely correct for
223227
# other components of the runtime

src/coreclr/inc/executableallocator.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,9 @@ class ExecutableAllocator
182182
// Return true if double mapping is enabled.
183183
static bool IsDoubleMappingEnabled();
184184

185+
// Release memory allocated via DoubleMapping for either templates or normal double mapped data
186+
void ReleaseWorker(void* pRX, bool releaseTemplate);
187+
185188
// Initialize the allocator instance
186189
bool Initialize();
187190

@@ -262,6 +265,18 @@ class ExecutableAllocator
262265

263266
// Unmap the RW mapping at the specified address
264267
void UnmapRW(void* pRW);
268+
269+
// Allocate thunks from a template. pTemplate is the return value from CreateTemplate
270+
void* AllocateThunksFromTemplate(void *pTemplate, size_t templateSize);
271+
272+
// Free a set of thunks allocated from templates. pThunks must have been returned from AllocateThunksFromTemplate
273+
void FreeThunksFromTemplate(void *pThunks, size_t templateSize);
274+
275+
// Create a template
276+
// If templateInImage is not null, it will attempt to use it as the template, otherwise it will create an temporary in memory file to serve as the template
277+
// Some OS/Architectures may/may not be able to work with this, so this api is permitted to return NULL, and callers should have an alternate approach using
278+
// the codePageGenerator directly.
279+
void* CreateTemplate(void* templateInImage, size_t templateSize, void (*codePageGenerator)(uint8_t* pageBase, uint8_t* pageBaseRX, size_t size));
265280
};
266281

267282
#define ExecutableWriterHolder ExecutableWriterHolderNoLog

src/coreclr/inc/loaderheap.h

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -455,10 +455,19 @@ class UnlockedLoaderHeap : public UnlockedLoaderHeapBase
455455
static void WeGotAFaultNowWhat(UnlockedLoaderHeap *pHeap);
456456
};
457457

458+
struct InterleavedLoaderHeapConfig
459+
{
460+
uint32_t StubSize;
461+
void* Template;
462+
void (*CodePageGenerator)(uint8_t* pageBase, uint8_t* pageBaseRX, size_t size);
463+
};
464+
465+
void InitializeLoaderHeapConfig(InterleavedLoaderHeapConfig *pConfig, size_t stubSize, void* templateInImage, void (*codePageGenerator)(uint8_t* pageBase, uint8_t* pageBaseRX, size_t size));
466+
458467
//===============================================================================
459468
// This is the base class for InterleavedLoaderHeap It's used as a simple
460469
// allocator for stubs in a scheme where each stub is a small fixed size, and is paired
461-
// with memory which is GetOSStubPageSize() bytes away. In addition there is an
470+
// with memory which is GetStubCodePageSize() bytes away. In addition there is an
462471
// ability to free is via a "backout" mechanism that is not considered to have good performance.
463472
//
464473
//===============================================================================
@@ -492,16 +501,13 @@ class UnlockedInterleavedLoaderHeap : public UnlockedLoaderHeapBase
492501

493502
InterleavedStubFreeListNode *m_pFreeListHead;
494503

495-
public:
496-
public:
497-
void (*m_codePageGenerator)(BYTE* pageBase, BYTE* pageBaseRX, SIZE_T size);
504+
const InterleavedLoaderHeapConfig *m_pConfig;
498505

499506
#ifndef DACCESS_COMPILE
500507
protected:
501508
UnlockedInterleavedLoaderHeap(
502509
RangeList *pRangeList,
503-
void (*codePageGenerator)(BYTE* pageBase, BYTE* pageBaseRX, SIZE_T size),
504-
DWORD dwGranularity);
510+
const InterleavedLoaderHeapConfig *pConfig);
505511

506512
virtual ~UnlockedInterleavedLoaderHeap();
507513
#endif
@@ -1039,13 +1045,11 @@ class InterleavedLoaderHeap : public UnlockedInterleavedLoaderHeap
10391045
public:
10401046
InterleavedLoaderHeap(RangeList *pRangeList,
10411047
BOOL fUnlocked,
1042-
void (*codePageGenerator)(BYTE* pageBase, BYTE* pageBaseRX, SIZE_T size),
1043-
DWORD dwGranularity
1048+
const InterleavedLoaderHeapConfig *pConfig
10441049
)
10451050
: UnlockedInterleavedLoaderHeap(
10461051
pRangeList,
1047-
codePageGenerator,
1048-
dwGranularity),
1052+
pConfig),
10491053
m_CriticalSection(fUnlocked ? NULL : CreateLoaderHeapLock())
10501054
{
10511055
WRAPPER_NO_CONTRACT;

0 commit comments

Comments
 (0)