summaryrefslogtreecommitdiff
path: root/src/gc/objecthandle.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/gc/objecthandle.cpp')
-rw-r--r--src/gc/objecthandle.cpp138
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;