From 85a890944d1bfa585d7add6fa2198a497afbd6b2 Mon Sep 17 00:00:00 2001 From: Aditya Mandaleeka Date: Fri, 7 Apr 2017 15:58:29 -0700 Subject: [PATCH] Move handle destruction code to IGCHandleTable. Conflicts: src/vm/gchandletableutilities.h Commit migrated from https://github.com/dotnet/coreclr/commit/ac0ba59034c46da198b12812899e34dec21990e9 --- src/coreclr/src/gc/gchandletable.cpp | 17 ++- src/coreclr/src/gc/gchandletableimpl.h | 6 + src/coreclr/src/gc/gcinterface.h | 6 + src/coreclr/src/gc/objecthandle.cpp | 45 ------ src/coreclr/src/gc/objecthandle.h | 225 ---------------------------- src/coreclr/src/gc/sample/GCSample.cpp | 2 +- src/coreclr/src/vm/gchandletableutilities.h | 173 +++++++++++++++++++++ 7 files changed, 202 insertions(+), 272 deletions(-) diff --git a/src/coreclr/src/gc/gchandletable.cpp b/src/coreclr/src/gc/gchandletable.cpp index f8222b1..accc72d 100644 --- a/src/coreclr/src/gc/gchandletable.cpp +++ b/src/coreclr/src/gc/gchandletable.cpp @@ -54,4 +54,19 @@ OBJECTHANDLE GCHandleTable::CreateDependentHandle(void* table, Object* primary, ::SetDependentHandleSecondary(handle, ObjectToOBJECTREF(secondary)); return handle; -} \ No newline at end of file +} + +void GCHandleTable::DestroyHandleOfType(OBJECTHANDLE handle, int type) +{ + ::HndDestroyHandle(::HndGetHandleTable(handle), type, handle); +} + +void GCHandleTable::DestroyHandleOfUnknownType(OBJECTHANDLE handle) +{ + ::HndDestroyHandleOfUnknownType(::HndGetHandleTable(handle), handle); +} + +void* GCHandleTable::GetExtraInfoFromHandle(OBJECTHANDLE handle) +{ + return (void*)::HndGetHandleExtraInfo(handle); +} diff --git a/src/coreclr/src/gc/gchandletableimpl.h b/src/coreclr/src/gc/gchandletableimpl.h index 787e0c1..350ae58 100644 --- a/src/coreclr/src/gc/gchandletableimpl.h +++ b/src/coreclr/src/gc/gchandletableimpl.h @@ -25,6 +25,12 @@ public: virtual OBJECTHANDLE CreateDependentHandle(void* table, Object* primary, Object* secondary); virtual OBJECTHANDLE CreateGlobalHandleOfType(Object* object, int type); + + virtual void DestroyHandleOfType(OBJECTHANDLE handle, int type); + + virtual void DestroyHandleOfUnknownType(OBJECTHANDLE handle); + + virtual void* GetExtraInfoFromHandle(OBJECTHANDLE handle); }; #endif // GCHANDLETABLE_H_ diff --git a/src/coreclr/src/gc/gcinterface.h b/src/coreclr/src/gc/gcinterface.h index d0fa879..b10e081 100644 --- a/src/coreclr/src/gc/gcinterface.h +++ b/src/coreclr/src/gc/gcinterface.h @@ -420,6 +420,12 @@ public: virtual OBJECTHANDLE CreateDependentHandle(void* table, Object* primary, Object* secondary) = 0; virtual OBJECTHANDLE CreateGlobalHandleOfType(Object* object, int type) = 0; + + virtual void DestroyHandleOfType(OBJECTHANDLE handle, int type) = 0; + + virtual void DestroyHandleOfUnknownType(OBJECTHANDLE handle) = 0; + + virtual void* GetExtraInfoFromHandle(OBJECTHANDLE handle) = 0; }; // IGCHeap is the interface that the VM will use when interacting with the GC. diff --git a/src/coreclr/src/gc/objecthandle.cpp b/src/coreclr/src/gc/objecthandle.cpp index a100037..5df53ba 100644 --- a/src/coreclr/src/gc/objecthandle.cpp +++ b/src/coreclr/src/gc/objecthandle.cpp @@ -1856,51 +1856,6 @@ bool HandleTableBucket::Contains(OBJECTHANDLE handle) return FALSE; } -void DestroySizedRefHandle(OBJECTHANDLE handle) -{ - CONTRACTL - { - NOTHROW; - GC_NOTRIGGER; - SO_TOLERANT; - MODE_ANY; - } - CONTRACTL_END; - - HHANDLETABLE hTable = HndGetHandleTable(handle); - HndDestroyHandle(hTable , HNDTYPE_SIZEDREF, handle); - AppDomain* pDomain = SystemDomain::GetAppDomainAtIndex(HndGetHandleTableADIndex(hTable)); - pDomain->DecNumSizedRefHandles(); -} - -#ifdef FEATURE_COMINTEROP - -void DestroyWinRTWeakHandle(OBJECTHANDLE handle) -{ - CONTRACTL - { - NOTHROW; - GC_NOTRIGGER; - MODE_ANY; - CAN_TAKE_LOCK; - SO_TOLERANT; - } - CONTRACTL_END; - - // Release the WinRT weak reference if we have one. We're assuming that this will not reenter the - // runtime, since if we are pointing at a managed object, we should not be using a HNDTYPE_WEAK_WINRT - // but rather a HNDTYPE_WEAK_SHORT or HNDTYPE_WEAK_LONG. - IWeakReference* pWinRTWeakReference = reinterpret_cast(HndGetHandleExtraInfo(handle)); - if (pWinRTWeakReference != NULL) - { - pWinRTWeakReference->Release(); - } - - HndDestroyHandle(HndGetHandleTable(handle), HNDTYPE_WEAK_WINRT, handle); -} - -#endif // FEATURE_COMINTEROP - #endif // !DACCESS_COMPILE OBJECTREF GetDependentHandleSecondary(OBJECTHANDLE handle) diff --git a/src/coreclr/src/gc/objecthandle.h b/src/coreclr/src/gc/objecthandle.h index 73d363f..9b2b525 100644 --- a/src/coreclr/src/gc/objecthandle.h +++ b/src/coreclr/src/gc/objecthandle.h @@ -73,119 +73,10 @@ struct HandleTableBucket (flag == VHT_STRONG) || \ (flag == VHT_PINNED)) -#ifndef DACCESS_COMPILE -/* - * Convenience macros and prototypes for the various handle types we define - */ - -inline void DestroyTypedHandle(OBJECTHANDLE handle) -{ - WRAPPER_NO_CONTRACT; - - HndDestroyHandleOfUnknownType(HndGetHandleTable(handle), handle); -} - -inline void DestroyHandle(OBJECTHANDLE handle) -{ - CONTRACTL - { - NOTHROW; - GC_NOTRIGGER; - MODE_ANY; - CAN_TAKE_LOCK; - SO_TOLERANT; - } - CONTRACTL_END; - - HndDestroyHandle(HndGetHandleTable(handle), HNDTYPE_DEFAULT, handle); -} - -inline void DestroyWeakHandle(OBJECTHANDLE handle) -{ - WRAPPER_NO_CONTRACT; - - HndDestroyHandle(HndGetHandleTable(handle), HNDTYPE_WEAK_DEFAULT, handle); -} - -inline void DestroyShortWeakHandle(OBJECTHANDLE handle) -{ - WRAPPER_NO_CONTRACT; - - HndDestroyHandle(HndGetHandleTable(handle), HNDTYPE_WEAK_SHORT, handle); -} - -inline void DestroyLongWeakHandle(OBJECTHANDLE handle) -{ - WRAPPER_NO_CONTRACT; - - HndDestroyHandle(HndGetHandleTable(handle), HNDTYPE_WEAK_LONG, handle); -} - -#ifndef FEATURE_REDHAWK -typedef Holder,DestroyLongWeakHandle> LongWeakHandleHolder; -#endif - -inline void DestroyStrongHandle(OBJECTHANDLE handle) -{ - WRAPPER_NO_CONTRACT; - - HndDestroyHandle(HndGetHandleTable(handle), HNDTYPE_STRONG, handle); -} - -inline void DestroyPinningHandle(OBJECTHANDLE handle) -{ - WRAPPER_NO_CONTRACT; - - HndDestroyHandle(HndGetHandleTable(handle), HNDTYPE_PINNED, handle); -} - -#ifndef FEATURE_REDHAWK -typedef Wrapper, DestroyPinningHandle, NULL> PinningHandleHolder; -#endif - -inline void DestroyAsyncPinningHandle(OBJECTHANDLE handle) -{ - WRAPPER_NO_CONTRACT; - - HndDestroyHandle(HndGetHandleTable(handle), HNDTYPE_ASYNCPINNED, handle); -} - -#ifndef FEATURE_REDHAWK -typedef Wrapper, DestroyAsyncPinningHandle, NULL> AsyncPinningHandleHolder; -#endif - -void DestroySizedRefHandle(OBJECTHANDLE handle); - -#ifndef FEATURE_REDHAWK -typedef Wrapper, DestroySizedRefHandle, NULL> SizeRefHandleHolder; -#endif - -#ifdef FEATURE_COMINTEROP - -inline void DestroyRefcountedHandle(OBJECTHANDLE handle) -{ - WRAPPER_NO_CONTRACT; - - HndDestroyHandle(HndGetHandleTable(handle), HNDTYPE_REFCOUNTED, handle); -} - -void DestroyWinRTWeakHandle(OBJECTHANDLE handle); - -#endif // FEATURE_COMINTEROP - -#endif // !DACCESS_COMPILE - OBJECTREF GetDependentHandleSecondary(OBJECTHANDLE handle); #ifndef DACCESS_COMPILE void SetDependentHandleSecondary(OBJECTHANDLE handle, OBJECTREF secondary); - -inline void DestroyDependentHandle(OBJECTHANDLE handle) -{ - WRAPPER_NO_CONTRACT; - - HndDestroyHandle(HndGetHandleTable(handle), HNDTYPE_DEPENDENT, handle); -} #endif // !DACCESS_COMPILE #ifndef DACCESS_COMPILE @@ -193,130 +84,14 @@ uint32_t GetVariableHandleType(OBJECTHANDLE handle); void UpdateVariableHandleType(OBJECTHANDLE handle, uint32_t type); uint32_t CompareExchangeVariableHandleType(OBJECTHANDLE handle, uint32_t oldType, uint32_t newType); -inline void DestroyVariableHandle(OBJECTHANDLE handle) -{ - WRAPPER_NO_CONTRACT; - - HndDestroyHandle(HndGetHandleTable(handle), HNDTYPE_VARIABLE, handle); -} - void GCHandleValidatePinnedObject(OBJECTREF obj); /* - * Holder for OBJECTHANDLE - */ - -#ifndef FEATURE_REDHAWK -typedef Wrapper, DestroyHandle > OHWrapper; - -class OBJECTHANDLEHolder : public OHWrapper -{ -public: - FORCEINLINE OBJECTHANDLEHolder(OBJECTHANDLE p = NULL) : OHWrapper(p) - { - LIMITED_METHOD_CONTRACT; - } - FORCEINLINE void operator=(OBJECTHANDLE p) - { - WRAPPER_NO_CONTRACT; - - OHWrapper::operator=(p); - } -}; -#endif - -#ifdef FEATURE_COMINTEROP - -typedef Wrapper, DestroyRefcountedHandle> RefCountedOHWrapper; - -class RCOBJECTHANDLEHolder : public RefCountedOHWrapper -{ -public: - FORCEINLINE RCOBJECTHANDLEHolder(OBJECTHANDLE p = NULL) : RefCountedOHWrapper(p) - { - LIMITED_METHOD_CONTRACT; - } - FORCEINLINE void operator=(OBJECTHANDLE p) - { - WRAPPER_NO_CONTRACT; - - RefCountedOHWrapper::operator=(p); - } -}; - -#endif // FEATURE_COMINTEROP -/* * Convenience prototypes for using the global handles */ int GetCurrentThreadHomeHeapNumber(); -inline void DestroyGlobalTypedHandle(OBJECTHANDLE handle) -{ - WRAPPER_NO_CONTRACT; - - HndDestroyHandleOfUnknownType(HndGetHandleTable(handle), handle); -} - -inline void DestroyGlobalHandle(OBJECTHANDLE handle) -{ - WRAPPER_NO_CONTRACT; - - HndDestroyHandle(HndGetHandleTable(handle), HNDTYPE_DEFAULT, handle); -} - -inline void DestroyGlobalWeakHandle(OBJECTHANDLE handle) -{ - WRAPPER_NO_CONTRACT; - - HndDestroyHandle(HndGetHandleTable(handle), HNDTYPE_WEAK_DEFAULT, handle); -} - -inline void DestroyGlobalShortWeakHandle(OBJECTHANDLE handle) -{ - WRAPPER_NO_CONTRACT; - - HndDestroyHandle(HndGetHandleTable(handle), HNDTYPE_WEAK_SHORT, handle); -} - -#ifndef FEATURE_REDHAWK -typedef Holder,DestroyGlobalShortWeakHandle> GlobalShortWeakHandleHolder; -#endif - -inline void DestroyGlobalLongWeakHandle(OBJECTHANDLE handle) -{ - WRAPPER_NO_CONTRACT; - - HndDestroyHandle(HndGetHandleTable(handle), HNDTYPE_WEAK_LONG, handle); -} - -inline void DestroyGlobalStrongHandle(OBJECTHANDLE handle) -{ - WRAPPER_NO_CONTRACT; - - HndDestroyHandle(HndGetHandleTable(handle), HNDTYPE_STRONG, handle); -} - -#ifndef FEATURE_REDHAWK -typedef Holder,DestroyGlobalStrongHandle> GlobalStrongHandleHolder; -#endif - -inline void DestroyGlobalPinningHandle(OBJECTHANDLE handle) -{ - WRAPPER_NO_CONTRACT; - - HndDestroyHandle(HndGetHandleTable(handle), HNDTYPE_PINNED, handle); -} - -#ifdef FEATURE_COMINTEROP -inline void DestroyGlobalRefcountedHandle(OBJECTHANDLE handle) -{ - WRAPPER_NO_CONTRACT; - - HndDestroyHandle(HndGetHandleTable(handle), HNDTYPE_REFCOUNTED, handle); -} -#endif // FEATURE_COMINTEROP - inline void ResetOBJECTHANDLE(OBJECTHANDLE handle) { WRAPPER_NO_CONTRACT; diff --git a/src/coreclr/src/gc/sample/GCSample.cpp b/src/coreclr/src/gc/sample/GCSample.cpp index ed67e89..2914ee1 100644 --- a/src/coreclr/src/gc/sample/GCSample.cpp +++ b/src/coreclr/src/gc/sample/GCSample.cpp @@ -229,7 +229,7 @@ int __cdecl main(int argc, char* argv[]) return -1; // Destroy the strong handle so that nothing will be keeping out object alive - DestroyGlobalHandle(oh); + HndDestroyHandle(HndGetHandleTable(oh), HNDTYPE_DEFAULT, oh); // Explicitly trigger full GC pGCHeap->GarbageCollect(); diff --git a/src/coreclr/src/vm/gchandletableutilities.h b/src/coreclr/src/vm/gchandletableutilities.h index a631b55..7849c02 100644 --- a/src/coreclr/src/vm/gchandletableutilities.h +++ b/src/coreclr/src/vm/gchandletableutilities.h @@ -155,6 +155,179 @@ inline OBJECTHANDLE CreateVariableHandle(HHANDLETABLE table, OBJECTREF object, u (void*)((uintptr_t)type)); } +// Handle destruction convenience functions + +inline void DestroyHandle(OBJECTHANDLE handle) +{ + CONTRACTL + { + NOTHROW; + GC_NOTRIGGER; + MODE_ANY; + CAN_TAKE_LOCK; + SO_TOLERANT; + } + CONTRACTL_END; + + GCHandleTableUtilities::GetGCHandleTable()->DestroyHandleOfType(handle, HNDTYPE_DEFAULT); +} + +inline void DestroyWeakHandle(OBJECTHANDLE handle) +{ + GCHandleTableUtilities::GetGCHandleTable()->DestroyHandleOfType(handle, HNDTYPE_WEAK_DEFAULT); +} + +inline void DestroyShortWeakHandle(OBJECTHANDLE handle) +{ + GCHandleTableUtilities::GetGCHandleTable()->DestroyHandleOfType(handle, HNDTYPE_WEAK_SHORT); +} + +inline void DestroyLongWeakHandle(OBJECTHANDLE handle) +{ + GCHandleTableUtilities::GetGCHandleTable()->DestroyHandleOfType(handle, HNDTYPE_WEAK_LONG); +} + +inline void DestroyStrongHandle(OBJECTHANDLE handle) +{ + GCHandleTableUtilities::GetGCHandleTable()->DestroyHandleOfType(handle, HNDTYPE_STRONG); +} + +inline void DestroyPinningHandle(OBJECTHANDLE handle) +{ + GCHandleTableUtilities::GetGCHandleTable()->DestroyHandleOfType(handle, HNDTYPE_PINNED); +} + +inline void DestroyAsyncPinningHandle(OBJECTHANDLE handle) +{ + GCHandleTableUtilities::GetGCHandleTable()->DestroyHandleOfType(handle, HNDTYPE_ASYNCPINNED); +} + +inline void DestroyRefcountedHandle(OBJECTHANDLE handle) +{ + GCHandleTableUtilities::GetGCHandleTable()->DestroyHandleOfType(handle, HNDTYPE_REFCOUNTED); +} + +inline void DestroyDependentHandle(OBJECTHANDLE handle) +{ + GCHandleTableUtilities::GetGCHandleTable()->DestroyHandleOfType(handle, HNDTYPE_DEPENDENT); +} + +inline void DestroyVariableHandle(OBJECTHANDLE handle) +{ + GCHandleTableUtilities::GetGCHandleTable()->DestroyHandleOfType(handle, HNDTYPE_VARIABLE); +} + +inline void DestroyGlobalHandle(OBJECTHANDLE handle) +{ + GCHandleTableUtilities::GetGCHandleTable()->DestroyHandleOfType(handle, HNDTYPE_DEFAULT); +} + +inline void DestroyGlobalWeakHandle(OBJECTHANDLE handle) +{ + GCHandleTableUtilities::GetGCHandleTable()->DestroyHandleOfType(handle, HNDTYPE_WEAK_DEFAULT); +} + +inline void DestroyGlobalShortWeakHandle(OBJECTHANDLE handle) +{ + GCHandleTableUtilities::GetGCHandleTable()->DestroyHandleOfType(handle, HNDTYPE_WEAK_SHORT); +} + +inline void DestroyGlobalLongWeakHandle(OBJECTHANDLE handle) +{ + GCHandleTableUtilities::GetGCHandleTable()->DestroyHandleOfType(handle, HNDTYPE_WEAK_LONG); +} + +inline void DestroyGlobalStrongHandle(OBJECTHANDLE handle) +{ + GCHandleTableUtilities::GetGCHandleTable()->DestroyHandleOfType(handle, HNDTYPE_STRONG); +} + +inline void DestroyGlobalPinningHandle(OBJECTHANDLE handle) +{ + GCHandleTableUtilities::GetGCHandleTable()->DestroyHandleOfType(handle, HNDTYPE_PINNED); +} + +inline void DestroyGlobalRefcountedHandle(OBJECTHANDLE handle) +{ + GCHandleTableUtilities::GetGCHandleTable()->DestroyHandleOfType(handle, HNDTYPE_REFCOUNTED); +} + +inline void DestroyTypedHandle(OBJECTHANDLE handle) +{ + GCHandleTableUtilities::GetGCHandleTable()->DestroyHandleOfUnknownType(handle); +} + +#ifdef FEATURE_COMINTEROP +inline void DestroyWinRTWeakHandle(OBJECTHANDLE handle) +{ + CONTRACTL + { + NOTHROW; + GC_NOTRIGGER; + MODE_ANY; + CAN_TAKE_LOCK; + SO_TOLERANT; + } + CONTRACTL_END; + + // Release the WinRT weak reference if we have one. We're assuming that this will not reenter the + // runtime, since if we are pointing at a managed object, we should not be using HNDTYPE_WEAK_WINRT + // but rather HNDTYPE_WEAK_SHORT or HNDTYPE_WEAK_LONG. + void* pExtraInfo = GCHandleTableUtilities::GetGCHandleTable()->GetExtraInfoFromHandle(handle); + IWeakReference* pWinRTWeakReference = reinterpret_cast(pExtraInfo); + if (pWinRTWeakReference != nullptr) + { + pWinRTWeakReference->Release(); + } + + GCHandleTableUtilities::GetGCHandleTable()->DestroyHandleOfType(handle, HNDTYPE_WEAK_WINRT); +} +#endif + +// Handle holders/wrappers + +#ifndef FEATURE_REDHAWK +typedef Wrapper, DestroyHandle> OHWrapper; +typedef Wrapper, DestroyPinningHandle, NULL> PinningHandleHolder; +typedef Wrapper, DestroyAsyncPinningHandle, NULL> AsyncPinningHandleHolder; +typedef Wrapper, DestroyRefcountedHandle> RefCountedOHWrapper; + +typedef Holder, DestroyLongWeakHandle> LongWeakHandleHolder; +typedef Holder, DestroyGlobalStrongHandle> GlobalStrongHandleHolder; +typedef Holder, DestroyGlobalShortWeakHandle> GlobalShortWeakHandleHolder; + +class RCOBJECTHANDLEHolder : public RefCountedOHWrapper +{ +public: + FORCEINLINE RCOBJECTHANDLEHolder(OBJECTHANDLE p = NULL) : RefCountedOHWrapper(p) + { + LIMITED_METHOD_CONTRACT; + } + FORCEINLINE void operator=(OBJECTHANDLE p) + { + WRAPPER_NO_CONTRACT; + + RefCountedOHWrapper::operator=(p); + } +}; + +class OBJECTHANDLEHolder : public OHWrapper +{ +public: + FORCEINLINE OBJECTHANDLEHolder(OBJECTHANDLE p = NULL) : OHWrapper(p) + { + LIMITED_METHOD_CONTRACT; + } + FORCEINLINE void operator=(OBJECTHANDLE p) + { + WRAPPER_NO_CONTRACT; + + OHWrapper::operator=(p); + } +}; + +#endif // !FEATURE_REDHAWK + #endif // !DACCESS_COMPILE #endif // _GCHANDLETABLEUTILITIES_H_ -- 2.7.4