diff options
-rw-r--r-- | src/gc/env/gcenv.ee.h | 1 | ||||
-rw-r--r-- | src/gc/gc.cpp | 9 | ||||
-rw-r--r-- | src/gc/gc.h | 6 | ||||
-rw-r--r-- | src/gc/gcenv.ee.standalone.inl | 6 | ||||
-rw-r--r-- | src/gc/gcinterface.ee.h | 9 | ||||
-rw-r--r-- | src/gc/sample/gcenv.ee.cpp | 6 | ||||
-rw-r--r-- | src/vm/gcenv.ee.cpp | 22 | ||||
-rw-r--r-- | src/vm/gcenv.ee.h | 1 |
8 files changed, 47 insertions, 13 deletions
diff --git a/src/gc/env/gcenv.ee.h b/src/gc/env/gcenv.ee.h index 8c4dfccce9..e7102b0731 100644 --- a/src/gc/env/gcenv.ee.h +++ b/src/gc/env/gcenv.ee.h @@ -71,6 +71,7 @@ public: static void HandleFatalError(unsigned int exitCode); static bool ShouldFinalizeObjectForUnload(AppDomain* pDomain, Object* obj); + static bool EagerFinalized(Object* obj); }; #endif // __GCENV_EE_H__ diff --git a/src/gc/gc.cpp b/src/gc/gc.cpp index ab8e56bc8a..aad6ec860c 100644 --- a/src/gc/gc.cpp +++ b/src/gc/gc.cpp @@ -36269,16 +36269,11 @@ CFinalize::ScanForFinalization (promote_func* pfn, int gen, BOOL mark_only_p, assert (method_table(obj)->HasFinalizer()); -#ifndef FEATURE_REDHAWK - if (method_table(obj) == pWeakReferenceMT || method_table(obj)->GetCanonicalMethodTable() == pWeakReferenceOfTCanonMT) + if (GCToEEInterface::EagerFinalized(obj)) { - //destruct the handle right there. - FinalizeWeakReference (obj); MoveItem (i, Seg, FreeList); } - else -#endif //!FEATURE_REDHAWK - if ((obj->GetHeader()->GetBits()) & BIT_SBLK_FINALIZER_RUN) + else if ((obj->GetHeader()->GetBits()) & BIT_SBLK_FINALIZER_RUN) { //remove the object because we don't want to //run the finalizer diff --git a/src/gc/gc.h b/src/gc/gc.h index 821b21ddb8..8cd92fd1c7 100644 --- a/src/gc/gc.h +++ b/src/gc/gc.h @@ -256,12 +256,6 @@ void TouchPages(void * pStart, size_t cb); void updateGCShadow(Object** ptr, Object* val); #endif -// the method table for the WeakReference class -extern MethodTable *pWeakReferenceMT; -// The canonical method table for WeakReference<T> -extern MethodTable *pWeakReferenceOfTCanonMT; -extern void FinalizeWeakReference(Object * obj); - // The single GC heap instance, shared with the VM. extern IGCHeapInternal* g_theGCHeap; diff --git a/src/gc/gcenv.ee.standalone.inl b/src/gc/gcenv.ee.standalone.inl index 328acef056..13febb5341 100644 --- a/src/gc/gcenv.ee.standalone.inl +++ b/src/gc/gcenv.ee.standalone.inl @@ -219,6 +219,12 @@ ALWAYS_INLINE bool GCToEEInterface::ShouldFinalizeObjectForUnload(AppDomain* pDo return g_theGCToCLR->ShouldFinalizeObjectForUnload(pDomain, obj); } +ALWAYS_INLINE bool GCToEEInterface::EagerFinalized(Object* obj) +{ + assert(g_theGCToCLR != nullptr); + return g_theGCToCLR->EagerFinalized(obj); +} + #undef ALWAYS_INLINE #endif // __GCTOENV_EE_STANDALONE_INL__ diff --git a/src/gc/gcinterface.ee.h b/src/gc/gcinterface.ee.h index 5c595b417f..ee1b8ecb1a 100644 --- a/src/gc/gcinterface.ee.h +++ b/src/gc/gcinterface.ee.h @@ -142,6 +142,15 @@ public: // an app domain. virtual bool ShouldFinalizeObjectForUnload(AppDomain* pDomain, Object* obj) = 0; + + // Offers the EE the option to finalize the given object eagerly, i.e. + // not on the finalizer thread but on the current thread. The + // EE returns true if it finalized the object eagerly and the GC does not + // need to do so, and false if it chose not to eagerly finalize the object + // and it's up to the GC to finalize it later. + virtual + bool EagerFinalized(Object* obj) = 0; + }; #endif // _GCINTERFACE_EE_H_ diff --git a/src/gc/sample/gcenv.ee.cpp b/src/gc/sample/gcenv.ee.cpp index aaca51e8b8..392bfa1cb5 100644 --- a/src/gc/sample/gcenv.ee.cpp +++ b/src/gc/sample/gcenv.ee.cpp @@ -275,6 +275,12 @@ bool GCToEEInterface::ShouldFinalizeObjectForUnload(AppDomain* pDomain, Object* return true; } +bool GCToEEInterface::EagerFinalized(Object* obj) +{ + // The sample does not finalize anything eagerly. + return false; +} + bool IsGCSpecialThread() { // TODO: Implement for background GC diff --git a/src/vm/gcenv.ee.cpp b/src/vm/gcenv.ee.cpp index f3c139e66d..a652359c4f 100644 --- a/src/vm/gcenv.ee.cpp +++ b/src/vm/gcenv.ee.cpp @@ -29,6 +29,15 @@ #include "comcallablewrapper.h" #endif // FEATURE_COMINTEROP +// the method table for the WeakReference class +extern MethodTable* pWeakReferenceMT; + +// The canonical method table for WeakReference<T> +extern MethodTable* pWeakReferenceOfTCanonMT; + +// Finalizes a weak reference directly. +extern void FinalizeWeakReference(Object* obj); + void GCToEEInterface::SuspendEE(SUSPEND_REASON reason) { WRAPPER_NO_CONTRACT; @@ -1359,3 +1368,16 @@ bool GCToEEInterface::ShouldFinalizeObjectForUnload(AppDomain* pDomain, Object* // to move them to a new app domain instead of finalizing them here. return true; } + +bool GCToEEInterface::EagerFinalized(Object* obj) +{ + MethodTable* pMT = obj->GetGCSafeMethodTable(); + if (pMT == pWeakReferenceMT || + pMT->GetCanonicalMethodTable() == pWeakReferenceOfTCanonMT) + { + FinalizeWeakReference(obj); + return true; + } + + return false; +} diff --git a/src/vm/gcenv.ee.h b/src/vm/gcenv.ee.h index 030eb71807..5eb3e3d12d 100644 --- a/src/vm/gcenv.ee.h +++ b/src/vm/gcenv.ee.h @@ -46,6 +46,7 @@ public: void EnableFinalization(bool foundFinalizers); void HandleFatalError(unsigned int exitCode); bool ShouldFinalizeObjectForUnload(AppDomain* pDomain, Object* obj); + bool EagerFinalized(Object* obj); }; #endif // FEATURE_STANDALONE_GC |