#include "gchandletableimpl.h"
#include "objecthandle.h"
+GCHandleStore* g_gcGlobalHandleStore;
+
IGCHandleTable* CreateGCHandleTable()
{
- return new(nothrow) GCHandleTable();
+ return new (nothrow) GCHandleTable();
}
-bool GCHandleTable::Initialize()
+void GCHandleStore::Uproot()
{
- return Ref_Initialize();
+ Ref_RemoveHandleTableBucket(_underlyingBucket);
}
-void GCHandleTable::Shutdown()
+bool GCHandleStore::ContainsHandle(OBJECTHANDLE handle)
{
- Ref_Shutdown();
+ return _underlyingBucket->Contains(handle);
}
-void* GCHandleTable::GetGlobalHandleStore()
+OBJECTHANDLE GCHandleStore::CreateHandleOfType(Object* object, int type)
{
- return (void*)g_HandleTableMap.pBuckets[0];
+ HHANDLETABLE handletable = _underlyingBucket->pTable[GetCurrentThreadHomeHeapNumber()];
+ return ::HndCreateHandle(handletable, type, ObjectToOBJECTREF(object));
}
-void* GCHandleTable::CreateHandleStore(void* context)
+OBJECTHANDLE GCHandleStore::CreateHandleOfType(Object* object, int type, int heapToAffinitizeTo)
{
-#ifndef FEATURE_REDHAWK
- return (void*)::Ref_CreateHandleTableBucket(ADIndex((DWORD)(uintptr_t)context));
-#else
- assert("CreateHandleStore is not implemented when FEATURE_REDHAWK is defined!");
- return nullptr;
-#endif
+ HHANDLETABLE handletable = _underlyingBucket->pTable[heapToAffinitizeTo];
+ return ::HndCreateHandle(handletable, type, ObjectToOBJECTREF(object));
}
-void* GCHandleTable::GetHandleContext(OBJECTHANDLE handle)
+OBJECTHANDLE GCHandleStore::CreateHandleWithExtraInfo(Object* object, int type, void* pExtraInfo)
{
- return (void*)((uintptr_t)::HndGetHandleTableADIndex(::HndGetHandleTable(handle)).m_dwIndex);
+ HHANDLETABLE handletable = _underlyingBucket->pTable[GetCurrentThreadHomeHeapNumber()];
+ return ::HndCreateHandle(handletable, type, ObjectToOBJECTREF(object), reinterpret_cast<uintptr_t>(pExtraInfo));
}
-void GCHandleTable::DestroyHandleStore(void* store)
+OBJECTHANDLE GCHandleStore::CreateDependentHandle(Object* primary, Object* secondary)
{
- Ref_DestroyHandleTableBucket((HandleTableBucket*) store);
+ HHANDLETABLE handletable = _underlyingBucket->pTable[GetCurrentThreadHomeHeapNumber()];
+ OBJECTHANDLE handle = ::HndCreateHandle(handletable, HNDTYPE_DEPENDENT, ObjectToOBJECTREF(primary));
+ ::SetDependentHandleSecondary(handle, ObjectToOBJECTREF(secondary));
+
+ return handle;
}
-void GCHandleTable::UprootHandleStore(void* store)
+GCHandleStore::~GCHandleStore()
{
- Ref_RemoveHandleTableBucket((HandleTableBucket*) store);
+ Ref_DestroyHandleTableBucket(_underlyingBucket);
}
-bool GCHandleTable::ContainsHandle(void* store, OBJECTHANDLE handle)
+bool GCHandleTable::Initialize()
{
- return ((HandleTableBucket*)store)->Contains(handle);
+ return Ref_Initialize();
}
-OBJECTHANDLE GCHandleTable::CreateHandleOfType(void* store, Object* object, int type)
+void GCHandleTable::Shutdown()
{
- HHANDLETABLE handletable = ((HandleTableBucket*)store)->pTable[GetCurrentThreadHomeHeapNumber()];
- return ::HndCreateHandle(handletable, type, ObjectToOBJECTREF(object));
+ Ref_Shutdown();
}
-OBJECTHANDLE GCHandleTable::CreateHandleOfType(void* store, Object* object, int type, int heapToAffinitizeTo)
+IGCHandleStore* GCHandleTable::GetGlobalHandleStore()
{
- HHANDLETABLE handletable = ((HandleTableBucket*)store)->pTable[heapToAffinitizeTo];
- return ::HndCreateHandle(handletable, type, ObjectToOBJECTREF(object));
+ return g_gcGlobalHandleStore;
}
-OBJECTHANDLE GCHandleTable::CreateGlobalHandleOfType(Object* object, int type)
+IGCHandleStore* GCHandleTable::CreateHandleStore(void* context)
{
- return ::HndCreateHandle(g_HandleTableMap.pBuckets[0]->pTable[GetCurrentThreadHomeHeapNumber()], type, ObjectToOBJECTREF(object));
+#ifndef FEATURE_REDHAWK
+ HandleTableBucket* newBucket = ::Ref_CreateHandleTableBucket(ADIndex((DWORD)(uintptr_t)context));
+ return new (nothrow) GCHandleStore(newBucket);
+#else
+ assert("CreateHandleStore is not implemented when FEATURE_REDHAWK is defined!");
+ return nullptr;
+#endif
}
-OBJECTHANDLE GCHandleTable::CreateHandleWithExtraInfo(void* store, Object* object, int type, void* pExtraInfo)
+void GCHandleTable::DestroyHandleStore(IGCHandleStore* store)
{
- HHANDLETABLE handletable = ((HandleTableBucket*)store)->pTable[GetCurrentThreadHomeHeapNumber()];
- return ::HndCreateHandle(handletable, type, ObjectToOBJECTREF(object), reinterpret_cast<uintptr_t>(pExtraInfo));
+ delete store;
}
-OBJECTHANDLE GCHandleTable::CreateDependentHandle(void* store, Object* primary, Object* secondary)
+void* GCHandleTable::GetHandleContext(OBJECTHANDLE handle)
{
- HHANDLETABLE handletable = ((HandleTableBucket*)store)->pTable[GetCurrentThreadHomeHeapNumber()];
- OBJECTHANDLE handle = ::HndCreateHandle(handletable, HNDTYPE_DEPENDENT, ObjectToOBJECTREF(primary));
- ::SetDependentHandleSecondary(handle, ObjectToOBJECTREF(secondary));
+ return (void*)((uintptr_t)::HndGetHandleTableADIndex(::HndGetHandleTable(handle)).m_dwIndex);
+}
- return handle;
+OBJECTHANDLE GCHandleTable::CreateGlobalHandleOfType(Object* object, int type)
+{
+ return ::HndCreateHandle(g_HandleTableMap.pBuckets[0]->pTable[GetCurrentThreadHomeHeapNumber()], type, ObjectToOBJECTREF(object));
}
OBJECTHANDLE GCHandleTable::CreateDuplicateHandle(OBJECTHANDLE handle)
#define GCHANDLETABLE_H_
#include "gcinterface.h"
+#include "objecthandle.h"
-class GCHandleTable : public IGCHandleTable
+class GCHandleStore : public IGCHandleStore
{
public:
- virtual bool Initialize();
+ GCHandleStore(HandleTableBucket *bucket)
+ : _underlyingBucket(bucket)
+ { }
- virtual void Shutdown();
+ virtual void Uproot();
- virtual void* GetGlobalHandleStore();
+ virtual bool ContainsHandle(OBJECTHANDLE handle);
- virtual void* CreateHandleStore(void* context);
+ virtual OBJECTHANDLE CreateHandleOfType(Object* object, int type);
- virtual void* GetHandleContext(OBJECTHANDLE handle);
+ virtual OBJECTHANDLE CreateHandleOfType(Object* object, int type, int heapToAffinitizeTo);
- virtual void DestroyHandleStore(void* store);
+ virtual OBJECTHANDLE CreateHandleWithExtraInfo(Object* object, int type, void* pExtraInfo);
- virtual void UprootHandleStore(void* store);
+ virtual OBJECTHANDLE CreateDependentHandle(Object* primary, Object* secondary);
- virtual bool ContainsHandle(void* store, OBJECTHANDLE handle);
+ virtual ~GCHandleStore();
- virtual OBJECTHANDLE CreateHandleOfType(void* store, Object* object, int type);
+private:
+ HandleTableBucket* _underlyingBucket;
+};
+
+extern GCHandleStore* g_gcGlobalHandleStore;
+
+class GCHandleTable : public IGCHandleTable
+{
+public:
+ virtual bool Initialize();
+
+ virtual void Shutdown();
+
+ virtual void* GetHandleContext(OBJECTHANDLE handle);
- virtual OBJECTHANDLE CreateHandleOfType(void* store, Object* object, int type, int heapToAffinitizeTo);
+ virtual IGCHandleStore* GetGlobalHandleStore();
- virtual OBJECTHANDLE CreateHandleWithExtraInfo(void* store, Object* object, int type, void* pExtraInfo);
+ virtual IGCHandleStore* CreateHandleStore(void* context);
- virtual OBJECTHANDLE CreateDependentHandle(void* store, Object* primary, Object* secondary);
+ virtual void DestroyHandleStore(IGCHandleStore* store);
virtual OBJECTHANDLE CreateGlobalHandleOfType(Object* object, int type);
typedef uintptr_t OBJECTHANDLE;
#endif
-class IGCHandleTable {
+class IGCHandleStore {
public:
- virtual bool Initialize() = 0;
+ virtual void Uproot() = 0;
- virtual void Shutdown() = 0;
+ virtual bool ContainsHandle(OBJECTHANDLE handle) = 0;
- virtual void* GetHandleContext(OBJECTHANDLE handle) = 0;
+ virtual OBJECTHANDLE CreateHandleOfType(Object* object, int type) = 0;
+
+ virtual OBJECTHANDLE CreateHandleOfType(Object* object, int type, int heapToAffinitizeTo) = 0;
+
+ virtual OBJECTHANDLE CreateHandleWithExtraInfo(Object* object, int type, void* pExtraInfo) = 0;
- virtual void* GetGlobalHandleStore() = 0;
+ virtual OBJECTHANDLE CreateDependentHandle(Object* primary, Object* secondary) = 0;
- virtual void* CreateHandleStore(void* context) = 0;
+ virtual ~IGCHandleStore() {};
+};
- virtual void DestroyHandleStore(void* store) = 0;
+class IGCHandleTable {
+public:
- virtual void UprootHandleStore(void* store) = 0;
+ virtual bool Initialize() = 0;
- virtual bool ContainsHandle(void* store, OBJECTHANDLE handle) = 0;
+ virtual void Shutdown() = 0;
- virtual OBJECTHANDLE CreateHandleOfType(void* store, Object* object, int type) = 0;
+ virtual void* GetHandleContext(OBJECTHANDLE handle) = 0;
- virtual OBJECTHANDLE CreateHandleOfType(void* store, Object* object, int type, int heapToAffinitizeTo) = 0;
+ virtual IGCHandleStore* GetGlobalHandleStore() = 0;
- virtual OBJECTHANDLE CreateHandleWithExtraInfo(void* store, Object* object, int type, void* pExtraInfo) = 0;
+ virtual IGCHandleStore* CreateHandleStore(void* context) = 0;
- virtual OBJECTHANDLE CreateDependentHandle(void* store, Object* primary, Object* secondary) = 0;
+ virtual void DestroyHandleStore(IGCHandleStore* store) = 0;
virtual OBJECTHANDLE CreateGlobalHandleOfType(Object* object, int type) = 0;
overlapped->m_userObject = NULL;
}
BashMTForPinnedObject(ObjectToOBJECTREF(value));
- overlapped->m_pinSelf = CreateAsyncPinningHandle((HHANDLETABLE)pTargetTable,ObjectToOBJECTREF(value));
+
+ overlapped->m_pinSelf = HndCreateHandle((HHANDLETABLE)pTargetTable, HNDTYPE_ASYNCPINNED, ObjectToOBJECTREF(value));
*pValue = NULL;
}
pValue ++;
#include "objecthandle.h"
#include "handletablepriv.h"
+#include "gchandletableimpl.h"
+
#ifdef FEATURE_COMINTEROP
#include "comcallablewrapper.h"
#endif // FEATURE_COMINTEROP
g_HandleTableMap.dwMaxIndex = INITIAL_HANDLE_TABLE_ARRAY_SIZE;
g_HandleTableMap.pNext = NULL;
+ g_gcGlobalHandleStore = new (nothrow) GCHandleStore(g_HandleTableMap.pBuckets[0]);
+ if (g_gcGlobalHandleStore == NULL)
+ goto CleanupAndFail;
+
// 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];
return true;
}
+
CleanupAndFail:
if (pBuckets != NULL)
delete[] pBuckets;
BaseDomain::Terminate();
- if (m_handleStore)
+ if (m_handleStore)
{
GCHandleTableUtilities::GetGCHandleTable()->DestroyHandleStore(m_handleStore);
m_handleStore = NULL;
// Keep async pin handles alive by moving them to default domain
HandleAsyncPinHandles();
- // Remove our handle table as a source of GC roots
- GCHandleTableUtilities::GetGCHandleTable()->UprootHandleStore(m_handleStore);
+ // Remove our handle store as a source of GC roots
+ m_handleStore->Uproot();
}
// When an AD is unloaded, we will release all objects in this AD.
// this point, so only need to synchronize the preemptive mode threads.
ExecutionManager::Unload(GetLoaderAllocator());
- IGCHandleTable* pHandleTable = GCHandleTableUtilities::GetGCHandleTable();
-
while ((pThread = ThreadStore::GetAllThreadList(pThread, 0, 0)) != NULL)
{
// Delete the thread local static store
pThread->DeleteThreadStaticData(this);
// <TODO>@TODO: A pre-allocated AppDomainUnloaded exception might be better.</TODO>
- if (pHandleTable->ContainsHandle(m_handleStore, pThread->m_LastThrownObjectHandle))
+ if (m_handleStore->ContainsHandle(pThread->m_LastThrownObjectHandle))
{
// Never delete a handle to a preallocated exception object.
if (!CLRException::IsPreallocatedExceptionHandle(pThread->m_LastThrownObjectHandle))
OBJECTHANDLE CreateTypedHandle(OBJECTREF object, int type)
{
WRAPPER_NO_CONTRACT;
-
- IGCHandleTable *pHandleTable = GCHandleTableUtilities::GetGCHandleTable();
- return pHandleTable->CreateHandleOfType(m_handleStore, OBJECTREFToObject(object), type);
+ return m_handleStore->CreateHandleOfType(OBJECTREFToObject(object), type);
}
OBJECTHANDLE CreateHandle(OBJECTREF object)
}
CONTRACTL_END;
- IGCHandleTable *pHandleTable = GCHandleTableUtilities::GetGCHandleTable();
- return pHandleTable->CreateDependentHandle(m_handleStore, OBJECTREFToObject(primary), OBJECTREFToObject(secondary));
+ return m_handleStore->CreateDependentHandle(OBJECTREFToObject(primary), OBJECTREFToObject(secondary));
}
#endif // DACCESS_COMPILE && !CROSSGEN_COMPILE
CLRPrivBinderCoreCLR *m_pTPABinderContext; // Reference to the binding context that holds TPA list details
- void* m_handleStore;
+ IGCHandleStore* m_handleStore;
// The large heap handle table.
LargeHeapHandleTable *m_pLargeHeapHandleTable;
}
}
-void ThreadExceptionState::ClearThrowablesForUnload(void* handleStore)
+void ThreadExceptionState::ClearThrowablesForUnload(IGCHandleStore* handleStore)
{
WRAPPER_NO_CONTRACT;
ExInfo* pNode = &m_currentExInfo;
#endif // WIN64EXCEPTIONS
- IGCHandleTable *pHandleTable = GCHandleTableUtilities::GetGCHandleTable();
-
for ( ;
pNode != NULL;
pNode = pNode->m_pPrevNestedInfo)
{
- if (pHandleTable->ContainsHandle(handleStore, pNode->m_hThrowable))
+ if (handleStore->ContainsHandle(pNode->m_hThrowable))
{
pNode->DestroyExceptionHandle();
}
public:
void FreeAllStackTraces();
- void ClearThrowablesForUnload(void* handleStore);
+ void ClearThrowablesForUnload(IGCHandleStore* handleStore);
#ifdef _DEBUG
typedef enum
// Handle creation convenience functions
-inline OBJECTHANDLE CreateHandle(void* table, OBJECTREF object)
+inline OBJECTHANDLE CreateHandle(IGCHandleStore* store, OBJECTREF object)
{
- return GCHandleTableUtilities::GetGCHandleTable()->CreateHandleOfType(table, OBJECTREFToObject(object), HNDTYPE_DEFAULT);
+ return store->CreateHandleOfType(OBJECTREFToObject(object), HNDTYPE_DEFAULT);
}
-inline OBJECTHANDLE CreateWeakHandle(void* table, OBJECTREF object)
+inline OBJECTHANDLE CreateWeakHandle(IGCHandleStore* store, OBJECTREF object)
{
- return GCHandleTableUtilities::GetGCHandleTable()->CreateHandleOfType(table, OBJECTREFToObject(object), HNDTYPE_WEAK_DEFAULT);
+ return store->CreateHandleOfType(OBJECTREFToObject(object), HNDTYPE_WEAK_DEFAULT);
}
-inline OBJECTHANDLE CreateShortWeakHandle(void* table, OBJECTREF object)
+inline OBJECTHANDLE CreateShortWeakHandle(IGCHandleStore* store, OBJECTREF object)
{
- return GCHandleTableUtilities::GetGCHandleTable()->CreateHandleOfType(table, OBJECTREFToObject(object), HNDTYPE_WEAK_SHORT);
+ return store->CreateHandleOfType(OBJECTREFToObject(object), HNDTYPE_WEAK_SHORT);
}
-inline OBJECTHANDLE CreateLongWeakHandle(void* table, OBJECTREF object)
+inline OBJECTHANDLE CreateLongWeakHandle(IGCHandleStore* store, OBJECTREF object)
{
- return GCHandleTableUtilities::GetGCHandleTable()->CreateHandleOfType(table, OBJECTREFToObject(object), HNDTYPE_WEAK_LONG);
+ return store->CreateHandleOfType(OBJECTREFToObject(object), HNDTYPE_WEAK_LONG);
}
-inline OBJECTHANDLE CreateStrongHandle(void* table, OBJECTREF object)
+inline OBJECTHANDLE CreateStrongHandle(IGCHandleStore* store, OBJECTREF object)
{
- return GCHandleTableUtilities::GetGCHandleTable()->CreateHandleOfType(table, OBJECTREFToObject(object), HNDTYPE_STRONG);
+ return store->CreateHandleOfType(OBJECTREFToObject(object), HNDTYPE_STRONG);
}
-inline OBJECTHANDLE CreatePinningHandle(void* table, OBJECTREF object)
+inline OBJECTHANDLE CreatePinningHandle(IGCHandleStore* store, OBJECTREF object)
{
- return GCHandleTableUtilities::GetGCHandleTable()->CreateHandleOfType(table, OBJECTREFToObject(object), HNDTYPE_PINNED);
+ return store->CreateHandleOfType(OBJECTREFToObject(object), HNDTYPE_PINNED);
}
-inline OBJECTHANDLE CreateAsyncPinningHandle(void* table, OBJECTREF object)
+inline OBJECTHANDLE CreateAsyncPinningHandle(IGCHandleStore* store, OBJECTREF object)
{
- return GCHandleTableUtilities::GetGCHandleTable()->CreateHandleOfType(table, OBJECTREFToObject(object), HNDTYPE_ASYNCPINNED);
+ return store->CreateHandleOfType(OBJECTREFToObject(object), HNDTYPE_ASYNCPINNED);
}
-inline OBJECTHANDLE CreateRefcountedHandle(void* table, OBJECTREF object)
+inline OBJECTHANDLE CreateRefcountedHandle(IGCHandleStore* store, OBJECTREF object)
{
- return GCHandleTableUtilities::GetGCHandleTable()->CreateHandleOfType(table, OBJECTREFToObject(object), HNDTYPE_REFCOUNTED);
+ return store->CreateHandleOfType(OBJECTREFToObject(object), HNDTYPE_REFCOUNTED);
}
-inline OBJECTHANDLE CreateSizedRefHandle(void* table, OBJECTREF object)
+inline OBJECTHANDLE CreateSizedRefHandle(IGCHandleStore* store, OBJECTREF object)
{
- return GCHandleTableUtilities::GetGCHandleTable()->CreateHandleOfType(table, OBJECTREFToObject(object), HNDTYPE_SIZEDREF);
+ return store->CreateHandleOfType(OBJECTREFToObject(object), HNDTYPE_SIZEDREF);
}
-inline OBJECTHANDLE CreateSizedRefHandle(void* table, OBJECTREF object, int heapToAffinitizeTo)
+inline OBJECTHANDLE CreateSizedRefHandle(IGCHandleStore* store, OBJECTREF object, int heapToAffinitizeTo)
{
- return GCHandleTableUtilities::GetGCHandleTable()->CreateHandleOfType(table, OBJECTREFToObject(object), HNDTYPE_SIZEDREF, heapToAffinitizeTo);
+ return store->CreateHandleOfType(OBJECTREFToObject(object), HNDTYPE_SIZEDREF, heapToAffinitizeTo);
}
// Global handle creation convenience functions
// Special handle creation convenience functions
#ifdef FEATURE_COMINTEROP
-inline OBJECTHANDLE CreateWinRTWeakHandle(void* table, OBJECTREF object, IWeakReference* pWinRTWeakReference)
+inline OBJECTHANDLE CreateWinRTWeakHandle(IGCHandleStore* store, OBJECTREF object, IWeakReference* pWinRTWeakReference)
{
- return GCHandleTableUtilities::GetGCHandleTable()->CreateHandleWithExtraInfo(table,
- OBJECTREFToObject(object),
- HNDTYPE_WEAK_WINRT,
- (void*)pWinRTWeakReference);
+ return store->CreateHandleWithExtraInfo(OBJECTREFToObject(object), HNDTYPE_WEAK_WINRT, (void*)pWinRTWeakReference);
}
#endif // FEATURE_COMINTEROP
// Creates a variable-strength handle
-inline OBJECTHANDLE CreateVariableHandle(void* table, OBJECTREF object, uint32_t type)
+inline OBJECTHANDLE CreateVariableHandle(IGCHandleStore* store, OBJECTREF object, uint32_t type)
{
- return GCHandleTableUtilities::GetGCHandleTable()->CreateHandleWithExtraInfo(table,
- OBJECTREFToObject(object),
- HNDTYPE_VARIABLE,
- (void*)((uintptr_t)type));
+ return store->CreateHandleWithExtraInfo(OBJECTREFToObject(object), HNDTYPE_VARIABLE, (void*)((uintptr_t)type));
}
// Handle destruction convenience functions