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<uintptr_t>(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));
GCHandleStore::~GCHandleStore()
{
- Ref_DestroyHandleTableBucket(_underlyingBucket);
+ ::Ref_DestroyHandleTableBucket(&_underlyingBucket);
}
bool GCHandleManager::Initialize()
void GCHandleManager::Shutdown()
{
- Ref_Shutdown();
+ if (g_gcGlobalHandleStore != nullptr)
+ {
+ DestroyHandleStore(g_gcGlobalHandleStore);
+ }
+
+ ::Ref_Shutdown();
}
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;
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;
}
// 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) {
}
#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
{
}
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
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();
}
if (Interlocked::CompareExchangePointer(&walk->pBuckets[i], result, NULL) == 0) {
// Get a free slot.
bucketHolder.SuppressRelease();
- return result;
+ return true;
}
}
}