diff options
author | Fadi Hanna <fadim@microsoft.com> | 2017-08-30 22:53:17 +0300 |
---|---|---|
committer | Fadi Hanna <fadim@microsoft.com> | 2017-08-30 22:53:17 +0300 |
commit | 4dad92cd3294a5511ba8ace84f7caf2379653935 (patch) | |
tree | 86b6fc2bb56e133f6a5d817cef0f6a0b096719e1 /src/Native | |
parent | 6a44a21cf36ac61890fca9507658c07ad786d1a3 (diff) |
Fixing CI break caused by previous checkin of the unboxing stubs region to enable the RhGetCodeTarget API:
1) Stubs are still grouped, but by section now. Linker will merge/fold/sort the unboxing stubs by section name.
2) All unboxing stubs are delimited by __unbox_a and __unbox_z symbols
3) __unbox_a and __unbox_z works on all platforms (tested on ProjectN (no regressions verification), ProjectX single and multi-file, Windows CoreRT, Unbuntu CoreRT, and OSX CoreRT)
4) Implementation uses a registration mechanism for unboxing stubs regions, and is multi-file ready for CoreRT (uses a linked list of stub regions)
5) Deleting the R2R section of unboxing stubs since it doesn't work on non-windows. Using extern "C" variables instead.
6) Removing the module enumeration API exposed by the TypeLoaderCallbacks (no longer needed)
[tfs-changeset: 1672333]
Diffstat (limited to 'src/Native')
-rw-r--r-- | src/Native/Bootstrap/main.cpp | 21 | ||||
-rw-r--r-- | src/Native/Runtime/MiscHelpers.cpp | 31 | ||||
-rw-r--r-- | src/Native/Runtime/RuntimeInstance.cpp | 43 | ||||
-rw-r--r-- | src/Native/Runtime/RuntimeInstance.h | 14 | ||||
-rw-r--r-- | src/Native/Runtime/inc/ModuleHeaders.h | 1 | ||||
-rw-r--r-- | src/Native/Runtime/unix/UnixNativeCodeManager.cpp | 19 | ||||
-rw-r--r-- | src/Native/Runtime/windows/CoffNativeCodeManager.cpp | 19 |
7 files changed, 119 insertions, 29 deletions
diff --git a/src/Native/Bootstrap/main.cpp b/src/Native/Bootstrap/main.cpp index fc0209f5a..5b3ae5186 100644 --- a/src/Native/Bootstrap/main.cpp +++ b/src/Native/Bootstrap/main.cpp @@ -39,9 +39,18 @@ __declspec(allocate(".modules$Z")) void * __modules_z[] = { nullptr }; // #pragma comment(linker, "/merge:.modules=.rdata") +// +// Unboxing stubs need to be merged, folded and sorted. They are delimited by two special sections (.unbox$A +// and .unbox$Z). All unboxing stubs are in .unbox$M sections. +// +#pragma comment(linker, "/merge:.unbox=.text") + extern "C" void __managedcode_a(); extern "C" void __managedcode_z(); +extern "C" void __unbox_a(); +extern "C" void __unbox_z(); + #else // _MSC_VER #if defined(__APPLE__) @@ -50,6 +59,8 @@ extern void * __modules_a[] __asm("section$start$__DATA$__modules"); extern void * __modules_z[] __asm("section$end$__DATA$__modules"); extern char __managedcode_a __asm("section$start$__TEXT$__managedcode"); extern char __managedcode_z __asm("section$end$__TEXT$__managedcode"); +extern char __unbox_a __asm("section$start$__TEXT$__unbox"); +extern char __unbox_z __asm("section$end$__TEXT$__unbox"); #else // __APPLE__ @@ -63,6 +74,11 @@ extern "C" char __stop___managedcode; static char& __managedcode_a = __start___managedcode; static char& __managedcode_z = __stop___managedcode; +extern "C" char __start___unbox; +extern "C" char __stop___unbox; +static char& __unbox_a = __start___unbox; +static char& __unbox_z = __stop___unbox; + #endif // __APPLE__ #endif // _MSC_VER @@ -233,7 +249,8 @@ extern "C" void RhpShutdown(); #ifndef CPPCODEGEN extern "C" bool RhRegisterOSModule(void * pModule, - void * pvStartRange, uint32_t cbRange, + void * pvManagedCodeStartRange, uint32_t cbManagedCodeRange, + void * pvUnboxingStubsStartRange, uint32_t cbUnboxingStubsRange, void ** pClasslibFunctions, uint32_t nClasslibFunctions); extern "C" void* PalGetModuleHandleFromPointer(void* pointer); @@ -277,9 +294,11 @@ int main(int argc, char* argv[]) #ifndef CPPCODEGEN void * osModule = PalGetModuleHandleFromPointer((void*)&__managed__Main); + // TODO: pass struct with parameters instead of the large signature of RhRegisterOSModule if (!RhRegisterOSModule( osModule, (void*)&__managedcode_a, (uint32_t)((char *)&__managedcode_z - (char*)&__managedcode_a), + (void*)&__unbox_a, (uint32_t)((char *)&__unbox_z - (char*)&__unbox_a), (void **)&c_classlibFunctions, _countof(c_classlibFunctions))) { return -1; diff --git a/src/Native/Runtime/MiscHelpers.cpp b/src/Native/Runtime/MiscHelpers.cpp index 49885a5a1..eaf55a79a 100644 --- a/src/Native/Runtime/MiscHelpers.cpp +++ b/src/Native/Runtime/MiscHelpers.cpp @@ -464,28 +464,31 @@ inline Int32 GetThumb2BlRel24(UInt16 * p) // Given a pointer to code, find out if this points to an import stub // or unboxing stub, and if so, return the address that stub jumps to -COOP_PINVOKE_HELPER(UInt8 *, RhGetCodeTarget, (TypeManagerHandle *pTypeManagerHandle, UInt8 * pCodeOrg)) +COOP_PINVOKE_HELPER(UInt8 *, RhGetCodeTarget, (UInt8 * pCodeOrg)) { Module * pModule = NULL; - TypeManagerHandle typeManagerHandle = *pTypeManagerHandle; + bool unboxingStub = false; - if (typeManagerHandle.IsTypeManager()) - { - Int32 length; - UInt8* pUnboxingStubsRegion = (UInt8*)typeManagerHandle.AsTypeManager()->GetModuleSection(ReadyToRunSectionType::UnboxingStubsRegion, &length); - if (pUnboxingStubsRegion == NULL || pCodeOrg < pUnboxingStubsRegion || pCodeOrg >= (pUnboxingStubsRegion + length)) - return pCodeOrg; - } - else + // First, check the unboxing stubs regions known by the runtime (if any exist) + if (!GetRuntimeInstance()->IsUnboxingStub(pCodeOrg)) { - pModule = GetRuntimeInstance()->FindModuleByOsHandle(typeManagerHandle.AsOsModule()); + // Search for the module containing the code + FOREACH_MODULE(pCurrentModule) + { + // If the code pointer doesn't point to a module's stub range, + // it can't be pointing to a stub + if (pCurrentModule->ContainsStubAddress(pCodeOrg)) + { + pModule = pCurrentModule; + break; + } + } + END_FOREACH_MODULE; - if (!pModule->ContainsStubAddress(pCodeOrg)) + if (pModule == NULL) return pCodeOrg; } - bool unboxingStub = false; - #ifdef _TARGET_AMD64_ UInt8 * pCode = pCodeOrg; diff --git a/src/Native/Runtime/RuntimeInstance.cpp b/src/Native/Runtime/RuntimeInstance.cpp index 30dfc9328..b7254a401 100644 --- a/src/Native/Runtime/RuntimeInstance.cpp +++ b/src/Native/Runtime/RuntimeInstance.cpp @@ -297,7 +297,8 @@ RuntimeInstance::RuntimeInstance() : m_pStaticGCRefsDescChunkList(NULL), m_pThreadStaticGCRefsDescChunkList(NULL), m_pGenericUnificationHashtable(NULL), - m_conservativeStackReportingEnabled(false) + m_conservativeStackReportingEnabled(false), + m_pUnboxingStubsRegion(NULL) { } @@ -430,6 +431,46 @@ extern "C" void __stdcall UnregisterCodeManager(ICodeManager * pCodeManager) } #endif +bool RuntimeInstance::RegisterUnboxingStubs(PTR_VOID pvStartRange, UInt32 cbRange) +{ + ASSERT(pvStartRange != NULL && cbRange > 0); + + UnboxingStubsRegion * pEntry = new (nothrow) UnboxingStubsRegion(); + if (NULL == pEntry) + return false; + + pEntry->m_pRegionStart = pvStartRange; + pEntry->m_cbRegion = cbRange; + + do + { + pEntry->m_pNextRegion = m_pUnboxingStubsRegion; + } + while (PalInterlockedCompareExchangePointer((void *volatile *)&m_pUnboxingStubsRegion, pEntry, pEntry->m_pNextRegion) != pEntry->m_pNextRegion); + + return true; +} + +bool RuntimeInstance::IsUnboxingStub(UInt8* pCode) +{ + UnboxingStubsRegion * pCurrent = m_pUnboxingStubsRegion; + while (pCurrent != NULL) + { + UInt8* pUnboxingStubsRegion = dac_cast<UInt8*>(pCurrent->m_pRegionStart); + if (pCode >= pUnboxingStubsRegion && pCode < (pUnboxingStubsRegion + pCurrent->m_cbRegion)) + return true; + + pCurrent = pCurrent->m_pNextRegion; + } + + return false; +} + +extern "C" bool __stdcall RegisterUnboxingStubs(PTR_VOID pvStartRange, UInt32 cbRange) +{ + return GetRuntimeInstance()->RegisterUnboxingStubs(pvStartRange, cbRange); +} + bool RuntimeInstance::RegisterTypeManager(TypeManager * pTypeManager) { TypeManagerEntry * pEntry = new (nothrow) TypeManagerEntry(); diff --git a/src/Native/Runtime/RuntimeInstance.h b/src/Native/Runtime/RuntimeInstance.h index 7a10ed837..3d1ab3ed6 100644 --- a/src/Native/Runtime/RuntimeInstance.h +++ b/src/Native/Runtime/RuntimeInstance.h @@ -132,6 +132,17 @@ private: bool m_conservativeStackReportingEnabled; + struct UnboxingStubsRegion + { + PTR_VOID m_pRegionStart; + UInt32 m_cbRegion; + UnboxingStubsRegion* m_pNextRegion; + + UnboxingStubsRegion() : m_pRegionStart(0), m_cbRegion(0), m_pNextRegion(NULL) { } + }; + + UnboxingStubsRegion* m_pUnboxingStubsRegion; + RuntimeInstance(); SList<Module>* GetModuleList(); @@ -177,6 +188,9 @@ public: OsModuleList* GetOsModuleList(); ReaderWriterLock& GetTypeManagerLock(); + bool RegisterUnboxingStubs(PTR_VOID pvStartRange, UInt32 cbRange); + bool IsUnboxingStub(UInt8* pCode); + // This will hold the module list lock over each callback. Make sure // the callback will not trigger any operation that needs to make use // of the module list. diff --git a/src/Native/Runtime/inc/ModuleHeaders.h b/src/Native/Runtime/inc/ModuleHeaders.h index 407e3ed2c..33f77c458 100644 --- a/src/Native/Runtime/inc/ModuleHeaders.h +++ b/src/Native/Runtime/inc/ModuleHeaders.h @@ -52,7 +52,6 @@ enum class ReadyToRunSectionType ThreadStaticGCDescRegion = 209, ThreadStaticIndex = 210, LoopHijackFlag = 211, - UnboxingStubsRegion = 212, // Sections 300 - 399 are reserved for RhFindBlob backwards compatibility ReadonlyBlobRegionStart = 300, diff --git a/src/Native/Runtime/unix/UnixNativeCodeManager.cpp b/src/Native/Runtime/unix/UnixNativeCodeManager.cpp index fdad0a3f2..f8b8c95e9 100644 --- a/src/Native/Runtime/unix/UnixNativeCodeManager.cpp +++ b/src/Native/Runtime/unix/UnixNativeCodeManager.cpp @@ -356,24 +356,31 @@ void * UnixNativeCodeManager::GetClasslibFunction(ClasslibFunctionId functionId) } extern "C" bool __stdcall RegisterCodeManager(ICodeManager * pCodeManager, PTR_VOID pvStartRange, UInt32 cbRange); +extern "C" void __stdcall UnregisterCodeManager(ICodeManager * pCodeManager); +extern "C" bool __stdcall RegisterUnboxingStubs(PTR_VOID pvStartRange, UInt32 cbRange); extern "C" bool RhRegisterOSModule(void * pModule, - void * pvStartRange, UInt32 cbRange, + void * pvManagedCodeStartRange, UInt32 cbManagedCodeRange, + void * pvUnboxingStubsStartRange, UInt32 cbUnboxingStubsRange, void ** pClasslibFunctions, UInt32 nClasslibFunctions) { - UnixNativeCodeManager * pUnixNativeCodeManager = new (nothrow) UnixNativeCodeManager((TADDR)pModule, + NewHolder<UnixNativeCodeManager> pUnixNativeCodeManager = new (nothrow) UnixNativeCodeManager((TADDR)pModule, pClasslibFunctions, nClasslibFunctions); + if (pUnixNativeCodeManager == nullptr) - { return false; - } - if (!RegisterCodeManager(pUnixNativeCodeManager, pvStartRange, cbRange)) + if (!RegisterCodeManager(pUnixNativeCodeManager, pvManagedCodeStartRange, cbManagedCodeRange)) + return false; + + if (!RegisterUnboxingStubs(pvUnboxingStubsStartRange, cbUnboxingStubsRange)) { - delete pUnixNativeCodeManager; + UnregisterCodeManager(pUnixNativeCodeManager); return false; } + pUnixNativeCodeManager.SuppressRelease(); + return true; } diff --git a/src/Native/Runtime/windows/CoffNativeCodeManager.cpp b/src/Native/Runtime/windows/CoffNativeCodeManager.cpp index d597eb46c..9ca2477c9 100644 --- a/src/Native/Runtime/windows/CoffNativeCodeManager.cpp +++ b/src/Native/Runtime/windows/CoffNativeCodeManager.cpp @@ -634,10 +634,13 @@ void * CoffNativeCodeManager::GetClasslibFunction(ClasslibFunctionId functionId) } extern "C" bool __stdcall RegisterCodeManager(ICodeManager * pCodeManager, PTR_VOID pvStartRange, UInt32 cbRange); +extern "C" void __stdcall UnregisterCodeManager(ICodeManager * pCodeManager); +extern "C" bool __stdcall RegisterUnboxingStubs(PTR_VOID pvStartRange, UInt32 cbRange); extern "C" bool RhRegisterOSModule(void * pModule, - void * pvStartRange, UInt32 cbRange, + void * pvManagedCodeStartRange, UInt32 cbManagedCodeRange, + void * pvUnboxingStubsStartRange, UInt32 cbUnboxingStubsRange, void ** pClasslibFunctions, UInt32 nClasslibFunctions) { PIMAGE_DOS_HEADER pDosHeader = (PIMAGE_DOS_HEADER)pModule; @@ -645,20 +648,24 @@ bool RhRegisterOSModule(void * pModule, IMAGE_DATA_DIRECTORY * pRuntimeFunctions = &(pNTHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXCEPTION]); - CoffNativeCodeManager * pCoffNativeCodeManager = new (nothrow) CoffNativeCodeManager((TADDR)pModule, + NewHolder<CoffNativeCodeManager> pCoffNativeCodeManager = new (nothrow) CoffNativeCodeManager((TADDR)pModule, dac_cast<PTR_RUNTIME_FUNCTION>((TADDR)pModule + pRuntimeFunctions->VirtualAddress), pRuntimeFunctions->Size / sizeof(RUNTIME_FUNCTION), pClasslibFunctions, nClasslibFunctions); + if (pCoffNativeCodeManager == nullptr) - { return false; - } - if (!RegisterCodeManager(pCoffNativeCodeManager, pvStartRange, cbRange)) + if (!RegisterCodeManager(pCoffNativeCodeManager, pvManagedCodeStartRange, cbManagedCodeRange)) + return false; + + if (!RegisterUnboxingStubs(pvUnboxingStubsStartRange, cbUnboxingStubsRange)) { - delete pCoffNativeCodeManager; + UnregisterCodeManager(pCoffNativeCodeManager); return false; } + pCoffNativeCodeManager.SuppressRelease(); + return true; } |