Skip to content
This repository was archived by the owner on Jan 23, 2023. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
110 changes: 40 additions & 70 deletions src/dlls/mscoree/unixinterface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,15 @@
//*****************************************************************************
// unixinterface.cpp
//
// Implementation for the interface exposed by the libcoreclr.so on Unix
// Implementation for the interface exposed by libcoreclr.so
//

//*****************************************************************************

#include "stdafx.h"
#include <utilcode.h>
#include <corhost.h>
#include <configuration.h>

typedef int (STDMETHODCALLTYPE *HostMain)(
const int argc,
Expand Down Expand Up @@ -86,76 +87,47 @@ static LPCWSTR* StringArrayToUnicode(int argc, LPCSTR* argv)
return argvW;
}

static void ExtractStartupFlagsAndConvertToUnicode(
static void InitializeStartupFlags(STARTUP_FLAGS* startupFlagsRef)
{
STARTUP_FLAGS startupFlags = static_cast<STARTUP_FLAGS>(
STARTUP_FLAGS::STARTUP_LOADER_OPTIMIZATION_SINGLE_DOMAIN |
STARTUP_FLAGS::STARTUP_SINGLE_APPDOMAIN);

if (Configuration::GetKnobBooleanValue(W("System.GC.Concurrent"), CLRConfig::UNSUPPORTED_gcConcurrent))
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we don't really need to set this flag anymore. For CoreCLR, we're going to default to concurrent GC enabled anyway, so the flag doesn't really do anything. To disable concurrent GC, the user will either set "System.GC.Concurrent" to false or set the COMPlus value to false.

Any thoughts?

{
startupFlags = static_cast<STARTUP_FLAGS>(startupFlags | STARTUP_CONCURRENT_GC);
}
if (Configuration::GetKnobBooleanValue(W("System.GC.Server"), CLRConfig::UNSUPPORTED_gcServer))
{
startupFlags = static_cast<STARTUP_FLAGS>(startupFlags | STARTUP_SERVER_GC);
}
if (Configuration::GetKnobBooleanValue(W("System.GC.RetainVM"), CLRConfig::UNSUPPORTED_GCRetainVM))
{
startupFlags = static_cast<STARTUP_FLAGS>(startupFlags | STARTUP_HOARD_GC_VM);
}

*startupFlagsRef = startupFlags;
}

static void ConvertConfigPropertiesToUnicode(
const char** propertyKeys,
const char** propertyValues,
int* propertyCountRef,
STARTUP_FLAGS* startupFlagsRef,
int propertyCount,
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;
propertyKeysW[propertyIndex] = StringToUnicode(propertyKeys[propertyIndex]);
propertyValuesW[propertyIndex] = StringToUnicode(propertyValues[propertyIndex]);
}

*propertyCountRef = propertyCountW;
*startupFlagsRef = startupFlags;
*propertyKeysWRef = propertyKeysW;
*propertyValuesWRef = propertyValuesW;
}
Expand Down Expand Up @@ -205,22 +177,20 @@ int coreclr_initialize(

ConstWStringHolder appDomainFriendlyNameW = StringToUnicode(appDomainFriendlyName);

STARTUP_FLAGS startupFlags;
LPCWSTR* propertyKeysWTemp;
LPCWSTR* propertyValuesWTemp;
ExtractStartupFlagsAndConvertToUnicode(
LPCWSTR* propertyKeysW;
LPCWSTR* propertyValuesW;
ConvertConfigPropertiesToUnicode(
propertyKeys,
propertyValues,
&propertyCount,
&startupFlags,
&propertyKeysWTemp,
&propertyValuesWTemp);

ConstWStringArrayHolder propertyKeysW;
propertyKeysW.Set(propertyKeysWTemp, propertyCount);

ConstWStringArrayHolder propertyValuesW;
propertyValuesW.Set(propertyValuesWTemp, propertyCount);
propertyCount,
&propertyKeysW,
&propertyValuesW);

// This will take ownership of propertyKeysWTemp and propertyValuesWTemp
Configuration::InitializeConfigurationKnobs(propertyCount, propertyKeysW, propertyValuesW);

STARTUP_FLAGS startupFlags;
InitializeStartupFlags(&startupFlags);

hr = host->SetStartupFlags(startupFlags);
IfFailRet(hr);
Expand Down
5 changes: 4 additions & 1 deletion src/inc/clrconfig.h
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,10 @@ class CLRConfig

// Look up a DWORD config value.
static DWORD GetConfigValue(const ConfigDWORDInfo & info);


// Look up a DWORD config value.
static DWORD GetConfigValue(const ConfigDWORDInfo & info, bool acceptExplicitDefaultFromRegutil, /* [Out] */ bool *isDefault);

// Look up a string config value.
// You own the string that's returned.
static LPWSTR GetConfigValue(const ConfigStringInfo & info);
Expand Down
3 changes: 2 additions & 1 deletion src/inc/clrconfigvalues.h
Original file line number Diff line number Diff line change
Expand Up @@ -309,6 +309,7 @@ CONFIG_DWORD_INFO(INTERNAL_FastGCCheckStack, W("FastGCCheckStack"), 0, "")
CONFIG_DWORD_INFO_DIRECT_ACCESS(INTERNAL_FastGCStress, W("FastGCStress"), "reduce the number of GCs done by enabling GCStress")
RETAIL_CONFIG_DWORD_INFO_DIRECT_ACCESS(UNSUPPORTED_GCBreakOnOOM, W("GCBreakOnOOM"), "Does a DebugBreak at the soonest time we detect an OOM")
RETAIL_CONFIG_DWORD_INFO(UNSUPPORTED_gcConcurrent, W("gcConcurrent"), (DWORD)-1, "Enables/Disables concurrent GC")

#ifdef FEATURE_CONSERVATIVE_GC
RETAIL_CONFIG_DWORD_INFO(UNSUPPORTED_gcConservative, W("gcConservative"), 0, "Enables/Disables conservative GC")
#endif
Expand All @@ -335,7 +336,7 @@ RETAIL_CONFIG_DWORD_INFO(UNSUPPORTED_GCCompactRatio, W("GCCompactRatio"), 0, "Sp
RETAIL_CONFIG_DWORD_INFO_DIRECT_ACCESS(EXTERNAL_GCPollType, W("GCPollType"), "")
RETAIL_CONFIG_STRING_INFO_EX(EXTERNAL_NewGCCalc, W("NewGCCalc"), "", CLRConfig::REGUTIL_default)
RETAIL_CONFIG_DWORD_INFO_DIRECT_ACCESS(UNSUPPORTED_GCprnLvl, W("GCprnLvl"), "Specifies the maximum level of GC logging")
RETAIL_CONFIG_DWORD_INFO_DIRECT_ACCESS(UNSUPPORTED_GCRetainVM, W("GCRetainVM"), "When set we put the segments that should be deleted on a standby list (instead of releasing them back to the OS) which will be considered to satisfy new segment requests (note that the same thing can be specified via API which is the supported way)")
RETAIL_CONFIG_DWORD_INFO(UNSUPPORTED_GCRetainVM, W("GCRetainVM"), 0, "When set we put the segments that should be deleted on a standby list (instead of releasing them back to the OS) which will be considered to satisfy new segment requests (note that the same thing can be specified via API which is the supported way)")
RETAIL_CONFIG_DWORD_INFO_DIRECT_ACCESS(UNSUPPORTED_GCSegmentSize, W("GCSegmentSize"), "Specifies the managed heap segment size")
RETAIL_CONFIG_DWORD_INFO_DIRECT_ACCESS(UNSUPPORTED_GCLOHCompact, W("GCLOHCompact"), "Specifies the LOH compaction mode")
RETAIL_CONFIG_DWORD_INFO(EXTERNAL_gcAllowVeryLargeObjects, W("gcAllowVeryLargeObjects"), 0, "allow allocation of 2GB+ objects on GC heap")
Expand Down
57 changes: 57 additions & 0 deletions src/inc/configuration.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
//
// --------------------------------------------------------------------------------------------------
// configuration.h
//
//
// Access and update configuration values, falling back on legacy CLRConfig methods where necessary.
//
// --------------------------------------------------------------------------------------------------

#include "clrconfig.h"

#ifndef __configuration_h__
#define __configuration_h__

class Configuration
{
public:
static void InitializeConfigurationKnobs(int numberOfConfigs, LPCWSTR *configNames, LPCWSTR *configValues);

// Returns (in priority order):
// - The value of the ConfigDWORDInfo if it's set
// - The value of the ConfigurationKnob (searched by name) if it's set (performs a wcstoul).
// - The default set in the ConfigDWORDInfo
static DWORD GetKnobDWORDValue(LPCWSTR name, const CLRConfig::ConfigDWORDInfo& dwordInfo);

// Returns (in priority order):
// - The value of the ConfigurationKnob (searched by name) if it's set (performs a wcstoul)
// - The default value passed in
static DWORD GetKnobDWORDValue(LPCWSTR name, DWORD defaultValue);

// Returns (in priority order):
// - The value of the ConfigStringInfo if it's set
// - The value of the ConfigurationKnob (searched by name) if it's set
// - nullptr
static LPCWSTR GetKnobStringValue(LPCWSTR name, const CLRConfig::ConfigStringInfo& stringInfo);

// Returns (in priority order):
// - The value of the ConfigurationKnob (searched by name) if it's set
// - nullptr
static LPCWSTR GetKnobStringValue(LPCWSTR name);

// Returns (in priority order):
// - The value of the ConfigDWORDInfo if it's set (1 is true, anything else is false)
// - The value of the ConfigurationKnob (searched by name) if it's set (performs a wcscmp with "true").
// - The default set in the ConfigDWORDInfo (1 is true, anything else is false)
static bool GetKnobBooleanValue(LPCWSTR name, const CLRConfig::ConfigDWORDInfo& dwordInfo);

// Returns (in priority order):
// - The value of the ConfigurationKnob (searched by name) if it's set (performs a wcscmp with "true").
// - The default value passed in
static bool GetKnobBooleanValue(LPCWSTR name, bool defaultValue);
};

#endif // __configuration_h__
1 change: 1 addition & 0 deletions src/utilcode/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ set(UTILCODE_COMMON_SOURCES
makepath.cpp
splitpath.cpp
clrconfig.cpp
configuration.cpp
collections.cpp
posterror.cpp
fstream.cpp
Expand Down
3 changes: 3 additions & 0 deletions src/utilcode/UtilCode.vcproj
Original file line number Diff line number Diff line change
Expand Up @@ -375,6 +375,9 @@
<File
RelativePath=".\CLRConfig.cpp"
>
<File
RelativePath=".\configuration.cpp"
>
</File>
<File
RelativePath=".\clrhost.cpp"
Expand Down
1 change: 1 addition & 0 deletions src/utilcode/UtilCode.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -382,6 +382,7 @@
<ClCompile Include="check.cpp" />
<ClCompile Include="circularlog.cpp" />
<ClCompile Include="CLRConfig.cpp" />
<ClCompile Include="configuration.cpp" />
<ClCompile Include="clrhost.cpp" />
<ClCompile Include="COMEx.cpp" />
<ClCompile Include="corimage.cpp" />
Expand Down
Loading