From 5e5782ab46b44f35c519006291f358871745e4ed Mon Sep 17 00:00:00 2001 From: Aditya Mandaleeka Date: Thu, 13 Apr 2017 20:49:04 -0700 Subject: [PATCH] Make HandleStores contain their underlying bucket directly. Commit migrated from https://github.com/dotnet/coreclr/commit/0bb12f6ffb876eb51a85f62f7b9967eb31e0b40c --- src/coreclr/src/gc/gchandletable.cpp | 35 +++++++--- src/coreclr/src/gc/gchandletableimpl.h | 7 +- src/coreclr/src/gc/objecthandle.cpp | 113 ++++++++++++++++++--------------- src/coreclr/src/gc/objecthandle.h | 3 +- 4 files changed, 90 insertions(+), 68 deletions(-) diff --git a/src/coreclr/src/gc/gchandletable.cpp b/src/coreclr/src/gc/gchandletable.cpp index 6c9e098..68a1c97 100644 --- a/src/coreclr/src/gc/gchandletable.cpp +++ b/src/coreclr/src/gc/gchandletable.cpp @@ -17,35 +17,35 @@ IGCHandleManager* CreateGCHandleManager() void GCHandleStore::Uproot() { - Ref_RemoveHandleTableBucket(_underlyingBucket); + Ref_RemoveHandleTableBucket(&_underlyingBucket); } bool GCHandleStore::ContainsHandle(OBJECTHANDLE handle) { - return _underlyingBucket->Contains(handle); + return _underlyingBucket.Contains(handle); } OBJECTHANDLE GCHandleStore::CreateHandleOfType(Object* object, int type) { - HHANDLETABLE handletable = _underlyingBucket->pTable[GetCurrentThreadHomeHeapNumber()]; + HHANDLETABLE handletable = _underlyingBucket.pTable[GetCurrentThreadHomeHeapNumber()]; return ::HndCreateHandle(handletable, type, ObjectToOBJECTREF(object)); } OBJECTHANDLE GCHandleStore::CreateHandleOfType(Object* object, int type, int heapToAffinitizeTo) { - HHANDLETABLE handletable = _underlyingBucket->pTable[heapToAffinitizeTo]; + HHANDLETABLE handletable = _underlyingBucket.pTable[heapToAffinitizeTo]; return ::HndCreateHandle(handletable, type, ObjectToOBJECTREF(object)); } OBJECTHANDLE GCHandleStore::CreateHandleWithExtraInfo(Object* object, int type, void* pExtraInfo) { - HHANDLETABLE handletable = _underlyingBucket->pTable[GetCurrentThreadHomeHeapNumber()]; + HHANDLETABLE handletable = _underlyingBucket.pTable[GetCurrentThreadHomeHeapNumber()]; return ::HndCreateHandle(handletable, type, ObjectToOBJECTREF(object), reinterpret_cast(pExtraInfo)); } OBJECTHANDLE GCHandleStore::CreateDependentHandle(Object* primary, Object* secondary) { - HHANDLETABLE handletable = _underlyingBucket->pTable[GetCurrentThreadHomeHeapNumber()]; + HHANDLETABLE handletable = _underlyingBucket.pTable[GetCurrentThreadHomeHeapNumber()]; OBJECTHANDLE handle = ::HndCreateHandle(handletable, HNDTYPE_DEPENDENT, ObjectToOBJECTREF(primary)); ::SetDependentHandleSecondary(handle, ObjectToOBJECTREF(secondary)); @@ -54,7 +54,7 @@ OBJECTHANDLE GCHandleStore::CreateDependentHandle(Object* primary, Object* secon GCHandleStore::~GCHandleStore() { - Ref_DestroyHandleTableBucket(_underlyingBucket); + ::Ref_DestroyHandleTableBucket(&_underlyingBucket); } bool GCHandleManager::Initialize() @@ -64,7 +64,12 @@ bool GCHandleManager::Initialize() void GCHandleManager::Shutdown() { - Ref_Shutdown(); + if (g_gcGlobalHandleStore != nullptr) + { + DestroyHandleStore(g_gcGlobalHandleStore); + } + + ::Ref_Shutdown(); } IGCHandleStore* GCHandleManager::GetGlobalHandleStore() @@ -75,8 +80,18 @@ IGCHandleStore* GCHandleManager::GetGlobalHandleStore() IGCHandleStore* GCHandleManager::CreateHandleStore(void* context) { #ifndef FEATURE_REDHAWK - HandleTableBucket* newBucket = ::Ref_CreateHandleTableBucket(ADIndex((DWORD)(uintptr_t)context)); - return new (nothrow) GCHandleStore(newBucket); + GCHandleStore* store = new (nothrow) GCHandleStore(); + if (store == nullptr) + return nullptr; + + bool success = ::Ref_InitializeHandleTableBucket(&store->_underlyingBucket, context); + if (!success) + { + delete store; + return nullptr; + } + + return store; #else assert("CreateHandleStore is not implemented when FEATURE_REDHAWK is defined!"); return nullptr; diff --git a/src/coreclr/src/gc/gchandletableimpl.h b/src/coreclr/src/gc/gchandletableimpl.h index bd9d921..9247615 100644 --- a/src/coreclr/src/gc/gchandletableimpl.h +++ b/src/coreclr/src/gc/gchandletableimpl.h @@ -11,10 +11,6 @@ class GCHandleStore : public IGCHandleStore { public: - GCHandleStore(HandleTableBucket *bucket) - : _underlyingBucket(bucket) - { } - virtual void Uproot(); virtual bool ContainsHandle(OBJECTHANDLE handle); @@ -29,8 +25,7 @@ public: virtual ~GCHandleStore(); -private: - HandleTableBucket* _underlyingBucket; + HandleTableBucket _underlyingBucket; }; extern GCHandleStore* g_gcGlobalHandleStore; diff --git a/src/coreclr/src/gc/objecthandle.cpp b/src/coreclr/src/gc/objecthandle.cpp index f0a4fff..cd64ae2 100644 --- a/src/coreclr/src/gc/objecthandle.cpp +++ b/src/coreclr/src/gc/objecthandle.cpp @@ -629,59 +629,62 @@ bool Ref_Initialize() if (pBuckets == NULL) return false; - ZeroMemory(pBuckets, - INITIAL_HANDLE_TABLE_ARRAY_SIZE * sizeof (HandleTableBucket *)); + ZeroMemory(pBuckets, INITIAL_HANDLE_TABLE_ARRAY_SIZE * sizeof (HandleTableBucket *)); - // Crate the first bucket - HandleTableBucket * pBucket = new (nothrow) HandleTableBucket; - if (pBucket != NULL) + g_gcGlobalHandleStore = new (nothrow) GCHandleStore(); + if (g_gcGlobalHandleStore == NULL) { - pBucket->HandleTableIndex = 0; + delete[] pBuckets; + return false; + } - int n_slots = getNumberOfSlots(); + // Initialize the bucket in the global handle store + HandleTableBucket* pBucket = &g_gcGlobalHandleStore->_underlyingBucket; - HandleTableBucketHolder bucketHolder(pBucket, n_slots); + pBucket->HandleTableIndex = 0; - // create the handle table set for the first bucket - pBucket->pTable = new (nothrow) HHANDLETABLE[n_slots]; - if (pBucket->pTable == NULL) - goto CleanupAndFail; + int n_slots = getNumberOfSlots(); - ZeroMemory(pBucket->pTable, - n_slots * sizeof(HHANDLETABLE)); - for (int uCPUindex = 0; uCPUindex < n_slots; uCPUindex++) - { - pBucket->pTable[uCPUindex] = HndCreateHandleTable(s_rgTypeFlags, _countof(s_rgTypeFlags), ADIndex(1)); - if (pBucket->pTable[uCPUindex] == NULL) - goto CleanupAndFail; + HandleTableBucketHolder bucketHolder(pBucket, n_slots); - HndSetHandleTableIndex(pBucket->pTable[uCPUindex], 0); - } + // create the handle table set for the first bucket + pBucket->pTable = new (nothrow) HHANDLETABLE[n_slots]; + if (pBucket->pTable == NULL) + goto CleanupAndFail; - pBuckets[0] = pBucket; - bucketHolder.SuppressRelease(); + ZeroMemory(pBucket->pTable, + n_slots * sizeof(HHANDLETABLE)); + for (int uCPUindex = 0; uCPUindex < n_slots; uCPUindex++) + { + pBucket->pTable[uCPUindex] = HndCreateHandleTable(s_rgTypeFlags, _countof(s_rgTypeFlags), ADIndex(1)); + if (pBucket->pTable[uCPUindex] == NULL) + goto CleanupAndFail; - g_HandleTableMap.pBuckets = pBuckets; - g_HandleTableMap.dwMaxIndex = INITIAL_HANDLE_TABLE_ARRAY_SIZE; - g_HandleTableMap.pNext = NULL; + HndSetHandleTableIndex(pBucket->pTable[uCPUindex], 0); + } - g_gcGlobalHandleStore = new (nothrow) GCHandleStore(g_HandleTableMap.pBuckets[0]); - if (g_gcGlobalHandleStore == NULL) - goto CleanupAndFail; + pBuckets[0] = pBucket; + bucketHolder.SuppressRelease(); - // Allocate contexts used during dependent handle promotion scanning. There's one of these for every GC - // heap since they're scanned in parallel. - g_pDependentHandleContexts = new (nothrow) DhContext[n_slots]; - if (g_pDependentHandleContexts == NULL) - goto CleanupAndFail; + g_HandleTableMap.pBuckets = pBuckets; + g_HandleTableMap.dwMaxIndex = INITIAL_HANDLE_TABLE_ARRAY_SIZE; + g_HandleTableMap.pNext = NULL; - return true; - } + // Allocate contexts used during dependent handle promotion scanning. There's one of these for every GC + // heap since they're scanned in parallel. + g_pDependentHandleContexts = new (nothrow) DhContext[n_slots]; + if (g_pDependentHandleContexts == NULL) + goto CleanupAndFail; + return true; CleanupAndFail: if (pBuckets != NULL) delete[] pBuckets; + + if (g_gcGlobalHandleStore != NULL) + delete g_gcGlobalHandleStore; + return false; } @@ -701,9 +704,6 @@ void Ref_Shutdown() // don't destroy any of the indexed handle tables; they should // be destroyed externally. - // destroy the global handle table bucket tables - Ref_DestroyHandleTableBucket(g_HandleTableMap.pBuckets[0]); - // destroy the handle table bucket array HandleTableMap *walk = &g_HandleTableMap; while (walk) { @@ -721,9 +721,22 @@ void Ref_Shutdown() } #ifndef FEATURE_REDHAWK -// ATTENTION: interface changed -// Note: this function called only from AppDomain::Init() -HandleTableBucket *Ref_CreateHandleTableBucket(ADIndex uADIndex) +HandleTableBucket* Ref_CreateHandleTableBucket(void* context) +{ + HandleTableBucket* result = new (nothrow) HandleTableBucket(); + if (result == nullptr) + return nullptr; + + if (!Ref_InitializeHandleTableBucket(result, context)) + { + delete result; + return nullptr; + } + + return result; +} + +bool Ref_InitializeHandleTableBucket(HandleTableBucket* bucket, void* context) { CONTRACTL { @@ -733,14 +746,12 @@ HandleTableBucket *Ref_CreateHandleTableBucket(ADIndex uADIndex) } CONTRACTL_END; - HandleTableBucket *result = NULL; - HandleTableMap *walk; - - walk = &g_HandleTableMap; + HandleTableBucket *result = bucket; + HandleTableMap *walk = &g_HandleTableMap; + HandleTableMap *last = NULL; uint32_t offset = 0; - result = new HandleTableBucket; result->pTable = NULL; // create handle table set for the bucket @@ -748,11 +759,11 @@ HandleTableBucket *Ref_CreateHandleTableBucket(ADIndex uADIndex) HandleTableBucketHolder bucketHolder(result, n_slots); - result->pTable = new HHANDLETABLE [ n_slots ]; - ZeroMemory(result->pTable, n_slots * sizeof (HHANDLETABLE)); + result->pTable = new HHANDLETABLE[n_slots]; + ZeroMemory(result->pTable, n_slots * sizeof(HHANDLETABLE)); for (int uCPUindex=0; uCPUindex < n_slots; uCPUindex++) { - result->pTable[uCPUindex] = HndCreateHandleTable(s_rgTypeFlags, _countof(s_rgTypeFlags), uADIndex); + result->pTable[uCPUindex] = HndCreateHandleTable(s_rgTypeFlags, _countof(s_rgTypeFlags), ADIndex((DWORD)(uintptr_t)context)); if (!result->pTable[uCPUindex]) COMPlusThrowOM(); } @@ -769,7 +780,7 @@ HandleTableBucket *Ref_CreateHandleTableBucket(ADIndex uADIndex) if (Interlocked::CompareExchangePointer(&walk->pBuckets[i], result, NULL) == 0) { // Get a free slot. bucketHolder.SuppressRelease(); - return result; + return true; } } } diff --git a/src/coreclr/src/gc/objecthandle.h b/src/coreclr/src/gc/objecthandle.h index d3e45f8..945e8d6 100644 --- a/src/coreclr/src/gc/objecthandle.h +++ b/src/coreclr/src/gc/objecthandle.h @@ -106,7 +106,8 @@ typedef Holder,ResetOBJECTHANDLE> ObjectInH */ bool Ref_Initialize(); void Ref_Shutdown(); -HandleTableBucket *Ref_CreateHandleTableBucket(ADIndex uADIndex); +HandleTableBucket* Ref_CreateHandleTableBucket(void* context); +bool Ref_InitializeHandleTableBucket(HandleTableBucket* bucket, void* context); BOOL Ref_HandleAsyncPinHandles(); void Ref_RelocateAsyncPinHandles(HandleTableBucket *pSource, HandleTableBucket *pTarget); void Ref_RemoveHandleTableBucket(HandleTableBucket *pBucket); -- 2.7.4