summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/gc/env/gcenv.ee.h1
-rw-r--r--src/gc/gc.cpp9
-rw-r--r--src/gc/gc.h6
-rw-r--r--src/gc/gcenv.ee.standalone.inl6
-rw-r--r--src/gc/gcinterface.ee.h9
-rw-r--r--src/gc/sample/gcenv.ee.cpp6
-rw-r--r--src/vm/gcenv.ee.cpp22
-rw-r--r--src/vm/gcenv.ee.h1
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