diff --git a/src/Native/Runtime/FinalizerHelpers.cpp b/src/Native/Runtime/FinalizerHelpers.cpp index 00d9d6779b2..347345e7881 100644 --- a/src/Native/Runtime/FinalizerHelpers.cpp +++ b/src/Native/Runtime/FinalizerHelpers.cpp @@ -77,21 +77,22 @@ EXTERN_C REDHAWK_API void __cdecl RhpSignalFinalizationComplete() FinalizerThread::SignalFinalizationDone(TRUE); } +#ifndef CORERT // @TODO: Remove on next breaking change sweep #ifdef FEATURE_PREMORTEM_FINALIZATION // Enable a last pass of the finalizer during (clean) runtime shutdown. Specify the number of milliseconds // we'll wait before giving up a proceeding with the shutdown (INFINITE is an allowable value). COOP_PINVOKE_HELPER(void, RhEnableShutdownFinalization, (UInt32 uiTimeout)) { - g_fPerformShutdownFinalization = true; - g_uiShutdownFinalizationTimeout = uiTimeout; + UNREFERENCED_PARAMETER(uiTimeout); } // Returns true when shutdown has started and it is no longer safe to access other objects from finalizers. COOP_PINVOKE_HELPER(UInt8, RhHasShutdownStarted, ()) { - return g_fShutdownHasStarted ? 1 : 0; + return 0; } #endif // FEATURE_PREMORTEM_FINALIZATION +#endif // // The following helpers are special in that they interact with internal GC state or directly manipulate diff --git a/src/Native/Runtime/amd64/MiscStubs.asm b/src/Native/Runtime/amd64/MiscStubs.asm index a53885fad39..97b3840f8e9 100644 --- a/src/Native/Runtime/amd64/MiscStubs.asm +++ b/src/Native/Runtime/amd64/MiscStubs.asm @@ -4,34 +4,12 @@ include AsmMacros.inc -EXTERN RhpShutdownHelper : PROC EXTERN GetClasslibCCtorCheck : PROC EXTERN memcpy : PROC EXTERN memcpyGCRefs : PROC EXTERN memcpyGCRefsWithWriteBarrier : PROC EXTERN memcpyAnyWithWriteBarrier : PROC -;; -;; Currently called only from a managed executable once Main returns, this routine does whatever is needed to -;; cleanup managed state before exiting. -;; -;; Input: -;; rcx : Process exit code -;; -NESTED_ENTRY RhpShutdown, _TEXT - - INLINE_GETTHREAD rax, r10 ; rax <- Thread pointer, r10 <- trashed - PUSH_COOP_PINVOKE_FRAME rax, r10, no_extraStack ; rax <- in: Thread, out: trashed, r10 <- trashed - END_PROLOGUE - - ;; Call the bulk of the helper implemented in C++. Takes the exit code already in rcx. - call RhpShutdownHelper - - POP_COOP_PINVOKE_FRAME no_extraStack - ret - -NESTED_END RhpShutdown, _TEXT - ;; ;; Checks whether the static class constructor for the type indicated by the context structure has been ;; executed yet. If not the classlib is called via their CheckStaticClassConstruction callback which will diff --git a/src/Native/Runtime/arm/MiscStubs.asm b/src/Native/Runtime/arm/MiscStubs.asm index e7cf625e2de..6dc90fdb08b 100644 --- a/src/Native/Runtime/arm/MiscStubs.asm +++ b/src/Native/Runtime/arm/MiscStubs.asm @@ -4,7 +4,6 @@ #include "AsmMacros.h" - EXTERN RhpShutdownHelper EXTERN GetClasslibCCtorCheck EXTERN memcpy EXTERN memcpyGCRefs @@ -13,24 +12,6 @@ TEXTAREA -;; -;; Currently called only from a managed executable once Main returns, this routine does whatever is needed to -;; cleanup managed state before exiting. -;; -;; Input: -;; r0 : Process exit code -;; - NESTED_ENTRY RhpShutdown - - COOP_PINVOKE_FRAME_PROLOG - - ;; Call the bulk of the helper implemented in C++. Takes the exit code already in r0. - bl RhpShutdownHelper - - COOP_PINVOKE_FRAME_EPILOG - - NESTED_END RhpShutdown - ;; ;; Checks whether the static class constructor for the type indicated by the context structure has been ;; executed yet. If not the classlib is called via their CheckStaticClassConstruction callback which will diff --git a/src/Native/Runtime/gcenv.h b/src/Native/Runtime/gcenv.h index cbd654a5134..bb6af680c3b 100644 --- a/src/Native/Runtime/gcenv.h +++ b/src/Native/Runtime/gcenv.h @@ -227,26 +227,6 @@ class SyncBlockCache #endif // VERIFY_HEAP -// -// ----------------------------------------------------------------------------------------------------------- -// -// Support for shutdown finalization, which is off by default but can be enabled by the class library. -// - -// If true runtime shutdown will attempt to finalize all finalizable objects (even those still rooted). -extern bool g_fPerformShutdownFinalization; - -// Time to wait (in milliseconds) for the above finalization to complete before giving up and proceeding with -// shutdown. Can specify INFINITE for no timeout. -extern UInt32 g_uiShutdownFinalizationTimeout; - -// Flag set to true once we've begun shutdown (and before shutdown finalization begins). This is exported to -// the class library so that managed code can tell when it is safe to access other objects from finalizers. -extern bool g_fShutdownHasStarted; - - - - EXTERN_C UInt32 _tls_index; inline UInt16 GetClrInstanceId() { diff --git a/src/Native/Runtime/gcrhenv.cpp b/src/Native/Runtime/gcrhenv.cpp index cb59d875416..bcc287cc18f 100644 --- a/src/Native/Runtime/gcrhenv.cpp +++ b/src/Native/Runtime/gcrhenv.cpp @@ -925,40 +925,11 @@ COOP_PINVOKE_HELPER(void, RhUnbox, (Object * pObj, void * pData, EEType * pUnbox } } -#endif // !DACCESS_COMPILE - -// -// ----------------------------------------------------------------------------------------------------------- -// -// Support for shutdown finalization, which is off by default but can be enabled by the class library. -// - -// If true runtime shutdown will attempt to finalize all finalizable objects (even those still rooted). -bool g_fPerformShutdownFinalization = false; - -// Time to wait (in milliseconds) for the above finalization to complete before giving up and proceeding with -// shutdown. Can specify INFINITE for no timeout. -UInt32 g_uiShutdownFinalizationTimeout = 0; - -// Flag set to true once we've begun shutdown (and before shutdown finalization begins). This is exported to -// the class library so that managed code can tell when it is safe to access other objects from finalizers. -bool g_fShutdownHasStarted = false; - -#ifndef DACCESS_COMPILE Thread * GetThread() { return ThreadStore::GetCurrentThread(); } -// If the class library has requested it, call this method on clean shutdown (i.e. return from Main) to -// perform a final pass of finalization where all finalizable objects are processed regardless of whether -// they are still rooted. -// static -void RedhawkGCInterface::ShutdownFinalization() -{ - FinalizerThread::WatchDog(); -} - // Thread static representing the last allocation. // This is used to log the type information for each slow allocation. DECLSPEC_THREAD @@ -1253,69 +1224,6 @@ HANDLE FinalizerThread::GetFinalizerEvent() return hEventFinalizer->GetOSEvent(); } -// This is called during runtime shutdown to perform a final finalization run with all pontentially -// finalizable objects being finalized (as if their roots had all been cleared). The default behaviour is to -// skip this step, the classlib has to make an explicit request for this functionality and also specifies the -// maximum amount of time it will let the finalization take before we will give up and just let the shutdown -// proceed. -bool FinalizerThread::WatchDog() -{ - // Set the flag indicating that shutdown has started. This is only of interest to managed code running - // finalizers as it lets them know when it is no longer safe to access other objects (which from this - // point on can be finalized even if you hold a reference to them). - g_fShutdownHasStarted = true; - - if (g_fPerformShutdownFinalization) - { -#ifdef BACKGROUND_GC - // Switch off concurrent GC if necessary. - gc_heap::gc_can_use_concurrent = FALSE; - - if (pGenGCHeap->settings.concurrent) - pGenGCHeap->background_gc_wait(); -#endif //BACKGROUND_GC - - DWORD dwTimeout = g_uiShutdownFinalizationTimeout; - - // Wait for any outstanding finalization run to complete. Time this initial operation so that it forms - // part of the overall timeout budget. - DWORD dwStartTime = PalGetTickCount(); - Wait(dwTimeout); - DWORD dwEndTime = PalGetTickCount(); - - // In the exceedingly rare case that the tick count wrapped then we'll just reset the timeout to its - // initial value. Otherwise we'll subtract the time we waited from the timeout budget (being mindful - // of the fact that we might have waited slightly longer than the timeout specified). - if (dwTimeout != INFINITE) - { - if (dwEndTime < dwStartTime) - dwTimeout = g_uiShutdownFinalizationTimeout; - else - dwTimeout -= min(dwTimeout, dwEndTime - dwStartTime); - - if (dwTimeout == 0) - return false; - } - - // Inform the GC that all finalizable objects should now be placed in the queue for finalization. FALSE - // here means we don't hold the finalizer lock (so the routine will take it for us). - GCHeap::GetGCHeap()->SetFinalizeQueueForShutdown(FALSE); - - // Wait for the finalizer to process all of these objects. - Wait(dwTimeout); - - if (dwTimeout == INFINITE) - return true; - - // Do a zero timeout wait of the finalizer done event to determine if we timed out above (we don't - // want to modify the signature of GCHeap::FinalizerThreadWait to return this data since that bleeds - // into a CLR visible change to gc.h which is not really worth it for this minor case). - return hEventFinalizerDone->Wait(0, FALSE) == WAIT_OBJECT_0; - } - - return true; -} - void FinalizerThread::Wait(DWORD timeout, bool allowReentrantWait) { // Can't call this from the finalizer thread itself. diff --git a/src/Native/Runtime/gcrhinterface.h b/src/Native/Runtime/gcrhinterface.h index 9a5b3137129..3bf10e7dd68 100644 --- a/src/Native/Runtime/gcrhinterface.h +++ b/src/Native/Runtime/gcrhinterface.h @@ -179,11 +179,6 @@ class RedhawkGCInterface static GcScanObjectFunction GetCurrentScanCallbackFunction(); static void* GetCurrentScanContext(); - // If the class library has requested it, call this method on clean shutdown (i.e. return from Main) to - // perform a final pass of finalization where all finalizable objects are processed regardless of whether - // they are still rooted. - static void ShutdownFinalization(); - // Returns size GCDesc. Used by type cloning. static UInt32 GetGCDescSize(void * pType); diff --git a/src/Native/Runtime/i386/MiscStubs.asm b/src/Native/Runtime/i386/MiscStubs.asm index e6ffd4cc518..80ff054db5f 100644 --- a/src/Native/Runtime/i386/MiscStubs.asm +++ b/src/Native/Runtime/i386/MiscStubs.asm @@ -9,45 +9,12 @@ include AsmMacros.inc -EXTERN @RhpShutdownHelper@4 : PROC EXTERN @GetClasslibCCtorCheck@4 : PROC EXTERN _memcpy : PROC EXTERN _memcpyGCRefs : PROC EXTERN _memcpyGCRefsWithWriteBarrier : PROC EXTERN _memcpyAnyWithWriteBarrier : PROC -;; -;; Currently called only from a managed executable once Main returns, this routine does whatever is needed to -;; cleanup managed state before exiting. This routine never returns. -;; -;; Input: -;; ecx : Process exit code -;; -FASTCALL_FUNC RhpShutdown, 4 - - ;; Build an EBP frame, mostly so we get a good stack trace during debugging. - push ebp - mov ebp, esp - - ;; edx = GetThread(), TRASHES eax - INLINE_GETTHREAD edx, eax - - ;; Save managed state in a frame and update the thread so it can find this frame once we transition to - ;; pre-emptive mode in the garbage collection. - PUSH_COOP_PINVOKE_FRAME edx - - ;; Call the bulk of the helper implemented in C++. Takes the exit code already in ecx. - call @RhpShutdownHelper@4 - - ;; Restore register state. - POP_COOP_PINVOKE_FRAME - - ;; Epilog, tear down EBP frame and return. - pop ebp - ret - -FASTCALL_ENDFUNC - ;; ;; Checks whether the static class constructor for the type indicated by the context structure has been ;; executed yet. If not the classlib is called via their CheckStaticClassConstruction callback which will diff --git a/src/Native/Runtime/startup.cpp b/src/Native/Runtime/startup.cpp index 2d949e0e261..ce6298cffcf 100644 --- a/src/Native/Runtime/startup.cpp +++ b/src/Native/Runtime/startup.cpp @@ -324,11 +324,8 @@ HANDLE RtuCreateRuntimeInstance(HANDLE hPalInstance) // @TODO: Eventually we'll probably have a hosting API and explicit shutdown request. When that happens we'll // something more sophisticated here since we won't be able to rely on the OS cleaning up after us. // -COOP_PINVOKE_HELPER(void, RhpShutdownHelper, (UInt32 /*uExitCode*/)) +COOP_PINVOKE_HELPER(void, RhpShutdown, ()) { - // If the classlib has requested it perform a last pass of the finalizer thread. - RedhawkGCInterface::ShutdownFinalization(); - #ifdef FEATURE_PROFILING GetRuntimeInstance()->WriteProfileInfo(); #endif // FEATURE_PROFILING diff --git a/src/Native/gc/env/gcenv.base.h b/src/Native/gc/env/gcenv.base.h index 51adc64c055..61a0bc6795c 100644 --- a/src/Native/gc/env/gcenv.base.h +++ b/src/Native/gc/env/gcenv.base.h @@ -452,7 +452,6 @@ class FinalizerThread static bool IsCurrentThreadFinalizer(); static void Wait(DWORD timeout, bool allowReentrantWait = false); - static bool WatchDog(); static void SignalFinalizationDone(bool fFinalizer); static void SetFinalizerThread(Thread * pThread); static HANDLE GetFinalizerEvent(); diff --git a/src/Runtime.Base/src/System/Runtime/RuntimeExports.cs b/src/Runtime.Base/src/System/Runtime/RuntimeExports.cs index c3b2823d847..06442629f9f 100644 --- a/src/Runtime.Base/src/System/Runtime/RuntimeExports.cs +++ b/src/Runtime.Base/src/System/Runtime/RuntimeExports.cs @@ -13,7 +13,7 @@ namespace System.Runtime { internal static class RuntimeExports { -#if !CORERT +#if !CORERT // @TODO: Remove on next breaking change sweep // // internalcalls for System.Runtime.InteropServices.GCHandle. // diff --git a/src/System.Private.CoreLib/src/MembersMustExist.AnalyzerData b/src/System.Private.CoreLib/src/MembersMustExist.AnalyzerData index 8e411d3f260..2685fd179dc 100644 --- a/src/System.Private.CoreLib/src/MembersMustExist.AnalyzerData +++ b/src/System.Private.CoreLib/src/MembersMustExist.AnalyzerData @@ -114,7 +114,6 @@ internal static extern void System.Runtime.RuntimeImports.RhCheckArrayStore(obje internal static extern void System.Runtime.RuntimeImports.RhCollect(int generation, System.InternalGCCollectionMode mode) private static extern int System.Runtime.RuntimeImports.RhCompatibleReentrantWaitAny(int alertable, int timeout, int count, System.IntPtr* handles) internal static extern bool System.Runtime.RuntimeImports.RhCreateGenericInstanceDescForType2(System.EETypePtr pEEType, int arity, int nonGcStaticDataSize, int nonGCStaticDataOffset, int gcStaticDataSize, int threadStaticsOffset, void* pGcStaticsDesc, void* pThreadStaticsDesc, int* pGenericVarianceFlags) -internal static extern void System.Runtime.RuntimeImports.RhEnableShutdownFinalization(uint timeout) internal static extern bool System.Runtime.RuntimeImports.RhFindBlob(System.IntPtr hOsModule, uint blobId, byte** ppbBlob, uint* pcbBlob) internal static extern System.IntPtr System.Runtime.RuntimeImports.RhFindMethodStartAddress(System.IntPtr codeAddr) internal static extern System.IntPtr System.Runtime.RuntimeImports.RhGetCodeTarget(System.IntPtr pCode) @@ -167,7 +166,6 @@ internal static extern void System.Runtime.RuntimeImports.RhHandleSetDependentSe internal static extern void System.Runtime.RuntimeImports.RhHandleSetVariableType(System.IntPtr handle, uint type) internal static extern bool System.Runtime.RuntimeImports.RhHasCctor(System.EETypePtr pEEType) internal static extern bool System.Runtime.RuntimeImports.RhHasReferenceFields(System.EETypePtr pEEType) -internal static extern bool System.Runtime.RuntimeImports.RhHasShutdownStarted() internal static extern bool System.Runtime.RuntimeImports.RhIsArray(System.EETypePtr pEEType) internal static extern bool System.Runtime.RuntimeImports.RhIsDynamicType(System.EETypePtr pEEType) internal static extern bool System.Runtime.RuntimeImports.RhIsInterface(System.EETypePtr pEEType) diff --git a/src/System.Private.CoreLib/src/System/Environment.cs b/src/System.Private.CoreLib/src/System/Environment.cs index 7f67780f575..793263b4dc5 100644 --- a/src/System.Private.CoreLib/src/System/Environment.cs +++ b/src/System.Private.CoreLib/src/System/Environment.cs @@ -81,7 +81,8 @@ public static bool HasShutdownStarted { get { - return RuntimeImports.RhHasShutdownStarted(); + // .NET Core does not have shutdown finalization + return false; } } @@ -118,17 +119,6 @@ public static string[] GetCommandLineArgs() } #endif -#if CORERT - // .NET Core abandoned shutdown finalization. - // See discussion in https://github.com/dotnet/corefx/issues/5205 - // We should get rid of this in Project N too. -#else - static Environment() - { - RuntimeImports.RhEnableShutdownFinalization(0xffffffffu); - } -#endif - public static String StackTrace { get diff --git a/src/System.Private.CoreLib/src/System/Runtime/RuntimeImports.cs b/src/System.Private.CoreLib/src/System/Runtime/RuntimeImports.cs index 35b675bb442..c4023b102d9 100644 --- a/src/System.Private.CoreLib/src/System/Runtime/RuntimeImports.cs +++ b/src/System.Private.CoreLib/src/System/Runtime/RuntimeImports.cs @@ -448,16 +448,8 @@ internal enum RuntimeHelperKind internal static unsafe extern IntPtr RhGetDispatchMapForType(EETypePtr pEEType); // - // calls to runtime for process status + // Support for GC and HandleTable callouts. // - [MethodImplAttribute(MethodImplOptions.InternalCall)] - [RuntimeImport(RuntimeLibrary, "RhEnableShutdownFinalization")] - internal static extern void RhEnableShutdownFinalization(uint timeout); - - [MethodImplAttribute(MethodImplOptions.InternalCall)] - [RuntimeImport(RuntimeLibrary, "RhHasShutdownStarted")] - internal static extern bool RhHasShutdownStarted(); - internal enum GcRestrictedCalloutKind { @@ -467,9 +459,6 @@ internal enum GcRestrictedCalloutKind // no handles have been cleared } - // - // Support for GC and HandleTable callouts. - // [MethodImplAttribute(MethodImplOptions.InternalCall)] [RuntimeImport(RuntimeLibrary, "RhRegisterGcCallout")] internal static extern bool RhRegisterGcCallout(GcRestrictedCalloutKind eKind, IntPtr pCalloutMethod); diff --git a/src/System.Private.CoreLib/src/System/Threading/ManagedThreadId.cs b/src/System.Private.CoreLib/src/System/Threading/ManagedThreadId.cs index 22c33af4aeb..8dd4ceae4a3 100644 --- a/src/System.Private.CoreLib/src/System/Threading/ManagedThreadId.cs +++ b/src/System.Private.CoreLib/src/System/Threading/ManagedThreadId.cs @@ -241,11 +241,6 @@ private ManagedThreadId(int managedThreadId) ~ManagedThreadId() { - if (RuntimeImports.RhHasShutdownStarted()) - { - return; - } - if (_managedThreadId == ManagedThreadIdNone) { return;