Improve thread statics performance (#14560)
authorJan Kotas <jkotas@microsoft.com>
Wed, 18 Oct 2017 09:38:55 +0000 (02:38 -0700)
committerJan Vorlicek <janvorli@microsoft.com>
Wed, 18 Oct 2017 09:38:55 +0000 (11:38 +0200)
- Disable code to handle multiple appdomains
- Use more efficient object array accessor

src/vm/appdomain.cpp
src/vm/ceeload.h
src/vm/corhost.cpp
src/vm/object.h
src/vm/threadstatics.h

index edcc3df..1fe8a96 100644 (file)
@@ -11911,19 +11911,3 @@ void ZapperSetBindingPaths(ICorCompilationDomain *pDomain, SString &trustedPlatf
 }
 
 #endif
-
-#if !defined(CROSSGEN_COMPILE)
-bool IsSingleAppDomain()
-{
-    STARTUP_FLAGS flags = CorHost2::GetStartupFlags();
-    if(flags & STARTUP_SINGLE_APPDOMAIN)
-        return TRUE;
-    else
-        return FALSE;
-}
-#else
-bool IsSingleAppDomain()
-{
-    return FALSE;
-}
-#endif
index b70ea51..62facce 100644 (file)
@@ -3101,8 +3101,10 @@ public:
     static BOOL IsEncodedModuleIndex(SIZE_T ModuleID)
     {
         LIMITED_METHOD_DAC_CONTRACT;
-            
-        return (ModuleID&1)==1;
+        
+        // We should never see encoded module index in CoreCLR
+        _ASSERTE((ModuleID&1)==0);
+        return FALSE;
     }
 
     static SIZE_T IndexToID(ModuleIndex index)
@@ -3553,6 +3555,10 @@ struct VASigCookieEx : public VASigCookie
     const BYTE *m_pArgs;        // pointer to first unfixed unmanaged arg
 };
 
-bool IsSingleAppDomain();
+inline bool IsSingleAppDomain()
+{
+    // CoreCLR always runs as single AppDomain
+    return true;
+}
 
 #endif // !CEELOAD_H_
index b1e5a8a..7fe542e 100644 (file)
@@ -564,13 +564,6 @@ HRESULT CorHost2::ExecuteInAppDomain(DWORD dwAppDomainId,
         return HOST_E_CLRNOTAVAILABLE;
     }       
 
-    if(!(m_dwStartupFlags & STARTUP_SINGLE_APPDOMAIN))
-    {
-        // Ensure that code is not loaded in the Default AppDomain
-        if (dwAppDomainId == DefaultADID)
-           return HOST_E_INVALIDOPERATION;
-    }
-
     // Moved this here since no point validating the pointer
     // if the basic checks [above] fail
     if( pCallback == NULL)
@@ -626,7 +619,7 @@ HRESULT CorHost2::_CreateAppDomain(
     HRESULT hr=S_OK;
 
     //cannot call the function more than once when single appDomain is allowed
-    if (m_fAppDomainCreated && (m_dwStartupFlags & STARTUP_SINGLE_APPDOMAIN))
+    if (m_fAppDomainCreated)
     {
         return HOST_E_INVALIDOPERATION;
     }
@@ -655,15 +648,7 @@ HRESULT CorHost2::_CreateAppDomain(
 
     AppDomainCreationHolder<AppDomain> pDomain;
 
-    // If StartupFlag specifies single appDomain then return the default domain instead of creating new one
-    if(m_dwStartupFlags & STARTUP_SINGLE_APPDOMAIN)
-    {
-        pDomain.Assign(SystemDomain::System()->DefaultDomain());
-    }
-    else
-    {
-        AppDomain::CreateUnmanagedObject(pDomain);
-    }
+    pDomain.Assign(SystemDomain::System()->DefaultDomain());
 
     ETW::LoaderLog::DomainLoad(pDomain, (LPWSTR)wszFriendlyName);
 
@@ -738,11 +723,7 @@ HRESULT CorHost2::_CreateAppDomain(
 
         *pAppDomainID=pDomain->GetId().m_dwId;
 
-        // If StartupFlag specifies single appDomain then set the flag that appdomain has already been created
-        if(m_dwStartupFlags & STARTUP_SINGLE_APPDOMAIN)
-        {
-            m_fAppDomainCreated = TRUE;
-        }
+        m_fAppDomainCreated = TRUE;
     }
 #ifdef PROFILING_SUPPORTED
     EX_HOOK
@@ -815,13 +796,6 @@ HRESULT CorHost2::_CreateDelegate(
     if (!m_fStarted)
         return HOST_E_INVALIDOPERATION;
 
-    if(!(m_dwStartupFlags & STARTUP_SINGLE_APPDOMAIN))
-    {
-        // Ensure that code is not loaded in the Default AppDomain
-        if (appDomainID == DefaultADID)
-            return HOST_E_INVALIDOPERATION;
-    }
-
     BEGIN_ENTRYPOINT_NOTHROW;
 
     BEGIN_EXTERNAL_ENTRYPOINT(&hr);
@@ -1180,57 +1154,52 @@ STDMETHODIMP CorHost2::UnloadAppDomain2(DWORD dwDomainId, BOOL fWaitUntilDone, i
     if (!m_fStarted)
         return HOST_E_INVALIDOPERATION;
 
-    if(m_dwStartupFlags & STARTUP_SINGLE_APPDOMAIN)
+    if (!g_fEEStarted)
     {
-        if (!g_fEEStarted)
-        {
-            return HOST_E_CLRNOTAVAILABLE;
-        }
+        return HOST_E_CLRNOTAVAILABLE;
+    }
 
-        if(!m_fAppDomainCreated)
-        {
-            return HOST_E_INVALIDOPERATION;
-        }
+    if(!m_fAppDomainCreated)
+    {
+        return HOST_E_INVALIDOPERATION;
+    }
 
-        HRESULT hr=S_OK;
-        BEGIN_ENTRYPOINT_NOTHROW;
+    HRESULT hr=S_OK;
+    BEGIN_ENTRYPOINT_NOTHROW;
     
-        if (!m_fFirstToLoadCLR)
+    if (!m_fFirstToLoadCLR)
+    {
+        _ASSERTE(!"Not reachable");
+        hr = HOST_E_CLRNOTAVAILABLE;
+    }
+    else
+    {
+        LONG refCount = m_RefCount;
+        if (refCount == 0)
         {
-            _ASSERTE(!"Not reachable");
             hr = HOST_E_CLRNOTAVAILABLE;
         }
         else
+        if (1 == refCount)
         {
-            LONG refCount = m_RefCount;
-            if (refCount == 0)
-            {
-                hr = HOST_E_CLRNOTAVAILABLE;
-            }
-            else
-            if (1 == refCount)
-            {
-                // Stop coreclr on unload.
-                m_fStarted = FALSE;
-                EEShutDown(FALSE);
-            }
-            else
-            {
-                _ASSERTE(!"Not reachable");
-                hr = S_FALSE;
-            }
+            // Stop coreclr on unload.
+            m_fStarted = FALSE;
+            EEShutDown(FALSE);
         }
-        END_ENTRYPOINT_NOTHROW;
-
-        if (pLatchedExitCode)
+        else
         {
-            *pLatchedExitCode = GetLatchedExitCode();
+            _ASSERTE(!"Not reachable");
+            hr = S_FALSE;
         }
+    }
+    END_ENTRYPOINT_NOTHROW;
 
-        return hr;
+    if (pLatchedExitCode)
+    {
+        *pLatchedExitCode = GetLatchedExitCode();
     }
 
-    return CorRuntimeHostBase::UnloadAppDomain2(dwDomainId, fWaitUntilDone, pLatchedExitCode);
+    return hr;
 }
 
 HRESULT CorRuntimeHostBase::UnloadAppDomain(DWORD dwDomainId, BOOL fWaitUntilDone)
index 20d7d50..7de739a 100644 (file)
@@ -952,6 +952,13 @@ public:
         return GetMethodTable()->GetApproxArrayElementTypeHandle();
     }
 
+    PTR_OBJECTREF GetDataPtr()
+    {
+        LIMITED_METHOD_CONTRACT;
+        SUPPORTS_DAC;
+        return dac_cast<PTR_OBJECTREF>(dac_cast<PTR_BYTE>(this) + GetDataOffset());
+    }
+
     static SIZE_T GetDataOffset()
     {
         LIMITED_METHOD_CONTRACT;
index bd52496..970f730 100644 (file)
@@ -66,7 +66,7 @@ struct ThreadLocalModule
 
             _ASSERTE(m_pGCStatics != NULL);
 
-            return dac_cast<PTR_BYTE>((PTR_OBJECTREF)((PTRARRAYREF)ObjectFromHandle(m_pGCStatics))->GetDataPtr());
+            return dac_cast<PTR_BYTE>(((PTRARRAYREF)ObjectFromHandle(m_pGCStatics))->GetDataPtr());
         }
         inline PTR_BYTE GetGCStaticsBaseHandle()
         {
@@ -125,7 +125,7 @@ struct ThreadLocalModule
 
         _ASSERTE(m_pGCStatics != NULL);
 
-        return (PTR_OBJECTREF)((PTRARRAYREF)ObjectFromHandle(m_pGCStatics))->GetDataPtr();
+        return ((PTRARRAYREF)ObjectFromHandle(m_pGCStatics))->GetDataPtr();
     }
 
     inline OBJECTHANDLE GetPrecomputedGCStaticsBaseHandle()