Change GetAppDomain to return AppDomain from the global static (dotnet/coreclr#20910)
authorJan Vorlicek <janvorli@microsoft.com>
Tue, 13 Nov 2018 21:51:20 +0000 (22:51 +0100)
committerGitHub <noreply@github.com>
Tue, 13 Nov 2018 21:51:20 +0000 (22:51 +0100)
* Change GetAppDomain to return it from the global static

The current implementation of the GetAppDomain takes it from the TLS for
the current thread. But we only have one AppDomain in the system, so we
can change it to return just that one.
I have still left the ThreadLocalInfo.m_pAppDomain and its setter
present, because SOS uses that to access the AppDomain and the SOS needs
to be runtime versino agnostic.
This makes it to perform better for Unix where accessing TLS is not
trivial.

* Move the AppDomain instance pointer to own static

To enable access to the one and only AppDomain without unnecessary
indirections, I have moved the pointer out of the SystemDomain class.

Commit migrated from https://github.com/dotnet/coreclr/commit/89262cf66efe776a17c322efcbe896cc3073b446

src/coreclr/src/vm/appdomain.cpp
src/coreclr/src/vm/appdomain.hpp
src/coreclr/src/vm/threads.h
src/coreclr/src/vm/threads.inl

index a3a2602..368725f 100644 (file)
@@ -116,6 +116,9 @@ SVAL_IMPL(BOOL, SystemDomain, s_fForceDebug);
 SVAL_IMPL(BOOL, SystemDomain, s_fForceProfiling);
 SVAL_IMPL(BOOL, SystemDomain, s_fForceInstrument);
 
+// The one and only AppDomain
+AppDomain* AppDomain::m_pTheAppDomain = NULL;
+
 #ifndef DACCESS_COMPILE
 
 // Base Domain Statics
@@ -2071,8 +2074,8 @@ void SystemDomain::Attach()
     // We need to initialize the memory pools etc. for the system domain.
     m_pSystemDomain->BaseDomain::Init(); // Setup the memory heaps
 
-    // Create the default domain
-    m_pSystemDomain->CreateDefaultDomain();
+    // Create the one and only app domain
+    AppDomain::Create();
     SharedDomain::Attach();
 
     // Each domain gets its own ReJitManager, and ReJitManager has its own static
@@ -2113,8 +2116,9 @@ void SystemDomain::DetachEnd()
     {
         GCX_PREEMP();
         m_pSystemDomain->ClearFusionContext();
-        if (m_pSystemDomain->m_pDefaultDomain)
-            m_pSystemDomain->m_pDefaultDomain->ClearFusionContext();
+        AppDomain* pAppDomain = GetAppDomain();
+        if (pAppDomain)
+            pAppDomain->ClearFusionContext();
     }
 }
 
@@ -3575,7 +3579,7 @@ StackWalkAction SystemDomain::CallersMethodCallback(CrawlFrame* pCf, VOID* data)
 extern CompilationDomain * theDomain;
 #endif
 
-void SystemDomain::CreateDefaultDomain()
+void AppDomain::Create()
 {
     STANDARD_VM_CONTRACT;
 
@@ -3585,25 +3589,25 @@ void SystemDomain::CreateDefaultDomain()
     AppDomainRefHolder pDomain(new AppDomain());
 #endif
 
-    SystemDomain::LockHolder lh;
     pDomain->Init();
 
     // need to make this assignment here since we'll be releasing
     // the lock before calling AddDomain. So any other thread
     // grabbing this lock after we release it will find that
     // the COM Domain has already been created
-    m_pDefaultDomain = pDomain;
     _ASSERTE (pDomain->GetId().m_dwId == DefaultADID);
 
     // allocate a Virtual Call Stub Manager for the default domain
-    m_pDefaultDomain->InitVSD();
+    pDomain->InitVSD();
 
     pDomain->SetStage(AppDomain::STAGE_OPEN);
     pDomain.SuppressRelease();
 
+    m_pTheAppDomain = pDomain;
+
     LOG((LF_CLASSLOADER | LF_CORDB,
          LL_INFO10,
-         "Created default domain at %p\n", m_pDefaultDomain));
+         "Created the app domain at %p\n", m_pTheAppDomain));
 }
 
 #ifdef DEBUGGING_SUPPORTED
@@ -3957,7 +3961,6 @@ void AppDomain::Init()
     CONTRACTL
     {
         STANDARD_VM_CHECK;
-        PRECONDITION(SystemDomain::IsUnderDomainLock());
     }
     CONTRACTL_END;
 
@@ -9618,9 +9621,9 @@ SystemDomain::EnumMemoryRegions(CLRDataEnumMemoryFlags flags,
     {
         m_pSystemAssembly->EnumMemoryRegions(flags);
     }
-    if (m_pDefaultDomain.IsValid())
+    if (AppDomain::GetCurrentDomain())
     {
-        m_pDefaultDomain->EnumMemoryRegions(flags, true);
+        AppDomain::GetCurrentDomain()->EnumMemoryRegions(flags, true);
     }
 
     m_appDomainIndexList.EnumMem();
index a443c8c..143a012 100644 (file)
@@ -1897,16 +1897,16 @@ public:
 #ifndef DACCESS_COMPILE
     AppDomain();
     virtual ~AppDomain();
+    static void Create();
 #endif
+
     DomainAssembly* FindDomainAssembly(Assembly*);
     void EnterContext(Thread* pThread, Context* pCtx,ContextTransitionFrame *pFrame);
 
-#ifndef DACCESS_COMPILE
     //-----------------------------------------------------------------------------------------------------------------
     // Convenience wrapper for ::GetAppDomain to provide better encapsulation.
     static AppDomain * GetCurrentDomain()
-    { return ::GetAppDomain(); }
-#endif //!DACCESS_COMPILE
+    { return m_pTheAppDomain; }
     
     //-----------------------------------------------------------------------------------------------------------------
     // Initializes an AppDomain. (this functions is not called from the SystemDomain)
@@ -3299,6 +3299,9 @@ public:
 #endif
 
 private:
+    // The one and only AppDomain
+    static AppDomain* m_pTheAppDomain;
+
     SString         m_friendlyName;
     PTR_Assembly    m_pRootAssembly;
 
@@ -3855,7 +3858,7 @@ public:
     {
         LIMITED_METHOD_DAC_CONTRACT;
 
-        return m_pDefaultDomain;
+        return AppDomain::GetCurrentDomain();
     }
 
     // Notification when an assembly is loaded into the system domain
@@ -4179,7 +4182,6 @@ private:
     {
         STANDARD_VM_CONTRACT;
 
-        m_pDefaultDomain = NULL;
         m_pDelayedUnloadListOfLoaderAllocators=NULL;
 
         m_GlobalAllocator.Init(this);
@@ -4188,7 +4190,6 @@ private:
 
     PTR_PEAssembly  m_pSystemFile;      // Single assembly (here for quicker reference);
     PTR_Assembly    m_pSystemAssembly;  // Single assembly (here for quicker reference);
-    PTR_AppDomain   m_pDefaultDomain;   // Default domain for COM+ classes exposed through IClassFactory.
 
     GlobalLoaderAllocator m_GlobalAllocator;
 
index 3aa1681..444d4d4 100644 (file)
@@ -7277,7 +7277,7 @@ class Compiler;
 struct ThreadLocalInfo
 {
     Thread* m_pThread;
-    AppDomain* m_pAppDomain;
+    AppDomain* m_pAppDomain; // This field is read only by the SOS plugin to get the AppDomain
     void** m_EETlsData; // ClrTlsInfo::data
 };
 
index 1c07070..2da3c1a 100644 (file)
@@ -36,7 +36,7 @@ EXTERN_C inline Thread* STDCALL GetThread()
 
 EXTERN_C inline AppDomain* STDCALL GetAppDomain()
 {
-    return gCurrentThreadInfo.m_pAppDomain;
+    return AppDomain::GetCurrentDomain();
 }
 
 #endif // !DACCESS_COMPILE