diff options
Diffstat (limited to 'src/gc/objecthandle.cpp')
-rw-r--r-- | src/gc/objecthandle.cpp | 138 |
1 files changed, 85 insertions, 53 deletions
diff --git a/src/gc/objecthandle.cpp b/src/gc/objecthandle.cpp index 5df53baad5..dd43ec23d5 100644 --- a/src/gc/objecthandle.cpp +++ b/src/gc/objecthandle.cpp @@ -19,6 +19,8 @@ #include "objecthandle.h" #include "handletablepriv.h" +#include "gchandletableimpl.h" + #ifdef FEATURE_COMINTEROP #include "comcallablewrapper.h" #endif // FEATURE_COMINTEROP @@ -627,54 +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; - - int n_slots = getNumberOfSlots(); - - HandleTableBucketHolder bucketHolder(pBucket, n_slots); + delete[] pBuckets; + return false; + } - // create the handle table set for the first bucket - pBucket->pTable = new (nothrow) HHANDLETABLE[n_slots]; - if (pBucket->pTable == NULL) - goto CleanupAndFail; + // Initialize the bucket in the global handle store + HandleTableBucket* pBucket = &g_gcGlobalHandleStore->_underlyingBucket; - 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; + pBucket->HandleTableIndex = 0; - HndSetHandleTableIndex(pBucket->pTable[uCPUindex], 0); - } + int n_slots = getNumberOfSlots(); - pBuckets[0] = pBucket; - bucketHolder.SuppressRelease(); + HandleTableBucketHolder bucketHolder(pBucket, n_slots); - g_HandleTableMap.pBuckets = pBuckets; - g_HandleTableMap.dwMaxIndex = INITIAL_HANDLE_TABLE_ARRAY_SIZE; - g_HandleTableMap.pNext = NULL; + // create the handle table set for the first bucket + pBucket->pTable = new (nothrow) HHANDLETABLE[n_slots]; + if (pBucket->pTable == NULL) + goto CleanupAndFail; - // 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) + 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; - return true; + HndSetHandleTableIndex(pBucket->pTable[uCPUindex], 0); } + pBuckets[0] = pBucket; + bucketHolder.SuppressRelease(); + + g_HandleTableMap.pBuckets = pBuckets; + g_HandleTableMap.dwMaxIndex = INITIAL_HANDLE_TABLE_ARRAY_SIZE; + g_HandleTableMap.pNext = NULL; + + // 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; } @@ -694,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) { @@ -714,26 +721,37 @@ 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 { - THROWS; + NOTHROW; WRAPPER(GC_TRIGGERS); - INJECT_FAULT(COMPlusThrowOM()); + INJECT_FAULT(return false); } 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 @@ -741,13 +759,18 @@ 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 (nothrow) HHANDLETABLE[n_slots]; + if (!result->pTable) + { + return false; + } + + 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(); + return false; } for (;;) { @@ -762,7 +785,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; } } } @@ -774,9 +797,18 @@ HandleTableBucket *Ref_CreateHandleTableBucket(ADIndex uADIndex) // No free slot. // Let's create a new node NewHolder<HandleTableMap> newMap; - newMap = new HandleTableMap; + newMap = new (nothrow) HandleTableMap; + if (!newMap) + { + return false; + } + + newMap->pBuckets = new (nothrow) HandleTableBucket * [ INITIAL_HANDLE_TABLE_ARRAY_SIZE ]; + if (!newMap->pBuckets) + { + return false; + } - newMap->pBuckets = new HandleTableBucket * [ INITIAL_HANDLE_TABLE_ARRAY_SIZE ]; newMap.SuppressRelease(); newMap->dwMaxIndex = last->dwMaxIndex + INITIAL_HANDLE_TABLE_ARRAY_SIZE; |