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

Commit da00894

Browse files
Make a GCHandleStore class and interface for use by the VM.
1 parent 583713b commit da00894

10 files changed

+137
-112
lines changed

src/gc/gchandletable.cpp

Lines changed: 46 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -8,86 +8,94 @@
88
#include "gchandletableimpl.h"
99
#include "objecthandle.h"
1010

11+
GCHandleStore* g_gcGlobalHandleStore;
12+
1113
IGCHandleTable* CreateGCHandleTable()
1214
{
13-
return new(nothrow) GCHandleTable();
15+
return new (nothrow) GCHandleTable();
1416
}
1517

16-
bool GCHandleTable::Initialize()
18+
void GCHandleStore::Uproot()
1719
{
18-
return Ref_Initialize();
20+
Ref_RemoveHandleTableBucket(_underlyingBucket);
1921
}
2022

21-
void GCHandleTable::Shutdown()
23+
bool GCHandleStore::ContainsHandle(OBJECTHANDLE handle)
2224
{
23-
Ref_Shutdown();
25+
return _underlyingBucket->Contains(handle);
2426
}
2527

26-
void* GCHandleTable::GetGlobalHandleStore()
28+
OBJECTHANDLE GCHandleStore::CreateHandleOfType(Object* object, int type)
2729
{
28-
return (void*)g_HandleTableMap.pBuckets[0];
30+
HHANDLETABLE handletable = _underlyingBucket->pTable[GetCurrentThreadHomeHeapNumber()];
31+
return ::HndCreateHandle(handletable, type, ObjectToOBJECTREF(object));
2932
}
3033

31-
void* GCHandleTable::CreateHandleStore(void* context)
34+
OBJECTHANDLE GCHandleStore::CreateHandleOfType(Object* object, int type, int heapToAffinitizeTo)
3235
{
33-
#ifndef FEATURE_REDHAWK
34-
return (void*)::Ref_CreateHandleTableBucket(ADIndex((DWORD)(uintptr_t)context));
35-
#else
36-
assert("CreateHandleStore is not implemented when FEATURE_REDHAWK is defined!");
37-
return nullptr;
38-
#endif
36+
HHANDLETABLE handletable = _underlyingBucket->pTable[heapToAffinitizeTo];
37+
return ::HndCreateHandle(handletable, type, ObjectToOBJECTREF(object));
3938
}
4039

41-
void* GCHandleTable::GetHandleContext(OBJECTHANDLE handle)
40+
OBJECTHANDLE GCHandleStore::CreateHandleWithExtraInfo(Object* object, int type, void* pExtraInfo)
4241
{
43-
return (void*)((uintptr_t)::HndGetHandleTableADIndex(::HndGetHandleTable(handle)).m_dwIndex);
42+
HHANDLETABLE handletable = _underlyingBucket->pTable[GetCurrentThreadHomeHeapNumber()];
43+
return ::HndCreateHandle(handletable, type, ObjectToOBJECTREF(object), reinterpret_cast<uintptr_t>(pExtraInfo));
4444
}
4545

46-
void GCHandleTable::DestroyHandleStore(void* store)
46+
OBJECTHANDLE GCHandleStore::CreateDependentHandle(Object* primary, Object* secondary)
4747
{
48-
Ref_DestroyHandleTableBucket((HandleTableBucket*) store);
48+
HHANDLETABLE handletable = _underlyingBucket->pTable[GetCurrentThreadHomeHeapNumber()];
49+
OBJECTHANDLE handle = ::HndCreateHandle(handletable, HNDTYPE_DEPENDENT, ObjectToOBJECTREF(primary));
50+
::SetDependentHandleSecondary(handle, ObjectToOBJECTREF(secondary));
51+
52+
return handle;
4953
}
5054

51-
void GCHandleTable::UprootHandleStore(void* store)
55+
GCHandleStore::~GCHandleStore()
5256
{
53-
Ref_RemoveHandleTableBucket((HandleTableBucket*) store);
57+
Ref_DestroyHandleTableBucket(_underlyingBucket);
5458
}
5559

56-
bool GCHandleTable::ContainsHandle(void* store, OBJECTHANDLE handle)
60+
bool GCHandleTable::Initialize()
5761
{
58-
return ((HandleTableBucket*)store)->Contains(handle);
62+
return Ref_Initialize();
5963
}
6064

61-
OBJECTHANDLE GCHandleTable::CreateHandleOfType(void* store, Object* object, int type)
65+
void GCHandleTable::Shutdown()
6266
{
63-
HHANDLETABLE handletable = ((HandleTableBucket*)store)->pTable[GetCurrentThreadHomeHeapNumber()];
64-
return ::HndCreateHandle(handletable, type, ObjectToOBJECTREF(object));
67+
Ref_Shutdown();
6568
}
6669

67-
OBJECTHANDLE GCHandleTable::CreateHandleOfType(void* store, Object* object, int type, int heapToAffinitizeTo)
70+
IGCHandleStore* GCHandleTable::GetGlobalHandleStore()
6871
{
69-
HHANDLETABLE handletable = ((HandleTableBucket*)store)->pTable[heapToAffinitizeTo];
70-
return ::HndCreateHandle(handletable, type, ObjectToOBJECTREF(object));
72+
return g_gcGlobalHandleStore;
7173
}
7274

73-
OBJECTHANDLE GCHandleTable::CreateGlobalHandleOfType(Object* object, int type)
75+
IGCHandleStore* GCHandleTable::CreateHandleStore(void* context)
7476
{
75-
return ::HndCreateHandle(g_HandleTableMap.pBuckets[0]->pTable[GetCurrentThreadHomeHeapNumber()], type, ObjectToOBJECTREF(object));
77+
#ifndef FEATURE_REDHAWK
78+
HandleTableBucket* newBucket = ::Ref_CreateHandleTableBucket(ADIndex((DWORD)(uintptr_t)context));
79+
return new (nothrow) GCHandleStore(newBucket);
80+
#else
81+
assert("CreateHandleStore is not implemented when FEATURE_REDHAWK is defined!");
82+
return nullptr;
83+
#endif
7684
}
7785

78-
OBJECTHANDLE GCHandleTable::CreateHandleWithExtraInfo(void* store, Object* object, int type, void* pExtraInfo)
86+
void GCHandleTable::DestroyHandleStore(IGCHandleStore* store)
7987
{
80-
HHANDLETABLE handletable = ((HandleTableBucket*)store)->pTable[GetCurrentThreadHomeHeapNumber()];
81-
return ::HndCreateHandle(handletable, type, ObjectToOBJECTREF(object), reinterpret_cast<uintptr_t>(pExtraInfo));
88+
delete store;
8289
}
8390

84-
OBJECTHANDLE GCHandleTable::CreateDependentHandle(void* store, Object* primary, Object* secondary)
91+
void* GCHandleTable::GetHandleContext(OBJECTHANDLE handle)
8592
{
86-
HHANDLETABLE handletable = ((HandleTableBucket*)store)->pTable[GetCurrentThreadHomeHeapNumber()];
87-
OBJECTHANDLE handle = ::HndCreateHandle(handletable, HNDTYPE_DEPENDENT, ObjectToOBJECTREF(primary));
88-
::SetDependentHandleSecondary(handle, ObjectToOBJECTREF(secondary));
93+
return (void*)((uintptr_t)::HndGetHandleTableADIndex(::HndGetHandleTable(handle)).m_dwIndex);
94+
}
8995

90-
return handle;
96+
OBJECTHANDLE GCHandleTable::CreateGlobalHandleOfType(Object* object, int type)
97+
{
98+
return ::HndCreateHandle(g_HandleTableMap.pBuckets[0]->pTable[GetCurrentThreadHomeHeapNumber()], type, ObjectToOBJECTREF(object));
9199
}
92100

93101
OBJECTHANDLE GCHandleTable::CreateDuplicateHandle(OBJECTHANDLE handle)

src/gc/gchandletableimpl.h

Lines changed: 29 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -6,33 +6,49 @@
66
#define GCHANDLETABLE_H_
77

88
#include "gcinterface.h"
9+
#include "objecthandle.h"
910

10-
class GCHandleTable : public IGCHandleTable
11+
class GCHandleStore : public IGCHandleStore
1112
{
1213
public:
13-
virtual bool Initialize();
14+
GCHandleStore(HandleTableBucket *bucket)
15+
: _underlyingBucket(bucket)
16+
{ }
1417

15-
virtual void Shutdown();
18+
virtual void Uproot();
1619

17-
virtual void* GetGlobalHandleStore();
20+
virtual bool ContainsHandle(OBJECTHANDLE handle);
1821

19-
virtual void* CreateHandleStore(void* context);
22+
virtual OBJECTHANDLE CreateHandleOfType(Object* object, int type);
2023

21-
virtual void* GetHandleContext(OBJECTHANDLE handle);
24+
virtual OBJECTHANDLE CreateHandleOfType(Object* object, int type, int heapToAffinitizeTo);
2225

23-
virtual void DestroyHandleStore(void* store);
26+
virtual OBJECTHANDLE CreateHandleWithExtraInfo(Object* object, int type, void* pExtraInfo);
2427

25-
virtual void UprootHandleStore(void* store);
28+
virtual OBJECTHANDLE CreateDependentHandle(Object* primary, Object* secondary);
2629

27-
virtual bool ContainsHandle(void* store, OBJECTHANDLE handle);
30+
virtual ~GCHandleStore();
2831

29-
virtual OBJECTHANDLE CreateHandleOfType(void* store, Object* object, int type);
32+
private:
33+
HandleTableBucket* _underlyingBucket;
34+
};
35+
36+
extern GCHandleStore* g_gcGlobalHandleStore;
37+
38+
class GCHandleTable : public IGCHandleTable
39+
{
40+
public:
41+
virtual bool Initialize();
42+
43+
virtual void Shutdown();
44+
45+
virtual void* GetHandleContext(OBJECTHANDLE handle);
3046

31-
virtual OBJECTHANDLE CreateHandleOfType(void* store, Object* object, int type, int heapToAffinitizeTo);
47+
virtual IGCHandleStore* GetGlobalHandleStore();
3248

33-
virtual OBJECTHANDLE CreateHandleWithExtraInfo(void* store, Object* object, int type, void* pExtraInfo);
49+
virtual IGCHandleStore* CreateHandleStore(void* context);
3450

35-
virtual OBJECTHANDLE CreateDependentHandle(void* store, Object* primary, Object* secondary);
51+
virtual void DestroyHandleStore(IGCHandleStore* store);
3652

3753
virtual OBJECTHANDLE CreateGlobalHandleOfType(Object* object, int type);
3854

src/gc/gcinterface.h

Lines changed: 19 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -402,32 +402,38 @@ typedef struct OBJECTHANDLE__* OBJECTHANDLE;
402402
typedef uintptr_t OBJECTHANDLE;
403403
#endif
404404

405-
class IGCHandleTable {
405+
class IGCHandleStore {
406406
public:
407407

408-
virtual bool Initialize() = 0;
408+
virtual void Uproot() = 0;
409409

410-
virtual void Shutdown() = 0;
410+
virtual bool ContainsHandle(OBJECTHANDLE handle) = 0;
411411

412-
virtual void* GetHandleContext(OBJECTHANDLE handle) = 0;
412+
virtual OBJECTHANDLE CreateHandleOfType(Object* object, int type) = 0;
413+
414+
virtual OBJECTHANDLE CreateHandleOfType(Object* object, int type, int heapToAffinitizeTo) = 0;
415+
416+
virtual OBJECTHANDLE CreateHandleWithExtraInfo(Object* object, int type, void* pExtraInfo) = 0;
413417

414-
virtual void* GetGlobalHandleStore() = 0;
418+
virtual OBJECTHANDLE CreateDependentHandle(Object* primary, Object* secondary) = 0;
415419

416-
virtual void* CreateHandleStore(void* context) = 0;
420+
virtual ~IGCHandleStore() {};
421+
};
417422

418-
virtual void DestroyHandleStore(void* store) = 0;
423+
class IGCHandleTable {
424+
public:
419425

420-
virtual void UprootHandleStore(void* store) = 0;
426+
virtual bool Initialize() = 0;
421427

422-
virtual bool ContainsHandle(void* store, OBJECTHANDLE handle) = 0;
428+
virtual void Shutdown() = 0;
423429

424-
virtual OBJECTHANDLE CreateHandleOfType(void* store, Object* object, int type) = 0;
430+
virtual void* GetHandleContext(OBJECTHANDLE handle) = 0;
425431

426-
virtual OBJECTHANDLE CreateHandleOfType(void* store, Object* object, int type, int heapToAffinitizeTo) = 0;
432+
virtual IGCHandleStore* GetGlobalHandleStore() = 0;
427433

428-
virtual OBJECTHANDLE CreateHandleWithExtraInfo(void* store, Object* object, int type, void* pExtraInfo) = 0;
434+
virtual IGCHandleStore* CreateHandleStore(void* context) = 0;
429435

430-
virtual OBJECTHANDLE CreateDependentHandle(void* store, Object* primary, Object* secondary) = 0;
436+
virtual void DestroyHandleStore(IGCHandleStore* store) = 0;
431437

432438
virtual OBJECTHANDLE CreateGlobalHandleOfType(Object* object, int type) = 0;
433439

src/gc/handletablecore.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1003,7 +1003,8 @@ void SegmentRelocateAsyncPinHandles (TableSegment *pSegment, HandleTable *pTarge
10031003
overlapped->m_userObject = NULL;
10041004
}
10051005
BashMTForPinnedObject(ObjectToOBJECTREF(value));
1006-
overlapped->m_pinSelf = CreateAsyncPinningHandle((HHANDLETABLE)pTargetTable,ObjectToOBJECTREF(value));
1006+
1007+
overlapped->m_pinSelf = HndCreateHandle((HHANDLETABLE)pTargetTable, HNDTYPE_ASYNCPINNED, ObjectToOBJECTREF(value));
10071008
*pValue = NULL;
10081009
}
10091010
pValue ++;

src/gc/objecthandle.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@
1919
#include "objecthandle.h"
2020
#include "handletablepriv.h"
2121

22+
#include "gchandletableimpl.h"
23+
2224
#ifdef FEATURE_COMINTEROP
2325
#include "comcallablewrapper.h"
2426
#endif // FEATURE_COMINTEROP
@@ -663,6 +665,10 @@ bool Ref_Initialize()
663665
g_HandleTableMap.dwMaxIndex = INITIAL_HANDLE_TABLE_ARRAY_SIZE;
664666
g_HandleTableMap.pNext = NULL;
665667

668+
g_gcGlobalHandleStore = new (nothrow) GCHandleStore(g_HandleTableMap.pBuckets[0]);
669+
if (g_gcGlobalHandleStore == NULL)
670+
goto CleanupAndFail;
671+
666672
// Allocate contexts used during dependent handle promotion scanning. There's one of these for every GC
667673
// heap since they're scanned in parallel.
668674
g_pDependentHandleContexts = new (nothrow) DhContext[n_slots];
@@ -672,6 +678,7 @@ bool Ref_Initialize()
672678
return true;
673679
}
674680

681+
675682
CleanupAndFail:
676683
if (pBuckets != NULL)
677684
delete[] pBuckets;

src/vm/appdomain.cpp

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4578,7 +4578,7 @@ void AppDomain::Terminate()
45784578

45794579
BaseDomain::Terminate();
45804580

4581-
if (m_handleStore)
4581+
if (m_handleStore)
45824582
{
45834583
GCHandleTableUtilities::GetGCHandleTable()->DestroyHandleStore(m_handleStore);
45844584
m_handleStore = NULL;
@@ -9197,8 +9197,8 @@ void AppDomain::ClearGCHandles()
91979197
// Keep async pin handles alive by moving them to default domain
91989198
HandleAsyncPinHandles();
91999199

9200-
// Remove our handle table as a source of GC roots
9201-
GCHandleTableUtilities::GetGCHandleTable()->UprootHandleStore(m_handleStore);
9200+
// Remove our handle store as a source of GC roots
9201+
m_handleStore->Uproot();
92029202
}
92039203

92049204
// When an AD is unloaded, we will release all objects in this AD.
@@ -9247,15 +9247,13 @@ void AppDomain::ClearGCRoots()
92479247
// this point, so only need to synchronize the preemptive mode threads.
92489248
ExecutionManager::Unload(GetLoaderAllocator());
92499249

9250-
IGCHandleTable* pHandleTable = GCHandleTableUtilities::GetGCHandleTable();
9251-
92529250
while ((pThread = ThreadStore::GetAllThreadList(pThread, 0, 0)) != NULL)
92539251
{
92549252
// Delete the thread local static store
92559253
pThread->DeleteThreadStaticData(this);
92569254

92579255
// <TODO>@TODO: A pre-allocated AppDomainUnloaded exception might be better.</TODO>
9258-
if (pHandleTable->ContainsHandle(m_handleStore, pThread->m_LastThrownObjectHandle))
9256+
if (m_handleStore->ContainsHandle(pThread->m_LastThrownObjectHandle))
92599257
{
92609258
// Never delete a handle to a preallocated exception object.
92619259
if (!CLRException::IsPreallocatedExceptionHandle(pThread->m_LastThrownObjectHandle))

src/vm/appdomain.hpp

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1244,9 +1244,7 @@ class BaseDomain
12441244
OBJECTHANDLE CreateTypedHandle(OBJECTREF object, int type)
12451245
{
12461246
WRAPPER_NO_CONTRACT;
1247-
1248-
IGCHandleTable *pHandleTable = GCHandleTableUtilities::GetGCHandleTable();
1249-
return pHandleTable->CreateHandleOfType(m_handleStore, OBJECTREFToObject(object), type);
1247+
return m_handleStore->CreateHandleOfType(OBJECTREFToObject(object), type);
12501248
}
12511249

12521250
OBJECTHANDLE CreateHandle(OBJECTREF object)
@@ -1345,8 +1343,7 @@ class BaseDomain
13451343
}
13461344
CONTRACTL_END;
13471345

1348-
IGCHandleTable *pHandleTable = GCHandleTableUtilities::GetGCHandleTable();
1349-
return pHandleTable->CreateDependentHandle(m_handleStore, OBJECTREFToObject(primary), OBJECTREFToObject(secondary));
1346+
return m_handleStore->CreateDependentHandle(OBJECTREFToObject(primary), OBJECTREFToObject(secondary));
13501347
}
13511348
#endif // DACCESS_COMPILE && !CROSSGEN_COMPILE
13521349

@@ -1402,7 +1399,7 @@ class BaseDomain
14021399

14031400
CLRPrivBinderCoreCLR *m_pTPABinderContext; // Reference to the binding context that holds TPA list details
14041401

1405-
void* m_handleStore;
1402+
IGCHandleStore* m_handleStore;
14061403

14071404
// The large heap handle table.
14081405
LargeHeapHandleTable *m_pLargeHeapHandleTable;

src/vm/exstate.cpp

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ void ThreadExceptionState::FreeAllStackTraces()
102102
}
103103
}
104104

105-
void ThreadExceptionState::ClearThrowablesForUnload(void* handleStore)
105+
void ThreadExceptionState::ClearThrowablesForUnload(IGCHandleStore* handleStore)
106106
{
107107
WRAPPER_NO_CONTRACT;
108108

@@ -112,13 +112,11 @@ void ThreadExceptionState::ClearThrowablesForUnload(void* handleStore)
112112
ExInfo* pNode = &m_currentExInfo;
113113
#endif // WIN64EXCEPTIONS
114114

115-
IGCHandleTable *pHandleTable = GCHandleTableUtilities::GetGCHandleTable();
116-
117115
for ( ;
118116
pNode != NULL;
119117
pNode = pNode->m_pPrevNestedInfo)
120118
{
121-
if (pHandleTable->ContainsHandle(handleStore, pNode->m_hThrowable))
119+
if (handleStore->ContainsHandle(pNode->m_hThrowable))
122120
{
123121
pNode->DestroyExceptionHandle();
124122
}

src/vm/exstate.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ class ThreadExceptionState
5656
public:
5757

5858
void FreeAllStackTraces();
59-
void ClearThrowablesForUnload(void* handleStore);
59+
void ClearThrowablesForUnload(IGCHandleStore* handleStore);
6060

6161
#ifdef _DEBUG
6262
typedef enum

0 commit comments

Comments
 (0)