Make HandleStores contain their underlying bucket directly.
authorAditya Mandaleeka <adityam@microsoft.com>
Fri, 14 Apr 2017 03:49:04 +0000 (20:49 -0700)
committerAditya Mandaleeka <adityam@microsoft.com>
Fri, 14 Apr 2017 17:04:36 +0000 (10:04 -0700)
Commit migrated from https://github.com/dotnet/coreclr/commit/0bb12f6ffb876eb51a85f62f7b9967eb31e0b40c

src/coreclr/src/gc/gchandletable.cpp
src/coreclr/src/gc/gchandletableimpl.h
src/coreclr/src/gc/objecthandle.cpp
src/coreclr/src/gc/objecthandle.h

index 6c9e098..68a1c97 100644 (file)
@@ -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<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));
 
@@ -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;
index bd9d921..9247615 100644 (file)
 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;
index f0a4fff..cd64ae2 100644 (file)
@@ -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;
                     }
                 }
             }
index d3e45f8..945e8d6 100644 (file)
@@ -106,7 +106,8 @@ typedef Holder<OBJECTHANDLE,DoNothing<OBJECTHANDLE>,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);