Allow setting some startup flags outside Windows
authorKoundinya Veluri <kouvel@microsoft.com>
Wed, 11 Nov 2015 19:39:58 +0000 (11:39 -0800)
committerKoundinya Veluri <kouvel@microsoft.com>
Sat, 14 Nov 2015 07:26:52 +0000 (23:26 -0800)
Allowing the GC-related flags to be set using properties passed into coreclr_initialize.

src/coreclr/hosts/coreconsole/coreconsole.cpp
src/coreclr/hosts/corerun/corerun.cpp
src/dlls/mscoree/unixinterface.cpp

index 7b93dd8..d8bf6c8 100644 (file)
@@ -418,7 +418,8 @@ bool TryRun(const int argc, const wchar_t* argv[], Logger &log, const bool verbo
     // Default startup flags
     hr = host->SetStartupFlags((STARTUP_FLAGS)
         (STARTUP_FLAGS::STARTUP_LOADER_OPTIMIZATION_SINGLE_DOMAIN | 
-        STARTUP_FLAGS::STARTUP_SINGLE_APPDOMAIN)); 
+        STARTUP_FLAGS::STARTUP_SINGLE_APPDOMAIN |
+        STARTUP_FLAGS::STARTUP_CONCURRENT_GC));
     if (FAILED(hr)) {
         log << W("Failed to set startup flags. ERRORCODE: ") << hr << Logger::endl;
         return false;
index 2efe7e9..6505a36 100644 (file)
@@ -456,7 +456,8 @@ bool TryRun(const int argc, const wchar_t* argv[], Logger &log, const bool verbo
     // Default startup flags
     hr = host->SetStartupFlags((STARTUP_FLAGS)
         (STARTUP_FLAGS::STARTUP_LOADER_OPTIMIZATION_SINGLE_DOMAIN | 
-        STARTUP_FLAGS::STARTUP_SINGLE_APPDOMAIN)); 
+        STARTUP_FLAGS::STARTUP_SINGLE_APPDOMAIN |
+        STARTUP_FLAGS::STARTUP_CONCURRENT_GC));
     if (FAILED(hr)) {
         log << W("Failed to set startup flags. ERRORCODE: ") << Logger::hresult << hr << Logger::endl;
         return false;
index b02ce52..2f4e1e9 100644 (file)
@@ -87,6 +87,80 @@ static LPCWSTR* StringArrayToUnicode(int argc, LPCSTR* argv)
     return argvW;
 }
 
+static void ExtractStartupFlagsAndConvertToUnicode(
+    const char** propertyKeys,
+    const char** propertyValues,
+    int* propertyCountRef,
+    STARTUP_FLAGS* startupFlagsRef,
+    LPCWSTR** propertyKeysWRef,
+    LPCWSTR** propertyValuesWRef)
+{
+    int propertyCount = *propertyCountRef;
+
+    LPCWSTR* propertyKeysW = new (nothrow) LPCWSTR[propertyCount];
+    ASSERTE_ALL_BUILDS(propertyKeysW != nullptr);
+
+    LPCWSTR* propertyValuesW = new (nothrow) LPCWSTR[propertyCount];
+    ASSERTE_ALL_BUILDS(propertyValuesW != nullptr);
+
+    // Extract the startup flags from the properties, and convert the remaining properties into unicode
+    STARTUP_FLAGS startupFlags =
+        static_cast<STARTUP_FLAGS>(
+            STARTUP_FLAGS::STARTUP_LOADER_OPTIMIZATION_SINGLE_DOMAIN |
+            STARTUP_FLAGS::STARTUP_SINGLE_APPDOMAIN |
+            STARTUP_FLAGS::STARTUP_CONCURRENT_GC);
+    int propertyCountW = 0;
+    for (int propertyIndex = 0; propertyIndex < propertyCount; ++propertyIndex)
+    {
+        auto SetFlagValue = [&](STARTUP_FLAGS flag)
+        {
+            if (strcmp(propertyValues[propertyIndex], "0") == 0)
+            {
+                startupFlags = static_cast<STARTUP_FLAGS>(startupFlags & ~flag);
+            }
+            else if (strcmp(propertyValues[propertyIndex], "1") == 0)
+            {
+                startupFlags = static_cast<STARTUP_FLAGS>(startupFlags | flag);
+            }
+        };
+
+        if (strcmp(propertyKeys[propertyIndex], "CONCURRENT_GC") == 0)
+        {
+            SetFlagValue(STARTUP_CONCURRENT_GC);
+        }
+        else if (strcmp(propertyKeys[propertyIndex], "SERVER_GC") == 0)
+        {
+            SetFlagValue(STARTUP_SERVER_GC);
+        }
+        else if (strcmp(propertyKeys[propertyIndex], "HOARD_GC_VM") == 0)
+        {
+            SetFlagValue(STARTUP_HOARD_GC_VM);
+        }
+        else if (strcmp(propertyKeys[propertyIndex], "TRIM_GC_COMMIT") == 0)
+        {
+            SetFlagValue(STARTUP_TRIM_GC_COMMIT);
+        }
+        else
+        {
+            // This is not a CoreCLR startup flag, convert it to unicode and preserve it for returning
+            propertyKeysW[propertyCountW] = StringToUnicode(propertyKeys[propertyIndex]);
+            propertyValuesW[propertyCountW] = StringToUnicode(propertyValues[propertyIndex]);
+            ++propertyCountW;
+        }
+    }
+
+    for (int propertyIndex = propertyCountW; propertyIndex < propertyCount; ++propertyIndex)
+    {
+        propertyKeysW[propertyIndex] = nullptr;
+        propertyValuesW[propertyIndex] = nullptr;
+    }
+
+    *propertyCountRef = propertyCountW;
+    *startupFlagsRef = startupFlags;
+    *propertyKeysWRef = propertyKeysW;
+    *propertyValuesWRef = propertyValuesW;
+}
+
 //
 // Initialize the CoreCLR. Creates and starts CoreCLR host and creates an app domain
 //
@@ -130,21 +204,30 @@ int coreclr_initialize(
     hr = CorHost2::CreateObject(IID_ICLRRuntimeHost2, (void**)&host);
     IfFailRet(hr);
 
-    hr = host->SetStartupFlags((STARTUP_FLAGS)
-                               (STARTUP_FLAGS::STARTUP_LOADER_OPTIMIZATION_SINGLE_DOMAIN |
-                                STARTUP_FLAGS::STARTUP_SINGLE_APPDOMAIN));
-    IfFailRet(hr);
-
-    hr = host->Start();
-    IfFailRet(hr);
-    
     ConstWStringHolder appDomainFriendlyNameW = StringToUnicode(appDomainFriendlyName);
+
+    STARTUP_FLAGS startupFlags;
+    LPCWSTR* propertyKeysWTemp;
+    LPCWSTR* propertyValuesWTemp;
+    ExtractStartupFlagsAndConvertToUnicode(
+        propertyKeys,
+        propertyValues,
+        &propertyCount,
+        &startupFlags,
+        &propertyKeysWTemp,
+        &propertyValuesWTemp);
     
     ConstWStringArrayHolder propertyKeysW;
-    propertyKeysW.Set(StringArrayToUnicode(propertyCount, propertyKeys), propertyCount);
+    propertyKeysW.Set(propertyKeysWTemp, propertyCount);
     
     ConstWStringArrayHolder propertyValuesW;
-    propertyValuesW.Set(StringArrayToUnicode(propertyCount, propertyValues), propertyCount);
+    propertyValuesW.Set(propertyValuesWTemp, propertyCount);
+
+    hr = host->SetStartupFlags(startupFlags);
+    IfFailRet(hr);
+
+    hr = host->Start();
+    IfFailRet(hr);
 
     hr = host->CreateAppDomainWithManager(
         appDomainFriendlyNameW,