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

Commit 82e4aac

Browse files
Merge pull request #10911 from adityamandaleeka/handle_table_local_gc_hide_internals
[Local GC] Hide handle table internals from VM side
2 parents 45d0444 + ab43a5f commit 82e4aac

12 files changed

+154
-125
lines changed

src/gc/gchandletable.cpp

Lines changed: 49 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -23,39 +23,78 @@ void GCHandleTable::Shutdown()
2323
Ref_Shutdown();
2424
}
2525

26-
void* GCHandleTable::GetHandleTableContext(void* handleTable)
26+
void* GCHandleTable::GetGlobalHandleStore()
2727
{
28-
return (void*)((uintptr_t)::HndGetHandleTableADIndex((HHANDLETABLE)handleTable).m_dwIndex);
28+
return (void*)g_HandleTableMap.pBuckets[0];
2929
}
3030

31-
void* GCHandleTable::GetHandleTableForHandle(OBJECTHANDLE handle)
31+
void* GCHandleTable::CreateHandleStore(void* context)
3232
{
33-
return (void*)::HndGetHandleTable(handle);
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
3439
}
3540

36-
OBJECTHANDLE GCHandleTable::CreateHandleOfType(void* table, Object* object, int type)
41+
void* GCHandleTable::GetHandleContext(OBJECTHANDLE handle)
3742
{
38-
return ::HndCreateHandle((HHANDLETABLE)table, type, ObjectToOBJECTREF(object));
43+
return (void*)((uintptr_t)::HndGetHandleTableADIndex(::HndGetHandleTable(handle)).m_dwIndex);
44+
}
45+
46+
void GCHandleTable::DestroyHandleStore(void* store)
47+
{
48+
Ref_DestroyHandleTableBucket((HandleTableBucket*) store);
49+
}
50+
51+
void GCHandleTable::UprootHandleStore(void* store)
52+
{
53+
Ref_RemoveHandleTableBucket((HandleTableBucket*) store);
54+
}
55+
56+
bool GCHandleTable::ContainsHandle(void* store, OBJECTHANDLE handle)
57+
{
58+
return ((HandleTableBucket*)store)->Contains(handle);
59+
}
60+
61+
OBJECTHANDLE GCHandleTable::CreateHandleOfType(void* store, Object* object, int type)
62+
{
63+
HHANDLETABLE handletable = ((HandleTableBucket*)store)->pTable[GetCurrentThreadHomeHeapNumber()];
64+
return ::HndCreateHandle(handletable, type, ObjectToOBJECTREF(object));
65+
}
66+
67+
OBJECTHANDLE GCHandleTable::CreateHandleOfType(void* store, Object* object, int type, int heapToAffinitizeTo)
68+
{
69+
HHANDLETABLE handletable = ((HandleTableBucket*)store)->pTable[heapToAffinitizeTo];
70+
return ::HndCreateHandle(handletable, type, ObjectToOBJECTREF(object));
3971
}
4072

4173
OBJECTHANDLE GCHandleTable::CreateGlobalHandleOfType(Object* object, int type)
4274
{
4375
return ::HndCreateHandle(g_HandleTableMap.pBuckets[0]->pTable[GetCurrentThreadHomeHeapNumber()], type, ObjectToOBJECTREF(object));
4476
}
4577

46-
OBJECTHANDLE GCHandleTable::CreateHandleWithExtraInfo(void* table, Object* object, int type, void* pExtraInfo)
78+
OBJECTHANDLE GCHandleTable::CreateHandleWithExtraInfo(void* store, Object* object, int type, void* pExtraInfo)
4779
{
48-
return ::HndCreateHandle((HHANDLETABLE)table, type, ObjectToOBJECTREF(object), reinterpret_cast<uintptr_t>(pExtraInfo));
80+
HHANDLETABLE handletable = ((HandleTableBucket*)store)->pTable[GetCurrentThreadHomeHeapNumber()];
81+
return ::HndCreateHandle(handletable, type, ObjectToOBJECTREF(object), reinterpret_cast<uintptr_t>(pExtraInfo));
4982
}
5083

51-
OBJECTHANDLE GCHandleTable::CreateDependentHandle(void* table, Object* primary, Object* secondary)
84+
OBJECTHANDLE GCHandleTable::CreateDependentHandle(void* store, Object* primary, Object* secondary)
5285
{
53-
OBJECTHANDLE handle = ::HndCreateHandle((HHANDLETABLE)table, HNDTYPE_DEPENDENT, ObjectToOBJECTREF(primary));
86+
HHANDLETABLE handletable = ((HandleTableBucket*)store)->pTable[GetCurrentThreadHomeHeapNumber()];
87+
OBJECTHANDLE handle = ::HndCreateHandle(handletable, HNDTYPE_DEPENDENT, ObjectToOBJECTREF(primary));
5488
::SetDependentHandleSecondary(handle, ObjectToOBJECTREF(secondary));
5589

5690
return handle;
5791
}
5892

93+
OBJECTHANDLE GCHandleTable::CreateDuplicateHandle(OBJECTHANDLE handle)
94+
{
95+
return ::HndCreateHandle(HndGetHandleTable(handle), HNDTYPE_DEFAULT, ::HndFetchHandle(handle));
96+
}
97+
5998
void GCHandleTable::DestroyHandleOfType(OBJECTHANDLE handle, int type)
6099
{
61100
::HndDestroyHandle(::HndGetHandleTable(handle), type, handle);

src/gc/gchandletableimpl.h

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,18 +14,30 @@ class GCHandleTable : public IGCHandleTable
1414

1515
virtual void Shutdown();
1616

17-
virtual void* GetHandleTableContext(void* handleTable);
17+
virtual void* GetGlobalHandleStore();
1818

19-
virtual void* GetHandleTableForHandle(OBJECTHANDLE handle);
19+
virtual void* CreateHandleStore(void* context);
2020

21-
virtual OBJECTHANDLE CreateHandleOfType(void* table, Object* object, int type);
21+
virtual void* GetHandleContext(OBJECTHANDLE handle);
2222

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

25-
virtual OBJECTHANDLE CreateDependentHandle(void* table, Object* primary, Object* secondary);
25+
virtual void UprootHandleStore(void* store);
26+
27+
virtual bool ContainsHandle(void* store, OBJECTHANDLE handle);
28+
29+
virtual OBJECTHANDLE CreateHandleOfType(void* store, Object* object, int type);
30+
31+
virtual OBJECTHANDLE CreateHandleOfType(void* store, Object* object, int type, int heapToAffinitizeTo);
32+
33+
virtual OBJECTHANDLE CreateHandleWithExtraInfo(void* store, Object* object, int type, void* pExtraInfo);
34+
35+
virtual OBJECTHANDLE CreateDependentHandle(void* store, Object* primary, Object* secondary);
2636

2737
virtual OBJECTHANDLE CreateGlobalHandleOfType(Object* object, int type);
2838

39+
virtual OBJECTHANDLE CreateDuplicateHandle(OBJECTHANDLE handle);
40+
2941
virtual void DestroyHandleOfType(OBJECTHANDLE handle, int type);
3042

3143
virtual void DestroyHandleOfUnknownType(OBJECTHANDLE handle);

src/gc/gcinterface.h

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -409,18 +409,30 @@ class IGCHandleTable {
409409

410410
virtual void Shutdown() = 0;
411411

412-
virtual void* GetHandleTableContext(void* handleTable) = 0;
412+
virtual void* GetHandleContext(OBJECTHANDLE handle) = 0;
413413

414-
virtual void* GetHandleTableForHandle(OBJECTHANDLE handle) = 0;
414+
virtual void* GetGlobalHandleStore() = 0;
415415

416-
virtual OBJECTHANDLE CreateHandleOfType(void* table, Object* object, int type) = 0;
416+
virtual void* CreateHandleStore(void* context) = 0;
417417

418-
virtual OBJECTHANDLE CreateHandleWithExtraInfo(void* table, Object* object, int type, void* pExtraInfo) = 0;
418+
virtual void DestroyHandleStore(void* store) = 0;
419419

420-
virtual OBJECTHANDLE CreateDependentHandle(void* table, Object* primary, Object* secondary) = 0;
420+
virtual void UprootHandleStore(void* store) = 0;
421+
422+
virtual bool ContainsHandle(void* store, OBJECTHANDLE handle) = 0;
423+
424+
virtual OBJECTHANDLE CreateHandleOfType(void* store, Object* object, int type) = 0;
425+
426+
virtual OBJECTHANDLE CreateHandleOfType(void* store, Object* object, int type, int heapToAffinitizeTo) = 0;
427+
428+
virtual OBJECTHANDLE CreateHandleWithExtraInfo(void* store, Object* object, int type, void* pExtraInfo) = 0;
429+
430+
virtual OBJECTHANDLE CreateDependentHandle(void* store, Object* primary, Object* secondary) = 0;
421431

422432
virtual OBJECTHANDLE CreateGlobalHandleOfType(Object* object, int type) = 0;
423433

434+
virtual OBJECTHANDLE CreateDuplicateHandle(OBJECTHANDLE handle) = 0;
435+
424436
virtual void DestroyHandleOfType(OBJECTHANDLE handle, int type) = 0;
425437

426438
virtual void DestroyHandleOfUnknownType(OBJECTHANDLE handle) = 0;

src/gc/handletable.cpp

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1338,24 +1338,6 @@ void Ref_RelocateAsyncPinHandles(HandleTableBucket *pSource, HandleTableBucket
13381338
}
13391339
#endif // !FEATURE_REDHAWK
13401340

1341-
BOOL Ref_ContainHandle(HandleTableBucket *pBucket, OBJECTHANDLE handle)
1342-
{
1343-
CONTRACTL
1344-
{
1345-
NOTHROW;
1346-
GC_NOTRIGGER;
1347-
}
1348-
CONTRACTL_END;
1349-
1350-
int limit = getNumberOfSlots();
1351-
for (int n = 0; n < limit; n ++ )
1352-
{
1353-
if (TableContainHandle(Table(pBucket->pTable[n]), handle))
1354-
return TRUE;
1355-
}
1356-
1357-
return FALSE;
1358-
}
13591341
/*--------------------------------------------------------------------------*/
13601342

13611343

src/gc/objecthandle.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,6 @@ BOOL Ref_HandleAsyncPinHandles();
111111
void Ref_RelocateAsyncPinHandles(HandleTableBucket *pSource, HandleTableBucket *pTarget);
112112
void Ref_RemoveHandleTableBucket(HandleTableBucket *pBucket);
113113
void Ref_DestroyHandleTableBucket(HandleTableBucket *pBucket);
114-
BOOL Ref_ContainHandle(HandleTableBucket *pBucket, OBJECTHANDLE handle);
115114

116115
/*
117116
* GC-time scanning entrypoints

src/vm/appdomain.cpp

Lines changed: 21 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -740,10 +740,10 @@ BaseDomain::BaseDomain()
740740
m_pLargeHeapHandleTable = NULL;
741741

742742
#ifndef CROSSGEN_COMPILE
743-
// Note that m_hHandleTableBucket is overridden by app domains
744-
m_hHandleTableBucket = g_HandleTableMap.pBuckets[0];
743+
// Note that m_handleStore is overridden by app domains
744+
m_handleStore = GCHandleTableUtilities::GetGCHandleTable()->GetGlobalHandleStore();
745745
#else
746-
m_hHandleTableBucket = NULL;
746+
m_handleStore = NULL;
747747
#endif
748748

749749
m_pMarshalingData = NULL;
@@ -993,17 +993,6 @@ void BaseDomain::InitVSD()
993993
}
994994

995995
#ifndef CROSSGEN_COMPILE
996-
BOOL BaseDomain::ContainsOBJECTHANDLE(OBJECTHANDLE handle)
997-
{
998-
CONTRACTL
999-
{
1000-
NOTHROW;
1001-
GC_NOTRIGGER;
1002-
}
1003-
CONTRACTL_END;
1004-
1005-
return Ref_ContainHandle(m_hHandleTableBucket,handle);
1006-
}
1007996

1008997
DWORD BaseDomain::AllocateContextStaticsOffset(DWORD* pOffsetSlot)
1009998
{
@@ -4053,7 +4042,7 @@ AppDomain::AppDomain()
40534042
m_pUMEntryThunkCache = NULL;
40544043

40554044
m_pAsyncPool = NULL;
4056-
m_hHandleTableBucket = NULL;
4045+
m_handleStore = NULL;
40574046

40584047
m_ExposedObject = NULL;
40594048
m_pComIPForExposedObject = NULL;
@@ -4284,18 +4273,13 @@ void AppDomain::Init()
42844273
// default domain cannot be unloaded.
42854274
if (GetId().m_dwId == DefaultADID)
42864275
{
4287-
m_hHandleTableBucket = g_HandleTableMap.pBuckets[0];
4276+
m_handleStore = GCHandleTableUtilities::GetGCHandleTable()->GetGlobalHandleStore();
42884277
}
42894278
else
42904279
{
4291-
m_hHandleTableBucket = Ref_CreateHandleTableBucket(m_dwIndex);
4280+
m_handleStore = GCHandleTableUtilities::GetGCHandleTable()->CreateHandleStore((void*)(uintptr_t)m_dwIndex.m_dwIndex);
42924281
}
42934282

4294-
#ifdef _DEBUG
4295-
if (((HandleTable *)(m_hHandleTableBucket->pTable[0]))->uADIndex != m_dwIndex)
4296-
_ASSERTE (!"AD index mismatch");
4297-
#endif // _DEBUG
4298-
42994283
#endif // CROSSGEN_COMPILE
43004284

43014285
#ifdef FEATURE_TYPEEQUIVALENCE
@@ -4594,16 +4578,10 @@ void AppDomain::Terminate()
45944578

45954579
BaseDomain::Terminate();
45964580

4597-
#ifdef _DEBUG
4598-
if (m_hHandleTableBucket &&
4599-
m_hHandleTableBucket->pTable &&
4600-
((HandleTable *)(m_hHandleTableBucket->pTable[0]))->uADIndex != m_dwIndex)
4601-
_ASSERTE (!"AD index mismatch");
4602-
#endif // _DEBUG
4603-
4604-
if (m_hHandleTableBucket) {
4605-
Ref_DestroyHandleTableBucket(m_hHandleTableBucket);
4606-
m_hHandleTableBucket = NULL;
4581+
if (m_handleStore)
4582+
{
4583+
GCHandleTableUtilities::GetGCHandleTable()->DestroyHandleStore(m_handleStore);
4584+
m_handleStore = NULL;
46074585
}
46084586

46094587
#ifdef FEATURE_APPDOMAIN_RESOURCE_MONITORING
@@ -9220,14 +9198,7 @@ void AppDomain::ClearGCHandles()
92209198
HandleAsyncPinHandles();
92219199

92229200
// Remove our handle table as a source of GC roots
9223-
HandleTableBucket *pBucket = m_hHandleTableBucket;
9224-
9225-
#ifdef _DEBUG
9226-
if (((HandleTable *)(pBucket->pTable[0]))->uADIndex != m_dwIndex)
9227-
_ASSERTE (!"AD index mismatch");
9228-
#endif // _DEBUG
9229-
9230-
Ref_RemoveHandleTableBucket(pBucket);
9201+
GCHandleTableUtilities::GetGCHandleTable()->UprootHandleStore(m_handleStore);
92319202
}
92329203

92339204
// When an AD is unloaded, we will release all objects in this AD.
@@ -9243,13 +9214,17 @@ void AppDomain::HandleAsyncPinHandles()
92439214
}
92449215
CONTRACTL_END;
92459216

9246-
HandleTableBucket *pBucket = m_hHandleTableBucket;
9217+
// TODO: Temporarily casting stuff here until Ref_RelocateAsyncPinHandles is moved to the interface.
9218+
HandleTableBucket *pBucket = (HandleTableBucket*)m_handleStore;
9219+
92479220
// IO completion port picks IO job using FIFO. Here is how we know which AsyncPinHandle can be freed.
92489221
// 1. We mark all non-pending AsyncPinHandle with READYTOCLEAN.
92499222
// 2. We queue a dump Overlapped to the IO completion as a marker.
92509223
// 3. When the Overlapped is picked up by completion port, we wait until all previous IO jobs are processed.
92519224
// 4. Then we can delete all AsyncPinHandle marked with READYTOCLEAN.
9252-
HandleTableBucket *pBucketInDefault = SystemDomain::System()->DefaultDomain()->m_hHandleTableBucket;
9225+
HandleTableBucket *pBucketInDefault = (HandleTableBucket*)SystemDomain::System()->DefaultDomain()->m_handleStore;
9226+
9227+
// TODO: When this function is moved to the interface it will take void*s
92539228
Ref_RelocateAsyncPinHandles(pBucket, pBucketInDefault);
92549229

92559230
OverlappedDataObject::RequestCleanup();
@@ -9272,14 +9247,15 @@ void AppDomain::ClearGCRoots()
92729247
// this point, so only need to synchronize the preemptive mode threads.
92739248
ExecutionManager::Unload(GetLoaderAllocator());
92749249

9250+
IGCHandleTable* pHandleTable = GCHandleTableUtilities::GetGCHandleTable();
9251+
92759252
while ((pThread = ThreadStore::GetAllThreadList(pThread, 0, 0)) != NULL)
92769253
{
92779254
// Delete the thread local static store
92789255
pThread->DeleteThreadStaticData(this);
92799256

9280-
92819257
// <TODO>@TODO: A pre-allocated AppDomainUnloaded exception might be better.</TODO>
9282-
if (m_hHandleTableBucket->Contains(pThread->m_LastThrownObjectHandle))
9258+
if (pHandleTable->ContainsHandle(m_handleStore, pThread->m_LastThrownObjectHandle))
92839259
{
92849260
// Never delete a handle to a preallocated exception object.
92859261
if (!CLRException::IsPreallocatedExceptionHandle(pThread->m_LastThrownObjectHandle))
@@ -9291,7 +9267,7 @@ void AppDomain::ClearGCRoots()
92919267
}
92929268

92939269
// Clear out the exceptions objects held by a thread.
9294-
pThread->GetExceptionState()->ClearThrowablesForUnload(m_hHandleTableBucket);
9270+
pThread->GetExceptionState()->ClearThrowablesForUnload(m_handleStore);
92959271
}
92969272

92979273
//delete them while we still have the runtime suspended

0 commit comments

Comments
 (0)