Skip to content
This repository was archived by the owner on Jan 23, 2023. It is now read-only.

Commit 0bb12f6

Browse files
Make HandleStores contain their underlying bucket directly.
1 parent c9914b7 commit 0bb12f6

File tree

4 files changed

+90
-68
lines changed

4 files changed

+90
-68
lines changed

src/gc/gchandletable.cpp

Lines changed: 25 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -17,35 +17,35 @@ IGCHandleManager* CreateGCHandleManager()
1717

1818
void GCHandleStore::Uproot()
1919
{
20-
Ref_RemoveHandleTableBucket(_underlyingBucket);
20+
Ref_RemoveHandleTableBucket(&_underlyingBucket);
2121
}
2222

2323
bool GCHandleStore::ContainsHandle(OBJECTHANDLE handle)
2424
{
25-
return _underlyingBucket->Contains(handle);
25+
return _underlyingBucket.Contains(handle);
2626
}
2727

2828
OBJECTHANDLE GCHandleStore::CreateHandleOfType(Object* object, int type)
2929
{
30-
HHANDLETABLE handletable = _underlyingBucket->pTable[GetCurrentThreadHomeHeapNumber()];
30+
HHANDLETABLE handletable = _underlyingBucket.pTable[GetCurrentThreadHomeHeapNumber()];
3131
return ::HndCreateHandle(handletable, type, ObjectToOBJECTREF(object));
3232
}
3333

3434
OBJECTHANDLE GCHandleStore::CreateHandleOfType(Object* object, int type, int heapToAffinitizeTo)
3535
{
36-
HHANDLETABLE handletable = _underlyingBucket->pTable[heapToAffinitizeTo];
36+
HHANDLETABLE handletable = _underlyingBucket.pTable[heapToAffinitizeTo];
3737
return ::HndCreateHandle(handletable, type, ObjectToOBJECTREF(object));
3838
}
3939

4040
OBJECTHANDLE GCHandleStore::CreateHandleWithExtraInfo(Object* object, int type, void* pExtraInfo)
4141
{
42-
HHANDLETABLE handletable = _underlyingBucket->pTable[GetCurrentThreadHomeHeapNumber()];
42+
HHANDLETABLE handletable = _underlyingBucket.pTable[GetCurrentThreadHomeHeapNumber()];
4343
return ::HndCreateHandle(handletable, type, ObjectToOBJECTREF(object), reinterpret_cast<uintptr_t>(pExtraInfo));
4444
}
4545

4646
OBJECTHANDLE GCHandleStore::CreateDependentHandle(Object* primary, Object* secondary)
4747
{
48-
HHANDLETABLE handletable = _underlyingBucket->pTable[GetCurrentThreadHomeHeapNumber()];
48+
HHANDLETABLE handletable = _underlyingBucket.pTable[GetCurrentThreadHomeHeapNumber()];
4949
OBJECTHANDLE handle = ::HndCreateHandle(handletable, HNDTYPE_DEPENDENT, ObjectToOBJECTREF(primary));
5050
::SetDependentHandleSecondary(handle, ObjectToOBJECTREF(secondary));
5151

@@ -54,7 +54,7 @@ OBJECTHANDLE GCHandleStore::CreateDependentHandle(Object* primary, Object* secon
5454

5555
GCHandleStore::~GCHandleStore()
5656
{
57-
Ref_DestroyHandleTableBucket(_underlyingBucket);
57+
::Ref_DestroyHandleTableBucket(&_underlyingBucket);
5858
}
5959

6060
bool GCHandleManager::Initialize()
@@ -64,7 +64,12 @@ bool GCHandleManager::Initialize()
6464

6565
void GCHandleManager::Shutdown()
6666
{
67-
Ref_Shutdown();
67+
if (g_gcGlobalHandleStore != nullptr)
68+
{
69+
DestroyHandleStore(g_gcGlobalHandleStore);
70+
}
71+
72+
::Ref_Shutdown();
6873
}
6974

7075
IGCHandleStore* GCHandleManager::GetGlobalHandleStore()
@@ -75,8 +80,18 @@ IGCHandleStore* GCHandleManager::GetGlobalHandleStore()
7580
IGCHandleStore* GCHandleManager::CreateHandleStore(void* context)
7681
{
7782
#ifndef FEATURE_REDHAWK
78-
HandleTableBucket* newBucket = ::Ref_CreateHandleTableBucket(ADIndex((DWORD)(uintptr_t)context));
79-
return new (nothrow) GCHandleStore(newBucket);
83+
GCHandleStore* store = new (nothrow) GCHandleStore();
84+
if (store == nullptr)
85+
return nullptr;
86+
87+
bool success = ::Ref_InitializeHandleTableBucket(&store->_underlyingBucket, context);
88+
if (!success)
89+
{
90+
delete store;
91+
return nullptr;
92+
}
93+
94+
return store;
8095
#else
8196
assert("CreateHandleStore is not implemented when FEATURE_REDHAWK is defined!");
8297
return nullptr;

src/gc/gchandletableimpl.h

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,6 @@
1111
class GCHandleStore : public IGCHandleStore
1212
{
1313
public:
14-
GCHandleStore(HandleTableBucket *bucket)
15-
: _underlyingBucket(bucket)
16-
{ }
17-
1814
virtual void Uproot();
1915

2016
virtual bool ContainsHandle(OBJECTHANDLE handle);
@@ -29,8 +25,7 @@ class GCHandleStore : public IGCHandleStore
2925

3026
virtual ~GCHandleStore();
3127

32-
private:
33-
HandleTableBucket* _underlyingBucket;
28+
HandleTableBucket _underlyingBucket;
3429
};
3530

3631
extern GCHandleStore* g_gcGlobalHandleStore;

src/gc/objecthandle.cpp

Lines changed: 62 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -629,59 +629,62 @@ bool Ref_Initialize()
629629
if (pBuckets == NULL)
630630
return false;
631631

632-
ZeroMemory(pBuckets,
633-
INITIAL_HANDLE_TABLE_ARRAY_SIZE * sizeof (HandleTableBucket *));
632+
ZeroMemory(pBuckets, INITIAL_HANDLE_TABLE_ARRAY_SIZE * sizeof (HandleTableBucket *));
634633

635-
// Crate the first bucket
636-
HandleTableBucket * pBucket = new (nothrow) HandleTableBucket;
637-
if (pBucket != NULL)
634+
g_gcGlobalHandleStore = new (nothrow) GCHandleStore();
635+
if (g_gcGlobalHandleStore == NULL)
638636
{
639-
pBucket->HandleTableIndex = 0;
637+
delete[] pBuckets;
638+
return false;
639+
}
640640

641-
int n_slots = getNumberOfSlots();
641+
// Initialize the bucket in the global handle store
642+
HandleTableBucket* pBucket = &g_gcGlobalHandleStore->_underlyingBucket;
642643

643-
HandleTableBucketHolder bucketHolder(pBucket, n_slots);
644+
pBucket->HandleTableIndex = 0;
644645

645-
// create the handle table set for the first bucket
646-
pBucket->pTable = new (nothrow) HHANDLETABLE[n_slots];
647-
if (pBucket->pTable == NULL)
648-
goto CleanupAndFail;
646+
int n_slots = getNumberOfSlots();
649647

650-
ZeroMemory(pBucket->pTable,
651-
n_slots * sizeof(HHANDLETABLE));
652-
for (int uCPUindex = 0; uCPUindex < n_slots; uCPUindex++)
653-
{
654-
pBucket->pTable[uCPUindex] = HndCreateHandleTable(s_rgTypeFlags, _countof(s_rgTypeFlags), ADIndex(1));
655-
if (pBucket->pTable[uCPUindex] == NULL)
656-
goto CleanupAndFail;
648+
HandleTableBucketHolder bucketHolder(pBucket, n_slots);
657649

658-
HndSetHandleTableIndex(pBucket->pTable[uCPUindex], 0);
659-
}
650+
// create the handle table set for the first bucket
651+
pBucket->pTable = new (nothrow) HHANDLETABLE[n_slots];
652+
if (pBucket->pTable == NULL)
653+
goto CleanupAndFail;
660654

661-
pBuckets[0] = pBucket;
662-
bucketHolder.SuppressRelease();
655+
ZeroMemory(pBucket->pTable,
656+
n_slots * sizeof(HHANDLETABLE));
657+
for (int uCPUindex = 0; uCPUindex < n_slots; uCPUindex++)
658+
{
659+
pBucket->pTable[uCPUindex] = HndCreateHandleTable(s_rgTypeFlags, _countof(s_rgTypeFlags), ADIndex(1));
660+
if (pBucket->pTable[uCPUindex] == NULL)
661+
goto CleanupAndFail;
663662

664-
g_HandleTableMap.pBuckets = pBuckets;
665-
g_HandleTableMap.dwMaxIndex = INITIAL_HANDLE_TABLE_ARRAY_SIZE;
666-
g_HandleTableMap.pNext = NULL;
663+
HndSetHandleTableIndex(pBucket->pTable[uCPUindex], 0);
664+
}
667665

668-
g_gcGlobalHandleStore = new (nothrow) GCHandleStore(g_HandleTableMap.pBuckets[0]);
669-
if (g_gcGlobalHandleStore == NULL)
670-
goto CleanupAndFail;
666+
pBuckets[0] = pBucket;
667+
bucketHolder.SuppressRelease();
671668

672-
// Allocate contexts used during dependent handle promotion scanning. There's one of these for every GC
673-
// heap since they're scanned in parallel.
674-
g_pDependentHandleContexts = new (nothrow) DhContext[n_slots];
675-
if (g_pDependentHandleContexts == NULL)
676-
goto CleanupAndFail;
669+
g_HandleTableMap.pBuckets = pBuckets;
670+
g_HandleTableMap.dwMaxIndex = INITIAL_HANDLE_TABLE_ARRAY_SIZE;
671+
g_HandleTableMap.pNext = NULL;
677672

678-
return true;
679-
}
673+
// Allocate contexts used during dependent handle promotion scanning. There's one of these for every GC
674+
// heap since they're scanned in parallel.
675+
g_pDependentHandleContexts = new (nothrow) DhContext[n_slots];
676+
if (g_pDependentHandleContexts == NULL)
677+
goto CleanupAndFail;
680678

679+
return true;
681680

682681
CleanupAndFail:
683682
if (pBuckets != NULL)
684683
delete[] pBuckets;
684+
685+
if (g_gcGlobalHandleStore != NULL)
686+
delete g_gcGlobalHandleStore;
687+
685688
return false;
686689
}
687690

@@ -701,9 +704,6 @@ void Ref_Shutdown()
701704
// don't destroy any of the indexed handle tables; they should
702705
// be destroyed externally.
703706

704-
// destroy the global handle table bucket tables
705-
Ref_DestroyHandleTableBucket(g_HandleTableMap.pBuckets[0]);
706-
707707
// destroy the handle table bucket array
708708
HandleTableMap *walk = &g_HandleTableMap;
709709
while (walk) {
@@ -721,9 +721,22 @@ void Ref_Shutdown()
721721
}
722722

723723
#ifndef FEATURE_REDHAWK
724-
// ATTENTION: interface changed
725-
// Note: this function called only from AppDomain::Init()
726-
HandleTableBucket *Ref_CreateHandleTableBucket(ADIndex uADIndex)
724+
HandleTableBucket* Ref_CreateHandleTableBucket(void* context)
725+
{
726+
HandleTableBucket* result = new (nothrow) HandleTableBucket();
727+
if (result == nullptr)
728+
return nullptr;
729+
730+
if (!Ref_InitializeHandleTableBucket(result, context))
731+
{
732+
delete result;
733+
return nullptr;
734+
}
735+
736+
return result;
737+
}
738+
739+
bool Ref_InitializeHandleTableBucket(HandleTableBucket* bucket, void* context)
727740
{
728741
CONTRACTL
729742
{
@@ -733,26 +746,24 @@ HandleTableBucket *Ref_CreateHandleTableBucket(ADIndex uADIndex)
733746
}
734747
CONTRACTL_END;
735748

736-
HandleTableBucket *result = NULL;
737-
HandleTableMap *walk;
738-
739-
walk = &g_HandleTableMap;
749+
HandleTableBucket *result = bucket;
750+
HandleTableMap *walk = &g_HandleTableMap;
751+
740752
HandleTableMap *last = NULL;
741753
uint32_t offset = 0;
742754

743-
result = new HandleTableBucket;
744755
result->pTable = NULL;
745756

746757
// create handle table set for the bucket
747758
int n_slots = getNumberOfSlots();
748759

749760
HandleTableBucketHolder bucketHolder(result, n_slots);
750761

751-
result->pTable = new HHANDLETABLE [ n_slots ];
752-
ZeroMemory(result->pTable, n_slots * sizeof (HHANDLETABLE));
762+
result->pTable = new HHANDLETABLE[n_slots];
763+
ZeroMemory(result->pTable, n_slots * sizeof(HHANDLETABLE));
753764

754765
for (int uCPUindex=0; uCPUindex < n_slots; uCPUindex++) {
755-
result->pTable[uCPUindex] = HndCreateHandleTable(s_rgTypeFlags, _countof(s_rgTypeFlags), uADIndex);
766+
result->pTable[uCPUindex] = HndCreateHandleTable(s_rgTypeFlags, _countof(s_rgTypeFlags), ADIndex((DWORD)(uintptr_t)context));
756767
if (!result->pTable[uCPUindex])
757768
COMPlusThrowOM();
758769
}
@@ -769,7 +780,7 @@ HandleTableBucket *Ref_CreateHandleTableBucket(ADIndex uADIndex)
769780
if (Interlocked::CompareExchangePointer(&walk->pBuckets[i], result, NULL) == 0) {
770781
// Get a free slot.
771782
bucketHolder.SuppressRelease();
772-
return result;
783+
return true;
773784
}
774785
}
775786
}

src/gc/objecthandle.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,8 @@ typedef Holder<OBJECTHANDLE,DoNothing<OBJECTHANDLE>,ResetOBJECTHANDLE> ObjectInH
106106
*/
107107
bool Ref_Initialize();
108108
void Ref_Shutdown();
109-
HandleTableBucket *Ref_CreateHandleTableBucket(ADIndex uADIndex);
109+
HandleTableBucket* Ref_CreateHandleTableBucket(void* context);
110+
bool Ref_InitializeHandleTableBucket(HandleTableBucket* bucket, void* context);
110111
BOOL Ref_HandleAsyncPinHandles();
111112
void Ref_RelocateAsyncPinHandles(HandleTableBucket *pSource, HandleTableBucket *pTarget);
112113
void Ref_RemoveHandleTableBucket(HandleTableBucket *pBucket);

0 commit comments

Comments
 (0)