From 1789f75150a1577328896857eca160387b442493 Mon Sep 17 00:00:00 2001 From: RalfKornmannEnvision Date: Tue, 8 Sep 2020 15:29:58 +0200 Subject: [PATCH 1/2] Thunks: support for fixed size thunk pool Provides the platform independent (OS and CPU architecture) runtime code to support a fixed size thunk pool for systems that doesn't support any way to add more thunks on demand. Activated with FEATURE_FIXED_POOL_THUNKS.. FEATURE_RX_THUNKS will still override this. The default is still the template based system. The code blocks of the pool itself need to be either build and linked as part of the executable or generated by the compiler to be included in the object file. --- src/Native/Runtime/ThunksMapping.cpp | 63 +++++++++++++++++++++++++++- 1 file changed, 62 insertions(+), 1 deletion(-) diff --git a/src/Native/Runtime/ThunksMapping.cpp b/src/Native/Runtime/ThunksMapping.cpp index 7076a5af30f..bdb9a2ea04f 100644 --- a/src/Native/Runtime/ThunksMapping.cpp +++ b/src/Native/Runtime/ThunksMapping.cpp @@ -209,7 +209,68 @@ EXTERN_C REDHAWK_API void* __cdecl RhAllocateThunksMapping() return pThunksSection; } -#else // FEATURE_RX_THUNKS +// FEATURE_RX_THUNKS +#elif FEATURE_FIXED_POOL_THUNKS + +// This thread local variable is used for delegate marshalling +DECLSPEC_THREAD intptr_t tls_thunkData; + +extern "C" uintptr_t g_pThunkData; +uintptr_t g_pThunkData = NULL; + +#include "gcenv.os.h" + +COOP_PINVOKE_HELPER(int, RhpGetThunkBlockCount, ()); +COOP_PINVOKE_HELPER(int, RhpGetNumThunkBlocksPerMapping, ()); +COOP_PINVOKE_HELPER(int, RhpGetThunkBlockSize, ()); +COOP_PINVOKE_HELPER(void*, RhpGetThunkDataBlockAddress, (void* addr)); +COOP_PINVOKE_HELPER(void*, RhpGetThunkStubsBlockAddress, (void* addr)); + +EXTERN_C REDHAWK_API void* __cdecl RhAllocateThunksMapping() +{ + static int nextThunkDataMapping = 0; + + int thunkBlocksPerMapping = RhpGetNumThunkBlocksPerMapping(); + int thunkBlockSize = RhpGetThunkBlockSize(); + int blockCount = RhpGetThunkBlockCount(); + + ASSERT(blockCount % thunkBlocksPerMapping == 0) + + int thunkDataMappingSize = thunkBlocksPerMapping * thunkBlockSize; + int thunkDataMappingCount = blockCount / thunkBlocksPerMapping; + + if (nextThunkDataMapping == thunkDataMappingCount) + { + return NULL; + } + + if (g_pThunkData == NULL) + { + int thunkDataSize = thunkDataMappingSize * thunkDataMappingCount; + + g_pThunkData = (uintptr_t)GCToOSInterface::VirtualReserve(thunkDataSize, 4096, VirtualReserveFlags::None); + + if (g_pThunkData == NULL) + { + return NULL; + } + } + + void* pThunkDataBlock = (int8_t*)g_pThunkData + nextThunkDataMapping * thunkDataMappingSize; + nextThunkDataMapping++; + + if (!GCToOSInterface::VirtualCommit(pThunkDataBlock, thunkDataMappingSize)) + { + return NULL; + } + + void* pThunks = RhpGetThunkStubsBlockAddress(pThunkDataBlock); + ASSERT(RhpGetThunkDataBlockAddress(pThunks) == pThunkDataBlock); + + return pThunks; +} + +#else // FEATURE_FIXED_POOL_THUNKS COOP_PINVOKE_HELPER(void*, RhpGetThunksBase, ()); COOP_PINVOKE_HELPER(int, RhpGetNumThunkBlocksPerMapping, ()); From 5045f114582b3acb2d329e1f5e2b6bd19975fc67 Mon Sep 17 00:00:00 2001 From: RalfKornmannEnvision Date: Wed, 9 Sep 2020 08:39:25 +0200 Subject: [PATCH 2/2] fixed size thunk pool (#23) * Thunks: support for fixed size thunk pool Provides the platform independent (OS and CPU architecture) runtime code to support a fixed size thunk pool for systems that doesn't support any way to add more thunks on demand. Activated with FEATURE_FIXED_POOL_THUNKS.. FEATURE_RX_THUNKS will still override this. The default is still the template based system. The code blocks of the pool itself need to be either build and linked as part of the executable or generated by the compiler to be included in the object file. * Review changes - Use PalVirtualAlloc instead of GCToOSInterface for memory operations - Rename global variable to better match the usage --- src/Native/Runtime/ThunksMapping.cpp | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/Native/Runtime/ThunksMapping.cpp b/src/Native/Runtime/ThunksMapping.cpp index bdb9a2ea04f..e1673b09643 100644 --- a/src/Native/Runtime/ThunksMapping.cpp +++ b/src/Native/Runtime/ThunksMapping.cpp @@ -215,10 +215,9 @@ EXTERN_C REDHAWK_API void* __cdecl RhAllocateThunksMapping() // This thread local variable is used for delegate marshalling DECLSPEC_THREAD intptr_t tls_thunkData; -extern "C" uintptr_t g_pThunkData; -uintptr_t g_pThunkData = NULL; - -#include "gcenv.os.h" +// This is used by the thunk code to find the stub data for the called thunk slot +extern "C" uintptr_t g_pThunkStubData; +uintptr_t g_pThunkStubData = NULL; COOP_PINVOKE_HELPER(int, RhpGetThunkBlockCount, ()); COOP_PINVOKE_HELPER(int, RhpGetNumThunkBlocksPerMapping, ()); @@ -244,26 +243,27 @@ EXTERN_C REDHAWK_API void* __cdecl RhAllocateThunksMapping() return NULL; } - if (g_pThunkData == NULL) + if (g_pThunkStubData == NULL) { int thunkDataSize = thunkDataMappingSize * thunkDataMappingCount; - g_pThunkData = (uintptr_t)GCToOSInterface::VirtualReserve(thunkDataSize, 4096, VirtualReserveFlags::None); + g_pThunkStubData = (uintptr_t)PalVirtualAlloc(NULL, thunkDataSize, MEM_RESERVE, PAGE_READWRITE); - if (g_pThunkData == NULL) + if (g_pThunkStubData == NULL) { return NULL; } } - void* pThunkDataBlock = (int8_t*)g_pThunkData + nextThunkDataMapping * thunkDataMappingSize; - nextThunkDataMapping++; + void* pThunkDataBlock = (int8_t*)g_pThunkStubData + nextThunkDataMapping * thunkDataMappingSize; - if (!GCToOSInterface::VirtualCommit(pThunkDataBlock, thunkDataMappingSize)) + if (PalVirtualAlloc(pThunkDataBlock, thunkDataMappingSize, MEM_COMMIT, PAGE_READWRITE) == NULL) { return NULL; } + nextThunkDataMapping++; + void* pThunks = RhpGetThunkStubsBlockAddress(pThunkDataBlock); ASSERT(RhpGetThunkDataBlockAddress(pThunks) == pThunkDataBlock);