return (void*)((uintptr_t)::HndGetHandleTableADIndex(::HndGetHandleTable(handle)).m_dwIndex);
}
+void GCHandleTable::DestroyHandleTable(void* table)
+{
+ Ref_DestroyHandleTableBucket((HandleTableBucket*) table);
+}
+
+void GCHandleTable::UprootHandleTable(void* table)
+{
+ Ref_RemoveHandleTableBucket((HandleTableBucket*) table);
+}
+
+bool GCHandleTable::ContainsHandle(void* table, OBJECTHANDLE handle)
+{
+ return ((HandleTableBucket*)table)->Contains(handle);
+}
+
OBJECTHANDLE GCHandleTable::CreateHandleOfType(void* table, Object* object, int type)
{
- return ::HndCreateHandle((HHANDLETABLE)table, type, ObjectToOBJECTREF(object));
+ HHANDLETABLE handletable = ((HandleTableBucket*)table)->pTable[GetCurrentThreadHomeHeapNumber()];
+ return ::HndCreateHandle(handletable, type, ObjectToOBJECTREF(object));
+}
+
+OBJECTHANDLE GCHandleTable::CreateHandleOfType(void* table, Object* object, int type, int heapToAffinitizeTo)
+{
+ HHANDLETABLE handletable = ((HandleTableBucket*)table)->pTable[heapToAffinitizeTo];
+ return ::HndCreateHandle(handletable, type, ObjectToOBJECTREF(object));
}
OBJECTHANDLE GCHandleTable::CreateGlobalHandleOfType(Object* object, int type)
OBJECTHANDLE GCHandleTable::CreateHandleWithExtraInfo(void* table, Object* object, int type, void* pExtraInfo)
{
- return ::HndCreateHandle((HHANDLETABLE)table, type, ObjectToOBJECTREF(object), reinterpret_cast<uintptr_t>(pExtraInfo));
+ HHANDLETABLE handletable = ((HandleTableBucket*)table)->pTable[GetCurrentThreadHomeHeapNumber()];
+ return ::HndCreateHandle(handletable, type, ObjectToOBJECTREF(object), reinterpret_cast<uintptr_t>(pExtraInfo));
}
OBJECTHANDLE GCHandleTable::CreateDependentHandle(void* table, Object* primary, Object* secondary)
{
- OBJECTHANDLE handle = ::HndCreateHandle((HHANDLETABLE)table, HNDTYPE_DEPENDENT, ObjectToOBJECTREF(primary));
+ HHANDLETABLE handletable = ((HandleTableBucket*)table)->pTable[GetCurrentThreadHomeHeapNumber()];
+ OBJECTHANDLE handle = ::HndCreateHandle(handletable, HNDTYPE_DEPENDENT, ObjectToOBJECTREF(primary));
::SetDependentHandleSecondary(handle, ObjectToOBJECTREF(secondary));
return handle;
virtual void* GetHandleContext(OBJECTHANDLE handle);
+ virtual void DestroyHandleTable(void* table);
+
+ virtual void UprootHandleTable(void* table);
+
+ virtual bool ContainsHandle(void* table, OBJECTHANDLE handle);
+
virtual OBJECTHANDLE CreateHandleOfType(void* table, Object* object, int type);
+ virtual OBJECTHANDLE CreateHandleOfType(void* table, Object* object, int type, int heapToAffinitizeTo);
+
virtual OBJECTHANDLE CreateHandleWithExtraInfo(void* table, Object* object, int type, void* pExtraInfo);
virtual OBJECTHANDLE CreateDependentHandle(void* table, Object* primary, Object* secondary);
virtual void* GetNewHandleTable(void* context) = 0;
+ virtual void DestroyHandleTable(void* table) = 0;
+
+ virtual void UprootHandleTable(void* table) = 0;
+
+ virtual bool ContainsHandle(void* table, OBJECTHANDLE handle) = 0;
+
virtual OBJECTHANDLE CreateHandleOfType(void* table, Object* object, int type) = 0;
+ virtual OBJECTHANDLE CreateHandleOfType(void* table, Object* object, int type, int heapToAffinitizeTo) = 0;
+
virtual OBJECTHANDLE CreateHandleWithExtraInfo(void* table, Object* object, int type, void* pExtraInfo) = 0;
virtual OBJECTHANDLE CreateDependentHandle(void* table, Object* primary, Object* secondary) = 0;
m_pLargeHeapHandleTable = NULL;
#ifndef CROSSGEN_COMPILE
- // Note that m_hHandleTableBucket is overridden by app domains
- m_hHandleTableBucket = g_HandleTableMap.pBuckets[0];
+ // Note that m_gcHandleTable is overridden by app domains
+ m_gcHandleTable = GCHandleTableUtilities::GetGCHandleTable()->GetGlobalHandleTable();
#else
- m_hHandleTableBucket = NULL;
+ m_gcHandleTable = NULL;
#endif
m_pMarshalingData = NULL;
m_pUMEntryThunkCache = NULL;
m_pAsyncPool = NULL;
- m_hHandleTableBucket = NULL;
+ m_gcHandleTable = NULL;
m_ExposedObject = NULL;
m_pComIPForExposedObject = NULL;
// default domain cannot be unloaded.
if (GetId().m_dwId == DefaultADID)
{
- m_hHandleTableBucket = g_HandleTableMap.pBuckets[0];
+ m_gcHandleTable = GCHandleTableUtilities::GetGCHandleTable()->GetGlobalHandleTable();
}
else
{
- m_hHandleTableBucket = Ref_CreateHandleTableBucket(m_dwIndex);
+ m_gcHandleTable = GCHandleTableUtilities::GetGCHandleTable()->GetNewHandleTable((void*)(uintptr_t)m_dwIndex.m_dwIndex);
}
-#ifdef _DEBUG
- if (((HandleTable *)(m_hHandleTableBucket->pTable[0]))->uADIndex != m_dwIndex)
- _ASSERTE (!"AD index mismatch");
-#endif // _DEBUG
-
#endif // CROSSGEN_COMPILE
#ifdef FEATURE_TYPEEQUIVALENCE
BaseDomain::Terminate();
-#ifdef _DEBUG
- if (m_hHandleTableBucket &&
- m_hHandleTableBucket->pTable &&
- ((HandleTable *)(m_hHandleTableBucket->pTable[0]))->uADIndex != m_dwIndex)
- _ASSERTE (!"AD index mismatch");
-#endif // _DEBUG
-
- if (m_hHandleTableBucket) {
- Ref_DestroyHandleTableBucket(m_hHandleTableBucket);
- m_hHandleTableBucket = NULL;
+ if (m_gcHandleTable)
+ {
+ GCHandleTableUtilities::GetGCHandleTable()->DestroyHandleTable(m_gcHandleTable);
+ m_gcHandleTable = NULL;
}
#ifdef FEATURE_APPDOMAIN_RESOURCE_MONITORING
HandleAsyncPinHandles();
// Remove our handle table as a source of GC roots
- HandleTableBucket *pBucket = m_hHandleTableBucket;
-
-#ifdef _DEBUG
- if (((HandleTable *)(pBucket->pTable[0]))->uADIndex != m_dwIndex)
- _ASSERTE (!"AD index mismatch");
-#endif // _DEBUG
-
- Ref_RemoveHandleTableBucket(pBucket);
+ GCHandleTableUtilities::GetGCHandleTable()->UprootHandleTable(m_gcHandleTable);
}
// When an AD is unloaded, we will release all objects in this AD.
}
CONTRACTL_END;
- HandleTableBucket *pBucket = m_hHandleTableBucket;
+ // TODO: Temporarily casting stuff here until Ref_RelocateAsyncPinHandles is moved to the interface.
+ HandleTableBucket *pBucket = (HandleTableBucket*)m_gcHandleTable;
+
// IO completion port picks IO job using FIFO. Here is how we know which AsyncPinHandle can be freed.
// 1. We mark all non-pending AsyncPinHandle with READYTOCLEAN.
// 2. We queue a dump Overlapped to the IO completion as a marker.
// 3. When the Overlapped is picked up by completion port, we wait until all previous IO jobs are processed.
// 4. Then we can delete all AsyncPinHandle marked with READYTOCLEAN.
- HandleTableBucket *pBucketInDefault = SystemDomain::System()->DefaultDomain()->m_hHandleTableBucket;
+ HandleTableBucket *pBucketInDefault = (HandleTableBucket*)SystemDomain::System()->DefaultDomain()->m_gcHandleTable;
+
+ // TODO: When this function is moved to the interface it will take void*s
Ref_RelocateAsyncPinHandles(pBucket, pBucketInDefault);
OverlappedDataObject::RequestCleanup();
// 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 (m_hHandleTableBucket->Contains(pThread->m_LastThrownObjectHandle))
+ if (pHandleTable->ContainsHandle(m_gcHandleTable, pThread->m_LastThrownObjectHandle))
{
// Never delete a handle to a preallocated exception object.
if (!CLRException::IsPreallocatedExceptionHandle(pThread->m_LastThrownObjectHandle))
}
// Clear out the exceptions objects held by a thread.
- pThread->GetExceptionState()->ClearThrowablesForUnload(m_hHandleTableBucket);
+ pThread->GetExceptionState()->ClearThrowablesForUnload(m_gcHandleTable);
}
//delete them while we still have the runtime suspended
//****************************************************************************************
// Handles
-#if !defined(DACCESS_COMPILE) && !defined(CROSSGEN_COMPILE) // needs GetCurrentThreadHomeHeapNumber
+#if !defined(DACCESS_COMPILE) && !defined(CROSSGEN_COMPILE)
OBJECTHANDLE CreateTypedHandle(OBJECTREF object, int type)
{
WRAPPER_NO_CONTRACT;
IGCHandleTable *pHandleTable = GCHandleTableUtilities::GetGCHandleTable();
- return pHandleTable->CreateHandleOfType(m_hHandleTableBucket->pTable[GetCurrentThreadHomeHeapNumber()], OBJECTREFToObject(object), type);
+ return pHandleTable->CreateHandleOfType(m_gcHandleTable, OBJECTREFToObject(object), type);
}
OBJECTHANDLE CreateHandle(OBJECTREF object)
{
WRAPPER_NO_CONTRACT;
CONDITIONAL_CONTRACT_VIOLATION(ModeViolation, object == NULL)
- return ::CreateHandle(m_hHandleTableBucket->pTable[GetCurrentThreadHomeHeapNumber()], object);
+ return ::CreateHandle(m_gcHandleTable, object);
}
OBJECTHANDLE CreateWeakHandle(OBJECTREF object)
{
WRAPPER_NO_CONTRACT;
- return ::CreateWeakHandle(m_hHandleTableBucket->pTable[GetCurrentThreadHomeHeapNumber()], object);
+ return ::CreateWeakHandle(m_gcHandleTable, object);
}
OBJECTHANDLE CreateShortWeakHandle(OBJECTREF object)
{
WRAPPER_NO_CONTRACT;
- return ::CreateShortWeakHandle(m_hHandleTableBucket->pTable[GetCurrentThreadHomeHeapNumber()], object);
+ return ::CreateShortWeakHandle(m_gcHandleTable, object);
}
OBJECTHANDLE CreateLongWeakHandle(OBJECTREF object)
{
WRAPPER_NO_CONTRACT;
CONDITIONAL_CONTRACT_VIOLATION(ModeViolation, object == NULL)
- return ::CreateLongWeakHandle(m_hHandleTableBucket->pTable[GetCurrentThreadHomeHeapNumber()], object);
+ return ::CreateLongWeakHandle(m_gcHandleTable, object);
}
OBJECTHANDLE CreateStrongHandle(OBJECTREF object)
{
WRAPPER_NO_CONTRACT;
- return ::CreateStrongHandle(m_hHandleTableBucket->pTable[GetCurrentThreadHomeHeapNumber()], object);
+ return ::CreateStrongHandle(m_gcHandleTable, object);
}
OBJECTHANDLE CreatePinningHandle(OBJECTREF object)
{
WRAPPER_NO_CONTRACT;
-#if CHECK_APP_DOMAIN_LEAKS
+#if CHECK_APP_DOMAIN_LEAKS
if(IsAppDomain())
object->TryAssignAppDomain((AppDomain*)this,TRUE);
#endif
- return ::CreatePinningHandle(m_hHandleTableBucket->pTable[GetCurrentThreadHomeHeapNumber()], object);
+ return ::CreatePinningHandle(m_gcHandleTable, object);
}
OBJECTHANDLE CreateSizedRefHandle(OBJECTREF object)
{
WRAPPER_NO_CONTRACT;
- OBJECTHANDLE h = ::CreateSizedRefHandle(
- m_hHandleTableBucket->pTable[GCHeapUtilities::IsServerHeap() ? (m_dwSizedRefHandles % m_iNumberOfProcessors) : GetCurrentThreadHomeHeapNumber()],
- object);
+ OBJECTHANDLE h;
+ if (GCHeapUtilities::IsServerHeap())
+ {
+ h = ::CreateSizedRefHandle(m_gcHandleTable, object, m_dwSizedRefHandles % m_iNumberOfProcessors);
+ }
+ else
+ {
+ h = ::CreateSizedRefHandle(m_gcHandleTable, object);
+ }
+
InterlockedIncrement((LONG*)&m_dwSizedRefHandles);
return h;
}
OBJECTHANDLE CreateRefcountedHandle(OBJECTREF object)
{
WRAPPER_NO_CONTRACT;
- return ::CreateRefcountedHandle(m_hHandleTableBucket->pTable[GetCurrentThreadHomeHeapNumber()], object);
+ return ::CreateRefcountedHandle(m_gcHandleTable, object);
}
OBJECTHANDLE CreateWinRTWeakHandle(OBJECTREF object, IWeakReference* pWinRTWeakReference)
}
CONTRACTL_END;
- return ::CreateWinRTWeakHandle(m_hHandleTableBucket->pTable[GetCurrentThreadHomeHeapNumber()], object, pWinRTWeakReference);
+ return ::CreateWinRTWeakHandle(m_gcHandleTable, object, pWinRTWeakReference);
}
#endif // FEATURE_COMINTEROP
OBJECTHANDLE CreateVariableHandle(OBJECTREF object, UINT type)
{
WRAPPER_NO_CONTRACT;
- return ::CreateVariableHandle(m_hHandleTableBucket->pTable[GetCurrentThreadHomeHeapNumber()], object, type);
+ return ::CreateVariableHandle(m_gcHandleTable, object, type);
}
OBJECTHANDLE CreateDependentHandle(OBJECTREF primary, OBJECTREF secondary)
CONTRACTL_END;
IGCHandleTable *pHandleTable = GCHandleTableUtilities::GetGCHandleTable();
- return pHandleTable->CreateDependentHandle((void*)m_hHandleTableBucket->pTable[GetCurrentThreadHomeHeapNumber()], OBJECTREFToObject(primary), OBJECTREFToObject(secondary));
+ return pHandleTable->CreateDependentHandle(m_gcHandleTable, OBJECTREFToObject(primary), OBJECTREFToObject(secondary));
}
#endif // DACCESS_COMPILE && !CROSSGEN_COMPILE
CLRPrivBinderCoreCLR *m_pTPABinderContext; // Reference to the binding context that holds TPA list details
-
- HandleTableBucket *m_hHandleTableBucket;
+ void* m_gcHandleTable;
// The large heap handle table.
LargeHeapHandleTable *m_pLargeHeapHandleTable;
}
}
-void ThreadExceptionState::ClearThrowablesForUnload(HandleTableBucket* pHndTblBucket)
+void ThreadExceptionState::ClearThrowablesForUnload(void* handleTable)
{
WRAPPER_NO_CONTRACT;
ExInfo* pNode = &m_currentExInfo;
#endif // WIN64EXCEPTIONS
+ IGCHandleTable *pHandleTable = GCHandleTableUtilities::GetGCHandleTable();
+
for ( ;
pNode != NULL;
pNode = pNode->m_pPrevNestedInfo)
{
- if (pHndTblBucket->Contains(pNode->m_hThrowable))
+ if (pHandleTable->ContainsHandle(handleTable, pNode->m_hThrowable))
{
pNode->DestroyExceptionHandle();
}
public:
void FreeAllStackTraces();
- void ClearThrowablesForUnload(HandleTableBucket* pHndTblBucket);
+ void ClearThrowablesForUnload(void* handleTable);
#ifdef _DEBUG
typedef enum
// Handle creation convenience functions
-inline OBJECTHANDLE CreateHandle(HHANDLETABLE table, OBJECTREF object)
+inline OBJECTHANDLE CreateHandle(void* table, OBJECTREF object)
{
return GCHandleTableUtilities::GetGCHandleTable()->CreateHandleOfType(table, OBJECTREFToObject(object), HNDTYPE_DEFAULT);
}
-inline OBJECTHANDLE CreateWeakHandle(HHANDLETABLE table, OBJECTREF object)
+inline OBJECTHANDLE CreateWeakHandle(void* table, OBJECTREF object)
{
return GCHandleTableUtilities::GetGCHandleTable()->CreateHandleOfType(table, OBJECTREFToObject(object), HNDTYPE_WEAK_DEFAULT);
}
-inline OBJECTHANDLE CreateShortWeakHandle(HHANDLETABLE table, OBJECTREF object)
+inline OBJECTHANDLE CreateShortWeakHandle(void* table, OBJECTREF object)
{
return GCHandleTableUtilities::GetGCHandleTable()->CreateHandleOfType(table, OBJECTREFToObject(object), HNDTYPE_WEAK_SHORT);
}
-inline OBJECTHANDLE CreateLongWeakHandle(HHANDLETABLE table, OBJECTREF object)
+inline OBJECTHANDLE CreateLongWeakHandle(void* table, OBJECTREF object)
{
return GCHandleTableUtilities::GetGCHandleTable()->CreateHandleOfType(table, OBJECTREFToObject(object), HNDTYPE_WEAK_LONG);
}
-inline OBJECTHANDLE CreateStrongHandle(HHANDLETABLE table, OBJECTREF object)
+inline OBJECTHANDLE CreateStrongHandle(void* table, OBJECTREF object)
{
return GCHandleTableUtilities::GetGCHandleTable()->CreateHandleOfType(table, OBJECTREFToObject(object), HNDTYPE_STRONG);
}
-inline OBJECTHANDLE CreatePinningHandle(HHANDLETABLE table, OBJECTREF object)
+inline OBJECTHANDLE CreatePinningHandle(void* table, OBJECTREF object)
{
return GCHandleTableUtilities::GetGCHandleTable()->CreateHandleOfType(table, OBJECTREFToObject(object), HNDTYPE_PINNED);
}
-inline OBJECTHANDLE CreateSizedRefHandle(HHANDLETABLE table, OBJECTREF object)
+inline OBJECTHANDLE CreateAsyncPinningHandle(void* table, OBJECTREF object)
{
- return GCHandleTableUtilities::GetGCHandleTable()->CreateHandleOfType(table, OBJECTREFToObject(object), HNDTYPE_SIZEDREF);
+ return GCHandleTableUtilities::GetGCHandleTable()->CreateHandleOfType(table, OBJECTREFToObject(object), HNDTYPE_ASYNCPINNED);
}
-inline OBJECTHANDLE CreateAsyncPinningHandle(HHANDLETABLE table, OBJECTREF object)
+inline OBJECTHANDLE CreateRefcountedHandle(void* table, OBJECTREF object)
{
- return GCHandleTableUtilities::GetGCHandleTable()->CreateHandleOfType(table, OBJECTREFToObject(object), HNDTYPE_ASYNCPINNED);
+ return GCHandleTableUtilities::GetGCHandleTable()->CreateHandleOfType(table, OBJECTREFToObject(object), HNDTYPE_REFCOUNTED);
}
-inline OBJECTHANDLE CreateRefcountedHandle(HHANDLETABLE table, OBJECTREF object)
+inline OBJECTHANDLE CreateSizedRefHandle(void* table, OBJECTREF object)
{
- return GCHandleTableUtilities::GetGCHandleTable()->CreateHandleOfType(table, OBJECTREFToObject(object), HNDTYPE_REFCOUNTED);
+ return GCHandleTableUtilities::GetGCHandleTable()->CreateHandleOfType(table, OBJECTREFToObject(object), HNDTYPE_SIZEDREF);
+}
+
+inline OBJECTHANDLE CreateSizedRefHandle(void* table, OBJECTREF object, int heapToAffinitizeTo)
+{
+ return GCHandleTableUtilities::GetGCHandleTable()->CreateHandleOfType(table, OBJECTREFToObject(object), HNDTYPE_SIZEDREF, heapToAffinitizeTo);
}
// Global handle creation convenience functions
// Special handle creation convenience functions
#ifdef FEATURE_COMINTEROP
-inline OBJECTHANDLE CreateWinRTWeakHandle(HHANDLETABLE table, OBJECTREF object, IWeakReference* pWinRTWeakReference)
+inline OBJECTHANDLE CreateWinRTWeakHandle(void* table, OBJECTREF object, IWeakReference* pWinRTWeakReference)
{
return GCHandleTableUtilities::GetGCHandleTable()->CreateHandleWithExtraInfo(table,
OBJECTREFToObject(object),
#endif // FEATURE_COMINTEROP
// Creates a variable-strength handle
-inline OBJECTHANDLE CreateVariableHandle(HHANDLETABLE table, OBJECTREF object, uint32_t type)
+inline OBJECTHANDLE CreateVariableHandle(void* table, OBJECTREF object, uint32_t type)
{
return GCHandleTableUtilities::GetGCHandleTable()->CreateHandleWithExtraInfo(table,
OBJECTREFToObject(object),