Repository: dotnet/runtime
File: src/coreclr/vm/ceemain.cpp (C++)

Code before:
        // should have initialized FLS slot for thread cleanup notifications.
        // And ensured that COM is initialized (must happen before allocating FLS slot).
        // Make sure that this was done before we start creating Thread objects
        // Ex: The call to SetupThread below will create and attach a Thread object.
        //     Event pipe might also do that.
        FinalizerThread::WaitForFinalizerThreadStart();
#endif

        // throws on error
        _ASSERTE(GetThreadNULLOk() == NULL);
        SetupThread();

#ifdef DEBUGGING_SUPPORTED
        // Notify debugger once the first thread is created to finish initialization.
        if (g_pDebugInterface != NULL)
        {
            g_pDebugInterface->StartupPhase2(GetThread());
        }
#endif

#ifdef TARGET_WINDOWS
        // On windows the finalizer thread is already partially created and is waiting
        // right before doing HasStarted(). We will release it now.
        FinalizerThread::EnableFinalization();
#elif defined(TARGET_WASM)
        // on wasm this would just schedule finalization onto browser event loop
        FinalizerThread::EnableFinalization();
#else
        // This isn't done as part of InitializeGarbageCollector() above because
        // debugger must be initialized before creating EE thread objects
        FinalizerThread::FinalizerThreadCreate();
#endif // TARGET_WINDOWS

#ifdef FEATURE_PERFTRACING
        // Finish setting up rest of EventPipe - specifically enable SampleProfiler if it was requested at startup.
        // SampleProfiler needs to cooperate with the GC which hasn't fully finished setting up in the first part of the
        // EventPipe initialization, so this is done after the GC has been fully initialized.
        EventPipeAdapter::FinishInitialize();
#endif // FEATURE_PERFTRACING
        GenAnalysis::Initialize();

        // Now we really have fully initialized the garbage collector
        SetGarbageCollectorFullyInitialized();

#ifdef DEBUGGING_SUPPORTED
        // Make a call to publish the DefaultDomain for the debugger
        // This should be done before assemblies/modules are loaded into it (i.e. SystemDomain::Init)
        // and after its OK to switch GC modes and synchronize for sending events to the debugger.
        // @dbgtodo  synchronization: this can probably be simplified in V3
        LOG((LF_CORDB | LF_SYNC | LF_STARTUP, LL_INFO1000, "EEStartup: adding default domain 0x%x\n",
             SystemDomain::System()->DefaultDomain()));

Review comment (suggestion):
```suggestion
        // On wasm this schedules finalization onto the browser event loop.
```

Code after:
        // should have initialized FLS slot for thread cleanup notifications.
        // And ensured that COM is initialized (must happen before allocating FLS slot).
        // Make sure that this was done before we start creating Thread objects
        // Ex: The call to SetupThread below will create and attach a Thread object.
        //     Event pipe might also do that.
        FinalizerThread::WaitForFinalizerThreadStart();
#endif

        // throws on error
        _ASSERTE(GetThreadNULLOk() == NULL);
        SetupThread();

#ifdef DEBUGGING_SUPPORTED
        // Notify debugger once the first thread is created to finish initialization.
        if (g_pDebugInterface != NULL)
        {
            g_pDebugInterface->StartupPhase2(GetThread());
        }
#endif

#ifdef TARGET_WINDOWS
        // On windows the finalizer thread is already partially created and is waiting
        // right before doing HasStarted(). We will release it now.
        FinalizerThread::EnableFinalization();
#else
        // This isn't done as part of InitializeGarbageCollector() above because
        // debugger must be initialized before creating EE thread objects
        FinalizerThread::FinalizerThreadCreate();
#endif // TARGET_WINDOWS

#ifdef FEATURE_PERFTRACING
        // Finish setting up rest of EventPipe - specifically enable SampleProfiler if it was requested at startup.
        // SampleProfiler needs to cooperate with the GC which hasn't fully finished setting up in the first part of the
        // EventPipe initialization, so this is done after the GC has been fully initialized.
        EventPipeAdapter::FinishInitialize();
#endif // FEATURE_PERFTRACING
        GenAnalysis::Initialize();

        // Now we really have fully initialized the garbage collector
        SetGarbageCollectorFullyInitialized();

#ifdef DEBUGGING_SUPPORTED
        // Make a call to publish the DefaultDomain for the debugger
        // This should be done before assemblies/modules are loaded into it (i.e. SystemDomain::Init)
        // and after its OK to switch GC modes and synchronize for sending events to the debugger.
        // @dbgtodo  synchronization: this can probably be simplified in V3
        LOG((LF_CORDB | LF_SYNC | LF_STARTUP, LL_INFO1000, "EEStartup: adding default domain 0x%x\n",
             SystemDomain::System()->DefaultDomain()));
        SystemDomain::System()->PublishAppDomainAndInformDebugger(SystemDomain::System()->DefaultDomain());
#endif