Skip to content

Commit

Permalink
Add DOTNET_MODIFIABLE_ASSEMBLIES env var for hot reload support (dotn…
Browse files Browse the repository at this point in the history
…et#48731)

Add EXTERNAL_DOTNET_MODIFIABLE_ASSEMBLIES env var for hot reload support
  • Loading branch information
mikem8361 authored Feb 25, 2021
1 parent cbc05c4 commit 9981ccb
Show file tree
Hide file tree
Showing 7 changed files with 22 additions and 47 deletions.
1 change: 1 addition & 0 deletions src/coreclr/inc/clrconfigvalues.h
Original file line number Diff line number Diff line change
Expand Up @@ -450,6 +450,7 @@ CONFIG_DWORD_INFO_EX(INTERNAL_MD_MiniMDBreak, W("MD_MiniMDBreak"), 0, "ASSERT wh
CONFIG_DWORD_INFO_EX(INTERNAL_MD_PreSaveBreak, W("MD_PreSaveBreak"), 0, "ASSERT when calling CMiniMdRw::PreSave", CLRConfig::EEConfig_default)
CONFIG_DWORD_INFO_EX(INTERNAL_MD_RegMetaBreak, W("MD_RegMetaBreak"), 0, "ASSERT when creating RegMeta class", CLRConfig::EEConfig_default)
CONFIG_DWORD_INFO_EX(INTERNAL_MD_RegMetaDump, W("MD_RegMetaDump"), 0, "Dump MD in 4 functions (?)", CLRConfig::EEConfig_default)
RETAIL_CONFIG_STRING_INFO_EX(EXTERNAL_DOTNET_MODIFIABLE_ASSEMBLIES, W("DOTNET_MODIFIABLE_ASSEMBLIES"), "Enables hot reload on debug built assemblies with the 'debug' keyword", CLRConfig::DontPrependCOMPlus_ | CLRConfig::TrimWhiteSpaceFromStringValue);

// Metadata - mscordbi only - this flag is only intended to mitigate potential issues in bug fix 458597.
RETAIL_CONFIG_DWORD_INFO_EX(EXTERNAL_MD_PreserveDebuggerMetadataMemory, W("MD_PreserveDebuggerMetadataMemory"), 0, "Save all versions of metadata memory in the debugger when debuggee metadata is updated", CLRConfig::EEConfig_default)
Expand Down
21 changes: 6 additions & 15 deletions src/coreclr/vm/ceeload.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -686,11 +686,6 @@ void Module::Initialize(AllocMemTracker *pamTracker, LPCWSTR szName)
Module::CreateAssemblyRefByNameTable(pamTracker);
}

// If the program has the "ForceEnc" env variable set we ensure every eligible
// module has EnC turned on.
if (g_pConfig->ForceEnc() && IsEditAndContinueCapable())
EnableEditAndContinue();

#if defined(PROFILING_SUPPORTED) && !defined(DACCESS_COMPILE) && !defined(CROSSGEN_COMPILE)
m_pJitInlinerTrackingMap = NULL;
if (ReJitManager::IsReJITInlineTrackingEnabled())
Expand Down Expand Up @@ -1078,17 +1073,13 @@ void Module::SetDebuggerInfoBits(DebuggerAssemblyControlFlags newBits)
m_dwTransientFlags |= (newBits << DEBUGGER_INFO_SHIFT_PRIV);

#ifdef DEBUGGING_SUPPORTED
BOOL setEnC = ((newBits & DACF_ENC_ENABLED) != 0) && IsEditAndContinueCapable();

// The only way can change Enc is through debugger override.
if (setEnC)
if (IsEditAndContinueCapable())
{
EnableEditAndContinue();
}
else
{
if (!g_pConfig->ForceEnc())
DisableEditAndContinue();
BOOL setEnC = (newBits & DACF_ENC_ENABLED) != 0 || g_pConfig->ForceEnc() || (g_pConfig->DebugAssembliesModifiable() && CORDisableJITOptimizations(GetDebuggerInfoBits()));
if (setEnC)
{
EnableEditAndContinue();
}
}
#endif // DEBUGGING_SUPPORTED

Expand Down
22 changes: 4 additions & 18 deletions src/coreclr/vm/ceeload.h
Original file line number Diff line number Diff line change
Expand Up @@ -1769,27 +1769,22 @@ class Module
return m_moduleRef;
}


BOOL IsResource() const { WRAPPER_NO_CONTRACT; SUPPORTS_DAC; return GetFile()->IsResource(); }
BOOL IsPEFile() const { WRAPPER_NO_CONTRACT; return !GetFile()->IsDynamic(); }
BOOL IsReflection() const { WRAPPER_NO_CONTRACT; SUPPORTS_DAC; return GetFile()->IsDynamic(); }
BOOL IsIbcOptimized() const { WRAPPER_NO_CONTRACT; return GetFile()->IsIbcOptimized(); }
// Returns true iff the debugger can see this module.
BOOL IsVisibleToDebugger();


BOOL IsEditAndContinueEnabled()
{
LIMITED_METHOD_CONTRACT;
SUPPORTS_DAC;
// We are seeing cases where this flag is set for a module that is not an EditAndContinueModule. This should
// never happen unless the module is EditAndContinueCapable, in which case we would have created an EditAndContinueModule
// not a Module.
//_ASSERTE((m_dwTransientFlags & IS_EDIT_AND_CONTINUE) == 0 || IsEditAndContinueCapable());
return (IsEditAndContinueCapable()) && ((m_dwTransientFlags & IS_EDIT_AND_CONTINUE) != 0);
_ASSERTE((m_dwTransientFlags & IS_EDIT_AND_CONTINUE) == 0 || IsEditAndContinueCapable());
return (m_dwTransientFlags & IS_EDIT_AND_CONTINUE) != 0;
}

BOOL IsEditAndContinueCapable();
virtual BOOL IsEditAndContinueCapable() const { return FALSE; }

BOOL IsIStream() { LIMITED_METHOD_CONTRACT; return GetFile()->IsIStream(); }

Expand All @@ -1801,20 +1796,11 @@ class Module
{
LIMITED_METHOD_CONTRACT;
SUPPORTS_DAC;
// _ASSERTE(IsEditAndContinueCapable());
_ASSERTE(IsEditAndContinueCapable());
LOG((LF_ENC, LL_INFO100, "EnableEditAndContinue: this:0x%x, %s\n", this, GetDebugName()));
m_dwTransientFlags |= IS_EDIT_AND_CONTINUE;
}

void DisableEditAndContinue()
{
LIMITED_METHOD_CONTRACT;
SUPPORTS_DAC;
// don't _ASSERTE(IsEditAndContinueCapable());
LOG((LF_ENC, LL_INFO100, "DisableEditAndContinue: this:0x%x, %s\n", this, GetDebugName()));
m_dwTransientFlags = m_dwTransientFlags.Load() & (~IS_EDIT_AND_CONTINUE);
}

BOOL IsTenured()
{
LIMITED_METHOD_CONTRACT;
Expand Down
14 changes: 0 additions & 14 deletions src/coreclr/vm/ceeload.inl
Original file line number Diff line number Diff line change
Expand Up @@ -453,20 +453,6 @@ inline mdAssemblyRef Module::FindAssemblyRef(Assembly *targetAssembly)

#endif //DACCESS_COMPILE

inline BOOL Module::IsEditAndContinueCapable()
{
WRAPPER_NO_CONTRACT;
SUPPORTS_DAC;

BOOL isEnCCapable = IsEditAndContinueCapable(m_pAssembly, m_file);

// for now, Module::IsReflection is equivalent to m_file->IsDynamic,
// which is checked by IsEditAndContinueCapable(m_pAssembly, m_file)
_ASSERTE(!isEnCCapable || (!this->IsReflection()));

return isEnCCapable;
}

FORCEINLINE PTR_DomainLocalModule Module::GetDomainLocalModule()
{
WRAPPER_NO_CONTRACT;
Expand Down
7 changes: 7 additions & 0 deletions src/coreclr/vm/eeconfig.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -584,6 +584,13 @@ fTrackDynamicMethodDebugInfo = CLRConfig::GetConfigValue(CLRConfig::UNSUPPORTED_
fStressLog = GetConfigDWORD_DontUse_(CLRConfig::UNSUPPORTED_StressLog, fStressLog) != 0;
fForceEnc = GetConfigDWORD_DontUse_(CLRConfig::UNSUPPORTED_ForceEnc, fForceEnc) != 0;

{
NewArrayHolder<WCHAR> wszModifiableAssemblies;
IfFailRet(CLRConfig::GetConfigValue(CLRConfig::EXTERNAL_DOTNET_MODIFIABLE_ASSEMBLIES, &wszModifiableAssemblies));
if (wszModifiableAssemblies)
fDebugAssembliesModifiable = _wcsicmp(wszModifiableAssemblies, W("debug")) == 0;
}

iRequireZaps = RequireZapsType(GetConfigDWORD_DontUse_(CLRConfig::EXTERNAL_ZapRequire, iRequireZaps));
if (IsCompilationProcess() || iRequireZaps >= REQUIRE_ZAPS_COUNT)
iRequireZaps = REQUIRE_ZAPS_NONE;
Expand Down
2 changes: 2 additions & 0 deletions src/coreclr/vm/eeconfig.h
Original file line number Diff line number Diff line change
Expand Up @@ -463,6 +463,7 @@ class EEConfig

bool StressLog() const { LIMITED_METHOD_CONTRACT; return fStressLog; }
bool ForceEnc() const { LIMITED_METHOD_CONTRACT; return fForceEnc; }
bool DebugAssembliesModifiable() const { LIMITED_METHOD_CONTRACT; return fDebugAssembliesModifiable; }

// Optimizations to improve working set

Expand Down Expand Up @@ -691,6 +692,7 @@ class EEConfig

bool fStressLog;
bool fForceEnc;
bool fDebugAssembliesModifiable;
bool fProbeForStackOverflow;

// Stackwalk optimization flag
Expand Down
2 changes: 2 additions & 0 deletions src/coreclr/vm/encee.h
Original file line number Diff line number Diff line change
Expand Up @@ -224,6 +224,8 @@ class EditAndContinueModule : public Module
virtual void Destruct();
#endif

virtual BOOL IsEditAndContinueCapable() const { return TRUE; }

// Apply an EnC edit
HRESULT ApplyEditAndContinue(DWORD cbMetadata,
BYTE *pMetadata,
Expand Down

0 comments on commit 9981ccb

Please sign in to comment.