Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/corert.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Wrighton <davidwr@microsoft.com>2017-02-15 02:35:19 +0300
committerDavid Wrighton <davidwr@microsoft.com>2017-02-15 02:35:19 +0300
commit720e17f599c1d8aca941dbca8a9492f3474f3b05 (patch)
tree544ecb53dbff7736b2945c7b58c5b6f997ee4734 /src/Native/Runtime/MiscHelpers.cpp
parent1a8e729b2e9e3915947cace8c3bf316237d519e6 (diff)
Refactor use of TypeManager and Module pointers within the BCL
- Move from using an IntPtr which may represent a TypeManager* or a OS module pointer to using a struct TypeManagerHandle consistently - Except for RuntimeSignature, which has a third possible meaning of its IntPtr. That work will be done in a seperate change, and wil result in removal of nearly all of the new TypeManagerHandle calls in this delta. - This struct contains a bit which indicates which form of pointer is being worked with, as well as routines for performing RVA access as appropriate - Added new api to redhawk to get the OS module list (Used in crash dump generation) - Added new api to get the OS module of of a pointer. These are not yet enabled for TypeManager based scenarios, but that will be done in a followon change. Eventually these will exclusively be use for instruction pointers, and will tie into diagnostic scenarios around stack traces, etc. Currently, it is also used in a few reflection scenarios. Those code patterns will be removed soon. - Similarly distinguished between getting the OS module for an EEType, and getting the module for an EEType. This is used in error message scenarios. - Update RhFindBlob to work with both types of module pointers [tfs-changeset: 1647831]
Diffstat (limited to 'src/Native/Runtime/MiscHelpers.cpp')
-rw-r--r--src/Native/Runtime/MiscHelpers.cpp188
1 files changed, 144 insertions, 44 deletions
diff --git a/src/Native/Runtime/MiscHelpers.cpp b/src/Native/Runtime/MiscHelpers.cpp
index 17153dfaa..b1e0958dc 100644
--- a/src/Native/Runtime/MiscHelpers.cpp
+++ b/src/Native/Runtime/MiscHelpers.cpp
@@ -75,7 +75,7 @@ COOP_PINVOKE_HELPER(DispatchMap*, RhGetDispatchMapForType, (EEType * pEEType))
// modules are available based on the return count. It is also possible to call this method without an array,
// in which case just the module count is returned (note that it's still possible for the module count to
// increase between calls to this method).
-COOP_PINVOKE_HELPER(UInt32, RhGetLoadedModules, (Array * pResultArray))
+COOP_PINVOKE_HELPER(UInt32, RhGetLoadedOSModules, (Array * pResultArray))
{
// Note that we depend on the fact that this is a COOP helper to make writing into an unpinned array safe.
@@ -99,11 +99,69 @@ COOP_PINVOKE_HELPER(UInt32, RhGetLoadedModules, (Array * pResultArray))
}
END_FOREACH_MODULE
+ ReaderWriterLock::ReadHolder read(&GetRuntimeInstance()->GetTypeManagerLock());
+
+ RuntimeInstance::OsModuleList osModules = GetRuntimeInstance()->GetOsModuleList();
+
+ for (RuntimeInstance::OsModuleList::Iterator iter = osModules.Begin(); iter != osModules.End(); iter++)
+ {
+ if (pResultArray && (cModules < cResultArrayElements))
+ pResultElements[cModules] = iter->m_osModule;
+ cModules++;
+ }
+
return cModules;
}
-COOP_PINVOKE_HELPER(HANDLE, RhGetModuleFromPointer, (PTR_VOID pPointerVal))
+// Get the list of currently loaded Redhawk modules (as OS HMODULE handles or TypeManager pointers as appropriate).
+// The caller provides a reference
+// to an array of pointer-sized elements and we return the total number of modules currently loaded (whether
+// that is less than, equal to or greater than the number of elements in the array). If there are more modules
+// loaded than the array will hold then the array is filled to capacity and the caller can tell further
+// modules are available based on the return count. It is also possible to call this method without an array,
+// in which case just the module count is returned (note that it's still possible for the module count to
+// increase between calls to this method).
+COOP_PINVOKE_HELPER(UInt32, RhGetLoadedModules, (Array * pResultArray))
{
+ // Note that we depend on the fact that this is a COOP helper to make writing into an unpinned array safe.
+
+ // If a result array is passed then it should be an array type with pointer-sized components that are not
+ // GC-references.
+ ASSERT(!pResultArray || pResultArray->get_EEType()->IsArray());
+ ASSERT(!pResultArray || !pResultArray->get_EEType()->HasReferenceFields());
+ ASSERT(!pResultArray || pResultArray->get_EEType()->get_ComponentSize() == sizeof(void*));
+
+ UInt32 cResultArrayElements = pResultArray ? pResultArray->GetArrayLength() : 0;
+ TypeManagerHandle * pResultElements = pResultArray ? (TypeManagerHandle*)(pResultArray + 1) : NULL;
+
+ UInt32 cModules = 0;
+
+ FOREACH_MODULE(pModule)
+ {
+ if (pResultArray && (cModules < cResultArrayElements))
+ pResultElements[cModules] = TypeManagerHandle::Create(pModule->GetOsModuleHandle());
+
+ cModules++;
+ }
+ END_FOREACH_MODULE
+
+ ReaderWriterLock::ReadHolder read(&GetRuntimeInstance()->GetTypeManagerLock());
+
+ RuntimeInstance::TypeManagerList typeManagers = GetRuntimeInstance()->GetTypeManagerList();
+
+ for (RuntimeInstance::TypeManagerList::Iterator iter = typeManagers.Begin(); iter != typeManagers.End(); iter++)
+ {
+ if (pResultArray && (cModules < cResultArrayElements))
+ pResultElements[cModules] = TypeManagerHandle::Create(iter->m_pTypeManager);
+ cModules++;
+ }
+
+ return cModules;
+}
+
+COOP_PINVOKE_HELPER(HANDLE, RhGetOSModuleFromPointer, (PTR_VOID pPointerVal))
+{
+ // TODO, this will always return nullptr in TypeManager based systems.
Module * pModule = GetRuntimeInstance()->FindModuleByAddress(pPointerVal);
if (pModule != NULL)
@@ -112,14 +170,14 @@ COOP_PINVOKE_HELPER(HANDLE, RhGetModuleFromPointer, (PTR_VOID pPointerVal))
return NULL;
}
-COOP_PINVOKE_HELPER(HANDLE, RhGetModuleFromEEType, (EEType * pEEType))
+COOP_PINVOKE_HELPER(HANDLE, RhGetOSModuleFromEEType, (EEType * pEEType))
{
#if CORERT
- return (HANDLE)(pEEType->GetTypeManager());
+ return pEEType->GetTypeManagerPtr()->AsTypeManager()->GetOsModuleHandle();
#else
#if EETYPE_TYPE_MANAGER
if (pEEType->HasTypeManager())
- return (HANDLE)(pEEType->GetTypeManager());
+ return pEEType->GetTypeManagerPtr()->AsTypeManager()->GetOsModuleHandle();
#endif
// For dynamically created types, return the module handle that contains the template type
@@ -142,65 +200,107 @@ COOP_PINVOKE_HELPER(HANDLE, RhGetModuleFromEEType, (EEType * pEEType))
#endif // !CORERT
}
-COOP_PINVOKE_HELPER(Boolean, RhFindBlob, (HANDLE hOsModule, UInt32 blobId, UInt8 ** ppbBlob, UInt32 * pcbBlob))
+COOP_PINVOKE_HELPER(TypeManagerHandle, RhGetModuleFromEEType, (EEType * pEEType))
{
#if CORERT
- ReadyToRunSectionType section =
- (ReadyToRunSectionType)((UInt32)ReadyToRunSectionType::ReadonlyBlobRegionStart + blobId);
- ASSERT(section <= ReadyToRunSectionType::ReadonlyBlobRegionEnd);
-
- TypeManager* pModule = (TypeManager*)hOsModule;
+ return *pEEType->GetTypeManagerPtr();
+#else
+#if EETYPE_TYPE_MANAGER
+ if (pEEType->HasTypeManager())
+ return *pEEType->GetTypeManagerPtr();
+#endif
- int length;
- void* pBlob;
- pBlob = pModule->GetModuleSection(section, &length);
+ // For dynamically created types, return the module handle that contains the template type
+ if (pEEType->IsDynamicType())
+ pEEType = pEEType->get_DynamicTemplateType();
- *ppbBlob = (UInt8*)pBlob;
- *pcbBlob = (UInt32)length;
+ if (pEEType->get_DynamicModule() != nullptr)
+ {
+ // We should never get here (an EEType not located in any module) so fail fast to indicate the bug.
+ RhFailFast();
+ return TypeManagerHandle::Null();
+ }
- return pBlob != NULL;
-#else
- // Search for the Redhawk module contained by the OS module.
FOREACH_MODULE(pModule)
{
- if (pModule->GetOsModuleHandle() == hOsModule)
- {
- // Found a module match. Look through the blobs for one with a matching ID.
- UInt32 cbBlobs;
- BlobHeader * pBlob = pModule->GetReadOnlyBlobs(&cbBlobs);
+ if (pModule->ContainsReadOnlyDataAddress(pEEType) || pModule->ContainsDataAddress(pEEType))
+ return TypeManagerHandle::Create(pModule->GetOsModuleHandle());
+ }
+ END_FOREACH_MODULE
- while (cbBlobs)
+ // We should never get here (an EEType not located in any module) so fail fast to indicate the bug.
+ RhFailFast();
+ return TypeManagerHandle::Null();
+#endif // !CORERT
+}
+
+COOP_PINVOKE_HELPER(Boolean, RhFindBlob, (TypeManagerHandle *pTypeManagerHandle, UInt32 blobId, UInt8 ** ppbBlob, UInt32 * pcbBlob))
+{
+ TypeManagerHandle typeManagerHandle = *pTypeManagerHandle;
+
+ if (typeManagerHandle.IsTypeManager())
+ {
+ ReadyToRunSectionType section =
+ (ReadyToRunSectionType)((UInt32)ReadyToRunSectionType::ReadonlyBlobRegionStart + blobId);
+ ASSERT(section <= ReadyToRunSectionType::ReadonlyBlobRegionEnd);
+
+ TypeManager* pModule = typeManagerHandle.AsTypeManager();
+
+ int length;
+ void* pBlob;
+ pBlob = pModule->GetModuleSection(section, &length);
+
+ *ppbBlob = (UInt8*)pBlob;
+ *pcbBlob = (UInt32)length;
+
+ return pBlob != NULL;
+ }
+#if !CORERT
+ else
+ {
+ HANDLE hOsModule = typeManagerHandle.AsOsModule();
+ // Search for the Redhawk module contained by the OS module.
+ FOREACH_MODULE(pModule)
+ {
+ if (pModule->GetOsModuleHandle() == hOsModule)
{
- UInt32 cbTotalBlob = sizeof(BlobHeader) + pBlob->m_size;
- ASSERT(cbBlobs >= cbTotalBlob);
+ // Found a module match. Look through the blobs for one with a matching ID.
+ UInt32 cbBlobs;
+ BlobHeader * pBlob = pModule->GetReadOnlyBlobs(&cbBlobs);
- if (pBlob->m_id == blobId)
+ while (cbBlobs)
{
- // Found the matching blob, return it.
- *ppbBlob = (UInt8*)(pBlob + 1);
- *pcbBlob = pBlob->m_size;
- return TRUE;
+ UInt32 cbTotalBlob = sizeof(BlobHeader) + pBlob->m_size;
+ ASSERT(cbBlobs >= cbTotalBlob);
+
+ if (pBlob->m_id == blobId)
+ {
+ // Found the matching blob, return it.
+ *ppbBlob = (UInt8*)(pBlob + 1);
+ *pcbBlob = pBlob->m_size;
+ return TRUE;
+ }
+
+ cbBlobs -= cbTotalBlob;
+ pBlob = (BlobHeader*)((UInt8*)pBlob + cbTotalBlob);
}
- cbBlobs -= cbTotalBlob;
- pBlob = (BlobHeader*)((UInt8*)pBlob + cbTotalBlob);
+ // If we get here then we found a module match but didn't find a blob with a matching ID. That's a
+ // non-catastrophic error.
+ *ppbBlob = NULL;
+ *pcbBlob = 0;
+ return FALSE;
}
-
- // If we get here then we found a module match but didn't find a blob with a matching ID. That's a
- // non-catastrophic error.
- *ppbBlob = NULL;
- *pcbBlob = 0;
- return FALSE;
}
+ END_FOREACH_MODULE
}
- END_FOREACH_MODULE
+#endif // !CORERT
// If we get here we were passed a bad module handle and should fail fast since this indicates a nasty bug
// (which could lead to the wrong blob being returned in some cases).
RhFailFast();
return FALSE;
-#endif // !CORERT
}
// This helper is not called directly but is used by the implementation of RhpCheckCctor to locate the
@@ -640,9 +740,9 @@ COOP_PINVOKE_HELPER(Boolean, RhpRegisterFrozenSegment, (void* pSegmentStart, UIn
return RedhawkGCInterface::RegisterFrozenSection(pSegmentStart, length) != NULL;
}
-COOP_PINVOKE_HELPER(void*, RhpGetModuleSection, (TypeManager* pModule, Int32 headerId, Int32* length))
+COOP_PINVOKE_HELPER(void*, RhpGetModuleSection, (TypeManagerHandle pModule, Int32 headerId, Int32* length))
{
- return pModule->GetModuleSection((ReadyToRunSectionType)headerId, length);
+ return pModule.AsTypeManager()->GetModuleSection((ReadyToRunSectionType)headerId, length);
}
COOP_PINVOKE_HELPER(void, RhGetCurrentThreadStackBounds, (PTR_VOID * ppStackLow, PTR_VOID * ppStackHigh))