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

Commit bece89e

Browse files
Merge pull request #11033 from adityamandaleeka/handle_table_local_gc_store
Move handle object manipulation functions to interface
2 parents c111a57 + b560ecc commit bece89e

File tree

9 files changed

+90
-54
lines changed

9 files changed

+90
-54
lines changed

src/gc/gc.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34218,7 +34218,7 @@ bool GCHeap::StressHeap(gc_alloc_context * context)
3421834218
if (g_pConfig->AppDomainLeaks() && str->SetAppDomainNoThrow())
3421934219
{
3422034220
#endif
34221-
StoreObjectInHandle(m_StressObjs[i], ObjectToOBJECTREF(str));
34221+
HndAssignHandle(m_StressObjs[i], ObjectToOBJECTREF(str));
3422234222
#if CHECK_APP_DOMAIN_LEAKS
3422334223
}
3422434224
#endif
@@ -34251,7 +34251,7 @@ bool GCHeap::StressHeap(gc_alloc_context * context)
3425134251
{
3425234252
// Let the string itself become garbage.
3425334253
// will be realloced next time around
34254-
StoreObjectInHandle(m_StressObjs[m_CurStressObj], 0);
34254+
HndAssignHandle(m_StressObjs[m_CurStressObj], 0);
3425534255
}
3425634256
}
3425734257
}

src/gc/gchandletable.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,3 +132,18 @@ void* GCHandleManager::GetExtraInfoFromHandle(OBJECTHANDLE handle)
132132
{
133133
return (void*)::HndGetHandleExtraInfo(handle);
134134
}
135+
136+
void GCHandleManager::StoreObjectInHandle(OBJECTHANDLE handle, Object* object)
137+
{
138+
::HndAssignHandle(handle, ObjectToOBJECTREF(object));
139+
}
140+
141+
bool GCHandleManager::StoreObjectInHandleIfNull(OBJECTHANDLE handle, Object* object)
142+
{
143+
return !!::HndFirstAssignHandle(handle, ObjectToOBJECTREF(object));
144+
}
145+
146+
Object* GCHandleManager::InterlockedCompareExchangeObjectInHandle(OBJECTHANDLE handle, Object* object, Object* comparandObject)
147+
{
148+
return (Object*)::HndInterlockedCompareExchangeHandle(handle, ObjectToOBJECTREF(object), ObjectToOBJECTREF(comparandObject));
149+
}

src/gc/gchandletableimpl.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,12 @@ class GCHandleManager : public IGCHandleManager
5454
virtual void DestroyHandleOfUnknownType(OBJECTHANDLE handle);
5555

5656
virtual void* GetExtraInfoFromHandle(OBJECTHANDLE handle);
57+
58+
virtual void StoreObjectInHandle(OBJECTHANDLE handle, Object* object);
59+
60+
virtual bool StoreObjectInHandleIfNull(OBJECTHANDLE handle, Object* object);
61+
62+
virtual Object* InterlockedCompareExchangeObjectInHandle(OBJECTHANDLE handle, Object* object, Object* comparandObject);
5763
};
5864

5965
#endif // GCHANDLETABLE_H_

src/gc/gcinterface.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -444,6 +444,12 @@ class IGCHandleManager {
444444
virtual void DestroyHandleOfUnknownType(OBJECTHANDLE handle) = 0;
445445

446446
virtual void* GetExtraInfoFromHandle(OBJECTHANDLE handle) = 0;
447+
448+
virtual void StoreObjectInHandle(OBJECTHANDLE handle, Object* object) = 0;
449+
450+
virtual bool StoreObjectInHandleIfNull(OBJECTHANDLE handle, Object* object) = 0;
451+
452+
virtual Object* InterlockedCompareExchangeObjectInHandle(OBJECTHANDLE handle, Object* object, Object* comparandObject) = 0;
447453
};
448454

449455
// IGCHeap is the interface that the VM will use when interacting with the GC.

src/gc/handletable.inl

Lines changed: 0 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -22,13 +22,6 @@ inline void HndAssignHandle(OBJECTHANDLE handle, OBJECTREF objref)
2222
// sanity
2323
_ASSERTE(handle);
2424

25-
#ifdef _DEBUG_IMPL
26-
// handle should not be in unloaded domain
27-
ValidateAppDomainForHandle(handle);
28-
29-
// Make sure the objref is valid before it is assigned to a handle
30-
ValidateAssignObjrefForHandle(objref, HndGetHandleTableADIndex(HndGetHandleTable(handle)));
31-
#endif
3225
// unwrap the objectref we were given
3326
_UNCHECKED_OBJECTREF value = OBJECTREF_TO_UNCHECKED_OBJECTREF(objref);
3427

@@ -49,13 +42,6 @@ inline void* HndInterlockedCompareExchangeHandle(OBJECTHANDLE handle, OBJECTREF
4942
// sanity
5043
_ASSERTE(handle);
5144

52-
#ifdef _DEBUG_IMPL
53-
// handle should not be in unloaded domain
54-
ValidateAppDomainForHandle(handle);
55-
56-
// Make sure the objref is valid before it is assigned to a handle
57-
ValidateAssignObjrefForHandle(objref, HndGetHandleTableADIndex(HndGetHandleTable(handle)));
58-
#endif
5945
// unwrap the objectref we were given
6046
_UNCHECKED_OBJECTREF value = OBJECTREF_TO_UNCHECKED_OBJECTREF(objref);
6147
_UNCHECKED_OBJECTREF oldValue = OBJECTREF_TO_UNCHECKED_OBJECTREF(oldObjref);
@@ -88,13 +74,6 @@ inline BOOL HndFirstAssignHandle(OBJECTHANDLE handle, OBJECTREF objref)
8874
// sanity
8975
_ASSERTE(handle);
9076

91-
#ifdef _DEBUG_IMPL
92-
// handle should not be in unloaded domain
93-
ValidateAppDomainForHandle(handle);
94-
95-
// Make sure the objref is valid before it is assigned to a handle
96-
ValidateAssignObjrefForHandle(objref, HndGetHandleTableADIndex(HndGetHandleTable(handle)));
97-
#endif
9877
// unwrap the objectref we were given
9978
_UNCHECKED_OBJECTREF value = OBJECTREF_TO_UNCHECKED_OBJECTREF(objref);
10079
_UNCHECKED_OBJECTREF null = NULL;

src/gc/objecthandle.h

Lines changed: 0 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -21,16 +21,6 @@
2121
#include <weakreference.h>
2222
#endif // FEATURE_COMINTEROP
2323

24-
/*
25-
* Convenience macros for accessing handles. StoreFirstObjectInHandle is like
26-
* StoreObjectInHandle, except it only succeeds if transitioning from NULL to
27-
* non-NULL. In other words, if this handle is being initialized for the first
28-
* time.
29-
*/
30-
#define StoreObjectInHandle(handle, object) HndAssignHandle(handle, object)
31-
#define InterlockedCompareExchangeObjectInHandle(handle, object, oldObj) HndInterlockedCompareExchangeHandle(handle, object, oldObj)
32-
#define StoreFirstObjectInHandle(handle, object) HndFirstAssignHandle(handle, object)
33-
3424
typedef DPTR(struct HandleTableMap) PTR_HandleTableMap;
3525
typedef DPTR(struct HandleTableBucket) PTR_HandleTableBucket;
3626
typedef DPTR(PTR_HandleTableBucket) PTR_PTR_HandleTableBucket;
@@ -90,17 +80,6 @@ void GCHandleValidatePinnedObject(OBJECTREF obj);
9080

9181
int GetCurrentThreadHomeHeapNumber();
9282

93-
inline void ResetOBJECTHANDLE(OBJECTHANDLE handle)
94-
{
95-
WRAPPER_NO_CONTRACT;
96-
97-
StoreObjectInHandle(handle, NULL);
98-
}
99-
100-
#ifndef FEATURE_REDHAWK
101-
typedef Holder<OBJECTHANDLE,DoNothing<OBJECTHANDLE>,ResetOBJECTHANDLE> ObjectInHandleHolder;
102-
#endif
103-
10483
/*
10584
* Table maintenance routines
10685
*/

src/vm/appdomain.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4679,7 +4679,8 @@ OBJECTREF AppDomain::GetExposedObject()
46794679
obj = (APPDOMAINREF) AllocateObject(pMT);
46804680
obj->SetDomain(this);
46814681

4682-
if(StoreFirstObjectInHandle(m_ExposedObject, (OBJECTREF) obj) == FALSE) {
4682+
if (!StoreFirstObjectInHandle(m_ExposedObject, (OBJECTREF) obj))
4683+
{
46834684
obj = (APPDOMAINREF) GetRawExposedObject();
46844685
_ASSERTE(obj);
46854686
}

src/vm/gchandleutilities.h

Lines changed: 35 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,15 +30,19 @@ class GCHandleUtilities
3030
GCHandleUtilities() = delete;
3131
};
3232

33-
void ValidateHandleAndAppDomain(OBJECTHANDLE handle);
33+
void ValidateObjectAndAppDomain(OBJECTREF objRef, ADIndex appDomainIndex);
34+
void ValidateHandleAssignment(OBJECTHANDLE handle, OBJECTREF objRef);
3435

3536
// Given a handle, returns an OBJECTREF for the object it refers to.
3637
inline OBJECTREF ObjectFromHandle(OBJECTHANDLE handle)
3738
{
3839
_ASSERTE(handle);
3940

4041
#ifdef _DEBUG_IMPL
41-
ValidateHandleAndAppDomain(handle);
42+
DWORD context = (DWORD)GCHandleUtilities::GetGCHandleManager()->GetHandleContext(handle);
43+
OBJECTREF objRef = ObjectToOBJECTREF(*(Object**)handle);
44+
45+
ValidateObjectAndAppDomain(objRef, ADIndex(context));
4246
#endif // _DEBUG_IMPL
4347

4448
// Wrap the raw OBJECTREF and return it
@@ -169,6 +173,34 @@ inline OBJECTHANDLE CreateVariableHandle(IGCHandleStore* store, OBJECTREF object
169173
return store->CreateHandleWithExtraInfo(OBJECTREFToObject(object), HNDTYPE_VARIABLE, (void*)((uintptr_t)type));
170174
}
171175

176+
// Handle object manipulation convenience functions
177+
178+
inline void StoreObjectInHandle(OBJECTHANDLE handle, OBJECTREF object)
179+
{
180+
ValidateHandleAssignment(handle, object);
181+
182+
GCHandleUtilities::GetGCHandleManager()->StoreObjectInHandle(handle, OBJECTREFToObject(object));
183+
}
184+
185+
inline bool StoreFirstObjectInHandle(OBJECTHANDLE handle, OBJECTREF object)
186+
{
187+
ValidateHandleAssignment(handle, object);
188+
189+
return GCHandleUtilities::GetGCHandleManager()->StoreObjectInHandleIfNull(handle, OBJECTREFToObject(object));
190+
}
191+
192+
inline void* InterlockedCompareExchangeObjectInHandle(OBJECTHANDLE handle, OBJECTREF object, OBJECTREF comparandObject)
193+
{
194+
ValidateHandleAssignment(handle, object);
195+
196+
return GCHandleUtilities::GetGCHandleManager()->InterlockedCompareExchangeObjectInHandle(handle, OBJECTREFToObject(object), OBJECTREFToObject(comparandObject));
197+
}
198+
199+
inline void ResetOBJECTHANDLE(OBJECTHANDLE handle)
200+
{
201+
GCHandleUtilities::GetGCHandleManager()->StoreObjectInHandle(handle, NULL);
202+
}
203+
172204
// Handle destruction convenience functions
173205

174206
inline void DestroyHandle(OBJECTHANDLE handle)
@@ -309,6 +341,7 @@ typedef Wrapper<OBJECTHANDLE, DoNothing<OBJECTHANDLE>, DestroyRefcountedHandle>
309341
typedef Holder<OBJECTHANDLE, DoNothing<OBJECTHANDLE>, DestroyLongWeakHandle> LongWeakHandleHolder;
310342
typedef Holder<OBJECTHANDLE, DoNothing<OBJECTHANDLE>, DestroyGlobalStrongHandle> GlobalStrongHandleHolder;
311343
typedef Holder<OBJECTHANDLE, DoNothing<OBJECTHANDLE>, DestroyGlobalShortWeakHandle> GlobalShortWeakHandleHolder;
344+
typedef Holder<OBJECTHANDLE, DoNothing<OBJECTHANDLE>, ResetOBJECTHANDLE> ObjectInHandleHolder;
312345

313346
class RCOBJECTHANDLEHolder : public RefCountedOHWrapper
314347
{

src/vm/gcheaputilities.cpp

Lines changed: 24 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -40,17 +40,12 @@ bool g_sw_ww_enabled_for_gc_heap = false;
4040
gc_alloc_context g_global_alloc_context = {};
4141

4242
// Debug-only validation for handle.
43-
void ValidateHandleAndAppDomain(OBJECTHANDLE handle)
43+
44+
void ValidateObjectAndAppDomain(OBJECTREF objRef, ADIndex appDomainIndex)
4445
{
4546
#ifdef _DEBUG_IMPL
46-
OBJECTREF objRef = ObjectToOBJECTREF(*(Object**)handle);
4747
VALIDATEOBJECTREF(objRef);
4848

49-
IGCHandleManager *pHandleManager = GCHandleUtilities::GetGCHandleManager();
50-
51-
DWORD context = (DWORD)pHandleManager->GetHandleContext(handle);
52-
53-
ADIndex appDomainIndex = ADIndex(context);
5449
AppDomain *domain = SystemDomain::GetAppDomainAtIndex(appDomainIndex);
5550

5651
// Access to a handle in an unloaded domain is not allowed
@@ -72,3 +67,25 @@ void ValidateHandleAndAppDomain(OBJECTHANDLE handle)
7267
#endif // CHECK_APP_DOMAIN_LEAKS
7368
#endif // _DEBUG_IMPL
7469
}
70+
71+
void ValidateHandleAssignment(OBJECTHANDLE handle, OBJECTREF objRef)
72+
{
73+
#ifdef _DEBUG_IMPL
74+
_ASSERTE(handle);
75+
76+
#ifdef DEBUG_DestroyedHandleValue
77+
// Verify that we are not trying to access a freed handle.
78+
_ASSERTE("Attempt to access destroyed handle." && *(_UNCHECKED_OBJECTREF*)handle != DEBUG_DestroyedHandleValue);
79+
#endif
80+
81+
ADIndex appDomainIndex = HndGetHandleADIndex(handle);
82+
83+
AppDomain *unloadingDomain = SystemDomain::AppDomainBeingUnloaded();
84+
if (unloadingDomain && unloadingDomain->GetIndex() == appDomainIndex && unloadingDomain->NoAccessToHandleTable())
85+
{
86+
_ASSERTE (!"Access to a handle in unloaded domain is not allowed");
87+
}
88+
89+
ValidateObjectAndAppDomain(objRef, appDomainIndex);
90+
#endif // _DEBUG_IMPL
91+
}

0 commit comments

Comments
 (0)