summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/.nuget/Microsoft.NETCore.Jit/runtime.Windows_NT.Microsoft.NETCore.Jit.props2
-rw-r--r--src/.nuget/Microsoft.NETCore.Runtime.CoreCLR/runtime.Linux.Microsoft.NETCore.Runtime.CoreCLR.props6
-rw-r--r--src/.nuget/Microsoft.NETCore.Runtime.CoreCLR/runtime.Windows_NT.Microsoft.NETCore.Runtime.CoreCLR.props1
-rw-r--r--src/.nuget/dir.targets4
-rw-r--r--src/classlibnative/bcltype/system.cpp91
-rw-r--r--src/classlibnative/bcltype/system.h3
-rw-r--r--src/debug/daccess/dacdbiimpl.cpp4
-rw-r--r--src/debug/daccess/enummem.cpp4
-rw-r--r--src/debug/daccess/request.cpp28
-rw-r--r--src/debug/daccess/request_svr.cpp2
-rw-r--r--src/debug/di/process.cpp8
-rw-r--r--src/gc/env/gcenv.ee.h4
-rw-r--r--src/gc/gc.cpp80
-rw-r--r--src/gc/gc.h20
-rw-r--r--src/gc/gccommon.cpp16
-rw-r--r--src/gc/gcenv.ee.standalone.inl18
-rw-r--r--src/gc/gchandletable.cpp10
-rw-r--r--src/gc/gchandletableimpl.h4
-rw-r--r--src/gc/gcinterface.dac.h6
-rw-r--r--src/gc/gcinterface.dacvars.def1
-rw-r--r--src/gc/gcinterface.ee.h24
-rw-r--r--src/gc/gcinterface.h28
-rw-r--r--src/gc/handletable.h5
-rw-r--r--src/gc/objecthandle.h3
-rw-r--r--src/gc/sample/GCSample.cpp10
-rw-r--r--src/gc/sample/gcenv.ee.cpp16
-rw-r--r--src/gc/windows/gcenv.windows.cpp3
-rw-r--r--src/inc/corbbtprof.h27
-rw-r--r--src/inc/corhdr.h1
-rw-r--r--src/inc/corinfo.h13
-rw-r--r--src/inc/corjit.h2
-rw-r--r--src/inc/crosscomp.h4
-rw-r--r--src/inc/daccess.h4
-rw-r--r--src/inc/dacvars.h6
-rw-r--r--src/inc/eventtracebase.h10
-rw-r--r--src/inc/legacyactivationshim.h1382
-rw-r--r--src/inc/legacyactivationshimdelayload.h13
-rw-r--r--src/inc/winwrap.h3
-rw-r--r--src/jit/CMakeLists.txt15
-rwxr-xr-xsrc/jit/_typeinfo.h51
-rw-r--r--src/jit/codegenarm.cpp343
-rw-r--r--src/jit/codegenarm64.cpp47
-rw-r--r--src/jit/codegencommon.cpp58
-rw-r--r--src/jit/codegenlegacy.cpp2
-rw-r--r--src/jit/compiler.cpp6
-rw-r--r--src/jit/compiler.h11
-rw-r--r--src/jit/flowgraph.cpp70
-rw-r--r--src/jit/gentree.cpp8
-rw-r--r--src/jit/importer.cpp87
-rw-r--r--src/jit/jit.h17
-rw-r--r--src/jit/jitee.h4
-rw-r--r--src/jit/lclvars.cpp42
-rw-r--r--src/jit/legacynonjit/.gitmirror (renamed from src/jit/compatjit/.gitmirror)0
-rw-r--r--src/jit/legacynonjit/CMakeLists.txt (renamed from src/jit/compatjit/CMakeLists.txt)32
-rw-r--r--src/jit/legacynonjit/legacynonjit.def7
-rw-r--r--src/jit/lower.cpp20
-rw-r--r--src/jit/lsraarm.cpp92
-rw-r--r--src/jit/protononjit/CMakeLists.txt11
-rw-r--r--src/md/compiler/mdvalidator.cpp2
-rw-r--r--src/mscorlib/Resources/Strings.resx11
-rw-r--r--src/mscorlib/System.Private.CoreLib.csproj68
-rw-r--r--src/mscorlib/shared/Interop/Unix/System.Globalization.Native/Interop.Calendar.cs (renamed from src/mscorlib/src/Interop/Unix/System.Globalization.Native/Interop.Calendar.cs)0
-rw-r--r--src/mscorlib/shared/Interop/Unix/System.Globalization.Native/Interop.Casing.cs (renamed from src/mscorlib/src/Interop/Unix/System.Globalization.Native/Interop.Casing.cs)0
-rw-r--r--src/mscorlib/shared/Interop/Unix/System.Globalization.Native/Interop.Idna.cs (renamed from src/mscorlib/src/Interop/Unix/System.Globalization.Native/Interop.Idna.cs)0
-rw-r--r--src/mscorlib/shared/Interop/Unix/System.Globalization.Native/Interop.Locale.cs (renamed from src/mscorlib/src/Interop/Unix/System.Globalization.Native/Interop.Locale.cs)0
-rw-r--r--src/mscorlib/shared/Interop/Unix/System.Globalization.Native/Interop.Normalization.cs (renamed from src/mscorlib/src/Interop/Unix/System.Globalization.Native/Interop.Normalization.cs)0
-rw-r--r--src/mscorlib/shared/Interop/Unix/System.Globalization.Native/Interop.ResultCode.cs (renamed from src/mscorlib/src/Interop/Unix/System.Globalization.Native/Interop.ResultCode.cs)0
-rw-r--r--src/mscorlib/shared/Interop/Unix/System.Globalization.Native/Interop.TimeZoneInfo.cs (renamed from src/mscorlib/src/Interop/Unix/System.Globalization.Native/Interop.TimeZoneInfo.cs)0
-rw-r--r--src/mscorlib/shared/Interop/Unix/System.Globalization.Native/Interop.Utils.cs (renamed from src/mscorlib/src/Interop/Unix/System.Globalization.Native/Interop.Utils.cs)0
-rw-r--r--src/mscorlib/shared/Interop/Windows/Crypt32/Interop.CryptProtectMemory.cs (renamed from src/mscorlib/src/Interop/Windows/Crypt32/Interop.CryptProtectMemory.cs)0
-rw-r--r--src/mscorlib/shared/Interop/Windows/Interop.Errors.cs1
-rw-r--r--src/mscorlib/shared/Interop/Windows/Kernel32/Interop.WideCharToMultiByte.cs (renamed from src/mscorlib/src/Interop/Windows/kernel32/Interop.WideCharToMultiByte.cs)0
-rw-r--r--src/mscorlib/shared/System.Private.CoreLib.Shared.projitems59
-rw-r--r--src/mscorlib/shared/System/AssemblyLoadEventArgs.cs18
-rw-r--r--src/mscorlib/shared/System/AssemblyLoadEventHandler.cs8
-rw-r--r--src/mscorlib/shared/System/CurrentSystemTimeZone.cs (renamed from src/mscorlib/src/System/CurrentTimeZone.cs)61
-rw-r--r--src/mscorlib/shared/System/Globalization/CalendarAlgorithmType.cs (renamed from src/mscorlib/src/System/Globalization/CalendarAlgorithmType.cs)2
-rw-r--r--src/mscorlib/shared/System/Globalization/CalendarWeekRule.cs (renamed from src/mscorlib/src/System/Globalization/CalendarWeekRule.cs)2
-rw-r--r--src/mscorlib/shared/System/Globalization/CalendricalCalculationsHelper.cs (renamed from src/mscorlib/src/System/Globalization/CalendricalCalculationsHelper.cs)0
-rw-r--r--src/mscorlib/shared/System/Globalization/ChineseLunisolarCalendar.cs (renamed from src/mscorlib/src/System/Globalization/ChineseLunisolarCalendar.cs)6
-rw-r--r--src/mscorlib/shared/System/Globalization/CultureNotFoundException.cs (renamed from src/mscorlib/src/System/Globalization/CultureNotFoundException.cs)4
-rw-r--r--src/mscorlib/shared/System/Globalization/CultureTypes.cs27
-rw-r--r--src/mscorlib/shared/System/Globalization/DateTimeFormat.cs9
-rw-r--r--src/mscorlib/shared/System/Globalization/DateTimeFormatInfoScanner.cs3
-rw-r--r--src/mscorlib/shared/System/Globalization/DateTimeParse.cs29
-rw-r--r--src/mscorlib/shared/System/Globalization/DateTimeStyles.cs (renamed from src/mscorlib/src/System/Globalization/DateTimeStyles.cs)1
-rw-r--r--src/mscorlib/shared/System/Globalization/DaylightTime.cs (renamed from src/mscorlib/src/System/Globalization/DaylightTime.cs)2
-rw-r--r--src/mscorlib/shared/System/Globalization/DigitShapes.cs (renamed from src/mscorlib/src/System/Globalization/DigitShapes.cs)5
-rw-r--r--src/mscorlib/shared/System/Globalization/EastAsianLunisolarCalendar.cs (renamed from src/mscorlib/src/System/Globalization/EastAsianLunisolarCalendar.cs)7
-rw-r--r--src/mscorlib/shared/System/Globalization/GregorianCalendarTypes.cs (renamed from src/mscorlib/src/System/Globalization/GregorianCalendarTypes.cs)2
-rw-r--r--src/mscorlib/shared/System/Globalization/HebrewCalendar.cs (renamed from src/mscorlib/src/System/Globalization/HebrewCalendar.cs)0
-rw-r--r--src/mscorlib/shared/System/Globalization/HebrewNumber.cs (renamed from src/mscorlib/src/System/Globalization/HebrewNumber.cs)0
-rw-r--r--src/mscorlib/shared/System/Globalization/HijriCalendar.cs (renamed from src/mscorlib/src/System/Globalization/HijriCalendar.cs)2
-rw-r--r--src/mscorlib/shared/System/Globalization/InternalGlobalizationHelper.cs (renamed from src/mscorlib/src/System/Globalization/InternalGlobalizationHelper.cs)4
-rw-r--r--src/mscorlib/shared/System/Globalization/JapaneseCalendar.cs (renamed from src/mscorlib/src/System/Globalization/JapaneseCalendar.cs)2
-rw-r--r--src/mscorlib/shared/System/Globalization/JapaneseLunisolarCalendar.cs (renamed from src/mscorlib/src/System/Globalization/JapaneseLunisolarCalendar.cs)6
-rw-r--r--src/mscorlib/shared/System/Globalization/JulianCalendar.cs (renamed from src/mscorlib/src/System/Globalization/JulianCalendar.cs)1
-rw-r--r--src/mscorlib/shared/System/Globalization/KoreanCalendar.cs (renamed from src/mscorlib/src/System/Globalization/KoreanCalendar.cs)1
-rw-r--r--src/mscorlib/shared/System/Globalization/KoreanLunisolarCalendar.cs (renamed from src/mscorlib/src/System/Globalization/KoreanLunisolarCalendar.cs)6
-rw-r--r--src/mscorlib/shared/System/Globalization/LocaleData.Unix.cs (renamed from src/mscorlib/src/System/Globalization/LocaleData.Unix.cs)0
-rw-r--r--src/mscorlib/shared/System/Globalization/NumberStyles.cs (renamed from src/mscorlib/src/System/Globalization/NumberStyles.cs)3
-rw-r--r--src/mscorlib/shared/System/Globalization/PersianCalendar.cs (renamed from src/mscorlib/src/System/Globalization/PersianCalendar.cs)5
-rw-r--r--src/mscorlib/shared/System/Globalization/SortVersion.cs (renamed from src/mscorlib/src/System/Globalization/SortVersion.cs)3
-rw-r--r--src/mscorlib/shared/System/Globalization/TaiwanCalendar.cs (renamed from src/mscorlib/src/System/Globalization/TaiwanCalendar.cs)0
-rw-r--r--src/mscorlib/shared/System/Globalization/TaiwanLunisolarCalendar.cs (renamed from src/mscorlib/src/System/Globalization/TaiwanLunisolarCalendar.cs)13
-rw-r--r--src/mscorlib/shared/System/Globalization/ThaiBuddhistCalendar.cs (renamed from src/mscorlib/src/System/Globalization/ThaiBuddhistCalendar.cs)0
-rw-r--r--src/mscorlib/shared/System/Globalization/TimeSpanStyles.cs (renamed from src/mscorlib/src/System/Globalization/TimeSpanStyles.cs)0
-rw-r--r--src/mscorlib/shared/System/Globalization/UmAlQuraCalendar.cs (renamed from src/mscorlib/src/System/Globalization/UmAlQuraCalendar.cs)5
-rw-r--r--src/mscorlib/shared/System/Globalization/UnicodeCategory.cs (renamed from src/mscorlib/src/System/Globalization/UnicodeCategory.cs)30
-rw-r--r--src/mscorlib/shared/System/IO/StreamHelpers.CopyValidation.cs (renamed from src/mscorlib/src/System/IO/StreamHelpers.CopyValidation.cs)0
-rw-r--r--src/mscorlib/shared/System/ResolveEventArgs.cs25
-rw-r--r--src/mscorlib/shared/System/ResolveEventHandler.cs10
-rw-r--r--src/mscorlib/shared/System/Security/SecureString.Unix.cs (renamed from src/mscorlib/src/System/Security/SecureString.Unix.cs)0
-rw-r--r--src/mscorlib/shared/System/Security/SecureString.cs (renamed from src/mscorlib/src/System/Security/SecureString.cs)0
-rw-r--r--src/mscorlib/shared/System/Threading/Tasks/TaskCanceledException.cs (renamed from src/mscorlib/src/System/Threading/Tasks/TaskCanceledException.cs)0
-rw-r--r--src/mscorlib/shared/System/Threading/Tasks/TaskExtensions.cs (renamed from src/mscorlib/src/System/Threading/Tasks/TaskExtensions.cs)0
-rw-r--r--src/mscorlib/shared/System/Threading/Tasks/TaskSchedulerException.cs (renamed from src/mscorlib/src/System/Threading/Tasks/TaskSchedulerException.cs)0
-rw-r--r--src/mscorlib/shared/System/TimeZone.cs (renamed from src/mscorlib/src/System/TimeZone.cs)0
-rw-r--r--src/mscorlib/shared/System/TypeUnloadedException.cs (renamed from src/mscorlib/src/System/TypeUnloadedException.cs)17
-rw-r--r--src/mscorlib/src/Debug.cs29
-rw-r--r--src/mscorlib/src/Interop/Unix/System.Globalization.Native/Interop.Collation.cs1
-rw-r--r--src/mscorlib/src/Interop/Unix/System.Native/Interop.SysLog.cs58
-rw-r--r--src/mscorlib/src/Interop/Windows/kernel32/Interop.OutputDebugString.cs14
-rw-r--r--src/mscorlib/src/Microsoft/Win32/RegistryKey.cs250
-rw-r--r--src/mscorlib/src/Microsoft/Win32/Win32Native.cs14
-rw-r--r--src/mscorlib/src/System/AppDomain.cs57
-rw-r--r--src/mscorlib/src/System/AppDomainManager.cs5
-rw-r--r--src/mscorlib/src/System/AppDomainSetup.cs270
-rw-r--r--src/mscorlib/src/System/ArraySegment.cs1
-rw-r--r--src/mscorlib/src/System/CurrentSystemTimeZone.Cache.cs35
-rw-r--r--src/mscorlib/src/System/Diagnostics/Debug.Unix.cs95
-rw-r--r--src/mscorlib/src/System/Diagnostics/Debug.Windows.cs63
-rw-r--r--src/mscorlib/src/System/Diagnostics/Debug.cs323
-rw-r--r--src/mscorlib/src/System/Diagnostics/Eventing/EventSource.cs3
-rw-r--r--src/mscorlib/src/System/Enum.cs2
-rw-r--r--src/mscorlib/src/System/Environment.cs87
-rw-r--r--src/mscorlib/src/System/Globalization/Calendar.cs2
-rw-r--r--src/mscorlib/src/System/Globalization/CalendarData.Windows.cs1
-rw-r--r--src/mscorlib/src/System/Globalization/CultureInfo.Unix.cs1
-rw-r--r--src/mscorlib/src/System/Globalization/CultureInfo.Windows.cs2
-rw-r--r--src/mscorlib/src/System/Globalization/CultureTypes.cs28
-rw-r--r--src/mscorlib/src/System/Globalization/GregorianCalendarHelper.cs2
-rw-r--r--src/mscorlib/src/System/Globalization/IdnMapping.Unix.cs2
-rw-r--r--src/mscorlib/src/System/Globalization/IdnMapping.cs1
-rw-r--r--src/mscorlib/src/System/Globalization/JapaneseCalendar.Unix.cs1
-rw-r--r--src/mscorlib/src/System/Guid.cs75
-rw-r--r--src/mscorlib/src/System/Reflection/LocalVariableInfo.cs2
-rw-r--r--src/mscorlib/src/System/Reflection/RuntimeEventInfo.cs1
-rw-r--r--src/mscorlib/src/System/Reflection/RuntimeParameterInfo.cs1
-rw-r--r--src/mscorlib/src/System/Runtime/CompilerServices/ConditionalWeakTable.cs1
-rw-r--r--src/mscorlib/src/System/Runtime/Serialization/FormatterServices.cs24
-rw-r--r--src/mscorlib/src/System/Security/SecurityState.cs25
-rw-r--r--src/mscorlib/src/System/Security/Util/URLString.cs138
-rw-r--r--src/mscorlib/src/System/Span.cs45
-rw-r--r--src/mscorlib/src/System/ThrowHelper.cs1
-rw-r--r--src/mscorlib/src/System/TimeZoneInfo.Win32.cs1
-rw-r--r--src/mscorlib/src/System/TimeZoneInfo.cs1
-rw-r--r--src/pal/inc/pal.h12
-rw-r--r--src/pal/inc/palprivate.h6
-rw-r--r--src/pal/src/CMakeLists.txt1
-rw-r--r--src/pal/src/arch/i386/exceptionhelper.S14
-rw-r--r--src/pal/src/cruntime/misctls.cpp308
-rw-r--r--src/pal/src/misc/environ.cpp8
-rw-r--r--src/pal/src/misc/errorstrings.cpp2
-rw-r--r--src/pal/src/misc/version.cpp119
-rw-r--r--src/pal/tests/palsuite/miscellaneous/GetVersionExA/CMakeLists.txt4
-rw-r--r--src/pal/tests/palsuite/miscellaneous/GetVersionExA/test1/CMakeLists.txt17
-rw-r--r--src/pal/tests/palsuite/miscellaneous/GetVersionExA/test1/test.cpp83
-rw-r--r--src/pal/tests/palsuite/miscellaneous/GetVersionExA/test1/testinfo.dat16
-rw-r--r--src/pal/tests/palsuite/miscellaneous/GetVersionExW/CMakeLists.txt4
-rw-r--r--src/pal/tests/palsuite/miscellaneous/GetVersionExW/test1/CMakeLists.txt17
-rw-r--r--src/pal/tests/palsuite/miscellaneous/GetVersionExW/test1/test.cpp88
-rw-r--r--src/pal/tests/palsuite/miscellaneous/GetVersionExW/test1/testinfo.dat16
-rw-r--r--src/pal/tests/palsuite/paltestlist_to_be_reviewed.txt2
-rwxr-xr-xsrc/pal/tools/gen-buildsys-clang.sh11
-rw-r--r--src/unwinder/i386/unwinder_i386.cpp2
-rw-r--r--src/utilcode/CMakeLists.txt4
-rw-r--r--src/vm/arm64/asmhelpers.asm38
-rw-r--r--src/vm/baseassemblyspec.cpp4
-rw-r--r--src/vm/ceemain.cpp21
-rw-r--r--src/vm/codeman.cpp7
-rw-r--r--src/vm/crossgencompile.cpp4
-rw-r--r--src/vm/domainfile.cpp13
-rw-r--r--src/vm/ecalllist.h4
-rw-r--r--src/vm/eetwain.cpp25
-rw-r--r--src/vm/eventtrace.cpp21
-rw-r--r--src/vm/exinfo.h2
-rw-r--r--src/vm/gcenv.ee.cpp45
-rw-r--r--src/vm/gcenv.ee.h4
-rw-r--r--src/vm/gcheaputilities.cpp37
-rw-r--r--src/vm/gcheaputilities.h25
-rw-r--r--src/vm/gdbjit.cpp5
-rw-r--r--src/vm/i386/asmhelpers.S34
-rw-r--r--src/vm/jitinterface.cpp12
-rw-r--r--src/vm/prestub.cpp4
-rw-r--r--src/vm/readytoruninfo.cpp2
-rw-r--r--src/vm/rexcep.h3
-rw-r--r--src/vm/threads.cpp29
-rw-r--r--src/vm/threads.h1
-rw-r--r--src/vm/tieredcompilation.cpp2
-rw-r--r--src/zap/zapcode.cpp24
-rw-r--r--src/zap/zapimage.cpp279
-rw-r--r--src/zap/zapimage.h61
-rw-r--r--src/zap/zapinfo.cpp11
204 files changed, 2614 insertions, 3748 deletions
diff --git a/src/.nuget/Microsoft.NETCore.Jit/runtime.Windows_NT.Microsoft.NETCore.Jit.props b/src/.nuget/Microsoft.NETCore.Jit/runtime.Windows_NT.Microsoft.NETCore.Jit.props
index dcc864163c..c45358dec7 100644
--- a/src/.nuget/Microsoft.NETCore.Jit/runtime.Windows_NT.Microsoft.NETCore.Jit.props
+++ b/src/.nuget/Microsoft.NETCore.Jit/runtime.Windows_NT.Microsoft.NETCore.Jit.props
@@ -2,7 +2,7 @@
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<NativeBinary Include="$(BinDir)clrjit.dll" />
- <NativeBinary Condition="'$(Platform)' == 'x86'" Include="$(BinDir)compatjit.dll" />
+ <NativeBinary Condition="'$(Platform)' == 'x86' and '$(PackageCompatJit)' != ''" Include="$(BinDir)compatjit.dll" />
<CrossArchitectureSpecificNativeFileAndSymbol Include="$(BinDir)$(CrossTargetComponentFolder)\clrjit.dll" />
<!-- prevent accidental inclusion in AOT projects. -->
diff --git a/src/.nuget/Microsoft.NETCore.Runtime.CoreCLR/runtime.Linux.Microsoft.NETCore.Runtime.CoreCLR.props b/src/.nuget/Microsoft.NETCore.Runtime.CoreCLR/runtime.Linux.Microsoft.NETCore.Runtime.CoreCLR.props
index 85e9f5e793..db8b03173b 100644
--- a/src/.nuget/Microsoft.NETCore.Runtime.CoreCLR/runtime.Linux.Microsoft.NETCore.Runtime.CoreCLR.props
+++ b/src/.nuget/Microsoft.NETCore.Runtime.CoreCLR/runtime.Linux.Microsoft.NETCore.Runtime.CoreCLR.props
@@ -3,10 +3,14 @@
<PropertyGroup>
<_PlatformDoesNotSupportNiFiles Condition="'$(Platform)' == 'arm'">true</_PlatformDoesNotSupportNiFiles>
<_PlatformDoesNotSupportNiFiles Condition="'$(Platform)' == 'armel'">true</_PlatformDoesNotSupportNiFiles>
+ <_PlatformDoesNotSupportNiFiles Condition="'$(Platform)' == 'x86'">true</_PlatformDoesNotSupportNiFiles>
+ <_PlatformDoesNotSupportEventTrace Condition="'$(Platform)' == 'arm'">true</_PlatformDoesNotSupportEventTrace>
+ <_PlatformDoesNotSupportEventTrace Condition="'$(Platform)' == 'armel'">true</_PlatformDoesNotSupportEventTrace>
+ <_PlatformDoesNotSupportEventTrace Condition="'$(Platform)' == 'x86'">true</_PlatformDoesNotSupportEventTrace>
</PropertyGroup>
<ItemGroup>
<NativeBinary Include="$(BinDir)libcoreclr.so" />
- <NativeBinary Condition="'$(_PlatformDoesNotSupportNiFiles)' != 'true'" Include="$(BinDir)libcoreclrtraceptprovider.so" />
+ <NativeBinary Condition="'$(_PlatformDoesNotSupportEventTrace)' != 'true'" Include="$(BinDir)libcoreclrtraceptprovider.so" />
<NativeBinary Include="$(BinDir)libdbgshim.so" />
<NativeBinary Include="$(BinDir)libmscordaccore.so" />
<NativeBinary Include="$(BinDir)libmscordbi.so" />
diff --git a/src/.nuget/Microsoft.NETCore.Runtime.CoreCLR/runtime.Windows_NT.Microsoft.NETCore.Runtime.CoreCLR.props b/src/.nuget/Microsoft.NETCore.Runtime.CoreCLR/runtime.Windows_NT.Microsoft.NETCore.Runtime.CoreCLR.props
index 9c46df94aa..436901ebd2 100644
--- a/src/.nuget/Microsoft.NETCore.Runtime.CoreCLR/runtime.Windows_NT.Microsoft.NETCore.Runtime.CoreCLR.props
+++ b/src/.nuget/Microsoft.NETCore.Runtime.CoreCLR/runtime.Windows_NT.Microsoft.NETCore.Runtime.CoreCLR.props
@@ -20,6 +20,7 @@
<NativeBinary Include="$(BinDir)mscorrc.dll" />
<NativeBinary Include="$(BinDir)sos.dll" />
<NativeBinary Include="$(BinDir)System.Private.CoreLib.ni.dll" />
+ <NativeBinary Include="$(UniversalCRTSDKDir)Redist\ucrt\DLLs\$(BuildArch)\*.dll" Condition="'$(BuildType)'=='Release' AND '$(BuildArch)' != 'arm64'" />
<ArchitectureSpecificLibFile Include="$(BinDir)System.Private.CoreLib.dll" />
<ArchitectureSpecificLibFile Include="$(BinDir)SOS.NETCore.dll" />
<ArchitectureSpecificToolFile Include="$(BinDir)crossgen.exe" />
diff --git a/src/.nuget/dir.targets b/src/.nuget/dir.targets
index 6f7bae6b10..49e550a4b7 100644
--- a/src/.nuget/dir.targets
+++ b/src/.nuget/dir.targets
@@ -1,6 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+
+ <Target Name="VerifyVCRedist" BeforeTargets="GetSymbolPackageFiles" Condition="'$(_runtimeOSFamily)' == 'win'">
+ <Error Condition="'$(UniversalCRTSDKDir)' == ''" Text="Unable to find VC Redist binaries - check that UniversalCRTSDKDir environment variable is set" />
+ </Target>
<!--
Finds symbol files and injects them into the package build.
-->
diff --git a/src/classlibnative/bcltype/system.cpp b/src/classlibnative/bcltype/system.cpp
index 2767d1e749..c36d2e1066 100644
--- a/src/classlibnative/bcltype/system.cpp
+++ b/src/classlibnative/bcltype/system.cpp
@@ -609,8 +609,6 @@ FCIMPL2(VOID, SystemNative::FailFastWithException, StringObject* refMessageUNSAF
}
FCIMPLEND
-
-
FCIMPL0(FC_BOOL_RET, SystemNative::IsServerGC)
{
FCALL_CONTRACT;
@@ -636,95 +634,6 @@ BOOL QCALLTYPE SystemNative::WinRTSupported()
#endif // FEATURE_COMINTEROP
-// Helper method to retrieve OS Version based on the environment.
-BOOL GetOSVersionForEnvironment(LPOSVERSIONINFO lpVersionInformation)
-{
-#ifdef FEATURE_WINDOWSPHONE
- // Return phone version information if it is available
- if (!g_fGetPhoneVersionInitialized)
- {
- HMODULE hPhoneInfo = WszLoadLibrary(W("phoneinfo.dll"));
- if(hPhoneInfo != NULL)
- g_pfnGetPhoneVersion = (pfnGetPhoneVersion)GetProcAddress(hPhoneInfo, "GetPhoneVersion");
-
- g_fGetPhoneVersionInitialized = true;
- }
-
- if (g_pfnGetPhoneVersion!= NULL)
- return g_pfnGetPhoneVersion(lpVersionInformation);
-#endif // FEATURE_WINDOWSPHONE
-
- return ::GetOSVersion(lpVersionInformation);
-}
-
-
-/*
- * SystemNative::GetOSVersion - Fcall corresponding to System.Environment.GetVersion
- * It calls clr!GetOSVersion to get the real OS version even when running in
- * app compat. Calling kernel32!GetVersionEx() directly will be shimmed and will return the
- * fake OS version. In order to avoid this the call to getVersionEx is made via mscoree.dll.
- * Mscoree.dll resides in system32 dir and is never lied about OS version.
- */
-
-FCIMPL1(FC_BOOL_RET, SystemNative::GetOSVersion, OSVERSIONINFOObject *osVer)
-{
- FCALL_CONTRACT;
-
- OSVERSIONINFO ver;
- ver.dwOSVersionInfoSize = osVer->dwOSVersionInfoSize;
-
- BOOL ret = GetOSVersionForEnvironment(&ver);
-
- if(ret)
- {
- osVer->dwMajorVersion = ver.dwMajorVersion;
- osVer->dwMinorVersion = ver.dwMinorVersion;
- osVer->dwBuildNumber = ver.dwBuildNumber;
- osVer->dwPlatformId = ver.dwPlatformId;
-
- HELPER_METHOD_FRAME_BEGIN_RET_1(osVer);
- SetObjectReference((OBJECTREF*)&(osVer->szCSDVersion), StringObject::NewString(ver.szCSDVersion), GetAppDomain());
- HELPER_METHOD_FRAME_END();
- }
-
- FC_RETURN_BOOL(ret);
-}
-FCIMPLEND
-
-/*
- * SystemNative::GetOSVersionEx - Fcall implementation for System.Environment.GetVersionEx
- * Similar as above except this takes OSVERSIONINFOEX structure as input
- */
-
-FCIMPL1(FC_BOOL_RET, SystemNative::GetOSVersionEx, OSVERSIONINFOEXObject *osVer)
-{
- FCALL_CONTRACT;
-
- OSVERSIONINFOEX ver;
- ver.dwOSVersionInfoSize = osVer->dwOSVersionInfoSize;
-
- BOOL ret = GetOSVersionForEnvironment((OSVERSIONINFO *)&ver);
-
- if(ret)
- {
- osVer->dwMajorVersion = ver.dwMajorVersion;
- osVer->dwMinorVersion = ver.dwMinorVersion;
- osVer->dwBuildNumber = ver.dwBuildNumber;
- osVer->dwPlatformId = ver.dwPlatformId;
- osVer->wServicePackMajor = ver.wServicePackMajor;
- osVer->wServicePackMinor = ver.wServicePackMinor;
- osVer->wSuiteMask = ver.wSuiteMask;
- osVer->wProductType = ver.wProductType;
- osVer->wReserved = ver.wReserved;
-
- HELPER_METHOD_FRAME_BEGIN_RET_1(osVer);
- SetObjectReference((OBJECTREF*)&(osVer->szCSDVersion), StringObject::NewString(ver.szCSDVersion), GetAppDomain());
- HELPER_METHOD_FRAME_END();
- }
-
- FC_RETURN_BOOL(ret);
-}
-FCIMPLEND
diff --git a/src/classlibnative/bcltype/system.h b/src/classlibnative/bcltype/system.h
index 1da105841f..986c55b31e 100644
--- a/src/classlibnative/bcltype/system.h
+++ b/src/classlibnative/bcltype/system.h
@@ -74,9 +74,6 @@ public:
static FCDECL0(INT64, __GetSystemTimeAsFileTime);
static FCDECL0(UINT32, GetCurrentProcessorNumber);
static FCDECL0(UINT32, GetTickCount);
- static FCDECL1(FC_BOOL_RET, GetOSVersion, OSVERSIONINFOObject *osVer);
- static FCDECL1(FC_BOOL_RET, GetOSVersionEx, OSVERSIONINFOEXObject *osVer);
-
static
void QCALLTYPE Exit(INT32 exitcode);
diff --git a/src/debug/daccess/dacdbiimpl.cpp b/src/debug/daccess/dacdbiimpl.cpp
index 74ba14f2eb..605d5c7cee 100644
--- a/src/debug/daccess/dacdbiimpl.cpp
+++ b/src/debug/daccess/dacdbiimpl.cpp
@@ -5718,9 +5718,9 @@ BOOL DacDbiInterfaceImpl::IsVmObjectHandleValid(VMPTR_OBJECTHANDLE vmHandle)
// SEH exceptions will be caught
EX_TRY
{
- OBJECTREF objRef = ObjectFromHandle((OBJECTHANDLE)vmHandle.GetDacPtr());
+ OBJECTREF objRef = HndFetchHandle((OBJECTHANDLE)vmHandle.GetDacPtr());
- // NULL is certinally valid...
+ // NULL is certainly valid...
if (objRef != NULL)
{
if (objRef->ValidateObjectWithPossibleAV())
diff --git a/src/debug/daccess/enummem.cpp b/src/debug/daccess/enummem.cpp
index 0dc7a42b1e..027fe59543 100644
--- a/src/debug/daccess/enummem.cpp
+++ b/src/debug/daccess/enummem.cpp
@@ -317,12 +317,10 @@ HRESULT ClrDataAccess::EnumMemCLRStatic(IN CLRDataEnumMemoryFlags flags)
CATCH_ALL_EXCEPT_RETHROW_COR_E_OPERATIONCANCELLED( g_pFinalizerThread.EnumMem(); )
CATCH_ALL_EXCEPT_RETHROW_COR_E_OPERATIONCANCELLED( g_pSuspensionThread.EnumMem(); )
-#ifdef FEATURE_SVR_GC
CATCH_ALL_EXCEPT_RETHROW_COR_E_OPERATIONCANCELLED
(
- IGCHeap::gcHeapType.EnumMem();
+ g_heap_type.EnumMem();
);
-#endif // FEATURE_SVR_GC
m_dumpStats.m_cbClrStatics = m_cbMemoryReported - cbMemoryReported;
diff --git a/src/debug/daccess/request.cpp b/src/debug/daccess/request.cpp
index c30501f374..78ac831cd9 100644
--- a/src/debug/daccess/request.cpp
+++ b/src/debug/daccess/request.cpp
@@ -2929,31 +2929,33 @@ ClrDataAccess::GetGCHeapData(struct DacpGcHeapData *gcheapData)
SOSDacEnter();
- // for server GC-capable builds only, we need to check and see if IGCHeap::gcHeapType
+ // we need to check and see if g_heap_type
// is GC_HEAP_INVALID, in which case we fail.
- // IGCHeap::gcHeapType doesn't exist on non-server-GC capable builds.
-#ifdef FEATURE_SVR_GC
- ULONG32 gcHeapValue = *g_gcDacGlobals->gc_heap_type;
+ ULONG32 gcHeapValue = g_heap_type;
// GC_HEAP_TYPE has three possible values:
// GC_HEAP_INVALID = 0,
// GC_HEAP_WKS = 1,
// GC_HEAP_SVR = 2
// If we get something other than that, we probably read the wrong location.
- _ASSERTE(gcHeapValue >= IGCHeap::GC_HEAP_INVALID && gcHeapValue <= IGCHeap::GC_HEAP_SVR);
+ _ASSERTE(gcHeapValue >= GC_HEAP_INVALID && gcHeapValue <= GC_HEAP_SVR);
- // we have GC_HEAP_INVALID if gcHeapValue == 0, so we're done
- if (gcHeapValue == IGCHeap::GC_HEAP_INVALID)
+ // we have GC_HEAP_INVALID if gcHeapValue == 0, so we're done - we haven't
+ // initialized the heap yet.
+ if (gcHeapValue == GC_HEAP_INVALID)
{
hr = E_FAIL;
goto cleanup;
}
-#endif
// Now we can get other important information about the heap
+ // We can use GCHeapUtilities::IsServerHeap here because we have already validated
+ // that the heap is in a valid state. We couldn't use it above, because IsServerHeap
+ // asserts if the heap type is GC_HEAP_INVALID.
gcheapData->g_max_generation = *g_gcDacGlobals->max_gen;
- gcheapData->bServerMode = gcHeapValue == IGCHeap::GC_HEAP_SVR;
+ gcheapData->bServerMode = GCHeapUtilities::IsServerHeap();
gcheapData->bGcStructuresValid = *g_gcDacGlobals->gc_structures_invalid_cnt == 0;
+
if (GCHeapUtilities::IsServerHeap())
{
#if !defined (FEATURE_SVR_GC)
@@ -2968,10 +2970,8 @@ ClrDataAccess::GetGCHeapData(struct DacpGcHeapData *gcheapData)
gcheapData->HeapCount = 1;
}
-#ifdef FEATURE_SVR_GC
cleanup:
;
-#endif
SOSDacLeave();
return hr;
@@ -3069,7 +3069,7 @@ ClrDataAccess::GetGCInterestingInfoStaticData(struct DacpGCInterestingInfoData *
SOSDacEnter();
memset(data, 0, sizeof(DacpGCInterestingInfoData));
- if (*g_gcDacGlobals->gc_heap_type != IGCHeap::GC_HEAP_SVR)
+ if (g_heap_type != GC_HEAP_SVR)
{
for (int i = 0; i < NUM_GC_DATA_POINTS; i++)
data->interestingDataPoints[i] = g_gcDacGlobals->interesting_data_per_heap[i];
@@ -3890,7 +3890,7 @@ HRESULT ClrDataAccess::GetClrWatsonBucketsWorker(Thread * pThread, GenericModeBl
if (ohThrowable != NULL)
{
// Get the object from handle and check if the throwable is preallocated or not
- OBJECTREF oThrowable = ObjectFromHandle(ohThrowable);
+ OBJECTREF oThrowable = ::HndFetchHandle(ohThrowable);
if (oThrowable != NULL)
{
// Does the throwable have buckets?
@@ -4184,7 +4184,7 @@ HRESULT ClrDataAccess::GetCCWData(CLRDATA_ADDRESS ccw, struct DacpCCWData *ccwDa
ccwData->isAggregated = pCCW->GetSimpleWrapper()->IsAggregated();
if (pCCW->GetObjectHandle() != NULL)
- ccwData->managedObject = PTR_CDADDR(ObjectFromHandle(pCCW->GetObjectHandle()));
+ ccwData->managedObject = PTR_CDADDR(::HndFetchHandle(pCCW->GetObjectHandle()));
// count the number of COM vtables
ccwData->interfaceCount = 0;
diff --git a/src/debug/daccess/request_svr.cpp b/src/debug/daccess/request_svr.cpp
index 930a35bf1c..6a1de35ff9 100644
--- a/src/debug/daccess/request_svr.cpp
+++ b/src/debug/daccess/request_svr.cpp
@@ -240,7 +240,7 @@ ClrDataAccess::EnumSvrGlobalMemoryRegions(CLRDataEnumMemoryFlags flags)
DWORD DacGetNumHeaps()
{
- if (g_gcDacGlobals->gc_heap_type == IGCHeap::GC_HEAP_SVR)
+ if (g_heap_type == GC_HEAP_SVR)
return (DWORD)*g_gcDacGlobals->n_heaps;
// workstation gc
diff --git a/src/debug/di/process.cpp b/src/debug/di/process.cpp
index 4c32641290..b6d49c218d 100644
--- a/src/debug/di/process.cpp
+++ b/src/debug/di/process.cpp
@@ -4525,10 +4525,6 @@ void CordbProcess::QueueFakeConnectionEvents()
// from the runtime controller. This represents the last amount of processing
// the DI gets to do on an event before giving it to the user.
//
-#ifdef _PREFAST_
-#pragma warning(push)
-#pragma warning(disable:21000) // Suppress PREFast warning about overly large function
-#endif
void CordbProcess::DispatchRCEvent()
{
INTERNAL_API_ENTRY(this);
@@ -4729,6 +4725,10 @@ void CordbProcess::DbgAssertAppDomainDeleted(VMPTR_AppDomain vmAppDomainDeleted)
// A V2 shim can provide a proxy calllack that takes these events and queues them and
// does the real dispatch to the user to emulate V2 semantics.
//
+#ifdef _PREFAST_
+#pragma warning(push)
+#pragma warning(disable:21000) // Suppress PREFast warning about overly large function
+#endif
void CordbProcess::RawDispatchEvent(
DebuggerIPCEvent * pEvent,
RSLockHolder * pLockHolder,
diff --git a/src/gc/env/gcenv.ee.h b/src/gc/env/gcenv.ee.h
index 689b1cc6e1..63ae2fb555 100644
--- a/src/gc/env/gcenv.ee.h
+++ b/src/gc/env/gcenv.ee.h
@@ -70,6 +70,10 @@ public:
static void EnableFinalization(bool foundFinalizers);
static void HandleFatalError(unsigned int exitCode);
+ static bool ShouldFinalizeObjectForUnload(AppDomain* pDomain, Object* obj);
+ static bool ForceFullGCToBeBlocking();
+ static bool ShouldElevateForAppDomainCleanup();
+ static bool EagerFinalized(Object* obj);
};
#endif // __GCENV_EE_H__
diff --git a/src/gc/gc.cpp b/src/gc/gc.cpp
index 9435357eeb..ca03aaf3c2 100644
--- a/src/gc/gc.cpp
+++ b/src/gc/gc.cpp
@@ -15136,26 +15136,21 @@ exit:
}
}
-#ifndef FEATURE_REDHAWK
- if (n == max_generation)
+ if (n == max_generation && GCToEEInterface::ForceFullGCToBeBlocking())
{
- if (SystemDomain::System()->RequireAppDomainCleanup())
- {
#ifdef BACKGROUND_GC
- // do not turn stress-induced collections into blocking GCs, unless there
- // have already been more full BGCs than full NGCs
+ // do not turn stress-induced collections into blocking GCs, unless there
+ // have already been more full BGCs than full NGCs
#if 0
- // This exposes DevDiv 94129, so we'll leave this out for now
- if (!settings.stress_induced ||
- full_gc_counts[gc_type_blocking] <= full_gc_counts[gc_type_background])
+ // This exposes DevDiv 94129, so we'll leave this out for now
+ if (!settings.stress_induced ||
+ full_gc_counts[gc_type_blocking] <= full_gc_counts[gc_type_background])
#endif // 0
#endif // BACKGROUND_GC
- {
- *blocking_collection_p = TRUE;
- }
+ {
+ *blocking_collection_p = TRUE;
}
}
-#endif //!FEATURE_REDHAWK
return n;
}
@@ -33501,6 +33496,7 @@ void GCHeap::ValidateObjectMember (Object* obj)
{
dprintf (3, ("VOM: m: %Ix obj %Ix", (size_t)child_o, o));
MethodTable *pMT = method_table (child_o);
+ assert(pMT);
if (!pMT->SanityCheck()) {
dprintf (3, ("Bad member of %Ix %Ix",
(size_t)oo, (size_t)child_o));
@@ -34206,11 +34202,11 @@ bool GCHeap::StressHeap(gc_alloc_context * context)
StringObject* str;
// If the current string is used up
- if (ObjectFromHandle(m_StressObjs[m_CurStressObj]) == 0)
+ if (HndFetchHandle(m_StressObjs[m_CurStressObj]) == 0)
{
// Populate handles with strings
int i = m_CurStressObj;
- while(ObjectFromHandle(m_StressObjs[i]) == 0)
+ while(HndFetchHandle(m_StressObjs[i]) == 0)
{
_ASSERTE(m_StressObjs[i] != 0);
unsigned strLen = (LARGE_OBJECT_SIZE - 32) / sizeof(WCHAR);
@@ -34242,7 +34238,7 @@ bool GCHeap::StressHeap(gc_alloc_context * context)
}
// Get the current string
- str = (StringObject*) OBJECTREFToObject(ObjectFromHandle(m_StressObjs[m_CurStressObj]));
+ str = (StringObject*) OBJECTREFToObject(HndFetchHandle(m_StressObjs[m_CurStressObj]));
if (str)
{
// Chop off the end of the string and form a new object out of it.
@@ -36101,43 +36097,15 @@ CFinalize::FinalizeSegForAppDomain (AppDomain *pDomain,
// if it has the index we are looking for. If the methodtable is null, it can't be from the
// unloading domain, so skip it.
if (method_table(obj) == NULL)
+ {
continue;
+ }
- // eagerly finalize all objects except those that may be agile.
- if (obj->GetAppDomainIndex() != pDomain->GetIndex())
+ // does the EE actually want us to finalize this object?
+ if (!GCToEEInterface::ShouldFinalizeObjectForUnload(pDomain, obj))
+ {
continue;
-
-#ifndef FEATURE_REDHAWK
- if (method_table(obj)->IsAgileAndFinalizable())
- {
- // If an object is both agile & finalizable, we leave it in the
- // finalization queue during unload. This is OK, since it's agile.
- // Right now only threads can be this way, so if that ever changes, change
- // the assert to just continue if not a thread.
- _ASSERTE(method_table(obj) == g_pThreadClass);
-
- if (method_table(obj) == g_pThreadClass)
- {
- // However, an unstarted thread should be finalized. It could be holding a delegate
- // in the domain we want to unload. Once the thread has been started, its
- // delegate is cleared so only unstarted threads are a problem.
- Thread *pThread = ((THREADBASEREF)ObjectToOBJECTREF(obj))->GetInternal();
- if (! pThread || ! pThread->IsUnstarted())
- {
- // This appdomain is going to be gone soon so let us assign
- // it the appdomain that's guaranteed to exist
- // The object is agile and the delegate should be null so we can do it
- obj->GetHeader()->ResetAppDomainIndexNoFailure(SystemDomain::System()->DefaultDomain()->GetIndex());
- continue;
- }
- }
- else
- {
- obj->GetHeader()->ResetAppDomainIndexNoFailure(SystemDomain::System()->DefaultDomain()->GetIndex());
- continue;
- }
}
-#endif //!FEATURE_REDHAWK
if (!fRunFinalizers || (obj->GetHeader()->GetBits()) & BIT_SBLK_FINALIZER_RUN)
{
@@ -36296,16 +36264,11 @@ CFinalize::ScanForFinalization (promote_func* pfn, int gen, BOOL mark_only_p,
assert (method_table(obj)->HasFinalizer());
-#ifndef FEATURE_REDHAWK
- if (method_table(obj) == pWeakReferenceMT || method_table(obj)->GetCanonicalMethodTable() == pWeakReferenceOfTCanonMT)
+ if (GCToEEInterface::EagerFinalized(obj))
{
- //destruct the handle right there.
- FinalizeWeakReference (obj);
MoveItem (i, Seg, FreeList);
}
- else
-#endif //!FEATURE_REDHAWK
- if ((obj->GetHeader()->GetBits()) & BIT_SBLK_FINALIZER_RUN)
+ else if ((obj->GetHeader()->GetBits()) & BIT_SBLK_FINALIZER_RUN)
{
//remove the object because we don't want to
//run the finalizer
@@ -36945,10 +36908,7 @@ void PopulateDacVars(GcDacVars *gcDacVars)
gcDacVars->build_variant = &g_build_variant;
gcDacVars->gc_structures_invalid_cnt = const_cast<int32_t*>(&GCScan::m_GcStructuresInvalidCnt);
gcDacVars->generation_size = sizeof(generation);
-#ifdef FEATURE_SVR_GC
- gcDacVars->gc_heap_type = &IGCHeap::gcHeapType;
-#endif // FEATURE_SVR_GC
- gcDacVars->max_gen = &IGCHeap::maxGeneration;
+ gcDacVars->max_gen = &g_max_generation;
#ifndef MULTIPLE_HEAPS
gcDacVars->mark_array = &gc_heap::mark_array;
gcDacVars->ephemeral_heap_segment = reinterpret_cast<dac_heap_segment**>(&gc_heap::ephemeral_heap_segment);
diff --git a/src/gc/gc.h b/src/gc/gc.h
index ecb791f728..8cd92fd1c7 100644
--- a/src/gc/gc.h
+++ b/src/gc/gc.h
@@ -87,6 +87,7 @@ class IGCHeapInternal;
/* misc defines */
#define LARGE_OBJECT_SIZE ((size_t)(85000))
+#define max_generation 2
#ifdef GC_CONFIG_DRIVEN
#define MAX_GLOBAL_GC_MECHANISMS_COUNT 6
@@ -110,6 +111,8 @@ extern "C" uint32_t* g_gc_card_bundle_table;
extern "C" uint32_t* g_gc_card_table;
extern "C" uint8_t* g_gc_lowest_address;
extern "C" uint8_t* g_gc_highest_address;
+extern "C" GCHeapType g_gc_heap_type;
+extern "C" uint32_t g_max_generation;
::IGCHandleTable* CreateGCHandleTable();
@@ -219,7 +222,7 @@ public:
unsigned GetMaxGeneration()
{
- return IGCHeap::maxGeneration;
+ return max_generation;
}
bool IsValidSegmentSize(size_t cbSize)
@@ -235,8 +238,6 @@ public:
BOOL IsLargeObject(MethodTable *mt)
{
- WRAPPER_NO_CONTRACT;
-
return mt->GetBaseSize() >= LARGE_OBJECT_SIZE;
}
@@ -255,12 +256,6 @@ void TouchPages(void * pStart, size_t cb);
void updateGCShadow(Object** ptr, Object* val);
#endif
-// the method table for the WeakReference class
-extern MethodTable *pWeakReferenceMT;
-// The canonical method table for WeakReference<T>
-extern MethodTable *pWeakReferenceOfTCanonMT;
-extern void FinalizeWeakReference(Object * obj);
-
// The single GC heap instance, shared with the VM.
extern IGCHeapInternal* g_theGCHeap;
@@ -270,18 +265,15 @@ extern IGCHandleTable* g_theGCHandleTable;
#ifndef DACCESS_COMPILE
inline bool IsGCInProgress(bool bConsiderGCStart = false)
{
- WRAPPER_NO_CONTRACT;
-
return g_theGCHeap != nullptr ? g_theGCHeap->IsGCInProgressHelper(bConsiderGCStart) : false;
}
#endif // DACCESS_COMPILE
inline bool IsServerHeap()
{
- LIMITED_METHOD_CONTRACT;
#ifdef FEATURE_SVR_GC
- _ASSERTE(IGCHeap::gcHeapType != IGCHeap::GC_HEAP_INVALID);
- return (IGCHeap::gcHeapType == IGCHeap::GC_HEAP_SVR);
+ assert(g_gc_heap_type != GC_HEAP_INVALID);
+ return g_gc_heap_type == GC_HEAP_SVR;
#else // FEATURE_SVR_GC
return false;
#endif // FEATURE_SVR_GC
diff --git a/src/gc/gccommon.cpp b/src/gc/gccommon.cpp
index 8f6d1ac2be..1cd3c824ac 100644
--- a/src/gc/gccommon.cpp
+++ b/src/gc/gccommon.cpp
@@ -14,12 +14,6 @@
#include "gcenv.h"
#include "gc.h"
-#ifdef FEATURE_SVR_GC
-SVAL_IMPL_INIT(uint32_t,IGCHeap,gcHeapType,IGCHeap::GC_HEAP_INVALID);
-#endif // FEATURE_SVR_GC
-
-SVAL_IMPL_INIT(uint32_t,IGCHeap,maxGeneration,2);
-
IGCHeapInternal* g_theGCHeap;
IGCHandleTable* g_theGCHandleTable;
@@ -47,6 +41,8 @@ uint32_t* g_gc_card_bundle_table;
uint8_t* g_gc_lowest_address = 0;
uint8_t* g_gc_highest_address = 0;
+GCHeapType g_gc_heap_type = GC_HEAP_INVALID;
+uint32_t g_max_generation = max_generation;
#ifdef GC_CONFIG_DRIVEN
void record_global_mechanism (int mech_index)
@@ -122,9 +118,9 @@ void InitializeHeapType(bool bServerHeap)
{
LIMITED_METHOD_CONTRACT;
#ifdef FEATURE_SVR_GC
- IGCHeap::gcHeapType = bServerHeap ? IGCHeap::GC_HEAP_SVR : IGCHeap::GC_HEAP_WKS;
+ g_gc_heap_type = bServerHeap ? GC_HEAP_SVR : GC_HEAP_WKS;
#ifdef WRITE_BARRIER_CHECK
- if (IGCHeap::gcHeapType == IGCHeap::GC_HEAP_SVR)
+ if (g_gc_heap_type == GC_HEAP_SVR)
{
g_GCShadow = 0;
g_GCShadowEnd = 0;
@@ -163,9 +159,9 @@ bool InitializeGarbageCollector(IGCToCLR* clrToGC, IGCHeap** gcHeap, IGCHandleTa
}
#ifdef FEATURE_SVR_GC
- assert(IGCHeap::gcHeapType != IGCHeap::GC_HEAP_INVALID);
+ assert(g_gc_heap_type != GC_HEAP_INVALID);
- if (IGCHeap::gcHeapType == IGCHeap::GC_HEAP_SVR)
+ if (g_gc_heap_type == GC_HEAP_SVR)
{
heap = SVR::CreateGCHeap();
SVR::PopulateDacVars(gcDacVars);
diff --git a/src/gc/gcenv.ee.standalone.inl b/src/gc/gcenv.ee.standalone.inl
index c391ef8126..f26a7768d5 100644
--- a/src/gc/gcenv.ee.standalone.inl
+++ b/src/gc/gcenv.ee.standalone.inl
@@ -213,6 +213,24 @@ ALWAYS_INLINE void GCToEEInterface::HandleFatalError(unsigned int exitCode)
g_theGCToCLR->HandleFatalError(exitCode);
}
+ALWAYS_INLINE bool GCToEEInterface::ShouldFinalizeObjectForUnload(AppDomain* pDomain, Object* obj)
+{
+ assert(g_theGCToCLR != nullptr);
+ return g_theGCToCLR->ShouldFinalizeObjectForUnload(pDomain, obj);
+}
+
+ALWAYS_INLINE bool GCToEEInterface::ForceFullGCToBeBlocking()
+{
+ assert(g_theGCToCLR != nullptr);
+ return g_theGCToCLR->ForceFullGCToBeBlocking();
+}
+
+ALWAYS_INLINE bool GCToEEInterface::EagerFinalized(Object* obj)
+{
+ assert(g_theGCToCLR != nullptr);
+ return g_theGCToCLR->EagerFinalized(obj);
+}
+
#undef ALWAYS_INLINE
#endif // __GCTOENV_EE_STANDALONE_INL__
diff --git a/src/gc/gchandletable.cpp b/src/gc/gchandletable.cpp
index a4c3352b86..f468bd300f 100644
--- a/src/gc/gchandletable.cpp
+++ b/src/gc/gchandletable.cpp
@@ -22,3 +22,13 @@ void GCHandleTable::Shutdown()
{
Ref_Shutdown();
}
+
+void* GCHandleTable::GetHandleTableContext(void* handleTable)
+{
+ return (void*)((uintptr_t)::HndGetHandleTableADIndex((HHANDLETABLE)handleTable).m_dwIndex);
+}
+
+void* GCHandleTable::GetHandleTableForHandle(OBJECTHANDLE handle)
+{
+ return (void*)::HndGetHandleTable(handle);
+}
diff --git a/src/gc/gchandletableimpl.h b/src/gc/gchandletableimpl.h
index 233e326a64..11fa163df7 100644
--- a/src/gc/gchandletableimpl.h
+++ b/src/gc/gchandletableimpl.h
@@ -13,6 +13,10 @@ public:
virtual bool Initialize();
virtual void Shutdown();
+
+ virtual void* GetHandleTableContext(void* handleTable);
+
+ virtual void* GetHandleTableForHandle(OBJECTHANDLE handle);
};
#endif // GCHANDLETABLE_H_
diff --git a/src/gc/gcinterface.dac.h b/src/gc/gcinterface.dac.h
index 84c8ffb36a..647101fa1f 100644
--- a/src/gc/gcinterface.dac.h
+++ b/src/gc/gcinterface.dac.h
@@ -18,12 +18,6 @@
#define MAX_GLOBAL_GC_MECHANISMS_COUNT 6
#define NUMBERGENERATIONS 4
-// TODO(segilles) - Implement this scheme for Server GC
-namespace SVR {
- class heap_segment;
- class gc_heap;
-}
-
// Analogue for the GC heap_segment class, containing information regarding a single
// heap segment.
class dac_heap_segment {
diff --git a/src/gc/gcinterface.dacvars.def b/src/gc/gcinterface.dacvars.def
index f9c2078ee3..b788079dcb 100644
--- a/src/gc/gcinterface.dacvars.def
+++ b/src/gc/gcinterface.dacvars.def
@@ -38,7 +38,6 @@ GC_DAC_VAR (uint8_t, build_variant)
GC_DAC_VAR (bool, built_with_svr)
GC_DAC_ARRAY_VAR (size_t, gc_global_mechanisms)
GC_DAC_ARRAY_VAR (dac_generation, generation_table)
-GC_DAC_VAR (uint32_t, gc_heap_type)
GC_DAC_VAR (uint32_t, max_gen)
GC_DAC_PTR_VAR (uint32_t, mark_array)
GC_DAC_VAR (c_gc_state, current_c_gc_state)
diff --git a/src/gc/gcinterface.ee.h b/src/gc/gcinterface.ee.h
index da74665b69..0d3c579678 100644
--- a/src/gc/gcinterface.ee.h
+++ b/src/gc/gcinterface.ee.h
@@ -137,6 +137,30 @@ public:
// Signals to the EE that the GC encountered a fatal error and can't recover.
virtual
void HandleFatalError(unsigned int exitCode) = 0;
+
+ // Asks the EE if it wants a particular object to be finalized when unloading
+ // an app domain.
+ virtual
+ bool ShouldFinalizeObjectForUnload(AppDomain* pDomain, Object* obj) = 0;
+
+ // Asks the EE if the GC scheduled for the given condemned generation should be
+ // elevated to a blocking collection, to clean up an app domain.
+ virtual
+ bool ShouldElevateForAppDomainCleanup() = 0;
+
+ // Offers the EE the option to finalize the given object eagerly, i.e.
+ // not on the finalizer thread but on the current thread. The
+ // EE returns true if it finalized the object eagerly and the GC does not
+ // need to do so, and false if it chose not to eagerly finalize the object
+ // and it's up to the GC to finalize it later.
+ virtual
+ bool EagerFinalized(Object* obj) = 0;
+
+ // Asks the EE if it wishes for the current GC to be a blocking GC. The GC will
+ // only invoke this callback when it intends to do a full GC, so at this point
+ // the EE can opt to elevate that collection to be a blocking GC and not a background one.
+ virtual
+ bool ForceFullGCToBeBlocking() = 0;
};
#endif // _GCINTERFACE_EE_H_
diff --git a/src/gc/gcinterface.h b/src/gc/gcinterface.h
index 77425b1cc3..66d8b31a53 100644
--- a/src/gc/gcinterface.h
+++ b/src/gc/gcinterface.h
@@ -149,7 +149,7 @@ struct segment_info
void * pvMem; // base of the allocation, not the first object (must add ibFirstObject)
size_t ibFirstObject; // offset to the base of the first object in the segment
size_t ibAllocated; // limit of allocated memory in the segment (>= firstobject)
- size_t ibCommit; // limit of committed memory in the segment (>= alllocated)
+ size_t ibCommit; // limit of committed memory in the segment (>= allocated)
size_t ibReserved; // limit of reserved memory in the segment (>= commit)
};
@@ -163,8 +163,6 @@ struct segment_info
// one for the object header, and one for the first field in the object.
#define min_obj_size ((sizeof(uint8_t*) + sizeof(uintptr_t) + sizeof(size_t)))
-#define max_generation 2
-
// The bit shift used to convert a memory address into an index into the
// Software Write Watch table.
#define SOFTWARE_WRITE_WATCH_AddressToTableByteIndexShift 0xc
@@ -379,6 +377,13 @@ typedef enum
HNDTYPE_WEAK_WINRT = 9
} HandleType;
+typedef enum
+{
+ GC_HEAP_INVALID = 0,
+ GC_HEAP_WKS = 1,
+ GC_HEAP_SVR = 2
+} GCHeapType;
+
typedef bool (* walk_fn)(Object*, void*);
typedef void (* gen_walk_fn)(void* context, int generation, uint8_t* range_start, uint8_t* range_end, uint8_t* range_reserved);
typedef void (* record_surv_fn)(uint8_t* begin, uint8_t* end, ptrdiff_t reloc, void* context, bool compacting_p, bool bgc_p);
@@ -391,6 +396,10 @@ public:
virtual bool Initialize() = 0;
virtual void Shutdown() = 0;
+
+ virtual void* GetHandleTableContext(void* handleTable) = 0;
+
+ virtual void* GetHandleTableForHandle(OBJECTHANDLE handle) = 0;
};
// IGCHeap is the interface that the VM will use when interacting with the GC.
@@ -725,19 +734,6 @@ public:
IGCHeap() {}
virtual ~IGCHeap() {}
-
- typedef enum
- {
- GC_HEAP_INVALID = 0,
- GC_HEAP_WKS = 1,
- GC_HEAP_SVR = 2
- } GC_HEAP_TYPE;
-
-#ifdef FEATURE_SVR_GC
- SVAL_DECL(uint32_t, gcHeapType);
-#endif
-
- SVAL_DECL(uint32_t, maxGeneration);
};
#ifdef WRITE_BARRIER_CHECK
diff --git a/src/gc/handletable.h b/src/gc/handletable.h
index 2e847659f3..5b0299fe02 100644
--- a/src/gc/handletable.h
+++ b/src/gc/handletable.h
@@ -177,8 +177,11 @@ BOOL HndFirstAssignHandle(OBJECTHANDLE handle, OBJECTREF objref);
/*
* inline handle dereferencing
+ *
+ * NOTE: Changes to this implementation should be kept in sync with ObjectFromHandle
+ * on the VM side.
+ *
*/
-
FORCEINLINE OBJECTREF HndFetchHandle(OBJECTHANDLE handle)
{
WRAPPER_NO_CONTRACT;
diff --git a/src/gc/objecthandle.h b/src/gc/objecthandle.h
index b86572b276..386c5d4512 100644
--- a/src/gc/objecthandle.h
+++ b/src/gc/objecthandle.h
@@ -27,7 +27,6 @@
* non-NULL. In other words, if this handle is being initialized for the first
* time.
*/
-#define ObjectFromHandle(handle) HndFetchHandle(handle)
#define StoreObjectInHandle(handle, object) HndAssignHandle(handle, object)
#define InterlockedCompareExchangeObjectInHandle(handle, object, oldObj) HndInterlockedCompareExchangeHandle(handle, object, oldObj)
#define StoreFirstObjectInHandle(handle, object) HndFirstAssignHandle(handle, object)
@@ -119,7 +118,7 @@ inline OBJECTHANDLE CreateDuplicateHandle(OBJECTHANDLE handle) {
WRAPPER_NO_CONTRACT;
// Create a new STRONG handle in the same table as an existing handle.
- return HndCreateHandle(HndGetHandleTable(handle), HNDTYPE_DEFAULT, ObjectFromHandle(handle));
+ return HndCreateHandle(HndGetHandleTable(handle), HNDTYPE_DEFAULT, HndFetchHandle(handle));
}
diff --git a/src/gc/sample/GCSample.cpp b/src/gc/sample/GCSample.cpp
index 5d5371c76e..45915c0d04 100644
--- a/src/gc/sample/GCSample.cpp
+++ b/src/gc/sample/GCSample.cpp
@@ -207,24 +207,24 @@ int __cdecl main(int argc, char* argv[])
for (int i = 0; i < 1000000; i++)
{
- Object * pBefore = ((My *)ObjectFromHandle(oh))->m_pOther1;
+ Object * pBefore = ((My *)HndFetchHandle(oh))->m_pOther1;
// Allocate more instances of the same object
Object * p = AllocateObject(pMyMethodTable);
if (p == NULL)
return -1;
- Object * pAfter = ((My *)ObjectFromHandle(oh))->m_pOther1;
+ Object * pAfter = ((My *)HndFetchHandle(oh))->m_pOther1;
// Uncomment this assert to see how GC triggered inside AllocateObject moved objects around
// assert(pBefore == pAfter);
// Store the newly allocated object into a field using WriteBarrier
- WriteBarrier(&(((My *)ObjectFromHandle(oh))->m_pOther1), p);
+ WriteBarrier(&(((My *)HndFetchHandle(oh))->m_pOther1), p);
}
// Create weak handle that points to our object
- OBJECTHANDLE ohWeak = CreateGlobalWeakHandle(ObjectFromHandle(oh));
+ OBJECTHANDLE ohWeak = CreateGlobalWeakHandle(HndFetchHandle(oh));
if (ohWeak == NULL)
return -1;
@@ -235,7 +235,7 @@ int __cdecl main(int argc, char* argv[])
pGCHeap->GarbageCollect();
// Verify that the weak handle got cleared by the GC
- assert(ObjectFromHandle(ohWeak) == NULL);
+ assert(HndFetchHandle(ohWeak) == NULL);
printf("Done\n");
diff --git a/src/gc/sample/gcenv.ee.cpp b/src/gc/sample/gcenv.ee.cpp
index 07be244375..0f7dca1d98 100644
--- a/src/gc/sample/gcenv.ee.cpp
+++ b/src/gc/sample/gcenv.ee.cpp
@@ -270,6 +270,22 @@ void GCToEEInterface::HandleFatalError(unsigned int exitCode)
abort();
}
+bool GCToEEInterface::ShouldFinalizeObjectForUnload(AppDomain* pDomain, Object* obj)
+{
+ return true;
+}
+
+bool GCToEEInterface::ForceFullGCToBeBlocking()
+{
+ return false;
+}
+
+bool GCToEEInterface::EagerFinalized(Object* obj)
+{
+ // The sample does not finalize anything eagerly.
+ return false;
+}
+
bool IsGCSpecialThread()
{
// TODO: Implement for background GC
diff --git a/src/gc/windows/gcenv.windows.cpp b/src/gc/windows/gcenv.windows.cpp
index a636478245..30232bfb09 100644
--- a/src/gc/windows/gcenv.windows.cpp
+++ b/src/gc/windows/gcenv.windows.cpp
@@ -597,6 +597,9 @@ bool GCToOSInterface::CreateThread(GCThreadFunction function, void* param, GCThr
::SetThreadAffinityMask(gc_thread, (DWORD_PTR)1 << affinity->Processor);
}
+ ResumeThread(gc_thread);
+ CloseHandle(gc_thread);
+
return true;
}
diff --git a/src/inc/corbbtprof.h b/src/inc/corbbtprof.h
index 2f69dcccc8..5aa7782544 100644
--- a/src/inc/corbbtprof.h
+++ b/src/inc/corbbtprof.h
@@ -140,7 +140,7 @@ enum TypeProfilingDataFlags
ReadMethodTable = 0, // 0x00001
ReadEEClass = 1, // 0x00002
WriteEEClass = 2, // 0x00004
-// ReadStoredEnumData = 3, // 0x00008
+// ReadStoredEnumData = 3, // 0x00008 // obsolete
ReadFieldDescs = 4, // 0x00010
ReadCCtorInfo = 5, // 0x00020
ReadClassHashTable = 6, // 0x00040
@@ -148,34 +148,37 @@ enum TypeProfilingDataFlags
ReadDispatchTable = 8, // 0x00100
ReadMethodTableWriteableData = 9, // 0x00200
ReadFieldMarshalers = 10, // 0x00400
-// Unused = 11, // 0x00800 ... Was WriteDispatchTable in the past
-// WriteMethodTable = 12, // 0x01000
+// WriteDispatchTable = 11, // 0x00800 // obsolete
+// WriteMethodTable = 12, // 0x01000 // obsolete
WriteMethodTableWriteableData = 13, // 0x02000
ReadTypeDesc = 14, // 0x04000
WriteTypeDesc = 15, // 0x08000
ReadTypeHashTable = 16, // 0x10000
-// WriteTypeHashTable = 17, // 0x20000
-// ReadDictionary = 18, // 0x40000
-// WriteDictionary = 19, // 0x80000
+// WriteTypeHashTable = 17, // 0x20000 // obsolete
+// ReadDictionary = 18, // 0x40000 // obsolete
+// WriteDictionary = 19, // 0x80000 // obsolete
ReadNonVirtualSlots = 20, // 0x100000
};
enum MethodProfilingDataFlags
{
// Important: update toolbox\ibcmerge\ibcmerge.cs if you change these
- ReadMethodCode = 0, // 0x00001
+ ReadMethodCode = 0, // 0x00001 // Also means the method was executed
ReadMethodDesc = 1, // 0x00002
- RunOnceMethod = 2, // 0x00004 // was CommonMethod
- RunNeverMethod = 3, // 0x00008 // was MethodMetadataAccess
-// MethodStoredDataAccess = 4, // 0x00010
+ RunOnceMethod = 2, // 0x00004
+ RunNeverMethod = 3, // 0x00008
+// MethodStoredDataAccess = 4, // 0x00010 // obsolete
WriteMethodDesc = 5, // 0x00020
-// ReadFCallHash = 6, // 0x00040
+// ReadFCallHash = 6, // 0x00040 // obsolete
ReadGCInfo = 7, // 0x00080
CommonReadGCInfo = 8, // 0x00100
-// ReadMethodDefRidMap = 9, // 0x00200
+// ReadMethodDefRidMap = 9, // 0x00200 // obsolete
ReadCerMethodList = 10, // 0x00400
ReadMethodPrecode = 11, // 0x00800
WriteMethodPrecode = 12, // 0x01000
+ ExcludeHotMethodCode = 13, // 0x02000 // Hot method should be excluded from the ReadyToRun image
+ ExcludeColdMethodCode = 14, // 0x04000 // Cold method should be excluded from the ReadyToRun image
+ DisableInlining = 15, // 0x08000 // Disable inlining of this method in optimized AOT native code
};
enum GeneralProfilingDataFlags
diff --git a/src/inc/corhdr.h b/src/inc/corhdr.h
index c194def07f..4b757421cb 100644
--- a/src/inc/corhdr.h
+++ b/src/inc/corhdr.h
@@ -751,6 +751,7 @@ typedef enum CorAssemblyFlags
afEnableJITcompileTracking = 0x8000, // From "DebuggableAttribute".
afDisableJITcompileOptimizer = 0x4000, // From "DebuggableAttribute".
+ afDebuggableAttributeMask = 0xc000,
afRetargetable = 0x0100, // The assembly can be retargeted (at runtime) to an
// assembly from a different publisher.
diff --git a/src/inc/corinfo.h b/src/inc/corinfo.h
index 00c42cee4b..cbc4464e1d 100644
--- a/src/inc/corinfo.h
+++ b/src/inc/corinfo.h
@@ -214,11 +214,11 @@ TODO: Talk about initializing strutures before use
#endif
// Update this one
-SELECTANY const GUID JITEEVersionIdentifier = { /* 61783541-8fc0-44ce-80f7-7789b93a3309 */
- 0x61783541,
- 0x8fc0,
- 0x44ce,
- { 0x80, 0xf7, 0x77, 0x89, 0xb9, 0x3a, 0x33, 0x09 }
+SELECTANY const GUID JITEEVersionIdentifier = { /* f00b3f49-ddd2-49be-ba43-6e49ffa66959 */
+ 0xf00b3f49,
+ 0xddd2,
+ 0x49be,
+ { 0xba, 0x43, 0x6e, 0x49, 0xff, 0xa6, 0x69, 0x59 }
};
//////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -1568,6 +1568,9 @@ enum CorInfoTokenKind
// token comes from CEE_NEWOBJ
CORINFO_TOKENKIND_NewObj = 0x200 | CORINFO_TOKENKIND_Method,
+
+ // token comes from CEE_LDVIRTFTN
+ CORINFO_TOKENKIND_Ldvirtftn = 0x400 | CORINFO_TOKENKIND_Method,
};
struct CORINFO_RESOLVED_TOKEN
diff --git a/src/inc/corjit.h b/src/inc/corjit.h
index f434fee3e3..e6d067c0fe 100644
--- a/src/inc/corjit.h
+++ b/src/inc/corjit.h
@@ -146,6 +146,8 @@ public:
CORJIT_FLAG_USE_PINVOKE_HELPERS = 36, // The JIT should use the PINVOKE_{BEGIN,END} helpers instead of emitting inline transitions
CORJIT_FLAG_REVERSE_PINVOKE = 37, // The JIT should insert REVERSE_PINVOKE_{ENTER,EXIT} helpers into method prolog/epilog
CORJIT_FLAG_DESKTOP_QUIRKS = 38, // The JIT should generate desktop-quirk-compatible code
+ CORJIT_FLAG_TIER0 = 39, // This is the initial tier for tiered compilation which should generate code as quickly as possible
+ CORJIT_FLAG_TIER1 = 40, // This is the final tier (for now) for tiered compilation which should generate high quality code
};
CORJIT_FLAGS()
diff --git a/src/inc/crosscomp.h b/src/inc/crosscomp.h
index 494ca7c007..200c343a45 100644
--- a/src/inc/crosscomp.h
+++ b/src/inc/crosscomp.h
@@ -195,7 +195,7 @@ typedef union _NEON128 {
struct {
ULONGLONG Low;
LONGLONG High;
- } DUMMYSTRUCTNAME;
+ };
double D[2];
float S[4];
WORD H[8];
@@ -288,7 +288,7 @@ typedef struct _T_RUNTIME_FUNCTION {
DWORD CR : 2;
DWORD FrameSize : 9;
} PackedUnwindData;
- } DUMMYUNIONNAME;
+ };
} T_RUNTIME_FUNCTION, *PT_RUNTIME_FUNCTION;
diff --git a/src/inc/daccess.h b/src/inc/daccess.h
index 8ca9587a4c..7d82e86cb9 100644
--- a/src/inc/daccess.h
+++ b/src/inc/daccess.h
@@ -2393,6 +2393,10 @@ typedef DPTR(IMAGE_TLS_DIRECTORY) PTR_IMAGE_TLS_DIRECTORY;
#include <xclrdata.h>
#endif
+#if defined(_TARGET_X86_) && defined(FEATURE_PAL)
+typedef DPTR(struct _UNWIND_INFO) PTR_UNWIND_INFO;
+#endif
+
#ifdef _WIN64
typedef DPTR(T_RUNTIME_FUNCTION) PTR_RUNTIME_FUNCTION;
typedef DPTR(struct _UNWIND_INFO) PTR_UNWIND_INFO;
diff --git a/src/inc/dacvars.h b/src/inc/dacvars.h
index ab3bca20e3..4b7b7b1783 100644
--- a/src/inc/dacvars.h
+++ b/src/inc/dacvars.h
@@ -121,12 +121,8 @@ DEFINE_DACVAR(ULONG, int, dac__HillClimbingLogSize, ::HillClimbingLogSize)
DEFINE_DACVAR(ULONG, PTR_Thread, dac__g_pFinalizerThread, ::g_pFinalizerThread)
DEFINE_DACVAR(ULONG, PTR_Thread, dac__g_pSuspensionThread, ::g_pSuspensionThread)
-#ifdef FEATURE_SVR_GC
-DEFINE_DACVAR(ULONG, DWORD, IGCHeap__gcHeapType, IGCHeap::gcHeapType)
-#endif // FEATURE_SVR_GC
-
+DEFINE_DACVAR(ULONG, DWORD, dac__g_heap_type, g_heap_type)
DEFINE_DACVAR(ULONG, PTR_GcDacVars, dac__g_gcDacGlobals, g_gcDacGlobals)
-DEFINE_DACVAR(ULONG, DWORD, IGCHeap__maxGeneration, IGCHeap::maxGeneration)
DEFINE_DACVAR(ULONG, PTR_SystemDomain, SystemDomain__m_pSystemDomain, SystemDomain::m_pSystemDomain)
DEFINE_DACVAR(ULONG, ArrayListStatic, SystemDomain__m_appDomainIndexList, SystemDomain::m_appDomainIndexList)
diff --git a/src/inc/eventtracebase.h b/src/inc/eventtracebase.h
index f773a7c375..bd5ad1a2d0 100644
--- a/src/inc/eventtracebase.h
+++ b/src/inc/eventtracebase.h
@@ -154,11 +154,6 @@ public:
class Object;
#if !defined(FEATURE_PAL)
-/******************************/
-/* CLR ETW supported versions */
-/******************************/
-#define ETW_SUPPORTED_MAJORVER 5 // ETW is supported on win2k and above
-#define ETW_ENABLED_MAJORVER 6 // OS versions >= to this we enable ETW registration by default, since on XP and Windows 2003, registration is too slow.
/***************************************/
/* Tracing levels supported by CLR ETW */
@@ -201,11 +196,6 @@ struct ProfilingScanContext;
#include <wmistr.h>
#include <evntrace.h>
#include <evntprov.h>
-#if !defined(DONOT_DEFINE_ETW_CALLBACK) && !defined(DACCESS_COMPILE)
-#define GetVersionEx(Version) (GetOSVersion((LPOSVERSIONINFOW)Version))
-#else
-#define GetVersionEx(Version) (WszGetVersionEx((LPOSVERSIONINFOW)Version))
-#endif // !DONOT_DEFINE_ETW_CALLBACK && !DACCESS_COMPILE
#endif //!FEATURE_REDHAWK
#endif //!defined(FEATURE_PAL)
diff --git a/src/inc/legacyactivationshim.h b/src/inc/legacyactivationshim.h
deleted file mode 100644
index 4d8eaa5dd9..0000000000
--- a/src/inc/legacyactivationshim.h
+++ /dev/null
@@ -1,1382 +0,0 @@
-// 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.
-//
-// LegacyActivationShim.h
-//
-// This file allows simple migration from .NET Runtime v2 Host Activation APIs
-// to the .NET Runtime v4 Host Activation APIs through simple shim functions.
-
-#ifndef __LEGACYACTIVATIONSHIM_H__
-#define __LEGACYACTIVATIONSHIM_H__
-
-#pragma warning(push)
-#pragma warning(disable:4127) // warning C4127: conditional expression is constant
- // caused by IfHrFailRet's while(0) code.
-#pragma warning(disable:4917) // a GUID can only be associated with a class, interface or namespace
-#pragma warning(disable:4191) // 'reinterpret_cast' : unsafe conversion from 'FARPROC' to 'XXX'
-
-#ifdef _MANAGED
-// We are compiling Managed C++, switch to native code then (and store current managed/native status on the stack)
-#pragma managed(push, off)
-#endif //_MANAGED
-
-#include "mscoree.h"
-#include "metahost.h"
-
-#include "wchar.h"
-
-#include "corerror.h"
-
-// To minimize how much we perturb sources that we are included in, we make sure that
-// all macros we define/redefine are restored at the end of the header.
-#pragma push_macro("IfHrFailRet")
-#pragma push_macro("IfHrFailRetFALSE")
-#pragma push_macro("IfHrFailRetVOID")
-
-// ---IfHrFailRet------------------------------------------------------------------------------------
-#undef IfHrFailRet
-#undef IfHrFailRetFALSE
-#undef IfHrFailRetVOID
-#define IfHrFailRet(EXPR) do { hr = (EXPR); if(FAILED(hr)) { return (hr); } } while (0)
-#define IfHrFailRetFALSE(EXPR) do { HRESULT _hr_ = (EXPR); if(FAILED(_hr_)) { return false; } } while (0)
-#define IfHrFailRetVOID(EXPR) do { HRESULT _hr_ = (EXPR); if(FAILED(_hr_)) { return; } } while (0)
-
-#include "legacyactivationshimutil.h"
-
-// Use of deprecated APIs within LegacyActivationShim namespace will result in C4996 that we will
-// disable for our own use.
-#pragma warning(push)
-#pragma warning(disable:4996)
-// ---LEGACYACTIVATONSHIM NAMESPACE----------------------------------------------------------------
-namespace LegacyActivationShim
-{
- // ---HELPERS----------------------------------------------------------------------------------
-#define GET_CLRMETAHOST(x) \
- ICLRMetaHost *x = NULL; \
- IfHrFailRet(Util::GetCLRMetaHost(&x))
-
-#define GET_CLRMETAHOSTPOLICY(x) \
- ICLRMetaHostPolicy*x = NULL; \
- IfHrFailRet(Util::GetCLRMetaHostPolicy(&x))
-
-#define GET_CLRINFO(x) \
- ICLRRuntimeInfo *x = NULL; \
- IfHrFailRet(Util::GetCLRRuntimeInfo(&x))
-
-#define LEGACY_API_PASS_THROUGH_STATIC(_name, _ret_type, _ret_value, _sig, _args) \
- { \
- hr = S_OK; \
- _ret_value = ::_name _args; \
- }
-
-#define LEGACY_API_PASS_THROUGH_STATIC_VOIDRET(_name, _sig, _args) \
- { \
- ::_name _args; \
- }
-
-#define LEGACY_API_PASS_THROUGH_DELAYLOAD(_name, _ret_type, _ret_value, _sig, _args) \
- { \
- typedef _ret_type __stdcall t_FN _sig; \
- Util::MscoreeFunctor<t_FN> FN; \
- if (SUCCEEDED(hr = FN.Init(#_name))) { \
- _ret_value = FN()_args; \
- } \
- }
-
-#define LEGACY_API_PASS_THROUGH_DELAYLOAD_VOIDRET(_name, _sig, _args) \
- { \
- typedef void __stdcall t_FN _sig; \
- Util::MscoreeFunctor<t_FN> FN; \
- if (SUCCEEDED(FN.Init(#_name))) { \
- FN()_args; \
- } \
- }
-
-#ifndef LEGACY_ACTIVATION_SHIM_DELAY_LOAD
-#define CALL_LEGACY_API(_name, _sig, _args) \
- LEGACY_API_PASS_THROUGH_STATIC(_name, HRESULT, hr, _sig, _args)
-#define CALL_LEGACY_API_VOIDRET(_name, _sig, _args) \
- LEGACY_API_PASS_THROUGH_STATIC_VOIDRET(_name, _sig, _args)
-#else
-#define CALL_LEGACY_API(_name, _sig, _args) \
- LEGACY_API_PASS_THROUGH_DELAYLOAD(_name, HRESULT, hr, _sig, _args)
-#define CALL_LEGACY_API_VOIDRET(_name, _sig, _args) \
- LEGACY_API_PASS_THROUGH_DELAYLOAD_VOIDRET(_name, _sig, _args)
-#endif
-
- // ---LEGACY SHIM FUNCTIONS--------------------------------------------------------------------
-
- // --------------------------------------------------------------------------------------------
- inline
- HRESULT GetCORSystemDirectory(
- __out_ecount(cchBuffer) LPWSTR pBuffer,
- __in DWORD cchBuffer,
- __out DWORD *pdwLength)
- {
- HRESULT hr = S_OK;
-
- if (Util::HasNewActivationAPIs())
- {
- DWORD dwLengthDummy = cchBuffer;
- if (pdwLength == NULL)
- pdwLength = &dwLengthDummy;
- else
- *pdwLength = cchBuffer;
-
- GET_CLRINFO(pInfo);
- IfHrFailRet(pInfo->GetRuntimeDirectory(pBuffer, pdwLength));
- }
- else
- {
- CALL_LEGACY_API(GetCORSystemDirectory,
- (LPWSTR pBuffer,
- DWORD cchBuffer,
- DWORD *pdwLength),
- (pBuffer,
- cchBuffer,
- pdwLength));
- }
-
- return hr;
- }
-
- // --------------------------------------------------------------------------------------------
- inline
- HRESULT GetCORVersion(
- __out_ecount(cchBuffer) LPWSTR pbBuffer,
- __in DWORD cchBuffer,
- __out DWORD *pdwLength)
- {
- HRESULT hr = S_OK;
-
- if (Util::HasNewActivationAPIs())
- {
- DWORD dwLengthDummy = cchBuffer;
- if (pdwLength == NULL)
- pdwLength = &dwLengthDummy;
- else
- *pdwLength = cchBuffer;
-
- GET_CLRINFO(pInfo);
- IfHrFailRet(pInfo->GetVersionString(pbBuffer, pdwLength));
- }
- else
- {
- CALL_LEGACY_API(GetCORVersion,
- (LPWSTR pbBuffer,
- DWORD cchBuffer,
- DWORD *pdwLength),
- (pbBuffer,
- cchBuffer,
- pdwLength));
-
- }
-
- return hr;
- }
-
- // --------------------------------------------------------------------------------------------
- inline
- HRESULT GetFileVersion(
- __in LPCWSTR szFileName,
- __out_ecount(cchBuffer) LPWSTR szBuffer,
- __in DWORD cchBuffer,
- __out DWORD *pdwLength)
- {
- HRESULT hr = S_OK;
-
- if (Util::HasNewActivationAPIs())
- {
- DWORD dwLengthDummy = cchBuffer;
- if (pdwLength == NULL)
- pdwLength = &dwLengthDummy;
- else
- *pdwLength = cchBuffer;
-
- GET_CLRMETAHOST(pMH);
- IfHrFailRet(pMH->GetVersionFromFile(szFileName, szBuffer, pdwLength));
- }
- else
- {
- CALL_LEGACY_API(GetFileVersion,
- (LPCWSTR szFileName,
- LPWSTR szBuffer,
- DWORD cchBuffer,
- DWORD *pdwLength),
- (szFileName,
- szBuffer,
- cchBuffer,
- pdwLength));
- }
-
- return hr;
- }
-
- // --------------------------------------------------------------------------------------------
- inline
- HRESULT GetCORRequiredVersion(
- __out_ecount(cchBuffer) LPWSTR pBuffer,
- __in DWORD cchBuffer,
- __out DWORD *pdwLength)
- {
- HRESULT hr = S_OK;
-
- if (Util::HasNewActivationAPIs())
- {
- DWORD dwLengthDummy = cchBuffer;
- if (pdwLength == NULL)
- pdwLength = &dwLengthDummy;
- else
- *pdwLength = cchBuffer;
-
- IfHrFailRet(Util::GetConfigImageVersion(pBuffer, pdwLength));
- }
- else
- {
- CALL_LEGACY_API(GetCORRequiredVersion,
- (LPWSTR pBuffer,
- DWORD cchBuffer,
- DWORD *pdwLength),
- (pBuffer,
- cchBuffer,
- pdwLength));
- }
-
- return hr;
- }
-
- // --------------------------------------------------------------------------------------------
- // This API is the one exception that we don't have fully equivalent functionality for
- // in the new APIs. Specifically, we do not have the runtimeInfoFlags equivalent that
- // allows platform differentiation. As such, we just send the call to the legacy API,
- // which does not bind (thankfully) and so we do not cap this specific API to Whidbey.
- inline
- HRESULT GetRequestedRuntimeInfo(
- __in_opt LPCWSTR pExe,
- __in_opt LPCWSTR pwszVersion,
- __in_opt LPCWSTR pConfigurationFile,
- __in DWORD startupFlags,
- __in DWORD runtimeInfoFlags,
- __out_ecount(dwDirectory) LPWSTR pDirectory,
- __in DWORD dwDirectory,
- __out DWORD *pdwDirectoryLength,
- __out_ecount(cchBuffer) LPWSTR pVersion,
- __in DWORD cchBuffer,
- __out DWORD *pdwLength)
- {
- HRESULT hr = S_OK;
-
- CALL_LEGACY_API(GetRequestedRuntimeInfo,
- (LPCWSTR pExe,
- LPCWSTR pwszVersion,
- LPCWSTR pConfigurationFile,
- DWORD startupFlags,
- DWORD runtimeInfoFlags,
- LPWSTR pDirectory,
- DWORD dwDirectory,
- DWORD *pdwDirectoryLength,
- LPWSTR pVersion,
- DWORD cchBuffer,
- DWORD *pdwLength),
- (pExe,
- pwszVersion,
- pConfigurationFile,
- startupFlags,
- runtimeInfoFlags,
- pDirectory,
- dwDirectory,
- pdwDirectoryLength,
- pVersion,
- cchBuffer,
- pdwLength));
-
- return hr;
- }
-
- // --------------------------------------------------------------------------------------------
- inline
- HRESULT GetRequestedRuntimeVersion(
- __in LPWSTR pExe,
- __out_ecount(cchBuffer) LPWSTR pVersion,
- __in DWORD cchBuffer,
- __out DWORD *pdwLength)
- {
- HRESULT hr = S_OK;
-
- if (Util::HasNewActivationAPIs())
- {
- DWORD dwLengthDummy = cchBuffer;
- if (pdwLength == NULL)
- pdwLength = &dwLengthDummy;
- else
- *pdwLength = cchBuffer;
-
- GET_CLRMETAHOSTPOLICY(pMHP);
- ICLRRuntimeInfo *pInfo = NULL;
- IfHrFailRet(pMHP->GetRequestedRuntime(
- METAHOST_POLICY_USE_PROCESS_IMAGE_PATH,
- pExe,
- NULL, // config stream
- pVersion,
- pdwLength,
- NULL, // image version str
- NULL, // image version len
- NULL,
- IID_ICLRRuntimeInfo,
- reinterpret_cast<LPVOID*>(&pInfo)));// ppRuntime
- Util::ReleaseHolder<ICLRRuntimeInfo*> hInfo(pInfo);
- }
- else
- {
- CALL_LEGACY_API(GetRequestedRuntimeVersion,
- (LPWSTR pExe,
- LPWSTR pVersion,
- DWORD cchBuffer,
- DWORD *pdwLength),
- (pExe,
- pVersion,
- cchBuffer,
- pdwLength));
- }
-
- return hr;
- }
-
- // --------------------------------------------------------------------------------------------
- inline
- HRESULT CorBindToRuntimeHost(
- LPCWSTR pwszVersion,
- LPCWSTR pwszBuildFlavor,
- LPCWSTR pwszHostConfigFile,
- VOID* pReserved,
- DWORD startupFlags,
- REFCLSID rclsid,
- REFIID riid,
- LPVOID FAR *ppv)
- {
- HRESULT hr = S_OK;
-
- if (Util::HasNewActivationAPIs())
- {
- IStream *pConfigStream = NULL;
- Util::ReleaseHolder<IStream*> hConfigStream;
- if (pwszHostConfigFile != NULL)
- {
- IfHrFailRet(Util::CreateIStreamFromFile(pwszHostConfigFile, &pConfigStream));
- hConfigStream.Assign(pConfigStream);
- }
-
- WCHAR wszVersionLocal[512];
- DWORD cchVersionLocal = 512;
- if (pwszVersion != NULL)
- wcsncpy_s(&wszVersionLocal[0], cchVersionLocal, pwszVersion, _TRUNCATE);
-
- ICLRRuntimeInfo *pInfo = NULL;
- IfHrFailRet(Util::GetCLRRuntimeInfo(
- &pInfo,
- NULL,
- pConfigStream,
- pwszVersion == NULL ? NULL : &wszVersionLocal[0],
- pwszVersion == NULL ? NULL : &cchVersionLocal));
-
- // We're intentionally ignoring the HRESULT return value, since CorBindToRuntimeEx
- // always ignored these flags when a runtime had already been bound, and we need
- // to emulate that behavior for when multiple calls to CorBindToRuntimeEx are made
- // but with different startup flags (ICLRRuntimeInfo::SetDefaultStartupFlags will
- // return E_INVALIDARG in the case that the runtime has already been started with
- // different flags).
- Util::AddStartupFlags(pInfo, pwszBuildFlavor, startupFlags, pwszHostConfigFile);
-
- IfHrFailRet(pInfo->GetInterface(rclsid, riid, ppv));
- }
- else
- {
- CALL_LEGACY_API(CorBindToRuntimeHost,
- (LPCWSTR pwszVersion,
- LPCWSTR pwszBuildFlavor,
- LPCWSTR pwszHostConfigFile,
- VOID* pReserved,
- DWORD startupFlags,
- REFCLSID rclsid,
- REFIID riid,
- LPVOID FAR *ppv),
- (pwszVersion,
- pwszBuildFlavor,
- pwszHostConfigFile,
- pReserved,
- startupFlags,
- rclsid,
- riid,
- ppv));
- }
-
- return hr;
- }
-
- // --------------------------------------------------------------------------------------------
- inline
- HRESULT CorBindToRuntimeEx(
- LPCWSTR pwszVersion,
- LPCWSTR pwszBuildFlavor,
- DWORD startupFlags,
- REFCLSID rclsid,
- REFIID riid,
- LPVOID* ppv)
- {
- HRESULT hr = S_OK;
-
- if (Util::HasNewActivationAPIs())
- {
- WCHAR wszVersionLocal[512];
- DWORD cchVersionLocal = 512;
- if (pwszVersion != NULL)
- wcsncpy_s(&wszVersionLocal[0], cchVersionLocal, pwszVersion, _TRUNCATE);
-
- ICLRRuntimeInfo *pInfo = NULL;
- IfHrFailRet(Util::GetCLRRuntimeInfo(
- &pInfo,
- NULL, // exe path
- NULL, // config stream
- pwszVersion == NULL ? NULL : &wszVersionLocal[0],
- pwszVersion == NULL ? NULL : &cchVersionLocal));
-
- // We're intentionally ignoring the HRESULT return value, since CorBindToRuntimeEx
- // always ignored these flags when a runtime had already been bound, and we need
- // to emulate that behavior for when multiple calls to CorBindToRuntimeEx are made
- // but with different startup flags (ICLRRuntimeInfo::SetDefaultStartupFlags will
- // return E_INVALIDARG in the case that the runtime has already been started with
- // different flags).
- Util::AddStartupFlags(pInfo, pwszBuildFlavor, startupFlags, NULL);
-
- IfHrFailRet(pInfo->GetInterface(rclsid, riid, ppv));
- }
- else
- {
- CALL_LEGACY_API(CorBindToRuntimeEx,
- (LPCWSTR pwszVersion,
- LPCWSTR pwszBuildFlavor,
- DWORD startupFlags,
- REFCLSID rclsid,
- REFIID riid,
- LPVOID* ppv),
- (pwszVersion,
- pwszBuildFlavor,
- startupFlags,
- rclsid,
- riid,
- ppv));
- }
-
- return hr;
- }
-
- // --------------------------------------------------------------------------------------------
- inline
- HRESULT CorBindToRuntimeByCfg(
- IStream* pCfgStream,
- DWORD reserved,
- DWORD startupFlags,
- REFCLSID rclsid,
- REFIID riid,
- LPVOID* ppv)
- {
- HRESULT hr = S_OK;
-
- if (Util::HasNewActivationAPIs())
- {
- // The legacy CorBindToRuntimeByCfg picks up startup flags from both the config stream and
- // application config file if it is present. For simplicity, we ignore the app config here.
- ICLRRuntimeInfo *pInfo = NULL;
- IfHrFailRet(Util::GetCLRRuntimeInfo(
- &pInfo,
- NULL, // exe path
- pCfgStream));
-
- // We're intentionally ignoring the HRESULT return value, since CorBindToRuntimeEx
- // always ignored these flags when a runtime had already been bound, and we need
- // to emulate that behavior for when multiple calls to CorBindToRuntimeEx are made
- // but with different startup flags (ICLRRuntimeInfo::SetDefaultStartupFlags will
- // return E_INVALIDARG in the case that the runtime has already been started with
- // different flags).
- Util::AddStartupFlags(pInfo, NULL, startupFlags, NULL);
-
- IfHrFailRet(pInfo->GetInterface(rclsid, riid, ppv));
- }
- else
- {
- CALL_LEGACY_API(CorBindToRuntimeByCfg,
- (IStream* pCfgStream,
- DWORD reserved,
- DWORD startupFlags,
- REFCLSID rclsid,
- REFIID riid,
- LPVOID* ppv),
- (pCfgStream,
- reserved,
- startupFlags,
- rclsid,
- riid,
- ppv));
- }
-
- return hr;
- }
-
- // --------------------------------------------------------------------------------------------
- inline
- HRESULT CorBindToRuntime(
- LPCWSTR pwszVersion,
- LPCWSTR pwszBuildFlavor,
- REFCLSID rclsid,
- REFIID riid,
- LPVOID* ppv)
- {
- HRESULT hr = S_OK;
-
- if (Util::HasNewActivationAPIs())
- {
- WCHAR wszVersionLocal[512];
- DWORD cchVersionLocal = 512;
- if (pwszVersion != NULL)
- wcsncpy_s(&wszVersionLocal[0], cchVersionLocal, pwszVersion, _TRUNCATE);
-
- ICLRRuntimeInfo *pInfo = NULL;
- IfHrFailRet(Util::GetCLRRuntimeInfo(
- &pInfo,
- NULL, // exe path
- NULL, // config stream
- pwszVersion == NULL ? NULL : &wszVersionLocal[0],
- pwszVersion == NULL ? NULL : &cchVersionLocal));
-
- // CorBindToRuntime has its special default flags
- //
- // We're intentionally ignoring the HRESULT return value, since CorBindToRuntimeEx
- // always ignored these flags when a runtime had already been bound, and we need
- // to emulate that behavior for when multiple calls to CorBindToRuntimeEx are made
- // but with different startup flags (ICLRRuntimeInfo::SetDefaultStartupFlags will
- // return E_INVALIDARG in the case that the runtime has already been started with
- // different flags).
- Util::AddStartupFlags(pInfo, NULL, STARTUP_LOADER_OPTIMIZATION_MULTI_DOMAIN_HOST, NULL);
-
- IfHrFailRet(pInfo->GetInterface(rclsid, riid, ppv));
- }
- else
- {
- CALL_LEGACY_API(CorBindToRuntime,
- (LPCWSTR pwszVersion,
- LPCWSTR pwszBuildFlavor,
- REFCLSID rclsid,
- REFIID riid,
- LPVOID* ppv),
- (pwszVersion,
- pwszBuildFlavor,
- rclsid,
- riid,
- ppv));
- }
-
- return hr;
- }
-
- // --------------------------------------------------------------------------------------------
- inline
- HRESULT CorBindToCurrentRuntime(
- LPCWSTR pwszFileName,
- REFCLSID rclsid,
- REFIID riid,
- LPVOID FAR *ppv)
- {
- HRESULT hr = S_OK;
-
- if (Util::HasNewActivationAPIs())
- {
- ICLRRuntimeInfo *pInfo = NULL;
- IfHrFailRet(Util::GetCLRRuntimeInfo(
- &pInfo,
- pwszFileName));
-
- IfHrFailRet(pInfo->GetInterface(rclsid, riid, ppv));
- }
- else
- {
- CALL_LEGACY_API(CorBindToCurrentRuntime,
- (LPCWSTR pwszFileName,
- REFCLSID rclsid,
- REFIID riid,
- LPVOID FAR *ppv),
- (pwszFileName,
- rclsid,
- riid,
- ppv));
- }
-
- return hr;
- }
-
- // --------------------------------------------------------------------------------------------
- inline
- HRESULT ClrCreateManagedInstance(
- LPCWSTR pTypeName,
- REFIID riid,
- void **ppObject)
- {
- HRESULT hr = S_OK;
-
- if (Util::HasNewActivationAPIs())
- {
- GET_CLRINFO(pInfo);
- HRESULT (STDMETHODCALLTYPE *pfnClrCreateManagedInstance)(LPCWSTR typeName, REFIID riid, void ** ppv) = NULL;
- IfHrFailRet(pInfo->GetProcAddress("ClrCreateManagedInstance", (LPVOID *)&pfnClrCreateManagedInstance));
- IfHrFailRet(pfnClrCreateManagedInstance(pTypeName, riid, ppObject));
- }
- else
- {
- CALL_LEGACY_API(ClrCreateManagedInstance,
- (LPCWSTR pTypeName,
- REFIID riid,
- void **ppObject),
- (pTypeName,
- riid,
- ppObject));
- }
-
- return hr;
- }
-
- // --------------------------------------------------------------------------------------------
- inline
- HRESULT LoadLibraryShim(
- LPCWSTR szDllName,
- LPCWSTR szVersion,
- LPVOID pvReserved,
- HMODULE *phModDll)
- {
- HRESULT hr = S_OK;
-
- if (Util::HasNewActivationAPIs())
- {
- Util::ReleaseHolder<ICLRRuntimeInfo*> hInfo;
- ICLRRuntimeInfo *pInfo = NULL;
-
- // Semantics of LoadLibraryShim is that a non-null version must match exactly.
- if (szVersion != NULL)
- {
- GET_CLRMETAHOST(pMH);
- IfHrFailRet(pMH->GetRuntime(szVersion, IID_ICLRRuntimeInfo, reinterpret_cast<LPVOID*>(&pInfo)));
- hInfo.Assign(pInfo);
- }
- else
- {
- IfHrFailRet(Util::GetCLRRuntimeInfo(&pInfo));
- }
- IfHrFailRet(pInfo->LoadLibrary(szDllName, phModDll));
- }
- else
- {
- CALL_LEGACY_API(LoadLibraryShim,
- (LPCWSTR szDllName,
- LPCWSTR szVersion,
- LPVOID pvReserved,
- HMODULE *phModDll),
- (szDllName,
- szVersion,
- pvReserved,
- phModDll));
- }
-
- return hr;
- }
-
- // --------------------------------------------------------------------------------------------
- inline
- HRESULT CallFunctionShim(
- LPCWSTR szDllName,
- LPCSTR szFunctionName,
- LPVOID lpvArgument1,
- LPVOID lpvArgument2,
- LPCWSTR szVersion,
- LPVOID pvReserved)
- {
- HRESULT hr = S_OK;
-
- if (Util::HasNewActivationAPIs())
- {
- HMODULE hMod = NULL;
- HRESULT (__stdcall * pfn)(LPVOID,LPVOID) = NULL;
-
- // Load library
- IfHrFailRet(LegacyActivationShim::LoadLibraryShim(szDllName, szVersion, pvReserved, &hMod));
-
- // NOTE: Legacy CallFunctionShim does not release HMODULE, leak to maintain compat
- // Util::HMODULEHolder hModHolder(hMod);
-
- // Find function.
- pfn = (HRESULT (__stdcall *)(LPVOID,LPVOID))GetProcAddress(hMod, szFunctionName);
- if (pfn == NULL)
- return HRESULT_FROM_WIN32(GetLastError());
-
- // Call it.
- return pfn(lpvArgument1, lpvArgument2);
- }
- else
- {
- CALL_LEGACY_API(CallFunctionShim,
- (LPCWSTR szDllName,
- LPCSTR szFunctionName,
- LPVOID lpvArgument1,
- LPVOID lpvArgument2,
- LPCWSTR szVersion,
- LPVOID pvReserved),
- (szDllName,
- szFunctionName,
- lpvArgument1,
- lpvArgument2,
- szVersion,
- pvReserved));
- }
-
- return hr;
- }
-
- // --------------------------------------------------------------------------------------------
- inline
- HRESULT GetRealProcAddress(
- LPCSTR pwszProcName,
- VOID **ppv)
- {
- HRESULT hr = S_OK;
-
- if (Util::HasNewActivationAPIs())
- {
- GET_CLRINFO(pInfo);
- IfHrFailRet(pInfo->GetProcAddress(pwszProcName, ppv));
- }
- else
- {
- CALL_LEGACY_API(GetRealProcAddress,
- (LPCSTR pwszProcName,
- VOID **ppv),
- (pwszProcName,
- ppv));
- }
-
- return hr;
- }
-
- // --------------------------------------------------------------------------------------------
- inline
- void CorExitProcess(
- int exitCode)
- {
-#ifndef LEGACY_ACTIVATION_SHIM_DELAY_LOAD
- ::CorExitProcess(exitCode);
-#else
- typedef void __stdcall t_CorExitProcess(
- int exitCode);
-
- Util::MscoreeFunctor<t_CorExitProcess> FN;
- if (FAILED(FN.Init("CorExitProcess")))
- return;
-
- FN()(exitCode);
-#endif
- }
-
-// Define this method only if it is not yet defined as macro (see ndp\clr\src\inc\UtilCode.h).
-#ifndef LoadStringRC
- // --------------------------------------------------------------------------------------------
- inline
- HRESULT LoadStringRC(
- UINT nResourceID,
- __out_ecount(nMax) LPWSTR szBuffer,
- int nMax,
- int fQuiet)
- {
- HRESULT hr = S_OK;
-
- if (Util::HasNewActivationAPIs())
- {
- GET_CLRINFO(pInfo);
- DWORD cchMax = static_cast<DWORD>(nMax);
- IfHrFailRet(pInfo->LoadErrorString(nResourceID, szBuffer, &cchMax, -1));
- }
- else
- {
- CALL_LEGACY_API(LoadStringRC,
- (UINT nResourceID,
- LPWSTR szBuffer,
- int nMax,
- int fQuiet),
- (nResourceID,
- szBuffer,
- nMax,
- fQuiet));
- }
-
- return hr;
- }
-#endif //LoadStringRC
-
-// Define this method only if it is not yet defined as macro (see ndp\clr\src\inc\UtilCode.h).
-#if !defined(LoadStringRCEx) && !defined(FEATURE_CORESYSTEM)
- // --------------------------------------------------------------------------------------------
- inline
- HRESULT LoadStringRCEx(
- LCID lcid,
- UINT nResourceID,
- __out_ecount(nMax) LPWSTR szBuffer,
- int nMax,
- int fQuiet,
- int *pcwchUsed)
- {
- HRESULT hr = S_OK;
-
- if (Util::HasNewActivationAPIs())
- {
- GET_CLRINFO(pInfo);
- DWORD cchUsed = static_cast<DWORD>(nMax);
- IfHrFailRet(pInfo->LoadErrorString(nResourceID, szBuffer, &cchUsed, lcid));
- *pcwchUsed = cchUsed;
- }
- else
- {
- CALL_LEGACY_API(LoadStringRCEx,
- (LCID lcid,
- UINT nResourceID,
- LPWSTR szBuffer,
- int nMax,
- int fQuiet,
- int *pcwchUsed),
- (lcid,
- nResourceID,
- szBuffer,
- nMax,
- fQuiet,
- pcwchUsed));
- }
-
- return hr;
- }
-#endif //LoadStringRCEx
-
- // --------------------------------------------------------------------------------------------
- inline
- HRESULT LockClrVersion(
- FLockClrVersionCallback hostCallback,
- FLockClrVersionCallback *pBeginHostSetup,
- FLockClrVersionCallback *pEndHostSetup)
- {
- HRESULT hr = S_OK;
-
- CALL_LEGACY_API(LockClrVersion,
- (FLockClrVersionCallback hostCallback,
- FLockClrVersionCallback *pBeginHostSetup,
- FLockClrVersionCallback *pEndHostSetup),
- (hostCallback,
- pBeginHostSetup,
- pEndHostSetup));
-
- return hr;
- }
-
- // --------------------------------------------------------------------------------------------
- inline
- HRESULT CreateDebuggingInterfaceFromVersion(
- int nDebuggerVersion,
- LPCWSTR szDebuggeeVersion,
- IUnknown ** ppCordb)
- {
- HRESULT hr = S_OK;
-
- CALL_LEGACY_API(CreateDebuggingInterfaceFromVersion,
- (int nDebuggerVersion,
- LPCWSTR szDebuggeeVersion,
- IUnknown ** ppCordb),
- (nDebuggerVersion,
- szDebuggeeVersion,
- ppCordb));
-
- return hr;
- }
-
- // --------------------------------------------------------------------------------------------
- inline
- HRESULT GetVersionFromProcess(
- __in HANDLE hProcess,
- __out_ecount(cchBuffer) LPWSTR pVersion,
- __in DWORD cchBuffer,
- __out DWORD *pdwLength)
- {
- HRESULT hr = S_OK;
-
- CALL_LEGACY_API(GetVersionFromProcess,
- (HANDLE hProcess,
- LPWSTR pVersion,
- DWORD cchBuffer,
- DWORD *pdwLength),
- (hProcess,
- pVersion,
- cchBuffer,
- pdwLength));
-
- return hr;
- }
-
- // --------------------------------------------------------------------------------------------
-// CoInitializeEE is declared in cor.h, define it only if explicitly requested
-#ifdef LEGACY_ACTIVATION_SHIM_DEFINE_CoInitializeEE
- inline
- HRESULT CoInitializeEE(DWORD flags)
- {
- HRESULT hr = S_OK;
-
- if (Util::HasNewActivationAPIs())
- {
- GET_CLRINFO(pInfo);
- HRESULT (* pfnCoInitializeEE)(DWORD);
- IfHrFailRet(pInfo->GetProcAddress("CoInitializeEE", (LPVOID *)&pfnCoInitializeEE));
- return (*pfnCoInitializeEE)(flags);
- }
- else
- {
- CALL_LEGACY_API(CoInitializeEE,
- (DWORD flags),
- (flags));
- }
-
- return hr;
- }
-
- inline
- VOID CoUninitializeEE(BOOL flags)
- {
- if (Util::HasNewActivationAPIs())
- {
- ICLRRuntimeInfo *pInfo = NULL;
- if (FAILED(Util::GetCLRRuntimeInfo(&pInfo)))
- return;
-
- VOID (* pfnCoUninitializeEE)(BOOL);
- if (FAILED(pInfo->GetProcAddress("CoUninitializeEE", (LPVOID *)&pfnCoUninitializeEE)))
- return;
-
- (*pfnCoUninitializeEE)(flags);
- }
- else
- {
- CALL_LEGACY_API_VOIDRET(CoUninitializeEE,
- (BOOL flags),
- (flags));
- }
- }
-
- inline
- HRESULT CoInitializeCor(DWORD flags)
- {
- HRESULT hr = S_OK;
-
- if (Util::HasNewActivationAPIs())
- {
- GET_CLRINFO(pInfo);
- HRESULT (* pfnCoInitializeCor)(DWORD);
- IfHrFailRet(pInfo->GetProcAddress("CoInitializeCor", (LPVOID *)&pfnCoInitializeCor));
- return (*pfnCoInitializeCor)(flags);
- }
- else
- {
- CALL_LEGACY_API(CoInitializeCor,
- (DWORD flags),
- (flags));
- }
-
- return hr;
- }
-
- inline
- VOID CoUninitializeCor()
- {
- if (Util::HasNewActivationAPIs())
- {
- ICLRRuntimeInfo *pInfo = NULL;
- if (FAILED(Util::GetCLRRuntimeInfo(&pInfo)))
- return;
-
- VOID (* pfnCoUninitializeCor)();
- if (FAILED(pInfo->GetProcAddress("CoUninitializeCor", (LPVOID *)&pfnCoUninitializeCor)))
- return;
-
- (*pfnCoUninitializeCor)();
- }
- else
- {
- CALL_LEGACY_API_VOIDRET(CoUninitializeCor,
- (VOID),
- ());
- }
- }
-
-#endif //LEGACY_ACTIVATION_SHIM_DEFINE_CoInitializeEE
-
- // --------------------------------------------------------------------------------------------
-// CoEEShutDownCOM is declared in cor.h, define it only if explicitly requested
-#ifdef LEGACY_ACTIVATION_SHIM_DEFINE_CoEEShutDownCOM
- inline
- void CoEEShutDownCOM()
- {
- if (Util::HasNewActivationAPIs())
- {
- ICLRRuntimeInfo *pInfo = NULL;
- IfHrFailRetVOID(Util::GetCLRRuntimeInfo(&pInfo));
- void (* pfnCoEEShutDownCOM)();
- IfHrFailRetVOID(pInfo->GetProcAddress("CoEEShutDownCOM", (LPVOID *)&pfnCoEEShutDownCOM));
- (*pfnCoEEShutDownCOM)();
- }
- else
- {
- CALL_LEGACY_API_VOIDRET(CoEEShutDownCOM,
- (),
- ());
- }
-
- return;
- }
-#endif //LEGACY_ACTIVATION_SHIM_DEFINE_CoEEShutDownCOM
-
- // ---StrongName Function Helpers--------------------------------------------------------------
-#if !defined(LEGACY_ACTIVATION_SHIM_DELAY_LOAD) && defined(__STRONG_NAME_H)
-#define LEGACY_STRONGNAME_API_PASS_THROUGH(_name, _ret_type, _ret_value, _sig, _args) \
- LEGACY_API_PASS_THROUGH_STATIC(_name, _ret_type, _ret_value, _sig, _args)
-#define LEGACY_STRONGNAME_API_PASS_THROUGH_VOIDRET(_name, _sig, _args) \
- LEGACY_API_PASS_THROUGH_STATIC_VOIDRET(_name, _sig, _args)
-#else //defined(LEGACY_ACTIVATION_SHIM_DELAY_LOAD) || !defined(__STRONG_NAME_H)
-#define LEGACY_STRONGNAME_API_PASS_THROUGH(_name, _ret_type, _ret_value, _sig, _args) \
- LEGACY_API_PASS_THROUGH_DELAYLOAD(_name, _ret_type, _ret_value, _sig, _args)
-#define LEGACY_STRONGNAME_API_PASS_THROUGH_VOIDRET(_name, _sig, _args) \
- LEGACY_API_PASS_THROUGH_DELAYLOAD_VOIDRET(_name, _sig, _args)
-#endif //defined(LEGACY_ACTIVATION_SHIM_DELAY_LOAD) || !defined(__STRONG_NAME_H)
-
-// Defines a method that just delegates a call to the right runtime, this one is for SN APIs that
-// return HRESULT.
-#define PASS_THROUGH_IMPL_HRESULT(_name, _signature, _args) \
- inline \
- HRESULT _name##_signature \
- { \
- HRESULT hr = S_OK; \
- if (Util::HasNewActivationAPIs()) \
- { \
- ICLRStrongName *pSN = NULL; \
- IfHrFailRet(Util::GetCLRStrongName(&pSN)); \
- IfHrFailRet(pSN->_name _args); \
- } \
- else \
- { \
- LEGACY_STRONGNAME_API_PASS_THROUGH( \
- _name, HRESULT, hr, _signature, _args); \
- IfHrFailRet(hr); \
- } \
- return hr; \
- }
-
-// Defines a method that just delegates a call to the right runtime, this one is for SN APIs that
-// return BOOL.
-#define PASS_THROUGH_IMPL_BOOLEAN(_name, _signature, _args) \
- inline \
- BOOL _name##_signature \
- { \
- HRESULT hr = S_OK; \
- if (Util::HasNewActivationAPIs()) \
- { \
- ICLRStrongName *pSN = NULL; \
- IfHrFailRetFALSE(Util::GetCLRStrongName(&pSN)); \
- IfHrFailRetFALSE(pSN->_name _args); \
- return TRUE; \
- } \
- else \
- { \
- BOOL fResult = TRUE; \
- LEGACY_STRONGNAME_API_PASS_THROUGH( \
- _name, BOOL, fResult, _signature, _args); \
- IfHrFailRetFALSE(hr); \
- return fResult; \
- } \
- }
-
-// Defines a method that just delegates a call to the right runtime, this one is for SN APIs that
-// return VOID.
-#define PASS_THROUGH_IMPL_VOID(_name, _signature, _args) \
- inline \
- VOID _name##_signature \
- { \
- HRESULT hr = S_OK; \
- if (Util::HasNewActivationAPIs()) \
- { \
- ICLRStrongName *pSN = NULL; \
- IfHrFailRetVOID(Util::GetCLRStrongName(&pSN)); \
- IfHrFailRetVOID(pSN->_name _args); \
- return; \
- } \
- else \
- { \
- LEGACY_STRONGNAME_API_PASS_THROUGH_VOIDRET( \
- _name, _signature, _args); \
- IfHrFailRetVOID(hr); \
- return; \
- } \
- }
-
- // ---StrongName functions---------------------------------------------------------------------
-
-PASS_THROUGH_IMPL_HRESULT(GetHashFromAssemblyFile,
- (LPCSTR pszFilePath, unsigned int *piHashAlg, BYTE *pbHash, DWORD cchHash, DWORD *pchHash),
- (pszFilePath, piHashAlg, pbHash, cchHash, pchHash));
-
-PASS_THROUGH_IMPL_HRESULT(GetHashFromAssemblyFileW,
- (LPCWSTR pwzFilePath, unsigned int *piHashAlg, BYTE *pbHash, DWORD cchHash, DWORD *pchHash),
- (pwzFilePath, piHashAlg, pbHash, cchHash, pchHash));
-
-PASS_THROUGH_IMPL_HRESULT(GetHashFromBlob,
- (BYTE *pbBlob, DWORD cchBlob, unsigned int *piHashAlg, BYTE *pbHash, DWORD cchHash, DWORD *pchHash),
- (pbBlob, cchBlob, piHashAlg, pbHash, cchHash, pchHash));
-
-PASS_THROUGH_IMPL_HRESULT(GetHashFromFile,
- (LPCSTR pszFilePath, unsigned int *piHashAlg, BYTE *pbHash, DWORD cchHash, DWORD *pchHash),
- (pszFilePath, piHashAlg, pbHash, cchHash, pchHash));
-
-PASS_THROUGH_IMPL_HRESULT(GetHashFromFileW,
- (LPCWSTR pwzFilePath, unsigned int *piHashAlg, BYTE *pbHash, DWORD cchHash, DWORD *pchHash),
- (pwzFilePath, piHashAlg, pbHash, cchHash, pchHash));
-
-PASS_THROUGH_IMPL_HRESULT(GetHashFromHandle,
- (HANDLE hFile, unsigned int *piHashAlg, BYTE *pbHash, DWORD cchHash, DWORD *pchHash),
- (hFile, piHashAlg, pbHash, cchHash, pchHash));
-
-PASS_THROUGH_IMPL_BOOLEAN(StrongNameCompareAssemblies,
- (LPCWSTR pwzAssembly1, LPCWSTR pwzAssembly2, DWORD *pdwResult),
- (pwzAssembly1, pwzAssembly2, pdwResult));
-
-PASS_THROUGH_IMPL_VOID(StrongNameFreeBuffer,
- (BYTE *pbMemory),
- (pbMemory));
-
-PASS_THROUGH_IMPL_BOOLEAN(StrongNameGetBlob,
- (LPCWSTR pwzFilePath, BYTE *pbBlob, DWORD *pcbBlob),
- (pwzFilePath, pbBlob, pcbBlob));
-
-PASS_THROUGH_IMPL_BOOLEAN(StrongNameGetBlobFromImage,
- (BYTE *pbBase, DWORD dwLength, BYTE *pbBlob, DWORD *pcbBlob),
- (pbBase, dwLength, pbBlob, pcbBlob));
-
-PASS_THROUGH_IMPL_BOOLEAN(StrongNameGetPublicKey,
- (LPCWSTR pwzKeyContainer, BYTE *pbKeyBlob, ULONG cbKeyBlob, BYTE **ppbPublicKeyBlob, ULONG *pcbPublicKeyBlob),
- (pwzKeyContainer, pbKeyBlob, cbKeyBlob, ppbPublicKeyBlob, pcbPublicKeyBlob));
-
-PASS_THROUGH_IMPL_BOOLEAN(StrongNameHashSize,
- (ULONG ulHashAlg, DWORD *pcbSize),
- (ulHashAlg, pcbSize));
-
-PASS_THROUGH_IMPL_BOOLEAN(StrongNameKeyDelete,
- (LPCWSTR pwzKeyContainer),
- (pwzKeyContainer));
-
-PASS_THROUGH_IMPL_BOOLEAN(StrongNameKeyGen,
- (LPCWSTR pwzKeyContainer, DWORD dwFlags, BYTE **ppbKeyBlob, ULONG *pcbKeyBlob),
- (pwzKeyContainer, dwFlags, ppbKeyBlob, pcbKeyBlob));
-
-PASS_THROUGH_IMPL_BOOLEAN(StrongNameKeyGenEx,
- (LPCWSTR pwzKeyContainer, DWORD dwFlags, DWORD dwKeySize, BYTE **ppbKeyBlob, ULONG *pcbKeyBlob),
- (pwzKeyContainer, dwFlags, dwKeySize, ppbKeyBlob, pcbKeyBlob));
-
-PASS_THROUGH_IMPL_BOOLEAN(StrongNameKeyInstall,
- (LPCWSTR pwzKeyContainer, BYTE *pbKeyBlob, ULONG cbKeyBlob),
- (pwzKeyContainer, pbKeyBlob, cbKeyBlob));
-
-PASS_THROUGH_IMPL_BOOLEAN(StrongNameSignatureGeneration,
- (LPCWSTR pwzFilePath, LPCWSTR pwzKeyContainer, BYTE *pbKeyBlob, ULONG cbKeyBlob, BYTE **ppbSignatureBlob, ULONG *pcbSignatureBlob),
- (pwzFilePath, pwzKeyContainer, pbKeyBlob, cbKeyBlob, ppbSignatureBlob, pcbSignatureBlob));
-
-PASS_THROUGH_IMPL_BOOLEAN(StrongNameSignatureGenerationEx,
- (LPCWSTR wszFilePath, LPCWSTR wszKeyContainer, BYTE *pbKeyBlob, ULONG cbKeyBlob, BYTE **ppbSignatureBlob, ULONG *pcbSignatureBlob, DWORD dwFlags),
- (wszFilePath, wszKeyContainer, pbKeyBlob, cbKeyBlob, ppbSignatureBlob, pcbSignatureBlob, dwFlags));
-
-PASS_THROUGH_IMPL_BOOLEAN(StrongNameSignatureSize,
- (BYTE *pbPublicKeyBlob, ULONG cbPublicKeyBlob, DWORD *pcbSize),
- (pbPublicKeyBlob, cbPublicKeyBlob, pcbSize));
-
-PASS_THROUGH_IMPL_BOOLEAN(StrongNameSignatureVerification,
- (LPCWSTR pwzFilePath, DWORD dwInFlags, DWORD *pdwOutFlags),
- (pwzFilePath, dwInFlags, pdwOutFlags));
-
-PASS_THROUGH_IMPL_BOOLEAN(StrongNameSignatureVerificationEx,
- (LPCWSTR pwzFilePath, BOOLEAN fForceVerification, BOOLEAN *pfWasVerified),
- (pwzFilePath, fForceVerification, pfWasVerified));
-
-PASS_THROUGH_IMPL_BOOLEAN(StrongNameSignatureVerificationFromImage,
- (BYTE *pbBase, DWORD dwLength, DWORD dwInFlags, DWORD *pdwOutFlags),
- (pbBase, dwLength, dwInFlags, pdwOutFlags));
-
-PASS_THROUGH_IMPL_BOOLEAN(StrongNameTokenFromAssembly,
- (LPCWSTR pwzFilePath, BYTE **ppbStrongNameToken, ULONG *pcbStrongNameToken),
- (pwzFilePath, ppbStrongNameToken, pcbStrongNameToken));
-
-PASS_THROUGH_IMPL_BOOLEAN(StrongNameTokenFromAssemblyEx,
- (LPCWSTR pwzFilePath, BYTE **ppbStrongNameToken, ULONG *pcbStrongNameToken, BYTE **ppbPublicKeyBlob, ULONG *pcbPublicKeyBlob),
- (pwzFilePath, ppbStrongNameToken, pcbStrongNameToken, ppbPublicKeyBlob, pcbPublicKeyBlob));
-
-PASS_THROUGH_IMPL_BOOLEAN(StrongNameTokenFromPublicKey,
- (BYTE *pbPublicKeyBlob, ULONG cbPublicKeyBlob, BYTE **ppbStrongNameToken, ULONG *pcbStrongNameToken),
- (pbPublicKeyBlob, cbPublicKeyBlob, ppbStrongNameToken, pcbStrongNameToken));
-
-#undef PASS_THROUGH_IMPL_HRESULT
-#undef PASS_THROUGH_IMPL_BOOLEAN
-#undef PASS_THROUGH_IMPL_VOID
-
-// Defines a method that just delegates a call to the right runtime, this one is for SN APIs that
-// return BOOLEAN.
-#define WRAP_HRESULT_IMPL_BOOLEAN(_WrapperName, _name, _signature, _args) \
- inline \
- HRESULT _WrapperName##_signature \
- { \
- HRESULT hr = S_OK; \
- if (Util::HasNewActivationAPIs()) \
- { \
- ICLRStrongName *pSN = NULL; \
- IfHrFailRet(Util::GetCLRStrongName(&pSN)); \
- return pSN->_name _args; \
- } \
- else \
- { \
- typedef BOOL __stdcall t_FN _signature; \
- Util::MscoreeFunctor<t_FN> FN; \
- IfHrFailRet(FN.Init(#_name)); \
- if ((FN() _args)) \
- { \
- return S_OK; \
- } \
- else \
- { /*@TODO: Static bind version, if necessary*/ \
- typedef DWORD __stdcall t_FNStrongNameErrorInfo(void); \
- Util::MscoreeFunctor<t_FNStrongNameErrorInfo> FNStrongNameErrorInfo; \
- IfHrFailRet(FNStrongNameErrorInfo.Init("StrongNameErrorInfo")); \
- HRESULT hrResult = (HRESULT)FNStrongNameErrorInfo() (); \
- if (SUCCEEDED(hrResult)) \
- { \
- hrResult = E_FAIL; \
- } \
- return hrResult; \
- } \
- } \
- }
-
-WRAP_HRESULT_IMPL_BOOLEAN(StrongNameHashSize_HRESULT,
- StrongNameHashSize,
- (ULONG ulHashAlg, DWORD *pcbSize),
- (ulHashAlg, pcbSize));
-
-WRAP_HRESULT_IMPL_BOOLEAN(StrongNameTokenFromPublicKey_HRESULT,
- StrongNameTokenFromPublicKey,
- (BYTE *pbPublicKeyBlob, ULONG cbPublicKeyBlob, BYTE **ppbStrongNameToken, ULONG *pcbStrongNameToken),
- (pbPublicKeyBlob, cbPublicKeyBlob, ppbStrongNameToken, pcbStrongNameToken));
-
-WRAP_HRESULT_IMPL_BOOLEAN(StrongNameSignatureSize_HRESULT,
- StrongNameSignatureSize,
- (BYTE *pbPublicKeyBlob, ULONG cbPublicKeyBlob, DWORD *pcbSize),
- (pbPublicKeyBlob, cbPublicKeyBlob, pcbSize));
-
-WRAP_HRESULT_IMPL_BOOLEAN(StrongNameGetPublicKey_HRESULT,
- StrongNameGetPublicKey,
- (LPCWSTR pwzKeyContainer, BYTE *pbKeyBlob, ULONG cbKeyBlob, BYTE **ppbPublicKeyBlob, ULONG *pcbPublicKeyBlob),
- (pwzKeyContainer, pbKeyBlob, cbKeyBlob, ppbPublicKeyBlob, pcbPublicKeyBlob));
-
-WRAP_HRESULT_IMPL_BOOLEAN(StrongNameKeyInstall_HRESULT,
- StrongNameKeyInstall,
- (LPCWSTR pwzKeyContainer, BYTE *pbKeyBlob, ULONG cbKeyBlob),
- (pwzKeyContainer, pbKeyBlob, cbKeyBlob));
-
-WRAP_HRESULT_IMPL_BOOLEAN(StrongNameSignatureGeneration_HRESULT,
- StrongNameSignatureGeneration,
- (LPCWSTR pwzFilePath, LPCWSTR pwzKeyContainer, BYTE *pbKeyBlob, ULONG cbKeyBlob, BYTE **ppbSignatureBlob, ULONG *pcbSignatureBlob),
- (pwzFilePath, pwzKeyContainer, pbKeyBlob, cbKeyBlob, ppbSignatureBlob, pcbSignatureBlob));
-
-WRAP_HRESULT_IMPL_BOOLEAN(StrongNameKeyGen_HRESULT,
- StrongNameKeyGen,
- (LPCWSTR pwzKeyContainer, DWORD dwFlags, BYTE **ppbKeyBlob, ULONG *pcbKeyBlob),
- (pwzKeyContainer, dwFlags, ppbKeyBlob, pcbKeyBlob));
-
-#undef WRAP_HRESULT_IMPL_BOOLEAN
-
-// Defines a method that just delegates a call to the right runtime, this one is for ICLRStrongName2
-// APIs that return BOOLEAN.
-#define WRAP_HRESULT_IMPL_BOOLEAN(_WrapperName, _name, _signature, _args) \
- inline \
- HRESULT _WrapperName##_signature \
- { \
- HRESULT hr = S_OK; \
- if (Util::HasNewActivationAPIs()) \
- { \
- ICLRStrongName2 *pSN = NULL; \
- IfHrFailRet(Util::GetCLRStrongName2(&pSN)); \
- return pSN->_name _args; \
- } \
- else \
- { \
- return E_FAIL; \
- } \
- }
-
-
-WRAP_HRESULT_IMPL_BOOLEAN(StrongNameGetPublicKeyEx_HRESULT,
- StrongNameGetPublicKeyEx,
- (LPCWSTR pwzKeyContainer, BYTE *pbKeyBlob, ULONG cbKeyBlob, BYTE **ppbPublicKeyBlob, ULONG *pcbPublicKeyBlob, ULONG uHashAlgId, ULONG uReserved),
- (pwzKeyContainer, pbKeyBlob, cbKeyBlob, ppbPublicKeyBlob, pcbPublicKeyBlob, uHashAlgId, uReserved));
-
-#undef WRAP_HRESULT_IMPL_BOOLEAN
-
- inline
- HRESULT ClrCoCreateInstance(
- REFCLSID rclsid,
- LPUNKNOWN pUnkOuter,
- DWORD dwClsContext,
- REFIID riid,
- LPVOID * ppv)
- {
- HRESULT hr = S_OK;
-
- if (Util::HasNewActivationAPIs() /*&& Util::IsCLSIDHostedByClr(rclsid)*/)
- {
- GET_CLRINFO(pInfo);
- IfHrFailRet(pInfo->GetInterface(rclsid, riid, ppv));
- }
- else
- {
- IfHrFailRet(::CoCreateInstance(rclsid, pUnkOuter, dwClsContext, riid, ppv));
- }
-
- return hr;
- }
-}; // namespace LegacyActivationShim
-#pragma warning(pop) // Revert C4996 status
-
-#undef LEGACY_API_PASS_THROUGH_STATIC
-#undef LEGACY_API_PASS_THROUGH_STATIC_VOIDRET
-#undef LEGACY_API_PASS_THROUGH_DELAYLOAD
-#undef LEGACY_API_PASS_THROUGH_DELAYLOAD_VOIDRET
-#undef CALL_LEGACY_API
-#undef LEGACY_STRONGNAME_API_PASS_THROUGH
-#undef LEGACY_STRONGNAME_API_PASS_THROUGH_VOIDRET
-
-#undef LEGACY_ACTIVATION_SHIM_DEFAULT_PRODUCT_VER_HELPER_L
-#undef LEGACY_ACTIVATION_SHIM_DEFAULT_PRODUCT_VER_STR_L
-
-#pragma pop_macro("IfHrFailRetVOID")
-#pragma pop_macro("IfHrFailRetFALSE")
-#pragma pop_macro("IfHrFailRet")
-
-#ifdef _MANAGED
-// We are compiling Managed C++, restore previous managed/native status from the stack
-#pragma managed(pop)
-#endif //_MANAGED
-
-#pragma warning(pop)
-
-#endif // __LEGACYACTIVATIONSHIM_H__
diff --git a/src/inc/legacyactivationshimdelayload.h b/src/inc/legacyactivationshimdelayload.h
deleted file mode 100644
index 8e77ff2ce3..0000000000
--- a/src/inc/legacyactivationshimdelayload.h
+++ /dev/null
@@ -1,13 +0,0 @@
-// 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.
-//
-
-#ifndef __LEGACYACTIVATIONSHIMDELAYLOAD_H__
-#define __LEGACYACTIVATIONSHIMDELAYLOAD_H__
-
-#define LEGACY_ACTIVATION_SHIM_DELAY_LOAD
-#include <legacyactivationshim.h>
-#undef LEGACY_ACTIVATION_SHIM_DELAY_LOAD
-
-#endif //__LEGACYACTIVATIONSHIMDELAYLOAD_H__
diff --git a/src/inc/winwrap.h b/src/inc/winwrap.h
index be098156a2..820d64bdff 100644
--- a/src/inc/winwrap.h
+++ b/src/inc/winwrap.h
@@ -484,7 +484,6 @@
#define WszLogonUser LogonUserW
#define WszCreateProcessAsUser CreateProcessAsUserW
#define WszGetCurrentHwProfile GetCurrentHwProfileW
-#define WszGetVersionEx GetVersionExW
#define WszCreateJobObject CreateJobObjectW
#define WszOpenJobObject OpenJobObjectW
@@ -925,8 +924,6 @@ __forceinline LONGLONG __InterlockedExchangeAdd64(LONGLONG volatile * Addend, LO
#define CLR_VER_SUITENAME 0x0000040
#define CLR_VER_PRODUCT_TYPE 0x0000080
-BOOL GetOSVersion(LPOSVERSIONINFOW osVer);
-
// Output printf-style formatted text to the debugger if it's present or stdout otherwise.
inline void DbgWPrintf(const LPCWSTR wszFormat, ...)
{
diff --git a/src/jit/CMakeLists.txt b/src/jit/CMakeLists.txt
index 8f2170dafa..e8920a2860 100644
--- a/src/jit/CMakeLists.txt
+++ b/src/jit/CMakeLists.txt
@@ -218,18 +218,21 @@ if (CLR_CMAKE_PLATFORM_ARCH_ARM)
add_subdirectory(protojit)
endif (CLR_CMAKE_PLATFORM_ARCH_ARM)
-if ((CLR_CMAKE_PLATFORM_ARCH_I386 OR CLR_CMAKE_PLATFORM_ARCH_AMD64) AND WIN32)
+if (CLR_CMAKE_PLATFORM_ARCH_I386 OR CLR_CMAKE_PLATFORM_ARCH_AMD64)
# On x86, build RyuJIT/ARM32 cross-compiling altjit.
# On amd64, build RyuJIT/ARM64 cross-compiling altjit.
add_subdirectory(protononjit)
+endif ()
- # Build Linux/x86-running-on-Windows altjit or
- # Linux/AMD64-running-on-Windows altjit..
+if ((CLR_CMAKE_PLATFORM_ARCH_I386 OR CLR_CMAKE_PLATFORM_ARCH_AMD64) AND WIN32)
+ # On Windows, build altjit that targets the Linux ABI:
+ # On x86, build Linux/x86 altjit. This enables UNIX_X86_ABI.
+ # On amd64, build Linux/AMD64 altjit. This enables UNIX_AMD64_ABI and FEATURE_UNIX_AMD64_STRUCT_PASSING.
add_subdirectory(linuxnonjit)
endif ()
if (CLR_CMAKE_PLATFORM_ARCH_I386 AND WIN32)
- if (NOT CLR_BUILD_JIT32)
- add_subdirectory(compatjit)
- endif ()
+ # On Windows x86, build altjit generating Windows/ARM32 code using LEGACY_BACKEND.
+ # (Note: we could also create linuxlegacynonjit for generating Linux/ARM32 code using LEGACY_BACKEND, if needed.)
+ add_subdirectory(legacynonjit)
endif (CLR_CMAKE_PLATFORM_ARCH_I386 AND WIN32)
diff --git a/src/jit/_typeinfo.h b/src/jit/_typeinfo.h
index 08273adc8d..b024912dda 100755
--- a/src/jit/_typeinfo.h
+++ b/src/jit/_typeinfo.h
@@ -27,8 +27,7 @@ enum ti_types
#define DEF_TI(ti, nm) ti,
#include "titypes.h"
#undef DEF_TI
- TI_ONLY_ENUM = TI_METHOD, // Enum values above this are completely described by the enumeration
- TI_COUNT
+ TI_ONLY_ENUM = TI_METHOD, // Enum values with greater value are completely described by the enumeration.
};
#if defined(_TARGET_64BIT_)
@@ -190,8 +189,6 @@ inline ti_types JITtype2tiType(CorInfoType type)
*
*/
-// TI_COUNT is less than or equal to TI_FLAG_DATA_MASK
-
#define TI_FLAG_DATA_BITS 6
#define TI_FLAG_DATA_MASK ((1 << TI_FLAG_DATA_BITS) - 1)
@@ -225,6 +222,9 @@ inline ti_types JITtype2tiType(CorInfoType type)
// since conversions between them are not verifiable.
#define TI_FLAG_NATIVE_INT 0x00000200
+// This item contains resolved token. It is used for ctor delegate optimization.
+#define TI_FLAG_TOKEN 0x00000400
+
// This item contains the 'this' pointer (used for tracking)
#define TI_FLAG_THIS_PTR 0x00001000
@@ -287,12 +287,13 @@ private:
union {
struct
{
- ti_types type : 6;
+ ti_types type : TI_FLAG_DATA_BITS;
unsigned uninitobj : 1; // used
unsigned byref : 1; // used
unsigned byref_readonly : 1; // used
unsigned nativeInt : 1; // used
- unsigned : 2; // unused
+ unsigned token : 1; // used
+ unsigned : 1; // unused
unsigned thisPtr : 1; // used
unsigned thisPermHome : 1; // used
unsigned generic_type_var : 1; // used
@@ -303,8 +304,10 @@ private:
union {
CORINFO_CLASS_HANDLE m_cls;
- // Valid only for type TI_METHOD
+ // Valid only for type TI_METHOD without IsToken
CORINFO_METHOD_HANDLE m_method;
+ // Valid only for TI_TOKEN with IsToken
+ CORINFO_RESOLVED_TOKEN* m_token;
};
template <typename T>
@@ -368,6 +371,16 @@ public:
m_method = method;
}
+ typeInfo(CORINFO_RESOLVED_TOKEN* token)
+ {
+ assert(token != nullptr);
+ assert(token->hMethod != nullptr);
+ assert(!isInvalidHandle(token->hMethod));
+ m_flags = TI_METHOD;
+ SetIsToken();
+ m_token = token;
+ }
+
#ifdef DEBUG
#if VERBOSE_VERIFY
void Dump() const;
@@ -447,6 +460,12 @@ public:
// Operations
/////////////////////////////////////////////////////////////////////////
+ void SetIsToken()
+ {
+ m_flags |= TI_FLAG_TOKEN;
+ assert(m_bits.token);
+ }
+
void SetIsThisPtr()
{
m_flags |= TI_FLAG_THIS_PTR;
@@ -556,14 +575,17 @@ public:
CORINFO_METHOD_HANDLE GetMethod() const
{
assert(GetType() == TI_METHOD);
+ if (IsToken())
+ {
+ return m_token->hMethod;
+ }
return m_method;
}
- // If FEATURE_CORECLR is enabled, GetMethod can be called
- // before the pointer type is known to be a method pointer type.
- CORINFO_METHOD_HANDLE GetMethod2() const
+ CORINFO_RESOLVED_TOKEN* GetToken() const
{
- return m_method;
+ assert(IsToken());
+ return m_token;
}
// Get this item's type
@@ -626,7 +648,7 @@ public:
// Returns whether this is a method desc
BOOL IsMethod() const
{
- return (GetType() == TI_METHOD);
+ return GetType() == TI_METHOD;
}
BOOL IsStruct() const
@@ -730,6 +752,11 @@ public:
return (m_flags & TI_FLAG_UNINIT_OBJREF);
}
+ BOOL IsToken() const
+ {
+ return IsMethod() && ((m_flags & TI_FLAG_TOKEN) != 0);
+ }
+
private:
// used to make functions that return typeinfo efficient.
typeInfo(DWORD flags, CORINFO_CLASS_HANDLE cls)
diff --git a/src/jit/codegenarm.cpp b/src/jit/codegenarm.cpp
index 1a2c855473..ca3dce1167 100644
--- a/src/jit/codegenarm.cpp
+++ b/src/jit/codegenarm.cpp
@@ -40,14 +40,6 @@ void CodeGen::genSetRegToIcon(regNumber reg, ssize_t val, var_types type, insFla
}
//------------------------------------------------------------------------
-// genEmitGSCookieCheck: Generate code to check that the GS cookie wasn't thrashed by a buffer overrun.
-//
-void CodeGen::genEmitGSCookieCheck(bool pushReg)
-{
- NYI("ARM genEmitGSCookieCheck");
-}
-
-//------------------------------------------------------------------------
// genCallFinally: Generate a call to the finally block.
//
BasicBlock* CodeGen::genCallFinally(BasicBlock* block)
@@ -517,6 +509,10 @@ void CodeGen::genCodeForTreeNode(GenTreePtr treeNode)
switch (treeNode->gtOper)
{
+ case GT_LCLHEAP:
+ genLclHeap(treeNode);
+ break;
+
case GT_CNS_INT:
case GT_CNS_DBL:
genSetRegToConst(targetReg, targetType, treeNode);
@@ -1315,6 +1311,328 @@ void CodeGen::genMultiRegCallStoreToLocal(GenTreePtr treeNode)
varDsc->lvRegNum = REG_STK;
}
+//--------------------------------------------------------------------------------------
+// genLclHeap: Generate code for localloc
+//
+// Description:
+// There are 2 ways depending from build version to generate code for localloc:
+// 1) For debug build where memory should be initialized we generate loop
+// which invoke push {tmpReg} N times.
+// 2) Fore /o build However, we tickle the pages to ensure that SP is always
+// valid and is in sync with the "stack guard page". Amount of iteration
+// is N/PAGE_SIZE.
+//
+// Comments:
+// There can be some optimization:
+// 1) It's not needed to generate loop for zero size allocation
+// 2) For small allocation (less than 4 store) we unroll loop
+// 3) For allocation less than PAGE_SIZE and when it's not needed to initialize
+// memory to zero, we can just increment SP.
+//
+// Notes: Size N should be aligned to STACK_ALIGN before any allocation
+//
+void CodeGen::genLclHeap(GenTreePtr tree)
+{
+ assert(tree->OperGet() == GT_LCLHEAP);
+
+ GenTreePtr size = tree->gtOp.gtOp1;
+ noway_assert((genActualType(size->gtType) == TYP_INT) || (genActualType(size->gtType) == TYP_I_IMPL));
+
+ // Result of localloc will be returned in regCnt.
+ // Also it used as temporary register in code generation
+ // for storing allocation size
+ regNumber regCnt = tree->gtRegNum;
+ regMaskTP tmpRegsMask = tree->gtRsvdRegs;
+ regNumber pspSymReg = REG_NA;
+ var_types type = genActualType(size->gtType);
+ emitAttr easz = emitTypeSize(type);
+ BasicBlock* endLabel = nullptr;
+ BasicBlock* loop = nullptr;
+ unsigned stackAdjustment = 0;
+
+#ifdef DEBUG
+ // Verify ESP
+ if (compiler->opts.compStackCheckOnRet)
+ {
+ noway_assert(compiler->lvaReturnEspCheck != 0xCCCCCCCC &&
+ compiler->lvaTable[compiler->lvaReturnEspCheck].lvDoNotEnregister &&
+ compiler->lvaTable[compiler->lvaReturnEspCheck].lvOnFrame);
+ getEmitter()->emitIns_S_R(INS_cmp, EA_PTRSIZE, REG_SPBASE, compiler->lvaReturnEspCheck, 0);
+
+ BasicBlock* esp_check = genCreateTempLabel();
+ emitJumpKind jmpEqual = genJumpKindForOper(GT_EQ, CK_SIGNED);
+ inst_JMP(jmpEqual, esp_check);
+ getEmitter()->emitIns(INS_BREAKPOINT);
+ genDefineTempLabel(esp_check);
+ }
+#endif
+
+ noway_assert(isFramePointerUsed()); // localloc requires Frame Pointer to be established since SP changes
+ noway_assert(genStackLevel == 0); // Can't have anything on the stack
+
+ // Whether method has PSPSym.
+ bool hasPspSym;
+#if FEATURE_EH_FUNCLETS
+ hasPspSym = (compiler->lvaPSPSym != BAD_VAR_NUM);
+#else
+ hasPspSym = false;
+#endif
+
+ // Check to 0 size allocations
+ // size_t amount = 0;
+ if (size->IsCnsIntOrI())
+ {
+ // If size is a constant, then it must be contained.
+ assert(size->isContained());
+
+ // If amount is zero then return null in regCnt
+ size_t amount = size->gtIntCon.gtIconVal;
+ if (amount == 0)
+ {
+ instGen_Set_Reg_To_Zero(EA_PTRSIZE, regCnt);
+ goto BAILOUT;
+ }
+ }
+ else
+ {
+ // If 0 bail out by returning null in regCnt
+ genConsumeRegAndCopy(size, regCnt);
+ endLabel = genCreateTempLabel();
+ getEmitter()->emitIns_R_R(INS_TEST, easz, regCnt, regCnt);
+ emitJumpKind jmpEqual = genJumpKindForOper(GT_EQ, CK_SIGNED);
+ inst_JMP(jmpEqual, endLabel);
+ }
+
+ stackAdjustment = 0;
+#if FEATURE_EH_FUNCLETS
+ // If we have PSPsym, then need to re-locate it after localloc.
+ if (hasPspSym)
+ {
+ stackAdjustment += STACK_ALIGN;
+
+ // Save a copy of PSPSym
+ assert(genCountBits(tmpRegsMask) >= 1);
+ regMaskTP pspSymRegMask = genFindLowestBit(tmpRegsMask);
+ tmpRegsMask &= ~pspSymRegMask;
+ pspSymReg = genRegNumFromMask(pspSymRegMask);
+ getEmitter()->emitIns_R_S(ins_Load(TYP_I_IMPL), EA_PTRSIZE, pspSymReg, compiler->lvaPSPSym, 0);
+ }
+#endif
+
+#if FEATURE_FIXED_OUT_ARGS
+ // If we have an outgoing arg area then we must adjust the SP by popping off the
+ // outgoing arg area. We will restore it right before we return from this method.
+ if (compiler->lvaOutgoingArgSpaceSize > 0)
+ {
+ assert((compiler->lvaOutgoingArgSpaceSize % STACK_ALIGN) == 0); // This must be true for the stack to remain
+ // aligned
+ inst_RV_IV(INS_add, REG_SPBASE, compiler->lvaOutgoingArgSpaceSize, EA_PTRSIZE);
+ stackAdjustment += compiler->lvaOutgoingArgSpaceSize;
+ }
+#endif
+
+ // Put aligned allocation size to regCnt
+ if (size->IsCnsIntOrI())
+ {
+ // 'amount' is the total number of bytes to localloc to properly STACK_ALIGN
+ size_t amount = size->gtIntCon.gtIconVal;
+ amount = AlignUp(amount, STACK_ALIGN);
+
+ // For small allocations we will generate up to four stp instructions
+ size_t cntStackAlignedWidthItems = (amount >> STACK_ALIGN_SHIFT);
+ if (cntStackAlignedWidthItems <= 4)
+ {
+ instGen_Set_Reg_To_Zero(EA_PTRSIZE, regCnt);
+
+ while (cntStackAlignedWidthItems != 0)
+ {
+ inst_IV(INS_push, (unsigned)genRegMask(regCnt));
+ cntStackAlignedWidthItems -= 1;
+ }
+
+ goto ALLOC_DONE;
+ }
+ else if (!compiler->info.compInitMem && (amount < compiler->eeGetPageSize())) // must be < not <=
+ {
+ // Since the size is a page or less, simply adjust the SP value
+ // The SP might already be in the guard page, must touch it BEFORE
+ // the alloc, not after.
+ getEmitter()->emitIns_R_R_I(INS_ldr, EA_4BYTE, regCnt, REG_SP, 0);
+ inst_RV_IV(INS_sub, REG_SP, amount, EA_PTRSIZE);
+ goto ALLOC_DONE;
+ }
+
+ // regCnt will be the total number of bytes to locAlloc
+ genSetRegToIcon(regCnt, amount, ((int)amount == amount) ? TYP_INT : TYP_LONG);
+ }
+ else
+ {
+ // Round up the number of bytes to allocate to a STACK_ALIGN boundary.
+ inst_RV_IV(INS_add, regCnt, (STACK_ALIGN - 1), emitActualTypeSize(type));
+ inst_RV_IV(INS_AND, regCnt, ~(STACK_ALIGN - 1), emitActualTypeSize(type));
+ }
+
+ // Allocation
+ if (compiler->info.compInitMem)
+ {
+ // At this point 'regCnt' is set to the total number of bytes to locAlloc.
+ // Since we have to zero out the allocated memory AND ensure that RSP is always valid
+ // by tickling the pages, we will just push 0's on the stack.
+
+ assert(tmpRegsMask != RBM_NONE);
+ assert(genCountBits(tmpRegsMask) >= 1);
+
+ regMaskTP regCntMask = genFindLowestBit(tmpRegsMask);
+ tmpRegsMask &= ~regCntMask;
+ regNumber regTmp = genRegNumFromMask(regCntMask);
+ instGen_Set_Reg_To_Zero(EA_PTRSIZE, regTmp);
+
+ // Loop:
+ BasicBlock* loop = genCreateTempLabel();
+ genDefineTempLabel(loop);
+
+ noway_assert(STACK_ALIGN == 8);
+ inst_IV(INS_push, (unsigned)genRegMask(regTmp));
+ inst_IV(INS_push, (unsigned)genRegMask(regTmp));
+
+ // If not done, loop
+ // Note that regCnt is the number of bytes to stack allocate.
+ assert(genIsValidIntReg(regCnt));
+ getEmitter()->emitIns_R_R_I(INS_sub, EA_PTRSIZE, regCnt, regCnt, STACK_ALIGN);
+ emitJumpKind jmpNotEqual = genJumpKindForOper(GT_NE, CK_SIGNED);
+ inst_JMP(jmpNotEqual, loop);
+ }
+ else
+ {
+ // At this point 'regCnt' is set to the total number of bytes to locAlloc.
+ //
+ // We don't need to zero out the allocated memory. However, we do have
+ // to tickle the pages to ensure that SP is always valid and is
+ // in sync with the "stack guard page". Note that in the worst
+ // case SP is on the last byte of the guard page. Thus you must
+ // touch SP+0 first not SP+0x1000.
+ //
+ // Another subtlety is that you don't want SP to be exactly on the
+ // boundary of the guard page because PUSH is predecrement, thus
+ // call setup would not touch the guard page but just beyond it
+ //
+ // Note that we go through a few hoops so that SP never points to
+ // illegal pages at any time during the ticking process
+ //
+ // subs regCnt, SP, regCnt // regCnt now holds ultimate SP
+ // jb Loop // result is smaller than orignial SP (no wrap around)
+ // mov regCnt, #0 // Overflow, pick lowest possible value
+ //
+ // Loop:
+ // ldr regTmp, [SP + 0] // tickle the page - read from the page
+ // sub regTmp, SP, PAGE_SIZE // decrement SP by PAGE_SIZE
+ // cmp regTmp, regCnt
+ // jb Done
+ // mov SP, regTmp
+ // j Loop
+ //
+ // Done:
+ // mov SP, regCnt
+ //
+
+ // Setup the regTmp
+ assert(tmpRegsMask != RBM_NONE);
+ assert(genCountBits(tmpRegsMask) == 1);
+ regNumber regTmp = genRegNumFromMask(tmpRegsMask);
+
+ BasicBlock* loop = genCreateTempLabel();
+ BasicBlock* done = genCreateTempLabel();
+
+ // subs regCnt, SP, regCnt // regCnt now holds ultimate SP
+ getEmitter()->emitIns_R_R_R(INS_sub, EA_PTRSIZE, regCnt, REG_SPBASE, regCnt);
+
+ inst_JMP(EJ_vc, loop); // branch if the V flag is not set
+
+ // Ups... Overflow, set regCnt to lowest possible value
+ instGen_Set_Reg_To_Zero(EA_PTRSIZE, regCnt);
+
+ genDefineTempLabel(loop);
+
+ // tickle the page - Read from the updated SP - this triggers a page fault when on the guard page
+ getEmitter()->emitIns_R_R_I(INS_ldr, EA_4BYTE, regTmp, REG_SPBASE, 0);
+
+ // decrement SP by PAGE_SIZE
+ getEmitter()->emitIns_R_R_I(INS_sub, EA_PTRSIZE, regTmp, REG_SPBASE, compiler->eeGetPageSize());
+
+ getEmitter()->emitIns_R_R(INS_cmp, EA_PTRSIZE, regTmp, regCnt);
+ emitJumpKind jmpLTU = genJumpKindForOper(GT_LT, CK_UNSIGNED);
+ inst_JMP(jmpLTU, done);
+
+ // Update SP to be at the next page of stack that we will tickle
+ getEmitter()->emitIns_R_R(INS_mov, EA_PTRSIZE, REG_SPBASE, regCnt);
+
+ // Jump to loop and tickle new stack address
+ inst_JMP(EJ_jmp, loop);
+
+ // Done with stack tickle loop
+ genDefineTempLabel(done);
+
+ // Now just move the final value to SP
+ getEmitter()->emitIns_R_R(INS_mov, EA_PTRSIZE, REG_SPBASE, regCnt);
+ }
+
+ALLOC_DONE:
+ // Re-adjust SP to allocate PSPSym and out-going arg area
+ if (stackAdjustment != 0)
+ {
+ assert((stackAdjustment % STACK_ALIGN) == 0); // This must be true for the stack to remain aligned
+ assert(stackAdjustment > 0);
+ getEmitter()->emitIns_R_R_I(INS_sub, EA_PTRSIZE, REG_SPBASE, REG_SPBASE, (int)stackAdjustment);
+
+#if FEATURE_EH_FUNCLETS
+ // Write PSPSym to its new location.
+ if (hasPspSym)
+ {
+ assert(genIsValidIntReg(pspSymReg));
+ getEmitter()->emitIns_S_R(ins_Store(TYP_I_IMPL), EA_PTRSIZE, pspSymReg, compiler->lvaPSPSym, 0);
+ }
+#endif
+ // Return the stackalloc'ed address in result register.
+ // regCnt = RSP + stackAdjustment.
+ getEmitter()->emitIns_R_R_I(INS_add, EA_PTRSIZE, regCnt, REG_SPBASE, (int)stackAdjustment);
+ }
+ else // stackAdjustment == 0
+ {
+ // Move the final value of SP to regCnt
+ inst_RV_RV(INS_mov, regCnt, REG_SPBASE);
+ }
+
+BAILOUT:
+ if (endLabel != nullptr)
+ genDefineTempLabel(endLabel);
+
+ // Write the lvaLocAllocSPvar stack frame slot
+ if (compiler->lvaLocAllocSPvar != BAD_VAR_NUM)
+ {
+ getEmitter()->emitIns_S_R(ins_Store(TYP_I_IMPL), EA_PTRSIZE, regCnt, compiler->lvaLocAllocSPvar, 0);
+ }
+
+#if STACK_PROBES
+ if (compiler->opts.compNeedStackProbes)
+ {
+ genGenerateStackProbe();
+ }
+#endif
+
+#ifdef DEBUG
+ // Update new ESP
+ if (compiler->opts.compStackCheckOnRet)
+ {
+ noway_assert(compiler->lvaReturnEspCheck != 0xCCCCCCCC &&
+ compiler->lvaTable[compiler->lvaReturnEspCheck].lvDoNotEnregister &&
+ compiler->lvaTable[compiler->lvaReturnEspCheck].lvOnFrame);
+ getEmitter()->emitIns_S_R(ins_Store(TYP_I_IMPL), EA_PTRSIZE, regCnt, compiler->lvaReturnEspCheck, 0);
+ }
+#endif
+
+ genProduceReg(tree);
+}
+
//------------------------------------------------------------------------
// genTableBasedSwitch: generate code for a switch statement based on a table of ip-relative offsets
//
@@ -1993,8 +2311,13 @@ void CodeGen::genCallInstruction(GenTreeCall* call)
// Insert a null check on "this" pointer if asked.
if (call->NeedsNullCheck())
{
- const regNumber regThis = genGetThisArgReg(call);
- const regNumber tmpReg = genRegNumFromMask(call->gtRsvdRegs);
+ const regNumber regThis = genGetThisArgReg(call);
+ regMaskTP tempMask = genFindLowestBit(call->gtRsvdRegs);
+ const regNumber tmpReg = genRegNumFromMask(tempMask);
+ if (genCountBits(call->gtRsvdRegs) > 1)
+ {
+ call->gtRsvdRegs &= ~tempMask;
+ }
getEmitter()->emitIns_R_R_I(INS_ldr, EA_4BYTE, tmpReg, regThis, 0);
}
diff --git a/src/jit/codegenarm64.cpp b/src/jit/codegenarm64.cpp
index 5698be9820..c123136cc8 100644
--- a/src/jit/codegenarm64.cpp
+++ b/src/jit/codegenarm64.cpp
@@ -1283,49 +1283,6 @@ void CodeGen::genSetRegToIcon(regNumber reg, ssize_t val, var_types type, insFla
instGen_Set_Reg_To_Imm(emitActualTypeSize(type), reg, val, flags);
}
-/*****************************************************************************
- *
- * Generate code to check that the GS cookie wasn't thrashed by a buffer
- * overrun. On ARM64 we always use REG_TMP_0 and REG_TMP_1 as temp registers
- * and this works fine in the case of tail calls
- * Implementation Note: pushReg = true, in case of tail calls.
- */
-void CodeGen::genEmitGSCookieCheck(bool pushReg)
-{
- noway_assert(compiler->gsGlobalSecurityCookieAddr || compiler->gsGlobalSecurityCookieVal);
-
- // Make sure that the return register is reported as live GC-ref so that any GC that kicks in while
- // executing GS cookie check will not collect the object pointed to by REG_INTRET (R0).
- if (!pushReg && (compiler->info.compRetType == TYP_REF))
- gcInfo.gcRegGCrefSetCur |= RBM_INTRET;
-
- regNumber regGSConst = REG_TMP_0;
- regNumber regGSValue = REG_TMP_1;
-
- if (compiler->gsGlobalSecurityCookieAddr == nullptr)
- {
- // load the GS cookie constant into a reg
- //
- genSetRegToIcon(regGSConst, compiler->gsGlobalSecurityCookieVal, TYP_I_IMPL);
- }
- else
- {
- // Ngen case - GS cookie constant needs to be accessed through an indirection.
- instGen_Set_Reg_To_Imm(EA_HANDLE_CNS_RELOC, regGSConst, (ssize_t)compiler->gsGlobalSecurityCookieAddr);
- getEmitter()->emitIns_R_R_I(ins_Load(TYP_I_IMPL), EA_PTRSIZE, regGSConst, regGSConst, 0);
- }
- // Load this method's GS value from the stack frame
- getEmitter()->emitIns_R_S(ins_Load(TYP_I_IMPL), EA_PTRSIZE, regGSValue, compiler->lvaGSSecurityCookie, 0);
- // Compare with the GC cookie constant
- getEmitter()->emitIns_R_R(INS_cmp, EA_PTRSIZE, regGSConst, regGSValue);
-
- BasicBlock* gsCheckBlk = genCreateTempLabel();
- emitJumpKind jmpEqual = genJumpKindForOper(GT_EQ, CK_SIGNED);
- inst_JMP(jmpEqual, gsCheckBlk);
- genEmitHelperCall(CORINFO_HELP_FAIL_FAST, 0, EA_UNKNOWN);
- genDefineTempLabel(gsCheckBlk);
-}
-
BasicBlock* CodeGen::genCallFinally(BasicBlock* block)
{
// Generate a call to the finally, like this:
@@ -1883,8 +1840,8 @@ void CodeGen::genReturn(GenTreePtr treeNode)
if (movRequired)
{
- emitAttr movSize = EA_ATTR(genTypeSize(targetType));
- getEmitter()->emitIns_R_R(INS_mov, movSize, retReg, op1->gtRegNum);
+ emitAttr attr = emitTypeSize(targetType);
+ getEmitter()->emitIns_R_R(INS_mov, attr, retReg, op1->gtRegNum);
}
}
diff --git a/src/jit/codegencommon.cpp b/src/jit/codegencommon.cpp
index e9546f8048..29a76c48d8 100644
--- a/src/jit/codegencommon.cpp
+++ b/src/jit/codegencommon.cpp
@@ -2610,6 +2610,51 @@ emitJumpKind CodeGen::genJumpKindForOper(genTreeOps cmp, CompareKind compareKind
return result;
}
+#ifndef LEGACY_BACKEND
+#ifdef _TARGET_ARMARCH_
+//------------------------------------------------------------------------
+// genEmitGSCookieCheck: Generate code to check that the GS cookie
+// wasn't thrashed by a buffer overrun. Coomon code for ARM32 and ARM64
+//
+void CodeGen::genEmitGSCookieCheck(bool pushReg)
+{
+ noway_assert(compiler->gsGlobalSecurityCookieAddr || compiler->gsGlobalSecurityCookieVal);
+
+ // Make sure that the return register is reported as live GC-ref so that any GC that kicks in while
+ // executing GS cookie check will not collect the object pointed to by REG_INTRET (R0).
+ if (!pushReg && (compiler->info.compRetType == TYP_REF))
+ gcInfo.gcRegGCrefSetCur |= RBM_INTRET;
+
+ regNumber regGSConst = REG_TMP_0;
+ regNumber regGSValue = REG_TMP_1;
+
+ if (compiler->gsGlobalSecurityCookieAddr == nullptr)
+ {
+ // load the GS cookie constant into a reg
+ //
+ genSetRegToIcon(regGSConst, compiler->gsGlobalSecurityCookieVal, TYP_I_IMPL);
+ }
+ else
+ {
+ // Ngen case - GS cookie constant needs to be accessed through an indirection.
+ instGen_Set_Reg_To_Imm(EA_HANDLE_CNS_RELOC, regGSConst, (ssize_t)compiler->gsGlobalSecurityCookieAddr);
+ getEmitter()->emitIns_R_R_I(ins_Load(TYP_I_IMPL), EA_PTRSIZE, regGSConst, regGSConst, 0);
+ }
+ // Load this method's GS value from the stack frame
+ getEmitter()->emitIns_R_S(ins_Load(TYP_I_IMPL), EA_PTRSIZE, regGSValue, compiler->lvaGSSecurityCookie, 0);
+ // Compare with the GC cookie constant
+ getEmitter()->emitIns_R_R(INS_cmp, EA_PTRSIZE, regGSConst, regGSValue);
+
+ BasicBlock* gsCheckBlk = genCreateTempLabel();
+ emitJumpKind jmpEqual = genJumpKindForOper(GT_EQ, CK_SIGNED);
+ inst_JMP(jmpEqual, gsCheckBlk);
+ // regGSConst and regGSValue aren't needed anymore, we can use them for helper call
+ genEmitHelperCall(CORINFO_HELP_FAIL_FAST, 0, EA_UNKNOWN, regGSConst);
+ genDefineTempLabel(gsCheckBlk);
+}
+#endif // _TARGET_ARMARCH_
+#endif // !LEGACY_BACKEND
+
/*****************************************************************************
*
* Generate an exit sequence for a return from a method (note: when compiling
@@ -3158,14 +3203,11 @@ void CodeGen::genGenerateCode(void** codePtr, ULONG* nativeSizeOfCode)
bool trackedStackPtrsContig; // are tracked stk-ptrs contiguous ?
-#ifdef _TARGET_AMD64_
+#if defined(_TARGET_AMD64_) || defined(_TARGET_ARM64_)
trackedStackPtrsContig = false;
#elif defined(_TARGET_ARM_)
// On arm due to prespilling of arguments, tracked stk-ptrs may not be contiguous
trackedStackPtrsContig = !compiler->opts.compDbgEnC && !compiler->compIsProfilerHookNeeded();
-#elif defined(_TARGET_ARM64_)
- // Incoming vararg registers are homed on the top of the stack. Tracked var may not be contiguous.
- trackedStackPtrsContig = !compiler->opts.compDbgEnC && !compiler->info.compIsVarArgs;
#else
trackedStackPtrsContig = !compiler->opts.compDbgEnC;
#endif
@@ -8094,6 +8136,14 @@ void CodeGen::genFinalizeFrame()
}
#endif // defined(_TARGET_ARMARCH_)
+#if defined(_TARGET_ARM_)
+ // If there are any reserved registers, add them to the
+ if (regSet.rsMaskResvd != RBM_NONE)
+ {
+ regSet.rsSetRegsModified(regSet.rsMaskResvd);
+ }
+#endif // _TARGET_ARM_
+
#ifdef DEBUG
if (verbose)
{
diff --git a/src/jit/codegenlegacy.cpp b/src/jit/codegenlegacy.cpp
index ff6c14bca6..d65351115f 100644
--- a/src/jit/codegenlegacy.cpp
+++ b/src/jit/codegenlegacy.cpp
@@ -21029,8 +21029,6 @@ regMaskTP CodeGen::genPInvokeMethodProlog(regMaskTP initRegs)
}
else
{
- noway_assert(pInfo->osMajor >= 5);
-
DWORD basePtr = WIN_NT5_TLS_HIGHOFFSET;
threadTlsIndex -= 64;
diff --git a/src/jit/compiler.cpp b/src/jit/compiler.cpp
index 3f756233cf..df54c8f32a 100644
--- a/src/jit/compiler.cpp
+++ b/src/jit/compiler.cpp
@@ -2470,7 +2470,8 @@ void Compiler::compInitOptions(JitFlags* jitFlags)
opts.jitFlags = jitFlags;
opts.compFlags = CLFLG_MAXOPT; // Default value is for full optimization
- if (jitFlags->IsSet(JitFlags::JIT_FLAG_DEBUG_CODE) || jitFlags->IsSet(JitFlags::JIT_FLAG_MIN_OPT))
+ if (jitFlags->IsSet(JitFlags::JIT_FLAG_DEBUG_CODE) || jitFlags->IsSet(JitFlags::JIT_FLAG_MIN_OPT) ||
+ jitFlags->IsSet(JitFlags::JIT_FLAG_TIER0))
{
opts.compFlags = CLFLG_MINOPT;
}
@@ -2495,7 +2496,8 @@ void Compiler::compInitOptions(JitFlags* jitFlags)
//
// If the EE sets SPEED_OPT we will optimize for speed at the expense of code size
//
- else if (jitFlags->IsSet(JitFlags::JIT_FLAG_SPEED_OPT))
+ else if (jitFlags->IsSet(JitFlags::JIT_FLAG_SPEED_OPT) ||
+ (jitFlags->IsSet(JitFlags::JIT_FLAG_TIER1) && !jitFlags->IsSet(JitFlags::JIT_FLAG_MIN_OPT)))
{
opts.compCodeOpt = FAST_CODE;
assert(!jitFlags->IsSet(JitFlags::JIT_FLAG_SIZE_OPT));
diff --git a/src/jit/compiler.h b/src/jit/compiler.h
index 01e5735e5c..1c01953f46 100644
--- a/src/jit/compiler.h
+++ b/src/jit/compiler.h
@@ -2880,6 +2880,7 @@ protected:
StackEntry impPopStack(CORINFO_CLASS_HANDLE& structTypeRet);
GenTreePtr impPopStack(typeInfo& ti);
StackEntry& impStackTop(unsigned n = 0);
+ unsigned impStackHeight();
void impSaveStackState(SavedStack* savePtr, bool copy);
void impRestoreStackState(SavedStack* savePtr);
@@ -2903,10 +2904,6 @@ protected:
void impHandleAccessAllowed(CorInfoIsAccessAllowedResult result, CORINFO_HELPER_DESC* helperCall);
void impHandleAccessAllowedInternal(CorInfoIsAccessAllowedResult result, CORINFO_HELPER_DESC* helperCall);
- void impInsertCalloutForDelegate(CORINFO_METHOD_HANDLE callerMethodHnd,
- CORINFO_METHOD_HANDLE calleeMethodHnd,
- CORINFO_CLASS_HANDLE delegateTypeHnd);
-
var_types impImportCall(OPCODE opcode,
CORINFO_RESOLVED_TOKEN* pResolvedToken,
CORINFO_RESOLVED_TOKEN* pConstrainedResolvedToken, // Is this a "constrained." call on a
@@ -3388,6 +3385,8 @@ private:
bool impIsImplicitTailCallCandidate(
OPCODE curOpcode, const BYTE* codeAddrOfNextOpcode, const BYTE* codeEnd, int prefixFlags, bool isRecursive);
+ CORINFO_RESOLVED_TOKEN* impAllocateToken(CORINFO_RESOLVED_TOKEN token);
+
/*
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
@@ -4733,7 +4732,9 @@ private:
void fgNoteNonInlineCandidate(GenTreeStmt* stmt, GenTreeCall* call);
static fgWalkPreFn fgFindNonInlineCandidate;
#endif
- GenTreePtr fgOptimizeDelegateConstructor(GenTreeCall* call, CORINFO_CONTEXT_HANDLE* ExactContextHnd);
+ GenTreePtr fgOptimizeDelegateConstructor(GenTreeCall* call,
+ CORINFO_CONTEXT_HANDLE* ExactContextHnd,
+ CORINFO_RESOLVED_TOKEN* ldftnToken);
GenTreePtr fgMorphLeaf(GenTreePtr tree);
void fgAssignSetVarDef(GenTreePtr tree);
GenTreePtr fgMorphOneAsgBlockOp(GenTreePtr tree);
diff --git a/src/jit/flowgraph.cpp b/src/jit/flowgraph.cpp
index 6b13fd10c7..50d1cfa22d 100644
--- a/src/jit/flowgraph.cpp
+++ b/src/jit/flowgraph.cpp
@@ -420,6 +420,9 @@ BasicBlock* Compiler::fgNewBasicBlock(BBjumpKinds jumpKind)
void Compiler::fgEnsureFirstBBisScratch()
{
+ // This method does not update predecessor lists and so must only be called before they are computed.
+ assert(!fgComputePredsDone);
+
// Have we already allocated a scratch block?
if (fgFirstBBisScratch())
@@ -438,6 +441,7 @@ void Compiler::fgEnsureFirstBBisScratch()
{
block->inheritWeight(fgFirstBB);
}
+
fgInsertBBbefore(fgFirstBB, block);
}
else
@@ -7114,7 +7118,9 @@ bool Compiler::fgAddrCouldBeNull(GenTreePtr addr)
* Optimize the call to the delegate constructor.
*/
-GenTreePtr Compiler::fgOptimizeDelegateConstructor(GenTreeCall* call, CORINFO_CONTEXT_HANDLE* ExactContextHnd)
+GenTreePtr Compiler::fgOptimizeDelegateConstructor(GenTreeCall* call,
+ CORINFO_CONTEXT_HANDLE* ExactContextHnd,
+ CORINFO_RESOLVED_TOKEN* ldftnToken)
{
noway_assert(call->gtCallType == CT_USER_FUNC);
CORINFO_METHOD_HANDLE methHnd = call->gtCallMethHnd;
@@ -7178,8 +7184,37 @@ GenTreePtr Compiler::fgOptimizeDelegateConstructor(GenTreeCall* call, CORINFO_CO
#ifdef FEATURE_READYTORUN_COMPILER
if (opts.IsReadyToRun())
{
+ if (IsTargetAbi(CORINFO_CORERT_ABI))
+ {
+ if (ldftnToken != nullptr)
+ {
+ GenTreePtr thisPointer = call->gtCallObjp;
+ GenTreePtr targetObjPointers = call->gtCallArgs->Current();
+ GenTreeArgList* helperArgs = nullptr;
+ CORINFO_LOOKUP pLookup;
+ CORINFO_CONST_LOOKUP entryPoint;
+ info.compCompHnd->getReadyToRunDelegateCtorHelper(ldftnToken, clsHnd, &pLookup);
+ if (!pLookup.lookupKind.needsRuntimeLookup)
+ {
+ helperArgs = gtNewArgList(thisPointer, targetObjPointers);
+ entryPoint = pLookup.constLookup;
+ }
+ else
+ {
+ assert(oper != GT_FTN_ADDR);
+ CORINFO_CONST_LOOKUP genericLookup;
+ info.compCompHnd->getReadyToRunHelper(ldftnToken, &pLookup.lookupKind,
+ CORINFO_HELP_READYTORUN_GENERIC_HANDLE, &genericLookup);
+ GenTreePtr ctxTree = getRuntimeContextTree(pLookup.lookupKind.runtimeLookupKind);
+ helperArgs = gtNewArgList(thisPointer, targetObjPointers, ctxTree);
+ entryPoint = genericLookup;
+ }
+ call = gtNewHelperCallNode(CORINFO_HELP_READYTORUN_DELEGATE_CTOR, TYP_VOID, GTF_EXCEPT, helperArgs);
+ call->setEntryPoint(entryPoint);
+ }
+ }
// ReadyToRun has this optimization for a non-virtual function pointers only for now.
- if (oper == GT_FTN_ADDR)
+ else if (oper == GT_FTN_ADDR)
{
GenTreePtr thisPointer = call->gtCallObjp;
GenTreePtr targetObjPointers = call->gtCallArgs->Current();
@@ -7187,8 +7222,8 @@ GenTreePtr Compiler::fgOptimizeDelegateConstructor(GenTreeCall* call, CORINFO_CO
call = gtNewHelperCallNode(CORINFO_HELP_READYTORUN_DELEGATE_CTOR, TYP_VOID, GTF_EXCEPT, helperArgs);
- CORINFO_RESOLVED_TOKEN* ldftnToken = targetMethod->gtFptrVal.gtLdftnResolvedToken;
- CORINFO_LOOKUP entryPoint;
+ assert(ldftnToken == targetMethod->gtFptrVal.gtLdftnResolvedToken);
+ CORINFO_LOOKUP entryPoint;
info.compCompHnd->getReadyToRunDelegateCtorHelper(ldftnToken, clsHnd, &entryPoint);
assert(!entryPoint.lookupKind.needsRuntimeLookup);
call->setEntryPoint(entryPoint.constLookup);
@@ -8064,6 +8099,16 @@ void Compiler::fgAddInternal()
{
noway_assert(!compIsForInlining());
+#ifndef LEGACY_BACKEND
+ // The RyuJIT backend requires a scratch BB into which it can safely insert a P/Invoke method prolog if one is
+ // required. Create it here.
+ if (info.compCallUnmanaged != 0)
+ {
+ fgEnsureFirstBBisScratch();
+ fgFirstBB->bbFlags |= BBF_DONT_REMOVE;
+ }
+#endif // !LEGACY_BACKEND
+
/*
<BUGNUM> VSW441487 </BUGNUM>
@@ -23361,6 +23406,7 @@ void Compiler::fgRemoveEmptyTry()
// Handler index of any nested blocks will update when we
// remove the EH table entry. Change handler exits to jump to
// the continuation. Clear catch type on handler entry.
+ // Decrement nesting level of enclosed GT_END_LFINs.
for (BasicBlock* block = firstHandlerBlock; block != endHandlerBlock; block = block->bbNext)
{
if (block == firstHandlerBlock)
@@ -23390,6 +23436,22 @@ void Compiler::fgRemoveEmptyTry()
fgAddRefPred(continuation, block);
}
}
+
+#if !FEATURE_EH_FUNCLETS
+ // If we're in a non-funclet model, decrement the nesting
+ // level of any GT_END_LFIN we find in the handler region,
+ // since we're removing the enclosing handler.
+ for (GenTreeStmt* stmt = block->firstStmt(); stmt != nullptr; stmt = stmt->gtNextStmt)
+ {
+ GenTreePtr expr = stmt->gtStmtExpr;
+ if (expr->gtOper == GT_END_LFIN)
+ {
+ const unsigned nestLevel = expr->gtVal.gtVal1;
+ assert(nestLevel > 0);
+ expr->gtVal.gtVal1 = nestLevel - 1;
+ }
+ }
+#endif // !FEATURE_EH_FUNCLETS
}
// (6) Remove the try-finally EH region. This will compact the
diff --git a/src/jit/gentree.cpp b/src/jit/gentree.cpp
index 4e42f4fa4a..3628ff72be 100644
--- a/src/jit/gentree.cpp
+++ b/src/jit/gentree.cpp
@@ -16379,6 +16379,14 @@ CORINFO_CLASS_HANDLE Compiler::gtGetClassHandle(GenTreePtr tree, bool* isExact,
*isExact = false;
CORINFO_CLASS_HANDLE objClass = nullptr;
+ // Bail out if we're just importing and not generating code, since
+ // the jit uses TYP_REF for CORINFO_TYPE_VAR locals and args, but
+ // these may not be ref types.
+ if (compIsForImportOnly())
+ {
+ return objClass;
+ }
+
// Bail out if the tree is not a ref type.
var_types treeType = tree->TypeGet();
if (treeType != TYP_REF)
diff --git a/src/jit/importer.cpp b/src/jit/importer.cpp
index eaf647a924..11e1d470bb 100644
--- a/src/jit/importer.cpp
+++ b/src/jit/importer.cpp
@@ -350,6 +350,12 @@ StackEntry& Compiler::impStackTop(unsigned n)
return verCurrentState.esStack[verCurrentState.esStackDepth - n - 1];
}
+
+unsigned Compiler::impStackHeight()
+{
+ return verCurrentState.esStackDepth;
+}
+
/*****************************************************************************
* Some of the trees are spilled specially. While unspilling them, or
* making a copy, these need to be handled specially. The function
@@ -6126,25 +6132,6 @@ void Compiler::impInsertHelperCall(CORINFO_HELPER_DESC* helperInfo)
impAppendTree(callout, (unsigned)CHECK_SPILL_NONE, impCurStmtOffs);
}
-void Compiler::impInsertCalloutForDelegate(CORINFO_METHOD_HANDLE callerMethodHnd,
- CORINFO_METHOD_HANDLE calleeMethodHnd,
- CORINFO_CLASS_HANDLE delegateTypeHnd)
-{
-#ifdef FEATURE_CORECLR
- if (!info.compCompHnd->isDelegateCreationAllowed(delegateTypeHnd, calleeMethodHnd))
- {
- // Call the JIT_DelegateSecurityCheck helper before calling the actual function.
- // This helper throws an exception if the CLR host disallows the call.
-
- GenTreePtr helper = gtNewHelperCallNode(CORINFO_HELP_DELEGATE_SECURITY_CHECK, TYP_VOID, GTF_EXCEPT,
- gtNewArgList(gtNewIconEmbClsHndNode(delegateTypeHnd),
- gtNewIconEmbMethHndNode(calleeMethodHnd)));
- // Append the callout statement
- impAppendTree(helper, (unsigned)CHECK_SPILL_NONE, impCurStmtOffs);
- }
-#endif // FEATURE_CORECLR
-}
-
// Checks whether the return types of caller and callee are compatible
// so that callee can be tail called. Note that here we don't check
// compatibility in IL Verifier sense, but on the lines of return type
@@ -6397,6 +6384,8 @@ var_types Compiler::impImportCall(OPCODE opcode,
int tailCall = prefixFlags & PREFIX_TAILCALL;
bool readonlyCall = (prefixFlags & PREFIX_READONLY) != 0;
+ CORINFO_RESOLVED_TOKEN* ldftnToken = nullptr;
+
// Synchronized methods need to call CORINFO_HELP_MON_EXIT at the end. We could
// do that before tailcalls, but that is probably not the intended
// semantic. So just disallow tailcalls from synchronized methods.
@@ -7308,6 +7297,21 @@ var_types Compiler::impImportCall(OPCODE opcode,
exactContextHnd = nullptr;
}
+ if ((opcode == CEE_NEWOBJ) && ((clsFlags & CORINFO_FLG_DELEGATE) != 0))
+ {
+ // Only verifiable cases are supported.
+ // dup; ldvirtftn; newobj; or ldftn; newobj.
+ // IL test could contain unverifiable sequence, in this case optimization should not be done.
+ if (impStackHeight() > 0)
+ {
+ typeInfo delegateTypeInfo = impStackTop().seTypeInfo;
+ if (delegateTypeInfo.IsToken())
+ {
+ ldftnToken = delegateTypeInfo.GetToken();
+ }
+ }
+ }
+
//-------------------------------------------------------------------------
// The main group of arguments
@@ -7388,7 +7392,7 @@ var_types Compiler::impImportCall(OPCODE opcode,
{
// New inliner morph it in impImportCall.
// This will allow us to inline the call to the delegate constructor.
- call = fgOptimizeDelegateConstructor(call->AsCall(), &exactContextHnd);
+ call = fgOptimizeDelegateConstructor(call->AsCall(), &exactContextHnd, ldftnToken);
}
if (!bIntrinsicImported)
@@ -12291,7 +12295,8 @@ void Compiler::impImportBlockCode(BasicBlock* block)
return;
}
- impPushOnStack(op1, typeInfo(resolvedToken.hMethod));
+ CORINFO_RESOLVED_TOKEN* heapToken = impAllocateToken(resolvedToken);
+ impPushOnStack(op1, typeInfo(heapToken));
break;
}
@@ -12396,7 +12401,10 @@ void Compiler::impImportBlockCode(BasicBlock* block)
return;
}
- impPushOnStack(fptr, typeInfo(resolvedToken.hMethod));
+ CORINFO_RESOLVED_TOKEN* heapToken = impAllocateToken(resolvedToken);
+ assert(heapToken->tokenType == CORINFO_TOKENKIND_Method);
+ heapToken->tokenType = CORINFO_TOKENKIND_Ldvirtftn;
+ impPushOnStack(fptr, typeInfo(heapToken));
break;
}
@@ -12856,14 +12864,6 @@ void Compiler::impImportBlockCode(BasicBlock* block)
assert(verCheckDelegateCreation(delegateCreateStart, codeAddr - 1, delegateMethodRef));
}
#endif
-
-#ifdef FEATURE_CORECLR
- // In coreclr the delegate transparency rule needs to be enforced even if verification is disabled
- typeInfo tiActualFtn = impStackTop(0).seTypeInfo;
- CORINFO_METHOD_HANDLE delegateMethodHandle = tiActualFtn.GetMethod2();
-
- impInsertCalloutForDelegate(info.compMethodHnd, delegateMethodHandle, resolvedToken.hClass);
-#endif // FEATURE_CORECLR
}
callTyp = impImportCall(opcode, &resolvedToken, constraintCall ? &constrainedResolvedToken : nullptr,
@@ -18515,6 +18515,18 @@ void Compiler::impDevirtualizeCall(GenTreeCall* call,
CORINFO_CLASS_HANDLE baseClass = info.compCompHnd->getMethodClass(baseMethod);
const DWORD baseClassAttribs = info.compCompHnd->getClassAttribs(baseClass);
+#if !defined(FEATURE_CORECLR)
+ // If base class is not beforefieldinit then devirtualizing may
+ // cause us to miss a base class init trigger. Spec says we don't
+ // need a trigger for ref class callvirts but desktop seems to
+ // have one anyways. So defer.
+ if ((baseClassAttribs & CORINFO_FLG_BEFOREFIELDINIT) == 0)
+ {
+ JITDUMP("\nimpDevirtualizeCall: base class has precise initialization, sorry\n");
+ return;
+ }
+#endif // FEATURE_CORECLR
+
// Is the call an interface call?
const bool isInterface = (baseClassAttribs & CORINFO_FLG_INTERFACE) != 0;
@@ -18711,3 +18723,18 @@ void Compiler::impDevirtualizeCall(GenTreeCall* call,
}
#endif // defined(DEBUG)
}
+
+//------------------------------------------------------------------------
+// impAllocateToken: create CORINFO_RESOLVED_TOKEN into jit-allocated memory and init it.
+//
+// Arguments:
+// token - init value for the allocated token.
+//
+// Return Value:
+// pointer to token into jit-allocated memory.
+CORINFO_RESOLVED_TOKEN* Compiler::impAllocateToken(CORINFO_RESOLVED_TOKEN token)
+{
+ CORINFO_RESOLVED_TOKEN* memory = (CORINFO_RESOLVED_TOKEN*)compGetMem(sizeof(token));
+ *memory = token;
+ return memory;
+}
diff --git a/src/jit/jit.h b/src/jit/jit.h
index 916b6802d7..cec24a9b3f 100644
--- a/src/jit/jit.h
+++ b/src/jit/jit.h
@@ -248,23 +248,6 @@
#define __PLACEMENT_NEW_INLINE // don't bring in the global placement new, it is easy to make a mistake
// with our new(compiler*) pattern.
-#if COR_JIT_EE_VER > 460
-#define NO_CLRCONFIG // Don't bring in the usual CLRConfig infrastructure, since the JIT uses the JIT/EE
- // interface to retrieve config values.
-
-// This is needed for contract.inl when FEATURE_STACK_PROBE is enabled.
-struct CLRConfig
-{
- static struct ConfigKey
- {
- } EXTERNAL_NO_SO_NOT_MAINLINE;
- static DWORD GetConfigValue(const ConfigKey& key)
- {
- return 0;
- }
-};
-#endif
-
#include "utilcode.h" // this defines assert as _ASSERTE
#include "host.h" // this redefines assert for the JIT to use assertAbort
#include "utils.h"
diff --git a/src/jit/jitee.h b/src/jit/jitee.h
index 810c93e988..7b0e4a02dc 100644
--- a/src/jit/jitee.h
+++ b/src/jit/jitee.h
@@ -78,6 +78,8 @@ public:
JIT_FLAG_USE_PINVOKE_HELPERS = 36, // The JIT should use the PINVOKE_{BEGIN,END} helpers instead of emitting inline transitions
JIT_FLAG_REVERSE_PINVOKE = 37, // The JIT should insert REVERSE_PINVOKE_{ENTER,EXIT} helpers into method prolog/epilog
JIT_FLAG_DESKTOP_QUIRKS = 38, // The JIT should generate desktop-quirk-compatible code
+ JIT_FLAG_TIER0 = 39, // This is the initial tier for tiered compilation which should generate code as quickly as possible
+ JIT_FLAG_TIER1 = 40, // This is the final tier (for now) for tiered compilation which should generate high quality code
};
// clang-format on
@@ -187,6 +189,8 @@ public:
FLAGS_EQUAL(CORJIT_FLAGS::CORJIT_FLAG_USE_PINVOKE_HELPERS, JIT_FLAG_USE_PINVOKE_HELPERS);
FLAGS_EQUAL(CORJIT_FLAGS::CORJIT_FLAG_REVERSE_PINVOKE, JIT_FLAG_REVERSE_PINVOKE);
FLAGS_EQUAL(CORJIT_FLAGS::CORJIT_FLAG_DESKTOP_QUIRKS, JIT_FLAG_DESKTOP_QUIRKS);
+ FLAGS_EQUAL(CORJIT_FLAGS::CORJIT_FLAG_TIER0, JIT_FLAG_TIER0);
+ FLAGS_EQUAL(CORJIT_FLAGS::CORJIT_FLAG_TIER1, JIT_FLAG_TIER1);
#undef FLAGS_EQUAL
}
diff --git a/src/jit/lclvars.cpp b/src/jit/lclvars.cpp
index 99b5452f2f..ab7c15dd35 100644
--- a/src/jit/lclvars.cpp
+++ b/src/jit/lclvars.cpp
@@ -677,11 +677,6 @@ void Compiler::lvaInitUserArgs(InitVarDscInfo* varDscInfo)
codeGen->regSet.rsMaskPreSpillRegArg |= regMask;
}
}
- else
- {
- varDsc->lvOnFrame = true; // The final home for this incoming register might be our local stack frame
- }
-
#else // !_TARGET_ARM_
#if defined(FEATURE_UNIX_AMD64_STRUCT_PASSING)
SYSTEMV_AMD64_CORINFO_STRUCT_REG_PASSING_DESCRIPTOR structDesc;
@@ -723,13 +718,12 @@ void Compiler::lvaInitUserArgs(InitVarDscInfo* varDscInfo)
}
}
#endif // FEATURE_UNIX_AMD64_STRUCT_PASSING
+#endif // !_TARGET_ARM_
// The final home for this incoming register might be our local stack frame.
// For System V platforms the final home will always be on the local stack frame.
varDsc->lvOnFrame = true;
-#endif // !_TARGET_ARM_
-
bool canPassArgInRegisters = false;
#if defined(FEATURE_UNIX_AMD64_STRUCT_PASSING)
@@ -2312,6 +2306,15 @@ void Compiler::lvaSetStruct(unsigned varNum, CORINFO_CLASS_HANDLE typeHnd, bool
void Compiler::lvaSetClass(unsigned varNum, CORINFO_CLASS_HANDLE clsHnd, bool isExact)
{
noway_assert(varNum < lvaCount);
+
+ // If we are just importing, we cannot reliably track local ref types,
+ // since the jit maps CORINFO_TYPE_VAR to TYP_REF.
+ if (compIsForImportOnly())
+ {
+ return;
+ }
+
+ // Else we should have a type handle.
assert(clsHnd != nullptr);
LclVarDsc* varDsc = &lvaTable[varNum];
@@ -2384,6 +2387,15 @@ void Compiler::lvaSetClass(unsigned varNum, GenTreePtr tree, CORINFO_CLASS_HANDL
void Compiler::lvaUpdateClass(unsigned varNum, CORINFO_CLASS_HANDLE clsHnd, bool isExact)
{
noway_assert(varNum < lvaCount);
+
+ // If we are just importing, we cannot reliably track local ref types,
+ // since the jit maps CORINFO_TYPE_VAR to TYP_REF.
+ if (compIsForImportOnly())
+ {
+ return;
+ }
+
+ // Else we should have a class handle to consider
assert(clsHnd != nullptr);
LclVarDsc* varDsc = &lvaTable[varNum];
@@ -2392,12 +2404,22 @@ void Compiler::lvaUpdateClass(unsigned varNum, CORINFO_CLASS_HANDLE clsHnd, bool
// We should already have a class
assert(varDsc->lvClassHnd != nullptr);
- // This should be the first and only update for this var
- assert(!varDsc->lvClassInfoUpdated);
-
#if defined(DEBUG)
+
+ // In general we only expect one update per local var. However if
+ // a block is re-imported and that block has the only STLOC for
+ // the var, we may see multiple updates. All subsequent updates
+ // should agree on the type, since reimportation is triggered by
+ // type mismatches for things other than ref types.
+ if (varDsc->lvClassInfoUpdated)
+ {
+ assert(varDsc->lvClassHnd == clsHnd);
+ assert(varDsc->lvClassIsExact == isExact);
+ }
+
// This counts as an update, even if nothing changes.
varDsc->lvClassInfoUpdated = true;
+
#endif // defined(DEBUG)
// If previous type was exact, there is nothing to update. Would
diff --git a/src/jit/compatjit/.gitmirror b/src/jit/legacynonjit/.gitmirror
index f507630f94..f507630f94 100644
--- a/src/jit/compatjit/.gitmirror
+++ b/src/jit/legacynonjit/.gitmirror
diff --git a/src/jit/compatjit/CMakeLists.txt b/src/jit/legacynonjit/CMakeLists.txt
index 71b8dae304..de66d81e8e 100644
--- a/src/jit/compatjit/CMakeLists.txt
+++ b/src/jit/legacynonjit/CMakeLists.txt
@@ -1,28 +1,34 @@
-project(compatjit)
-
-# This compatjit.dll is only built if we are not building JIT32 as compatjit.dll.
-# It is a normal JIT build, and only exists so the JIT nuget package can build,
-# with both clrjit.dll and compatjit.dll, if JIT32 is not being built.
+project(legacynonjit)
+add_definitions(-DALT_JIT)
add_definitions(-DFEATURE_NO_HOST)
add_definitions(-DSELF_NO_HOST)
add_definitions(-DFEATURE_READYTORUN_COMPILER)
remove_definitions(-DFEATURE_MERGE_JIT_AND_ENGINE)
+remove_definitions(-DFEATURE_SIMD)
+remove_definitions(-DFEATURE_AVX_SUPPORT)
+
+add_definitions(-DLEGACY_BACKEND)
+
+remove_definitions(-D_TARGET_X86_=1)
+add_definitions(-D_TARGET_ARM_)
+set(JIT_ARCH_ALTJIT_SOURCES ${JIT_ARM_SOURCES})
+
if(WIN32)
- add_definitions(-DFX_VER_INTERNALNAME_STR=compatjit.dll)
+ add_definitions(-DFX_VER_INTERNALNAME_STR=legacynonjit.dll)
endif(WIN32)
-add_library_clr(compatjit
+add_library_clr(legacynonjit
SHARED
${SHARED_LIB_SOURCES}
- ${JIT_ARCH_SOURCES}
+ ${JIT_ARCH_ALTJIT_SOURCES}
)
-add_dependencies(compatjit jit_exports)
+add_dependencies(legacynonjit jit_exports)
-set_property(TARGET compatjit APPEND_STRING PROPERTY LINK_FLAGS ${JIT_EXPORTS_LINKER_OPTION})
-set_property(TARGET compatjit APPEND_STRING PROPERTY LINK_DEPENDS ${JIT_EXPORTS_FILE})
+set_property(TARGET legacynonjit APPEND_STRING PROPERTY LINK_FLAGS ${JIT_EXPORTS_LINKER_OPTION})
+set_property(TARGET legacynonjit APPEND_STRING PROPERTY LINK_DEPENDS ${JIT_EXPORTS_FILE})
set(RYUJIT_LINK_LIBRARIES
utilcodestaticnohost
@@ -53,9 +59,9 @@ else()
)
endif(CLR_CMAKE_PLATFORM_UNIX)
-target_link_libraries(compatjit
+target_link_libraries(legacynonjit
${RYUJIT_LINK_LIBRARIES}
)
# add the install targets
-install_clr(compatjit)
+install_clr(legacynonjit)
diff --git a/src/jit/legacynonjit/legacynonjit.def b/src/jit/legacynonjit/legacynonjit.def
new file mode 100644
index 0000000000..1603af74ca
--- /dev/null
+++ b/src/jit/legacynonjit/legacynonjit.def
@@ -0,0 +1,7 @@
+; 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.
+EXPORTS
+ getJit
+ jitStartup
+ sxsJitStartup
diff --git a/src/jit/lower.cpp b/src/jit/lower.cpp
index a6dd563b05..5aad06a065 100644
--- a/src/jit/lower.cpp
+++ b/src/jit/lower.cpp
@@ -2542,7 +2542,7 @@ GenTree* Lowering::LowerDirectCall(GenTreeCall* call)
GenTree* indir = Ind(cellAddr);
#ifdef FEATURE_READYTORUN_COMPILER
-#ifdef _TARGET_ARM64_
+#if defined(_TARGET_ARM64_)
// For arm64, we dispatch code same as VSD using X11 for indirection cell address,
// which ZapIndirectHelperThunk expects.
if (call->IsR2RRelativeIndir())
@@ -2550,6 +2550,11 @@ GenTree* Lowering::LowerDirectCall(GenTreeCall* call)
cellAddr->gtRegNum = REG_R2R_INDIRECT_PARAM;
indir->gtRegNum = REG_JUMP_THUNK_PARAM;
}
+#elif defined(_TARGET_ARM_)
+ if (call->IsR2RRelativeIndir())
+ {
+ cellAddr->gtRegNum = REG_JUMP_THUNK_PARAM;
+ }
#endif
#endif
result = indir;
@@ -2835,6 +2840,9 @@ void Lowering::InsertPInvokeMethodProlog()
JITDUMP("======= Inserting PInvoke method prolog\n");
+ // The first BB must be a scratch BB in order for us to be able to safely insert the P/Invoke prolog.
+ assert(comp->fgFirstBBisScratch());
+
LIR::Range& firstBlockRange = LIR::AsRange(comp->fgFirstBB);
const CORINFO_EE_INFO* pInfo = comp->eeGetEEInfo();
@@ -2869,10 +2877,8 @@ void Lowering::InsertPInvokeMethodProlog()
store->gtOp.gtOp1 = call;
store->gtFlags |= GTF_VAR_DEF;
- GenTree* insertionPoint = firstBlockRange.FirstNonPhiOrCatchArgNode();
-
comp->fgMorphTree(store);
- firstBlockRange.InsertBefore(insertionPoint, LIR::SeqTree(comp, store));
+ firstBlockRange.InsertAtEnd(LIR::SeqTree(comp, store));
DISPTREERANGE(firstBlockRange, store);
#if !defined(_TARGET_X86_) && !defined(_TARGET_ARM_)
@@ -2886,7 +2892,7 @@ void Lowering::InsertPInvokeMethodProlog()
GenTreeLclFld(GT_STORE_LCL_FLD, TYP_I_IMPL, comp->lvaInlinedPInvokeFrameVar, callFrameInfo.offsetOfCallSiteSP);
storeSP->gtOp1 = PhysReg(REG_SPBASE);
- firstBlockRange.InsertBefore(insertionPoint, LIR::SeqTree(comp, storeSP));
+ firstBlockRange.InsertAtEnd(LIR::SeqTree(comp, storeSP));
DISPTREERANGE(firstBlockRange, storeSP);
#endif // !defined(_TARGET_X86_) && !defined(_TARGET_ARM_)
@@ -2902,7 +2908,7 @@ void Lowering::InsertPInvokeMethodProlog()
callFrameInfo.offsetOfCalleeSavedFP);
storeFP->gtOp1 = PhysReg(REG_FPBASE);
- firstBlockRange.InsertBefore(insertionPoint, LIR::SeqTree(comp, storeFP));
+ firstBlockRange.InsertAtEnd(LIR::SeqTree(comp, storeFP));
DISPTREERANGE(firstBlockRange, storeFP);
#endif // !defined(_TARGET_ARM_)
@@ -2917,7 +2923,7 @@ void Lowering::InsertPInvokeMethodProlog()
// Push a frame - if we are NOT in an IL stub, this is done right before the call
// The init routine sets InlinedCallFrame's m_pNext, so we just set the thead's top-of-stack
GenTree* frameUpd = CreateFrameLinkUpdate(PushFrame);
- firstBlockRange.InsertBefore(insertionPoint, LIR::SeqTree(comp, frameUpd));
+ firstBlockRange.InsertAtEnd(LIR::SeqTree(comp, frameUpd));
DISPTREERANGE(firstBlockRange, frameUpd);
}
#endif // _TARGET_64BIT_
diff --git a/src/jit/lsraarm.cpp b/src/jit/lsraarm.cpp
index b6efc8c8f5..912fd36c19 100644
--- a/src/jit/lsraarm.cpp
+++ b/src/jit/lsraarm.cpp
@@ -728,6 +728,88 @@ void Lowering::TreeNodeInfoInitPutArgStk(GenTreePutArgStk* argNode, fgArgTabEntr
}
}
+void Lowering::TreeNodeInfoInitLclHeap(GenTree* tree)
+{
+ TreeNodeInfo* info = &(tree->gtLsraInfo);
+ LinearScan* l = m_lsra;
+ Compiler* compiler = comp;
+
+ info->srcCount = 1;
+ info->dstCount = 1;
+
+ // Need a variable number of temp regs (see genLclHeap() in codegenarm.cpp):
+ // Here '-' means don't care.
+ //
+ // Size? Init Memory? # temp regs
+ // 0 - 0
+ // const and <=4 ptr words - hasPspSym ? 1 : 0
+ // const and <PageSize No hasPspSym ? 1 : 0
+ // >4 ptr words Yes hasPspSym ? 2 : 1
+ // Non-const Yes hasPspSym ? 2 : 1
+ // Non-const No hasPspSym ? 2 : 1
+
+ bool hasPspSym;
+#if FEATURE_EH_FUNCLETS
+ hasPspSym = (compiler->lvaPSPSym != BAD_VAR_NUM);
+#else
+ hasPspSym = false;
+#endif
+
+ GenTreePtr size = tree->gtOp.gtOp1;
+ if (size->IsCnsIntOrI())
+ {
+ MakeSrcContained(tree, size);
+
+ size_t sizeVal = size->gtIntCon.gtIconVal;
+ if (sizeVal == 0)
+ {
+ info->internalIntCount = 0;
+ }
+ else
+ {
+ sizeVal = AlignUp(sizeVal, STACK_ALIGN);
+ size_t cntStackAlignedWidthItems = (sizeVal >> STACK_ALIGN_SHIFT);
+
+ // For small allocations up to 4 store instructions
+ if (cntStackAlignedWidthItems <= 4)
+ {
+ info->internalIntCount = 0;
+ }
+ else if (!compiler->info.compInitMem)
+ {
+ // No need to initialize allocated stack space.
+ if (sizeVal < compiler->eeGetPageSize())
+ {
+ info->internalIntCount = 0;
+ }
+ else
+ {
+ // target (regCnt) + tmp + [psp]
+ info->internalIntCount = 1;
+ info->isInternalRegDelayFree = true;
+ }
+ }
+ else
+ {
+ // target (regCnt) + tmp + [psp]
+ info->internalIntCount = 1;
+ info->isInternalRegDelayFree = true;
+ }
+
+ if (hasPspSym)
+ {
+ info->internalIntCount++;
+ }
+ }
+ }
+ else
+ {
+ // target (regCnt) + tmp + [psp]
+ info->internalIntCount = hasPspSym ? 2 : 1;
+ info->isInternalRegDelayFree = true;
+ }
+}
+
//------------------------------------------------------------------------
// TreeNodeInfoInitBlockStore: Set the NodeInfo for a block store.
//
@@ -897,7 +979,6 @@ void Lowering::TreeNodeInfoInit(GenTree* tree)
JITDUMP("TreeNodeInfoInit for: ");
DISPNODE(tree);
- NYI_IF(tree->TypeGet() == TYP_STRUCT, "lowering struct");
NYI_IF(tree->TypeGet() == TYP_DOUBLE, "lowering double");
switch (tree->OperGet())
@@ -1297,6 +1378,10 @@ void Lowering::TreeNodeInfoInit(GenTree* tree)
TreeNodeInfoInitBlockStore(tree->AsBlk());
break;
+ case GT_LCLHEAP:
+ TreeNodeInfoInitLclHeap(tree);
+ break;
+
case GT_STOREIND:
{
info->srcCount = 2;
@@ -1358,11 +1443,6 @@ void Lowering::TreeNodeInfoInit(GenTree* tree)
case GT_LCL_FLD_ADDR:
case GT_LCL_VAR:
case GT_LCL_VAR_ADDR:
- {
- unsigned varNum = tree->gtLclVarCommon.gtLclNum;
- LclVarDsc* varDsc = comp->lvaTable + varNum;
- NYI_IF(varTypeIsStruct(varDsc), "lowering struct var");
- }
case GT_PHYSREG:
case GT_CLS_VAR_ADDR:
case GT_IL_OFFSET:
diff --git a/src/jit/protononjit/CMakeLists.txt b/src/jit/protononjit/CMakeLists.txt
index ed6932e9a2..e209e4cd36 100644
--- a/src/jit/protononjit/CMakeLists.txt
+++ b/src/jit/protononjit/CMakeLists.txt
@@ -21,6 +21,17 @@ else()
clr_unknown_arch()
endif()
+if (NOT WIN32)
+ if (CLR_CMAKE_PLATFORM_ARCH_I386)
+ remove_definitions(-DUNIX_X86_ABI)
+ elseif(CLR_CMAKE_PLATFORM_ARCH_AMD64)
+ remove_definitions(-DUNIX_AMD64_ABI)
+ remove_definitions(-DFEATURE_UNIX_AMD64_STRUCT_PASSING)
+ else()
+ clr_unknown_arch()
+ endif()
+endif(NOT WIN32)
+
if(WIN32)
add_definitions(-DFX_VER_INTERNALNAME_STR=protononjit.dll)
endif(WIN32)
diff --git a/src/md/compiler/mdvalidator.cpp b/src/md/compiler/mdvalidator.cpp
index 0b86738cfb..ce6c14e468 100644
--- a/src/md/compiler/mdvalidator.cpp
+++ b/src/md/compiler/mdvalidator.cpp
@@ -5207,7 +5207,7 @@ HRESULT RegMeta::ValidateAssembly(RID rid)
dwFlags = (CorAssemblyFlags) pMiniMd->getFlagsOfAssembly(pRecord);
// Validate the flags
- invalidAssemblyFlags = dwFlags & (~(afPublicKey | afRetargetable | afPA_FullMask | afEnableJITcompileTracking | afDisableJITcompileOptimizer | afContentType_Mask));
+ invalidAssemblyFlags = dwFlags & (~(afPublicKey | afRetargetable | afPA_FullMask | afDebuggableAttributeMask | afContentType_Mask));
// Validate we only set a legal processor architecture flags
// The processor architecture flags were introduced in CLR v2.0.
diff --git a/src/mscorlib/Resources/Strings.resx b/src/mscorlib/Resources/Strings.resx
index 9769d5e721..0ff48147fd 100644
--- a/src/mscorlib/Resources/Strings.resx
+++ b/src/mscorlib/Resources/Strings.resx
@@ -3557,4 +3557,13 @@
<data name="Word_At" xml:space="preserve">
<value>at</value>
</data>
- </root>
+ <data name="DebugAssertBanner" xml:space="preserve">
+ <value>---- DEBUG ASSERTION FAILED ----</value>
+ </data>
+ <data name="DebugAssertLongMessage" xml:space="preserve">
+ <value>---- Assert Long Message ----</value>
+ </data>
+ <data name="DebugAssertShortMessage" xml:space="preserve">
+ <value>---- Assert Short Message ----</value>
+ </data>
+</root>
diff --git a/src/mscorlib/System.Private.CoreLib.csproj b/src/mscorlib/System.Private.CoreLib.csproj
index 6f18a4f771..41c7b9eb90 100644
--- a/src/mscorlib/System.Private.CoreLib.csproj
+++ b/src/mscorlib/System.Private.CoreLib.csproj
@@ -310,8 +310,7 @@
<Compile Include="$(BclSourcesRoot)\System\AppContext\AppContextDefaultValues.CoreClrOverrides.cs" />
<Compile Include="$(BclSourcesRoot)\System\AppContext\AppContextDefaultValues.Defaults.cs" />
<Compile Include="$(BclSourcesRoot)\System\AppContext\AppContextDefaultValues.Defaults.Central.cs" />
- <Compile Include="$(BclSourcesRoot)\System\CurrentTimeZone.cs" />
- <Compile Include="$(BclSourcesRoot)\System\TimeZone.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\CurrentSystemTimeZone.Cache.cs" />
<Compile Include="$(BclSourcesRoot)\System\Object.cs" />
<Compile Include="$(BclSourcesRoot)\System\ICloneable.cs" />
<Compile Include="$(BclSourcesRoot)\System\Array.cs" />
@@ -348,7 +347,6 @@
<Compile Include="$(BclSourcesRoot)\System\Boolean.cs" />
<Compile Include="$(BclSourcesRoot)\System\Buffer.cs" />
<Compile Include="$(BclSourcesRoot)\System\Byte.cs" />
- <Compile Include="$(BclSourcesRoot)\System\TypeUnloadedException.cs" />
<Compile Include="$(BclSourcesRoot)\System\CompatibilitySwitches.cs" />
<Compile Include="$(BclSourcesRoot)\System\Currency.cs" />
<Compile Include="$(BclSourcesRoot)\System\Decimal.cs" />
@@ -508,54 +506,25 @@
<ItemGroup>
<Compile Include="$(BclSourcesRoot)\System\Globalization\BidiCategory.cs" />
<Compile Include="$(BclSourcesRoot)\System\Globalization\Calendar.cs" />
- <Compile Include="$(BclSourcesRoot)\System\Globalization\CalendarAlgorithmType.cs" />
<Compile Include="$(BclSourcesRoot)\System\Globalization\CalendarData.cs" />
- <Compile Include="$(BclSourcesRoot)\System\Globalization\CalendarWeekRule.cs" />
- <Compile Include="$(BclSourcesRoot)\System\Globalization\CalendricalCalculationsHelper.cs" />
<Compile Include="$(BclSourcesRoot)\System\Globalization\CharUnicodeInfo.cs" />
<Compile Include="$(BclSourcesRoot)\System\Globalization\CharUnicodeInfoData.cs" />
- <Compile Include="$(BclSourcesRoot)\System\Globalization\ChineseLunisolarCalendar.cs" />
<Compile Include="$(BclSourcesRoot)\System\Globalization\CompareInfo.cs" />
<Compile Include="$(BclSourcesRoot)\System\Globalization\CompareInfo.Invariant.cs" />
<Compile Include="$(BclSourcesRoot)\System\Globalization\CultureData.cs" />
<Compile Include="$(BclSourcesRoot)\System\Globalization\CultureInfo.cs" />
- <Compile Include="$(BclSourcesRoot)\System\Globalization\CultureNotFoundException.cs" />
- <Compile Include="$(BclSourcesRoot)\System\Globalization\CultureTypes.cs" />
- <Compile Include="$(BclSourcesRoot)\System\Globalization\DaylightTime.cs" />
- <Compile Include="$(BclSourcesRoot)\System\Globalization\DateTimeStyles.cs" />
- <Compile Include="$(BclSourcesRoot)\System\Globalization\DigitShapes.cs" />
- <Compile Include="$(BclSourcesRoot)\System\Globalization\EastAsianLunisolarCalendar.cs" />
<Compile Include="$(BclSourcesRoot)\System\Globalization\GlobalizationMode.cs" />
<Compile Include="$(BclSourcesRoot)\System\Globalization\GregorianCalendar.cs" />
<Compile Include="$(BclSourcesRoot)\System\Globalization\GregorianCalendarHelper.cs" />
- <Compile Include="$(BclSourcesRoot)\System\Globalization\GregorianCalendarTypes.cs" />
- <Compile Include="$(BclSourcesRoot)\System\Globalization\HebrewCalendar.cs" />
- <Compile Include="$(BclSourcesRoot)\System\Globalization\HebrewNumber.cs" />
- <Compile Include="$(BclSourcesRoot)\System\Globalization\HijriCalendar.cs" />
<Compile Include="$(BclSourcesRoot)\System\Globalization\IdnMapping.cs" />
- <Compile Include="$(BclSourcesRoot)\System\Globalization\InternalGlobalizationHelper.cs" />
- <Compile Include="$(BclSourcesRoot)\System\Globalization\JapaneseCalendar.cs" />
- <Compile Include="$(BclSourcesRoot)\System\Globalization\JapaneseLunisolarCalendar.cs" />
- <Compile Include="$(BclSourcesRoot)\System\Globalization\JulianCalendar.cs" />
- <Compile Include="$(BclSourcesRoot)\System\Globalization\KoreanCalendar.cs" />
- <Compile Include="$(BclSourcesRoot)\System\Globalization\KoreanLunisolarCalendar.cs" />
<Compile Include="$(BclSourcesRoot)\System\Globalization\NumberFormatInfo.cs" />
- <Compile Include="$(BclSourcesRoot)\System\Globalization\NumberStyles.cs" />
- <Compile Include="$(BclSourcesRoot)\System\Globalization\PersianCalendar.cs" />
<Compile Include="$(BclSourcesRoot)\System\Globalization\RegionInfo.cs" />
<Compile Include="$(BclSourcesRoot)\System\Globalization\SortKey.cs" />
- <Compile Include="$(BclSourcesRoot)\System\Globalization\SortVersion.cs" />
<Compile Include="$(BclSourcesRoot)\System\Globalization\StringInfo.cs" />
- <Compile Include="$(BclSourcesRoot)\System\Globalization\TaiwanCalendar.cs" />
- <Compile Include="$(BclSourcesRoot)\System\Globalization\TaiwanLunisolarCalendar.cs" />
<Compile Include="$(BclSourcesRoot)\System\Globalization\TextElementEnumerator.cs" />
<Compile Include="$(BclSourcesRoot)\System\Globalization\TextInfo.cs" />
- <Compile Include="$(BclSourcesRoot)\System\Globalization\ThaiBuddhistCalendar.cs" />
<Compile Include="$(BclSourcesRoot)\System\Globalization\TimeSpanFormat.cs" />
<Compile Include="$(BclSourcesRoot)\System\Globalization\TimeSpanParse.cs" />
- <Compile Include="$(BclSourcesRoot)\System\Globalization\UmAlQuraCalendar.cs" />
- <Compile Include="$(BclSourcesRoot)\System\Globalization\UnicodeCategory.cs" />
- <Compile Include="$(BclSourcesRoot)\System\Globalization\TimeSpanStyles.cs" />
</ItemGroup>
<ItemGroup Condition="'$(FeatureCoreFxGlobalization)' != 'true'">
<Compile Include="$(BclSourcesRoot)\System\Globalization\EncodingDataItem.cs" />
@@ -581,24 +550,15 @@
<Compile Include="$(BclSourcesRoot)\System\Globalization\JapaneseCalendar.Win32.cs" />
<Compile Include="$(BclSourcesRoot)\System\Globalization\TextInfo.Windows.cs" />
</ItemGroup>
- <ItemGroup Condition="'$(FeatureCoreFxGlobalization)' == 'true' and '$(TargetsUnix)' == 'true'">
+ <ItemGroup Condition="'$(TargetsUnix)' == 'true'">
<Compile Include="$(BclSourcesRoot)\System\Globalization\EncodingTable.Unix.cs" />
<Compile Include="$(BclSourcesRoot)\System\Globalization\EncodingDataItem.Unix.cs" />
<Compile Include="$(BclSourcesRoot)\System\Text\Normalization.Unix.cs" />
- <Compile Include="$(BclSourcesRoot)\Interop\Unix\System.Globalization.Native\Interop.Calendar.cs" />
- <Compile Include="$(BclSourcesRoot)\Interop\Unix\System.Globalization.Native\Interop.Casing.cs" />
<Compile Include="$(BclSourcesRoot)\Interop\Unix\System.Globalization.Native\Interop.Collation.cs" />
<Compile Include="$(BclSourcesRoot)\Interop\Unix\System.Globalization.Native\Interop.ICU.cs" />
- <Compile Include="$(BclSourcesRoot)\Interop\Unix\System.Globalization.Native\Interop.Idna.cs" />
- <Compile Include="$(BclSourcesRoot)\Interop\Unix\System.Globalization.Native\Interop.Locale.cs" />
- <Compile Include="$(BclSourcesRoot)\Interop\Unix\System.Globalization.Native\Interop.Normalization.cs" />
- <Compile Include="$(BclSourcesRoot)\Interop\Unix\System.Globalization.Native\Interop.ResultCode.cs" />
- <Compile Include="$(BclSourcesRoot)\Interop\Unix\System.Globalization.Native\Interop.TimeZoneInfo.cs" />
- <Compile Include="$(BclSourcesRoot)\Interop\Unix\System.Globalization.Native\Interop.Utils.cs" />
<Compile Include="$(BclSourcesRoot)\System\Globalization\HijriCalendar.Unix.cs" />
<Compile Include="$(BclSourcesRoot)\System\Globalization\IdnMapping.Unix.cs" />
<Compile Include="$(BclSourcesRoot)\System\Globalization\JapaneseCalendar.Unix.cs" />
- <Compile Include="$(BclSourcesRoot)\System\Globalization\LocaleData.Unix.cs" />
</ItemGroup>
<ItemGroup>
<Compile Include="$(BclSourcesRoot)\System\Threading\AbandonedMutexException.cs" />
@@ -646,9 +606,6 @@
<Compile Include="$(BclSourcesRoot)\System\Threading\Tasks\FutureFactory.cs" />
<Compile Include="$(BclSourcesRoot)\System\Threading\Tasks\Task.cs" />
<Compile Include="$(BclSourcesRoot)\System\Threading\Tasks\TaskContinuation.cs" />
- <Compile Include="$(BclSourcesRoot)\System\Threading\Tasks\TaskCanceledException.cs" />
- <Compile Include="$(BclSourcesRoot)\System\Threading\Tasks\TaskExtensions.cs" />
- <Compile Include="$(BclSourcesRoot)\System\Threading\Tasks\TaskSchedulerException.cs" />
<Compile Include="$(BclSourcesRoot)\System\Threading\Tasks\TaskExceptionHolder.cs" />
<Compile Include="$(BclSourcesRoot)\System\Threading\Tasks\TaskFactory.cs" />
<Compile Include="$(BclSourcesRoot)\System\Threading\Tasks\TaskScheduler.cs" />
@@ -692,7 +649,6 @@
<Compile Include="$(BclSourcesRoot)\System\IO\PinnedBufferMemoryStream.cs" />
<Compile Include="$(BclSourcesRoot)\System\IO\SeekOrigin.cs" />
<Compile Include="$(BclSourcesRoot)\System\IO\Stream.cs" />
- <Compile Include="$(BclSourcesRoot)\System\IO\StreamHelpers.CopyValidation.cs" />
<Compile Include="$(BclSourcesRoot)\System\IO\TextReader.cs" Condition="'$(TargetsUnix)' == 'true'" />
<Compile Include="$(BclSourcesRoot)\System\IO\StreamReader.cs" Condition="'$(TargetsUnix)' == 'true'" />
<Compile Include="$(BclSourcesRoot)\System\IO\UnmanagedMemoryAccessor.cs" />
@@ -701,17 +657,17 @@
</ItemGroup>
<ItemGroup>
<Compile Include="$(BclSourcesRoot)\System\Security\DynamicSecurityMethodAttribute.cs" />
- <Compile Include="$(BclSourcesRoot)\System\Security\SecurityState.cs" />
<Compile Include="$(BclSourcesRoot)\System\Security\VerificationException.cs" />
</ItemGroup>
<ItemGroup>
- <Compile Include="$(BclSourcesRoot)\System\Security\Util\URLString.cs" />
- </ItemGroup>
- <ItemGroup>
<Compile Include="$(BclSourcesRoot)\System\Diagnostics\Assert.cs" />
<Compile Include="$(BclSourcesRoot)\System\Diagnostics\AssertFilter.cs" />
<Compile Include="$(BclSourcesRoot)\System\Diagnostics\AssertFilters.cs" />
<Compile Include="$(BclSourcesRoot)\System\Diagnostics\ConditionalAttribute.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Diagnostics\Debug.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Diagnostics\Debug.Unix.cs" Condition="'$(TargetsUnix)' == 'true'" />
+ <Compile Include="$(BclSourcesRoot)\System\Diagnostics\Debug.Windows.cs" Condition="'$(TargetsUnix)' != 'true'" />
+ <Compile Include="$(BclSourcesRoot)\Interop\Windows\kernel32\Interop.OutputDebugString.cs" Condition="'$(TargetsUnix)' != 'true'" />
<Compile Include="$(BclSourcesRoot)\System\Diagnostics\Debugger.cs" />
<Compile Include="$(BclSourcesRoot)\System\Diagnostics\DebuggerAttributes.cs" />
<Compile Include="$(BclSourcesRoot)\System\Diagnostics\ICustomDebuggerNotification.cs" />
@@ -894,28 +850,18 @@
<Compile Include="$(BclSourcesRoot)\Interop\Windows\Normaliz\Interop.Idna.cs" />
<Compile Include="$(BclSourcesRoot)\Interop\Windows\Normaliz\Interop.Normalization.cs" />
</ItemGroup>
- <ItemGroup>
- <Compile Include="$(BclSourcesRoot)\System\Security\SecureString.cs" />
- </ItemGroup>
<ItemGroup Condition="'$(TargetsUnix)' != 'true'">
<Compile Include="$(BclSourcesRoot)\System\Security\SafeBSTRHandle.cs" />
<Compile Include="$(BclSourcesRoot)\System\Security\SecureString.Windows.cs" />
<!-- Interop sources -->
- <Compile Include="$(BclSourcesRoot)\Interop\Windows\Crypt32\Interop.CryptProtectMemory.cs" />
<Compile Include="$(BclSourcesRoot)\Interop\Windows\NtDll\Interop.ZeroMemory.cs" />
- <Compile Include="$(BclSourcesRoot)\Interop\Windows\kernel32\Interop.WideCharToMultiByte.cs" />
<Compile Include="$(BclSourcesRoot)\Interop\Windows\oleaut32\Interop.SysAllocStringLen.cs" />
<Compile Include="$(BclSourcesRoot)\Interop\Windows\oleaut32\Interop.SysStringLen.cs" />
</ItemGroup>
<ItemGroup Condition="'$(TargetsUnix)' == 'true'">
- <Compile Include="$(BclSourcesRoot)\System\Security\SecureString.Unix.cs" />
- </ItemGroup>
- <ItemGroup Condition="'$(TargetsUnix)' == 'true'">
<Compile Include="$(BclSourcesRoot)\System\HResults.cs" />
<Compile Include="$(BclSourcesRoot)\Interop\Unix\System.Native\Interop.GetRandomBytes.cs" />
- </ItemGroup>
- <ItemGroup>
- <Compile Include="$(BclSourcesRoot)\Debug.cs" />
+ <Compile Include="$(BclSourcesRoot)\Interop\Unix\System.Native\Interop.SysLog.cs" />
</ItemGroup>
<!-- Include additional sources shared files in the compilation -->
<ItemGroup>
diff --git a/src/mscorlib/src/Interop/Unix/System.Globalization.Native/Interop.Calendar.cs b/src/mscorlib/shared/Interop/Unix/System.Globalization.Native/Interop.Calendar.cs
index 7b3caeabdd..7b3caeabdd 100644
--- a/src/mscorlib/src/Interop/Unix/System.Globalization.Native/Interop.Calendar.cs
+++ b/src/mscorlib/shared/Interop/Unix/System.Globalization.Native/Interop.Calendar.cs
diff --git a/src/mscorlib/src/Interop/Unix/System.Globalization.Native/Interop.Casing.cs b/src/mscorlib/shared/Interop/Unix/System.Globalization.Native/Interop.Casing.cs
index 769506b8f6..769506b8f6 100644
--- a/src/mscorlib/src/Interop/Unix/System.Globalization.Native/Interop.Casing.cs
+++ b/src/mscorlib/shared/Interop/Unix/System.Globalization.Native/Interop.Casing.cs
diff --git a/src/mscorlib/src/Interop/Unix/System.Globalization.Native/Interop.Idna.cs b/src/mscorlib/shared/Interop/Unix/System.Globalization.Native/Interop.Idna.cs
index 43c72281ae..43c72281ae 100644
--- a/src/mscorlib/src/Interop/Unix/System.Globalization.Native/Interop.Idna.cs
+++ b/src/mscorlib/shared/Interop/Unix/System.Globalization.Native/Interop.Idna.cs
diff --git a/src/mscorlib/src/Interop/Unix/System.Globalization.Native/Interop.Locale.cs b/src/mscorlib/shared/Interop/Unix/System.Globalization.Native/Interop.Locale.cs
index fcea708ee8..fcea708ee8 100644
--- a/src/mscorlib/src/Interop/Unix/System.Globalization.Native/Interop.Locale.cs
+++ b/src/mscorlib/shared/Interop/Unix/System.Globalization.Native/Interop.Locale.cs
diff --git a/src/mscorlib/src/Interop/Unix/System.Globalization.Native/Interop.Normalization.cs b/src/mscorlib/shared/Interop/Unix/System.Globalization.Native/Interop.Normalization.cs
index c4cb9fb851..c4cb9fb851 100644
--- a/src/mscorlib/src/Interop/Unix/System.Globalization.Native/Interop.Normalization.cs
+++ b/src/mscorlib/shared/Interop/Unix/System.Globalization.Native/Interop.Normalization.cs
diff --git a/src/mscorlib/src/Interop/Unix/System.Globalization.Native/Interop.ResultCode.cs b/src/mscorlib/shared/Interop/Unix/System.Globalization.Native/Interop.ResultCode.cs
index cca6ae4dcb..cca6ae4dcb 100644
--- a/src/mscorlib/src/Interop/Unix/System.Globalization.Native/Interop.ResultCode.cs
+++ b/src/mscorlib/shared/Interop/Unix/System.Globalization.Native/Interop.ResultCode.cs
diff --git a/src/mscorlib/src/Interop/Unix/System.Globalization.Native/Interop.TimeZoneInfo.cs b/src/mscorlib/shared/Interop/Unix/System.Globalization.Native/Interop.TimeZoneInfo.cs
index 26a9fe0579..26a9fe0579 100644
--- a/src/mscorlib/src/Interop/Unix/System.Globalization.Native/Interop.TimeZoneInfo.cs
+++ b/src/mscorlib/shared/Interop/Unix/System.Globalization.Native/Interop.TimeZoneInfo.cs
diff --git a/src/mscorlib/src/Interop/Unix/System.Globalization.Native/Interop.Utils.cs b/src/mscorlib/shared/Interop/Unix/System.Globalization.Native/Interop.Utils.cs
index 33b10c0d74..33b10c0d74 100644
--- a/src/mscorlib/src/Interop/Unix/System.Globalization.Native/Interop.Utils.cs
+++ b/src/mscorlib/shared/Interop/Unix/System.Globalization.Native/Interop.Utils.cs
diff --git a/src/mscorlib/src/Interop/Windows/Crypt32/Interop.CryptProtectMemory.cs b/src/mscorlib/shared/Interop/Windows/Crypt32/Interop.CryptProtectMemory.cs
index b10cb6a041..b10cb6a041 100644
--- a/src/mscorlib/src/Interop/Windows/Crypt32/Interop.CryptProtectMemory.cs
+++ b/src/mscorlib/shared/Interop/Windows/Crypt32/Interop.CryptProtectMemory.cs
diff --git a/src/mscorlib/shared/Interop/Windows/Interop.Errors.cs b/src/mscorlib/shared/Interop/Windows/Interop.Errors.cs
index 97746fde5f..ff2653765c 100644
--- a/src/mscorlib/shared/Interop/Windows/Interop.Errors.cs
+++ b/src/mscorlib/shared/Interop/Windows/Interop.Errors.cs
@@ -4,6 +4,7 @@
internal partial class Interop
{
+ // As defined in winerror.h and https://msdn.microsoft.com/en-us/library/windows/desktop/ms681382.aspx
internal partial class Errors
{
internal const int ERROR_SUCCESS = 0x0;
diff --git a/src/mscorlib/src/Interop/Windows/kernel32/Interop.WideCharToMultiByte.cs b/src/mscorlib/shared/Interop/Windows/Kernel32/Interop.WideCharToMultiByte.cs
index a06c9153f4..a06c9153f4 100644
--- a/src/mscorlib/src/Interop/Windows/kernel32/Interop.WideCharToMultiByte.cs
+++ b/src/mscorlib/shared/Interop/Windows/Kernel32/Interop.WideCharToMultiByte.cs
diff --git a/src/mscorlib/shared/System.Private.CoreLib.Shared.projitems b/src/mscorlib/shared/System.Private.CoreLib.Shared.projitems
index ed578b35ca..7c6d039f77 100644
--- a/src/mscorlib/shared/System.Private.CoreLib.Shared.projitems
+++ b/src/mscorlib/shared/System.Private.CoreLib.Shared.projitems
@@ -15,6 +15,7 @@
</PropertyGroup>
<ItemGroup Condition="$(TargetsWindows)">
<Compile Include="$(MSBuildThisFileDirectory)Interop\Windows\BCrypt\Interop.BCryptGenRandom.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)Interop\Windows\Crypt32\Interop.CryptProtectMemory.cs"/>
<Compile Include="$(MSBuildThisFileDirectory)Interop\Windows\Interop.BOOL.cs"/>
<Compile Include="$(MSBuildThisFileDirectory)Interop\Windows\Interop.Errors.cs"/>
<Compile Include="$(MSBuildThisFileDirectory)Interop\Windows\Interop.Libraries.cs"/>
@@ -40,6 +41,7 @@
<Compile Include="$(MSBuildThisFileDirectory)Interop\Windows\Kernel32\Interop.SetEndOfFile.cs"/>
<Compile Include="$(MSBuildThisFileDirectory)Interop\Windows\Kernel32\Interop.SetErrorMode.cs"/>
<Compile Include="$(MSBuildThisFileDirectory)Interop\Windows\Kernel32\Interop.SetFilePointerEx.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)Interop\Windows\Kernel32\Interop.WideCharToMultiByte.cs"/>
<Compile Include="$(MSBuildThisFileDirectory)Interop\Windows\Kernel32\Interop.WriteFile_SafeHandle_IntPtr.cs"/>
<Compile Include="$(MSBuildThisFileDirectory)Interop\Windows\Kernel32\Interop.WriteFile_SafeHandle_NativeOverlapped.cs"/>
</ItemGroup>
@@ -47,6 +49,14 @@
<Compile Include="$(MSBuildThisFileDirectory)Interop\Unix\Interop.Errors.cs"/>
<Compile Include="$(MSBuildThisFileDirectory)Interop\Unix\Interop.IOErrors.cs"/>
<Compile Include="$(MSBuildThisFileDirectory)Interop\Unix\Interop.Libraries.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)Interop\Unix\System.Globalization.Native\Interop.Calendar.cs" Condition="'$(EnableDummyGlobalizationImplementation)' != 'true'"/>
+ <Compile Include="$(MSBuildThisFileDirectory)Interop\Unix\System.Globalization.Native\Interop.Casing.cs" Condition="'$(EnableDummyGlobalizationImplementation)' != 'true'"/>
+ <Compile Include="$(MSBuildThisFileDirectory)Interop\Unix\System.Globalization.Native\Interop.Idna.cs" Condition="'$(EnableDummyGlobalizationImplementation)' != 'true'"/>
+ <Compile Include="$(MSBuildThisFileDirectory)Interop\Unix\System.Globalization.Native\Interop.Locale.cs" Condition="'$(EnableDummyGlobalizationImplementation)' != 'true'"/>
+ <Compile Include="$(MSBuildThisFileDirectory)Interop\Unix\System.Globalization.Native\Interop.Normalization.cs" Condition="'$(EnableDummyGlobalizationImplementation)' != 'true'"/>
+ <Compile Include="$(MSBuildThisFileDirectory)Interop\Unix\System.Globalization.Native\Interop.ResultCode.cs" Condition="'$(EnableDummyGlobalizationImplementation)' != 'true'"/>
+ <Compile Include="$(MSBuildThisFileDirectory)Interop\Unix\System.Globalization.Native\Interop.TimeZoneInfo.cs" Condition="'$(EnableDummyGlobalizationImplementation)' != 'true'"/>
+ <Compile Include="$(MSBuildThisFileDirectory)Interop\Unix\System.Globalization.Native\Interop.Utils.cs" Condition="'$(EnableDummyGlobalizationImplementation)' != 'true'"/>
<Compile Include="$(MSBuildThisFileDirectory)Interop\Unix\System.Native\Interop.Close.cs"/>
<Compile Include="$(MSBuildThisFileDirectory)Interop\Unix\System.Native\Interop.FLock.cs"/>
<Compile Include="$(MSBuildThisFileDirectory)Interop\Unix\System.Native\Interop.FSync.cs"/>
@@ -73,6 +83,8 @@
<Compile Include="$(MSBuildThisFileDirectory)System\ArgumentNullException.cs"/>
<Compile Include="$(MSBuildThisFileDirectory)System\ArithmeticException.cs"/>
<Compile Include="$(MSBuildThisFileDirectory)System\ArrayTypeMismatchException.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\AssemblyLoadEventArgs.cs" />
+ <Compile Include="$(MSBuildThisFileDirectory)System\AssemblyLoadEventHandler.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\AsyncCallback.cs"/>
<Compile Include="$(MSBuildThisFileDirectory)System\AttributeTargets.cs"/>
<Compile Include="$(MSBuildThisFileDirectory)System\AttributeUsageAttribute.cs"/>
@@ -108,6 +120,7 @@
<Compile Include="$(MSBuildThisFileDirectory)System\Collections\IStructuralEquatable.cs"/>
<Compile Include="$(MSBuildThisFileDirectory)System\ComponentModel\EditorBrowsableAttribute.cs"/>
<Compile Include="$(MSBuildThisFileDirectory)System\Convert.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\CurrentSystemTimeZone.cs"/>
<Compile Include="$(MSBuildThisFileDirectory)System\DataMisalignedException.cs"/>
<Compile Include="$(MSBuildThisFileDirectory)System\DateTime.cs"/>
<Compile Include="$(MSBuildThisFileDirectory)System\DateTimeKind.cs"/>
@@ -125,10 +138,39 @@
<Compile Include="$(MSBuildThisFileDirectory)System\FlagsAttribute.cs"/>
<Compile Include="$(MSBuildThisFileDirectory)System\FormatException.cs"/>
<Compile Include="$(MSBuildThisFileDirectory)System\FormattableString.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Globalization\CalendarAlgorithmType.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Globalization\CalendarWeekRule.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Globalization\CalendricalCalculationsHelper.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Globalization\ChineseLunisolarCalendar.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Globalization\CultureNotFoundException.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Globalization\CultureTypes.cs"/>
<Compile Include="$(MSBuildThisFileDirectory)System\Globalization\DateTimeFormat.cs"/>
<Compile Include="$(MSBuildThisFileDirectory)System\Globalization\DateTimeFormatInfo.cs"/>
<Compile Include="$(MSBuildThisFileDirectory)System\Globalization\DateTimeFormatInfoScanner.cs"/>
<Compile Include="$(MSBuildThisFileDirectory)System\Globalization\DateTimeParse.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Globalization\DateTimeStyles.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Globalization\DaylightTime.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Globalization\DigitShapes.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Globalization\EastAsianLunisolarCalendar.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Globalization\GregorianCalendarTypes.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Globalization\HebrewCalendar.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Globalization\HebrewNumber.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Globalization\HijriCalendar.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Globalization\InternalGlobalizationHelper.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Globalization\JapaneseCalendar.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Globalization\JapaneseLunisolarCalendar.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Globalization\JulianCalendar.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Globalization\KoreanCalendar.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Globalization\KoreanLunisolarCalendar.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Globalization\NumberStyles.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Globalization\PersianCalendar.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Globalization\SortVersion.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Globalization\TaiwanCalendar.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Globalization\TaiwanLunisolarCalendar.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Globalization\ThaiBuddhistCalendar.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Globalization\TimeSpanStyles.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Globalization\UmAlQuraCalendar.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Globalization\UnicodeCategory.cs"/>
<Compile Include="$(MSBuildThisFileDirectory)System\IAsyncResult.cs"/>
<Compile Include="$(MSBuildThisFileDirectory)System\IComparable.cs"/>
<Compile Include="$(MSBuildThisFileDirectory)System\IConvertible.cs"/>
@@ -144,9 +186,10 @@
<Compile Include="$(MSBuildThisFileDirectory)System\InvalidProgramException.cs"/>
<Compile Include="$(MSBuildThisFileDirectory)System\InvalidTimeZoneException.cs"/>
<Compile Include="$(MSBuildThisFileDirectory)System\IO\Error.cs"/>
- <Compile Include="$(MSBuildThisFileDirectory)System\IO\FileStream.cs" />
- <Compile Include="$(MSBuildThisFileDirectory)System\IO\Path.cs" />
- <Compile Include="$(MSBuildThisFileDirectory)System\IO\PathInternal.cs" />
+ <Compile Include="$(MSBuildThisFileDirectory)System\IO\FileStream.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\IO\Path.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\IO\PathInternal.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\IO\StreamHelpers.CopyValidation.cs"/>
<Compile Include="$(MSBuildThisFileDirectory)System\IObservable.cs"/>
<Compile Include="$(MSBuildThisFileDirectory)System\IObserver.cs"/>
<Compile Include="$(MSBuildThisFileDirectory)System\IProgress.cs"/>
@@ -242,6 +285,8 @@
<Compile Include="$(MSBuildThisFileDirectory)System\Reflection\TypeDelegator.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Reflection\TypeFilter.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Reflection\TypeInfo.cs" />
+ <Compile Include="$(MSBuildThisFileDirectory)System\ResolveEventArgs.cs" />
+ <Compile Include="$(MSBuildThisFileDirectory)System\ResolveEventHandler.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Runtime\CompilerServices\CompilationRelaxations.cs"/>
<Compile Include="$(MSBuildThisFileDirectory)System\Runtime\CompilerServices\CompilerGlobalScopeAttribute.cs"/>
<Compile Include="$(MSBuildThisFileDirectory)System\Runtime\CompilerServices\DefaultDependencyAttribute.cs"/>
@@ -267,6 +312,7 @@
<Compile Include="$(MSBuildThisFileDirectory)System\Security\AllowPartiallyTrustedCallersAttribute.cs"/>
<Compile Include="$(MSBuildThisFileDirectory)System\Security\CryptographicException.cs"/>
<Compile Include="$(MSBuildThisFileDirectory)System\Security\PartialTrustVisibilityLevel.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Security\SecureString.cs"/>
<Compile Include="$(MSBuildThisFileDirectory)System\Security\SecurityCriticalAttribute.cs"/>
<Compile Include="$(MSBuildThisFileDirectory)System\Security\SecurityCriticalScope.cs"/>
<Compile Include="$(MSBuildThisFileDirectory)System\Security\SecurityException.cs"/>
@@ -282,10 +328,14 @@
<Compile Include="$(MSBuildThisFileDirectory)System\StringComparison.cs"/>
<Compile Include="$(MSBuildThisFileDirectory)System\StringSplitOptions.cs"/>
<Compile Include="$(MSBuildThisFileDirectory)System\SystemException.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\TimeZone.cs"/>
<Compile Include="$(MSBuildThisFileDirectory)System\Text\Normalization.cs"/>
<Compile Include="$(MSBuildThisFileDirectory)System\Text\StringBuilder.cs"/>
<Compile Include="$(MSBuildThisFileDirectory)System\ThreadAttributes.cs"/>
<Compile Include="$(MSBuildThisFileDirectory)System\Threading\DeferredDisposableLifetime.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Threading\Tasks\TaskCanceledException.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Threading\Tasks\TaskExtensions.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Threading\Tasks\TaskSchedulerException.cs"/>
<Compile Include="$(MSBuildThisFileDirectory)System\Threading\Timeout.cs"/>
<Compile Include="$(MSBuildThisFileDirectory)System\ThreadStaticAttribute.cs"/>
<Compile Include="$(MSBuildThisFileDirectory)System\TimeoutException.cs"/>
@@ -297,6 +347,7 @@
<Compile Include="$(MSBuildThisFileDirectory)System\TypeAccessException.cs"/>
<Compile Include="$(MSBuildThisFileDirectory)System\TypeCode.cs"/>
<Compile Include="$(MSBuildThisFileDirectory)System\TypeInitializationException.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\TypeUnloadedException.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\UnauthorizedAccessException.cs"/>
<Compile Include="$(MSBuildThisFileDirectory)System\UnhandledExceptionEventArgs.cs"/>
<Compile Include="$(MSBuildThisFileDirectory)System\UnhandledExceptionEventHandler.cs"/>
@@ -317,9 +368,11 @@
</ItemGroup>
<ItemGroup Condition="$(TargetsUnix)">
<Compile Include="$(MSBuildThisFileDirectory)Microsoft\Win32\SafeHandles\SafeFileHandle.Unix.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Globalization\LocaleData.Unix.cs" Condition="'$(EnableDummyGlobalizationImplementation)' != 'true'"/>
<Compile Include="$(MSBuildThisFileDirectory)System\IO\FileStream.Unix.cs"/>
<Compile Include="$(MSBuildThisFileDirectory)System\IO\Path.Unix.cs"/>
<Compile Include="$(MSBuildThisFileDirectory)System\IO\PathInternal.Unix.cs"/>
+ <Compile Include="$(MSBuildThisFileDirectory)System\Security\SecureString.Unix.cs"/>
</ItemGroup>
<ItemGroup Condition="$(TargetsUnix) and $(TargetsOSX)">
<Compile Include="$(MSBuildThisFileDirectory)System\IO\FileStream.OSX.cs"/>
diff --git a/src/mscorlib/shared/System/AssemblyLoadEventArgs.cs b/src/mscorlib/shared/System/AssemblyLoadEventArgs.cs
new file mode 100644
index 0000000000..d7e5249693
--- /dev/null
+++ b/src/mscorlib/shared/System/AssemblyLoadEventArgs.cs
@@ -0,0 +1,18 @@
+// 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.
+
+using System.Reflection;
+
+namespace System
+{
+ public class AssemblyLoadEventArgs : EventArgs
+ {
+ public AssemblyLoadEventArgs(Assembly loadedAssembly)
+ {
+ LoadedAssembly = loadedAssembly;
+ }
+
+ public Assembly LoadedAssembly { get; }
+ }
+}
diff --git a/src/mscorlib/shared/System/AssemblyLoadEventHandler.cs b/src/mscorlib/shared/System/AssemblyLoadEventHandler.cs
new file mode 100644
index 0000000000..752379fdc7
--- /dev/null
+++ b/src/mscorlib/shared/System/AssemblyLoadEventHandler.cs
@@ -0,0 +1,8 @@
+// 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.
+
+namespace System
+{
+ public delegate void AssemblyLoadEventHandler(object sender, AssemblyLoadEventArgs args);
+}
diff --git a/src/mscorlib/src/System/CurrentTimeZone.cs b/src/mscorlib/shared/System/CurrentSystemTimeZone.cs
index d0957477b6..2d848397a9 100644
--- a/src/mscorlib/src/System/CurrentTimeZone.cs
+++ b/src/mscorlib/shared/System/CurrentSystemTimeZone.cs
@@ -29,12 +29,8 @@ namespace System
{
[Obsolete("System.CurrentSystemTimeZone has been deprecated. Please investigate the use of System.TimeZoneInfo.Local instead.")]
[Serializable]
- internal class CurrentSystemTimeZone : TimeZone
+ internal partial class CurrentSystemTimeZone : TimeZone
{
- // The per-year information is cached in in this instance value. As a result it can
- // be cleaned up by CultureInfo.ClearCachedData, which will clear the instance of this object
- private readonly Hashtable m_CachedDaylightChanges = new Hashtable();
-
// Standard offset in ticks to the Universal time if
// no daylight saving is in used.
// E.g. the offset for PST (Pacific Standard time) should be -8 * 60 * 60 * 1000 * 10000.
@@ -152,51 +148,40 @@ namespace System
{
throw new ArgumentOutOfRangeException(nameof(year), SR.Format(SR.ArgumentOutOfRange_Range, 1, 9999));
}
- Contract.EndContractBlock();
- Object objYear = (Object)year;
+ return GetCachedDaylightChanges(year);
+ }
+
+ private static DaylightTime CreateDaylightChanges(int year)
+ {
+ DaylightTime currentDaylightChanges = null;
- if (!m_CachedDaylightChanges.Contains(objYear))
+ if (TimeZoneInfo.Local.SupportsDaylightSavingTime)
{
- DaylightTime currentDaylightChanges = null;
+ DateTime start;
+ DateTime end;
+ TimeSpan delta;
- if (TimeZoneInfo.Local.SupportsDaylightSavingTime)
+ foreach (var rule in TimeZoneInfo.Local.GetAdjustmentRules())
{
- DateTime start;
- DateTime end;
- TimeSpan delta;
-
- foreach (var rule in TimeZoneInfo.Local.GetAdjustmentRules())
+ if (rule.DateStart.Year <= year && rule.DateEnd.Year >= year && rule.DaylightDelta != TimeSpan.Zero)
{
- if (rule.DateStart.Year <= year && rule.DateEnd.Year >= year && rule.DaylightDelta != TimeSpan.Zero)
- {
- start = TimeZoneInfo.TransitionTimeToDateTime(year, rule.DaylightTransitionStart);
- end = TimeZoneInfo.TransitionTimeToDateTime(year, rule.DaylightTransitionEnd);
- delta = rule.DaylightDelta;
-
- currentDaylightChanges = new DaylightTime(start, end, delta);
- break;
- }
- }
- }
+ start = TimeZoneInfo.TransitionTimeToDateTime(year, rule.DaylightTransitionStart);
+ end = TimeZoneInfo.TransitionTimeToDateTime(year, rule.DaylightTransitionEnd);
+ delta = rule.DaylightDelta;
- if (currentDaylightChanges == null)
- {
- currentDaylightChanges = new DaylightTime(DateTime.MinValue, DateTime.MinValue, TimeSpan.Zero);
- }
-
- lock (m_CachedDaylightChanges)
- {
- if (!m_CachedDaylightChanges.Contains(objYear))
- {
- m_CachedDaylightChanges.Add(objYear, currentDaylightChanges);
+ currentDaylightChanges = new DaylightTime(start, end, delta);
+ break;
}
}
}
- DaylightTime result = (DaylightTime)m_CachedDaylightChanges[objYear];
+ if (currentDaylightChanges == null)
+ {
+ currentDaylightChanges = new DaylightTime(DateTime.MinValue, DateTime.MinValue, TimeSpan.Zero);
+ }
- return result;
+ return currentDaylightChanges;
}
public override TimeSpan GetUtcOffset(DateTime time)
diff --git a/src/mscorlib/src/System/Globalization/CalendarAlgorithmType.cs b/src/mscorlib/shared/System/Globalization/CalendarAlgorithmType.cs
index 159b0e6f77..4ddc307abf 100644
--- a/src/mscorlib/src/System/Globalization/CalendarAlgorithmType.cs
+++ b/src/mscorlib/shared/System/Globalization/CalendarAlgorithmType.cs
@@ -2,8 +2,6 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
-using System;
-
namespace System.Globalization
{
public enum CalendarAlgorithmType
diff --git a/src/mscorlib/src/System/Globalization/CalendarWeekRule.cs b/src/mscorlib/shared/System/Globalization/CalendarWeekRule.cs
index 4013ce7237..b381b5c544 100644
--- a/src/mscorlib/src/System/Globalization/CalendarWeekRule.cs
+++ b/src/mscorlib/shared/System/Globalization/CalendarWeekRule.cs
@@ -2,8 +2,6 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
-using System;
-
namespace System.Globalization
{
[Serializable]
diff --git a/src/mscorlib/src/System/Globalization/CalendricalCalculationsHelper.cs b/src/mscorlib/shared/System/Globalization/CalendricalCalculationsHelper.cs
index 7de75d6aee..7de75d6aee 100644
--- a/src/mscorlib/src/System/Globalization/CalendricalCalculationsHelper.cs
+++ b/src/mscorlib/shared/System/Globalization/CalendricalCalculationsHelper.cs
diff --git a/src/mscorlib/src/System/Globalization/ChineseLunisolarCalendar.cs b/src/mscorlib/shared/System/Globalization/ChineseLunisolarCalendar.cs
index dc9e5fd13d..404add0936 100644
--- a/src/mscorlib/src/System/Globalization/ChineseLunisolarCalendar.cs
+++ b/src/mscorlib/shared/System/Globalization/ChineseLunisolarCalendar.cs
@@ -2,16 +2,10 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
-using System;
using System.Diagnostics.Contracts;
namespace System.Globalization
{
- ////////////////////////////////////////////////////////////////////////////
- //
- // Notes about ChineseLunisolarCalendar
- //
- ////////////////////////////////////////////////////////////////////////////
/*
** Calendar support range:
** Calendar Minimum Maximum
diff --git a/src/mscorlib/src/System/Globalization/CultureNotFoundException.cs b/src/mscorlib/shared/System/Globalization/CultureNotFoundException.cs
index d296ad88e5..929f4bb000 100644
--- a/src/mscorlib/src/System/Globalization/CultureNotFoundException.cs
+++ b/src/mscorlib/shared/System/Globalization/CultureNotFoundException.cs
@@ -2,14 +2,12 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
-using System;
using System.Runtime.Serialization;
-using System.Threading;
namespace System.Globalization
{
[Serializable]
- public class CultureNotFoundException : ArgumentException, ISerializable
+ public class CultureNotFoundException : ArgumentException
{
private string _invalidCultureName; // unrecognized culture name
private int? _invalidCultureId; // unrecognized culture Lcid
diff --git a/src/mscorlib/shared/System/Globalization/CultureTypes.cs b/src/mscorlib/shared/System/Globalization/CultureTypes.cs
new file mode 100644
index 0000000000..f52ac82a83
--- /dev/null
+++ b/src/mscorlib/shared/System/Globalization/CultureTypes.cs
@@ -0,0 +1,27 @@
+// 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.
+
+// The enumeration constants used in CultureInfo.GetCultures().
+// On Linux platforms, the only enum values used there is NeutralCultures and SpecificCultures
+// the rest are obsolete or not valid on Linux
+
+namespace System.Globalization
+{
+ [Flags]
+ public enum CultureTypes
+ {
+ NeutralCultures = 0x0001, // Neutral cultures are cultures like "en", "de", "zh", etc, for enumeration this includes ALL neutrals regardless of other flags
+ SpecificCultures = 0x0002, // Non-netural cultuers. Examples are "en-us", "zh-tw", etc., for enumeration this includes ALL specifics regardless of other flags
+ InstalledWin32Cultures = 0x0004, // Win32 installed cultures in the system and exists in the framework too., this is effectively all cultures
+
+ AllCultures = NeutralCultures | SpecificCultures | InstalledWin32Cultures,
+
+ UserCustomCulture = 0x0008, // User defined custom culture
+ ReplacementCultures = 0x0010, // User defined replacement custom culture.
+ [Obsolete("This value has been deprecated. Please use other values in CultureTypes.")]
+ WindowsOnlyCultures = 0x0020, // this will always return empty list.
+ [Obsolete("This value has been deprecated. Please use other values in CultureTypes.")]
+ FrameworkCultures = 0x0040, // will return only the v2 cultures marked as Framework culture.
+ }
+}
diff --git a/src/mscorlib/shared/System/Globalization/DateTimeFormat.cs b/src/mscorlib/shared/System/Globalization/DateTimeFormat.cs
index d3bf255e28..840409f55a 100644
--- a/src/mscorlib/shared/System/Globalization/DateTimeFormat.cs
+++ b/src/mscorlib/shared/System/Globalization/DateTimeFormat.cs
@@ -2,16 +2,11 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
-using System.Text;
-using System.Threading;
-using System.Globalization;
using System.Collections.Generic;
-using System.Runtime.CompilerServices;
-using System.Runtime.InteropServices;
-using System.Runtime.Versioning;
-using System.Security;
using System.Diagnostics;
using System.Diagnostics.Contracts;
+using System.Globalization;
+using System.Text;
namespace System
{
diff --git a/src/mscorlib/shared/System/Globalization/DateTimeFormatInfoScanner.cs b/src/mscorlib/shared/System/Globalization/DateTimeFormatInfoScanner.cs
index ddf7d7e640..15af1b7d84 100644
--- a/src/mscorlib/shared/System/Globalization/DateTimeFormatInfoScanner.cs
+++ b/src/mscorlib/shared/System/Globalization/DateTimeFormatInfoScanner.cs
@@ -19,9 +19,6 @@
//
////////////////////////////////////////////////////////////////////////////
-using System;
-using System.Globalization;
-using System.Collections;
using System.Collections.Generic;
using System.Text;
diff --git a/src/mscorlib/shared/System/Globalization/DateTimeParse.cs b/src/mscorlib/shared/System/Globalization/DateTimeParse.cs
index 857ffc615b..910fbf2ff0 100644
--- a/src/mscorlib/shared/System/Globalization/DateTimeParse.cs
+++ b/src/mscorlib/shared/System/Globalization/DateTimeParse.cs
@@ -2,33 +2,14 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
-////////////////////////////////////////////////////////////////////////////
-//
-//
-// Purpose: This class is called by DateTime to parse a date/time string.
-//
-////////////////////////////////////////////////////////////////////////////
+using System.Diagnostics;
+using System.Diagnostics.Contracts;
+using System.Globalization;
+using System.Text;
namespace System
{
- using System;
- using System.Text;
- using System.Globalization;
- using System.Threading;
- using System.Collections;
- using System.Runtime.CompilerServices;
- using System.Runtime.InteropServices;
- using System.Runtime.Versioning;
- using System.Security;
- using System.Diagnostics;
- using System.Diagnostics.Contracts;
-
- ////////////////////////////////////////////////////////////////////////
-
- //This class contains only static members
-
- internal static
- class DateTimeParse
+ internal static class DateTimeParse
{
internal const Int32 MaxDateTimeNumberDigits = 8;
diff --git a/src/mscorlib/src/System/Globalization/DateTimeStyles.cs b/src/mscorlib/shared/System/Globalization/DateTimeStyles.cs
index cd551cb08e..79232ff199 100644
--- a/src/mscorlib/src/System/Globalization/DateTimeStyles.cs
+++ b/src/mscorlib/shared/System/Globalization/DateTimeStyles.cs
@@ -14,7 +14,6 @@
namespace System.Globalization
{
- [Serializable]
[Flags]
public enum DateTimeStyles
{
diff --git a/src/mscorlib/src/System/Globalization/DaylightTime.cs b/src/mscorlib/shared/System/Globalization/DaylightTime.cs
index f066e4b1e7..b3c70e1d10 100644
--- a/src/mscorlib/src/System/Globalization/DaylightTime.cs
+++ b/src/mscorlib/shared/System/Globalization/DaylightTime.cs
@@ -2,8 +2,6 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
-using System;
-
namespace System.Globalization
{
// This class represents a starting/ending time for a period of daylight saving time.
diff --git a/src/mscorlib/src/System/Globalization/DigitShapes.cs b/src/mscorlib/shared/System/Globalization/DigitShapes.cs
index b21f480805..1ce45dbeb6 100644
--- a/src/mscorlib/src/System/Globalization/DigitShapes.cs
+++ b/src/mscorlib/shared/System/Globalization/DigitShapes.cs
@@ -2,13 +2,8 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
-//
-// The enumeration constants used in NumberFormatInfo.DigitSubstitution.
-//
-
namespace System.Globalization
{
- [Serializable]
public enum DigitShapes : int
{
Context = 0x0000, // The shape depends on the previous text in the same output.
diff --git a/src/mscorlib/src/System/Globalization/EastAsianLunisolarCalendar.cs b/src/mscorlib/shared/System/Globalization/EastAsianLunisolarCalendar.cs
index f82fad8e5b..d06b13cd7d 100644
--- a/src/mscorlib/src/System/Globalization/EastAsianLunisolarCalendar.cs
+++ b/src/mscorlib/shared/System/Globalization/EastAsianLunisolarCalendar.cs
@@ -2,17 +2,10 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
-using System;
using System.Diagnostics.Contracts;
namespace System.Globalization
{
- ////////////////////////////////////////////////////////////////////////////
- //
- // Notes about EastAsianLunisolarCalendar
- //
- ////////////////////////////////////////////////////////////////////////////
-
[Serializable]
public abstract class EastAsianLunisolarCalendar : Calendar
{
diff --git a/src/mscorlib/src/System/Globalization/GregorianCalendarTypes.cs b/src/mscorlib/shared/System/Globalization/GregorianCalendarTypes.cs
index a14010fe60..1b61e5256e 100644
--- a/src/mscorlib/src/System/Globalization/GregorianCalendarTypes.cs
+++ b/src/mscorlib/shared/System/Globalization/GregorianCalendarTypes.cs
@@ -2,8 +2,6 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
-using System;
-
namespace System.Globalization
{
// Note: The values of the members of this enum must match the coresponding values
diff --git a/src/mscorlib/src/System/Globalization/HebrewCalendar.cs b/src/mscorlib/shared/System/Globalization/HebrewCalendar.cs
index b4f54f8fbb..b4f54f8fbb 100644
--- a/src/mscorlib/src/System/Globalization/HebrewCalendar.cs
+++ b/src/mscorlib/shared/System/Globalization/HebrewCalendar.cs
diff --git a/src/mscorlib/src/System/Globalization/HebrewNumber.cs b/src/mscorlib/shared/System/Globalization/HebrewNumber.cs
index 1e8fff2bcb..1e8fff2bcb 100644
--- a/src/mscorlib/src/System/Globalization/HebrewNumber.cs
+++ b/src/mscorlib/shared/System/Globalization/HebrewNumber.cs
diff --git a/src/mscorlib/src/System/Globalization/HijriCalendar.cs b/src/mscorlib/shared/System/Globalization/HijriCalendar.cs
index 0c72d9eaf5..cafde5fbb8 100644
--- a/src/mscorlib/src/System/Globalization/HijriCalendar.cs
+++ b/src/mscorlib/shared/System/Globalization/HijriCalendar.cs
@@ -2,8 +2,6 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
-using System;
-using System.Runtime.Versioning;
using System.Diagnostics.Contracts;
namespace System.Globalization
diff --git a/src/mscorlib/src/System/Globalization/InternalGlobalizationHelper.cs b/src/mscorlib/shared/System/Globalization/InternalGlobalizationHelper.cs
index 0a4e6f0600..f5eea1b629 100644
--- a/src/mscorlib/src/System/Globalization/InternalGlobalizationHelper.cs
+++ b/src/mscorlib/shared/System/Globalization/InternalGlobalizationHelper.cs
@@ -2,11 +2,9 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
-using System;
-
namespace System.Globalization
{
- internal class InternalGloablizationHelper
+ internal class InternalGlobalizationHelper
{
// Copied from the TimeSpan to be used inside the globalization code and avoid internal dependancy on TimeSpan class
internal static long TimeToTicks(int hour, int minute, int second)
diff --git a/src/mscorlib/src/System/Globalization/JapaneseCalendar.cs b/src/mscorlib/shared/System/Globalization/JapaneseCalendar.cs
index f0216c8f51..4655e08a4e 100644
--- a/src/mscorlib/src/System/Globalization/JapaneseCalendar.cs
+++ b/src/mscorlib/shared/System/Globalization/JapaneseCalendar.cs
@@ -2,8 +2,6 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
-using System;
-using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Diagnostics.Contracts;
diff --git a/src/mscorlib/src/System/Globalization/JapaneseLunisolarCalendar.cs b/src/mscorlib/shared/System/Globalization/JapaneseLunisolarCalendar.cs
index cc3d34954d..95e87f85d7 100644
--- a/src/mscorlib/src/System/Globalization/JapaneseLunisolarCalendar.cs
+++ b/src/mscorlib/shared/System/Globalization/JapaneseLunisolarCalendar.cs
@@ -2,16 +2,10 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
-using System;
using System.Diagnostics.Contracts;
namespace System.Globalization
{
- ////////////////////////////////////////////////////////////////////////////
- //
- // Notes about JapaneseLunisolarCalendar
- //
- ////////////////////////////////////////////////////////////////////////////
/*
** Calendar support range:
** Calendar Minimum Maximum
diff --git a/src/mscorlib/src/System/Globalization/JulianCalendar.cs b/src/mscorlib/shared/System/Globalization/JulianCalendar.cs
index 43e6ad07a2..f4678c1a85 100644
--- a/src/mscorlib/src/System/Globalization/JulianCalendar.cs
+++ b/src/mscorlib/shared/System/Globalization/JulianCalendar.cs
@@ -2,7 +2,6 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
-using System;
using System.Diagnostics.Contracts;
namespace System.Globalization
diff --git a/src/mscorlib/src/System/Globalization/KoreanCalendar.cs b/src/mscorlib/shared/System/Globalization/KoreanCalendar.cs
index b015aa0716..b962b1c427 100644
--- a/src/mscorlib/src/System/Globalization/KoreanCalendar.cs
+++ b/src/mscorlib/shared/System/Globalization/KoreanCalendar.cs
@@ -2,7 +2,6 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
-using System;
using System.Diagnostics.CodeAnalysis;
using System.Diagnostics.Contracts;
diff --git a/src/mscorlib/src/System/Globalization/KoreanLunisolarCalendar.cs b/src/mscorlib/shared/System/Globalization/KoreanLunisolarCalendar.cs
index 6d091285b2..d4c71632aa 100644
--- a/src/mscorlib/src/System/Globalization/KoreanLunisolarCalendar.cs
+++ b/src/mscorlib/shared/System/Globalization/KoreanLunisolarCalendar.cs
@@ -2,16 +2,10 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
-using System;
using System.Diagnostics.Contracts;
namespace System.Globalization
{
- ////////////////////////////////////////////////////////////////////////////
- //
- // Notes about KoreanLunisolarCalendar
- //
- ////////////////////////////////////////////////////////////////////////////
/*
** Calendar support range:
** Calendar Minimum Maximum
diff --git a/src/mscorlib/src/System/Globalization/LocaleData.Unix.cs b/src/mscorlib/shared/System/Globalization/LocaleData.Unix.cs
index d4c58d8a3d..d4c58d8a3d 100644
--- a/src/mscorlib/src/System/Globalization/LocaleData.Unix.cs
+++ b/src/mscorlib/shared/System/Globalization/LocaleData.Unix.cs
diff --git a/src/mscorlib/src/System/Globalization/NumberStyles.cs b/src/mscorlib/shared/System/Globalization/NumberStyles.cs
index 31eafc9299..5909d65a2c 100644
--- a/src/mscorlib/src/System/Globalization/NumberStyles.cs
+++ b/src/mscorlib/shared/System/Globalization/NumberStyles.cs
@@ -12,11 +12,8 @@
**
===========================================================*/
-using System;
-
namespace System.Globalization
{
- [Serializable]
[Flags]
public enum NumberStyles
{
diff --git a/src/mscorlib/src/System/Globalization/PersianCalendar.cs b/src/mscorlib/shared/System/Globalization/PersianCalendar.cs
index b8b3da6911..445bbd6d0c 100644
--- a/src/mscorlib/src/System/Globalization/PersianCalendar.cs
+++ b/src/mscorlib/shared/System/Globalization/PersianCalendar.cs
@@ -7,11 +7,6 @@ using System.Diagnostics.Contracts;
namespace System.Globalization
{
- ////////////////////////////////////////////////////////////////////////////
- //
- // Notes about PersianCalendar
- //
- ////////////////////////////////////////////////////////////////////////////
// Modern Persian calendar is a solar observation based calendar. Each new year begins on the day when the vernal equinox occurs before noon.
// The epoch is the date of the vernal equinox prior to the epoch of the Islamic calendar (March 19, 622 Julian or March 22, 622 Gregorian)
diff --git a/src/mscorlib/src/System/Globalization/SortVersion.cs b/src/mscorlib/shared/System/Globalization/SortVersion.cs
index 9d6118e7ec..a7aef6d84b 100644
--- a/src/mscorlib/src/System/Globalization/SortVersion.cs
+++ b/src/mscorlib/shared/System/Globalization/SortVersion.cs
@@ -2,9 +2,6 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
-using System;
-using System.Diagnostics.Contracts;
-
namespace System.Globalization
{
[Serializable]
diff --git a/src/mscorlib/src/System/Globalization/TaiwanCalendar.cs b/src/mscorlib/shared/System/Globalization/TaiwanCalendar.cs
index 2e735e0cb9..2e735e0cb9 100644
--- a/src/mscorlib/src/System/Globalization/TaiwanCalendar.cs
+++ b/src/mscorlib/shared/System/Globalization/TaiwanCalendar.cs
diff --git a/src/mscorlib/src/System/Globalization/TaiwanLunisolarCalendar.cs b/src/mscorlib/shared/System/Globalization/TaiwanLunisolarCalendar.cs
index 1f75ac9a04..8ba1f278e7 100644
--- a/src/mscorlib/src/System/Globalization/TaiwanLunisolarCalendar.cs
+++ b/src/mscorlib/shared/System/Globalization/TaiwanLunisolarCalendar.cs
@@ -7,17 +7,12 @@ using System.Diagnostics.Contracts;
namespace System.Globalization
{
- ////////////////////////////////////////////////////////////////////////////
- //
- // Notes about TaiwanLunisolarCalendar
- //
- ////////////////////////////////////////////////////////////////////////////
/*
** Calendar support range:
- ** Calendar Minimum Maximum
- ** ========== ========== ==========
- ** Gregorian 1912/02/18 2051/02/10
- ** TaiwanLunisolar 1912/01/01 2050/13/29
+ ** Calendar Minimum Maximum
+ ** ========== ========== ==========
+ ** Gregorian 1912/02/18 2051/02/10
+ ** TaiwanLunisolar 1912/01/01 2050/13/29
*/
[Serializable]
diff --git a/src/mscorlib/src/System/Globalization/ThaiBuddhistCalendar.cs b/src/mscorlib/shared/System/Globalization/ThaiBuddhistCalendar.cs
index 9e6e30406c..9e6e30406c 100644
--- a/src/mscorlib/src/System/Globalization/ThaiBuddhistCalendar.cs
+++ b/src/mscorlib/shared/System/Globalization/ThaiBuddhistCalendar.cs
diff --git a/src/mscorlib/src/System/Globalization/TimeSpanStyles.cs b/src/mscorlib/shared/System/Globalization/TimeSpanStyles.cs
index 68a47bcbe6..68a47bcbe6 100644
--- a/src/mscorlib/src/System/Globalization/TimeSpanStyles.cs
+++ b/src/mscorlib/shared/System/Globalization/TimeSpanStyles.cs
diff --git a/src/mscorlib/src/System/Globalization/UmAlQuraCalendar.cs b/src/mscorlib/shared/System/Globalization/UmAlQuraCalendar.cs
index 7b47d9c02b..b7ba6d0112 100644
--- a/src/mscorlib/src/System/Globalization/UmAlQuraCalendar.cs
+++ b/src/mscorlib/shared/System/Globalization/UmAlQuraCalendar.cs
@@ -7,11 +7,6 @@ using System.Diagnostics.Contracts;
namespace System.Globalization
{
- ////////////////////////////////////////////////////////////////////////////
- //
- // Notes about UmAlQuraCalendar
- //
- ////////////////////////////////////////////////////////////////////////////
/*
** Calendar support range:
** Calendar Minimum Maximum
diff --git a/src/mscorlib/src/System/Globalization/UnicodeCategory.cs b/src/mscorlib/shared/System/Globalization/UnicodeCategory.cs
index 1c5e6bca56..f0ae1fdfd9 100644
--- a/src/mscorlib/src/System/Globalization/UnicodeCategory.cs
+++ b/src/mscorlib/shared/System/Globalization/UnicodeCategory.cs
@@ -4,67 +4,37 @@
namespace System.Globalization
{
- [Serializable]
public enum UnicodeCategory
{
UppercaseLetter = 0,
-
LowercaseLetter = 1,
-
TitlecaseLetter = 2,
-
ModifierLetter = 3,
-
OtherLetter = 4,
-
NonSpacingMark = 5,
-
SpacingCombiningMark = 6,
-
EnclosingMark = 7,
-
DecimalDigitNumber = 8,
-
LetterNumber = 9,
-
OtherNumber = 10,
-
SpaceSeparator = 11,
-
LineSeparator = 12,
-
ParagraphSeparator = 13,
-
Control = 14,
-
Format = 15,
-
Surrogate = 16,
-
PrivateUse = 17,
-
ConnectorPunctuation = 18,
-
DashPunctuation = 19,
-
OpenPunctuation = 20,
-
ClosePunctuation = 21,
-
InitialQuotePunctuation = 22,
-
FinalQuotePunctuation = 23,
-
OtherPunctuation = 24,
-
MathSymbol = 25,
-
CurrencySymbol = 26,
-
ModifierSymbol = 27,
-
OtherSymbol = 28,
-
OtherNotAssigned = 29,
}
}
diff --git a/src/mscorlib/src/System/IO/StreamHelpers.CopyValidation.cs b/src/mscorlib/shared/System/IO/StreamHelpers.CopyValidation.cs
index 45bbd816df..45bbd816df 100644
--- a/src/mscorlib/src/System/IO/StreamHelpers.CopyValidation.cs
+++ b/src/mscorlib/shared/System/IO/StreamHelpers.CopyValidation.cs
diff --git a/src/mscorlib/shared/System/ResolveEventArgs.cs b/src/mscorlib/shared/System/ResolveEventArgs.cs
new file mode 100644
index 0000000000..6196947bb5
--- /dev/null
+++ b/src/mscorlib/shared/System/ResolveEventArgs.cs
@@ -0,0 +1,25 @@
+// 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.
+
+using System.Reflection;
+
+namespace System
+{
+ public class ResolveEventArgs : EventArgs
+ {
+ public ResolveEventArgs(string name)
+ {
+ Name = name;
+ }
+
+ public ResolveEventArgs(string name, Assembly requestingAssembly)
+ {
+ Name = name;
+ RequestingAssembly = requestingAssembly;
+ }
+
+ public string Name { get; }
+ public Assembly RequestingAssembly { get; }
+ }
+}
diff --git a/src/mscorlib/shared/System/ResolveEventHandler.cs b/src/mscorlib/shared/System/ResolveEventHandler.cs
new file mode 100644
index 0000000000..cb9af5de66
--- /dev/null
+++ b/src/mscorlib/shared/System/ResolveEventHandler.cs
@@ -0,0 +1,10 @@
+// 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.
+
+using System.Reflection;
+
+namespace System
+{
+ public delegate Assembly ResolveEventHandler(object sender, ResolveEventArgs args);
+}
diff --git a/src/mscorlib/src/System/Security/SecureString.Unix.cs b/src/mscorlib/shared/System/Security/SecureString.Unix.cs
index 0ef38e40ee..0ef38e40ee 100644
--- a/src/mscorlib/src/System/Security/SecureString.Unix.cs
+++ b/src/mscorlib/shared/System/Security/SecureString.Unix.cs
diff --git a/src/mscorlib/src/System/Security/SecureString.cs b/src/mscorlib/shared/System/Security/SecureString.cs
index 9059f90e60..9059f90e60 100644
--- a/src/mscorlib/src/System/Security/SecureString.cs
+++ b/src/mscorlib/shared/System/Security/SecureString.cs
diff --git a/src/mscorlib/src/System/Threading/Tasks/TaskCanceledException.cs b/src/mscorlib/shared/System/Threading/Tasks/TaskCanceledException.cs
index d7690d4c7c..d7690d4c7c 100644
--- a/src/mscorlib/src/System/Threading/Tasks/TaskCanceledException.cs
+++ b/src/mscorlib/shared/System/Threading/Tasks/TaskCanceledException.cs
diff --git a/src/mscorlib/src/System/Threading/Tasks/TaskExtensions.cs b/src/mscorlib/shared/System/Threading/Tasks/TaskExtensions.cs
index 1098299517..1098299517 100644
--- a/src/mscorlib/src/System/Threading/Tasks/TaskExtensions.cs
+++ b/src/mscorlib/shared/System/Threading/Tasks/TaskExtensions.cs
diff --git a/src/mscorlib/src/System/Threading/Tasks/TaskSchedulerException.cs b/src/mscorlib/shared/System/Threading/Tasks/TaskSchedulerException.cs
index 148b6300ef..148b6300ef 100644
--- a/src/mscorlib/src/System/Threading/Tasks/TaskSchedulerException.cs
+++ b/src/mscorlib/shared/System/Threading/Tasks/TaskSchedulerException.cs
diff --git a/src/mscorlib/src/System/TimeZone.cs b/src/mscorlib/shared/System/TimeZone.cs
index 88e2e21864..88e2e21864 100644
--- a/src/mscorlib/src/System/TimeZone.cs
+++ b/src/mscorlib/shared/System/TimeZone.cs
diff --git a/src/mscorlib/src/System/TypeUnloadedException.cs b/src/mscorlib/shared/System/TypeUnloadedException.cs
index d1d55d55dc..a4fb4524ad 100644
--- a/src/mscorlib/src/System/TypeUnloadedException.cs
+++ b/src/mscorlib/shared/System/TypeUnloadedException.cs
@@ -2,16 +2,6 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
-/*=============================================================================
-**
-**
-**
-** Purpose: Exception class for attempt to access an unloaded class
-**
-**
-=============================================================================*/
-
-
using System.Runtime.Serialization;
namespace System
@@ -25,13 +15,13 @@ namespace System
SetErrorCode(__HResults.COR_E_TYPEUNLOADED);
}
- public TypeUnloadedException(String message)
+ public TypeUnloadedException(string message)
: base(message)
{
SetErrorCode(__HResults.COR_E_TYPEUNLOADED);
}
- public TypeUnloadedException(String message, Exception innerException)
+ public TypeUnloadedException(string message, Exception innerException)
: base(message, innerException)
{
SetErrorCode(__HResults.COR_E_TYPEUNLOADED);
@@ -40,7 +30,8 @@ namespace System
//
// This constructor is required for serialization;
//
- protected TypeUnloadedException(SerializationInfo info, StreamingContext context) : base(info, context)
+ protected TypeUnloadedException(SerializationInfo info, StreamingContext context)
+ : base(info, context)
{
}
}
diff --git a/src/mscorlib/src/Debug.cs b/src/mscorlib/src/Debug.cs
deleted file mode 100644
index 35cb680ffd..0000000000
--- a/src/mscorlib/src/Debug.cs
+++ /dev/null
@@ -1,29 +0,0 @@
-// 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.
-
-using System.Diagnostics;
-
-namespace System
-{
- internal static class Debug
- {
- [Conditional("_DEBUG")]
- static public void Assert(bool condition)
- {
- BCLDebug.Assert(condition);
- }
-
- [Conditional("_DEBUG")]
- static public void Assert(bool condition, string message)
- {
- BCLDebug.Assert(condition, message);
- }
-
- [Conditional("_DEBUG")]
- static public void Fail(string message)
- {
- BCLDebug.Assert(false, message);
- }
- }
-}
diff --git a/src/mscorlib/src/Interop/Unix/System.Globalization.Native/Interop.Collation.cs b/src/mscorlib/src/Interop/Unix/System.Globalization.Native/Interop.Collation.cs
index 5cd2ee52c5..fe14560a3a 100644
--- a/src/mscorlib/src/Interop/Unix/System.Globalization.Native/Interop.Collation.cs
+++ b/src/mscorlib/src/Interop/Unix/System.Globalization.Native/Interop.Collation.cs
@@ -3,6 +3,7 @@
// See the LICENSE file in the project root for more information.
using System;
+using System.Diagnostics;
using System.Globalization;
using System.Runtime.InteropServices;
using System.Security;
diff --git a/src/mscorlib/src/Interop/Unix/System.Native/Interop.SysLog.cs b/src/mscorlib/src/Interop/Unix/System.Native/Interop.SysLog.cs
new file mode 100644
index 0000000000..6b6a74b743
--- /dev/null
+++ b/src/mscorlib/src/Interop/Unix/System.Native/Interop.SysLog.cs
@@ -0,0 +1,58 @@
+// 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.
+
+using System.Runtime.InteropServices;
+
+internal static partial class Interop
+{
+ internal static partial class Sys
+ {
+ internal enum SysLogPriority : int
+ {
+ // Priorities
+ LOG_EMERG = 0, /* system is unusable */
+ LOG_ALERT = 1, /* action must be taken immediately */
+ LOG_CRIT = 2, /* critical conditions */
+ LOG_ERR = 3, /* error conditions */
+ LOG_WARNING = 4, /* warning conditions */
+ LOG_NOTICE = 5, /* normal but significant condition */
+ LOG_INFO = 6, /* informational */
+ LOG_DEBUG = 7, /* debug-level messages */
+ // Facilities
+ LOG_KERN = (0<<3), /* kernel messages */
+ LOG_USER = (1<<3), /* random user-level messages */
+ LOG_MAIL = (2<<3), /* mail system */
+ LOG_DAEMON = (3<<3), /* system daemons */
+ LOG_AUTH = (4<<3), /* authorization messages */
+ LOG_SYSLOG = (5<<3), /* messages generated internally by syslogd */
+ LOG_LPR = (6<<3), /* line printer subsystem */
+ LOG_NEWS = (7<<3), /* network news subsystem */
+ LOG_UUCP = (8<<3), /* UUCP subsystem */
+ LOG_CRON = (9<<3), /* clock daemon */
+ LOG_AUTHPRIV = (10<<3), /* authorization messages (private) */
+ LOG_FTP = (11<<3), /* ftp daemon */
+ // Between FTP and Local is reserved for system use
+ LOG_LOCAL0 = (16<<3), /* reserved for local use */
+ LOG_LOCAL1 = (17<<3), /* reserved for local use */
+ LOG_LOCAL2 = (18<<3), /* reserved for local use */
+ LOG_LOCAL3 = (19<<3), /* reserved for local use */
+ LOG_LOCAL4 = (20<<3), /* reserved for local use */
+ LOG_LOCAL5 = (21<<3), /* reserved for local use */
+ LOG_LOCAL6 = (22<<3), /* reserved for local use */
+ LOG_LOCAL7 = (23<<3), /* reserved for local use */
+ }
+
+ /// <summary>
+ /// Write a message to the system logger, which in turn writes the message to the system console, log files, etc.
+ /// See man 3 syslog for more info
+ /// </summary>
+ /// <param name="priority">
+ /// The OR of a priority and facility in the SysLogPriority enum to declare the priority and facility of the log entry
+ /// </param>
+ /// <param name="message">The message to put in the log entry</param>
+ /// <param name="arg1">Like printf, the argument is passed to the variadic part of the C++ function to wildcards in the message</param>
+ [DllImport(Libraries.SystemNative, EntryPoint = "SystemNative_SysLog")]
+ internal static extern void SysLog(SysLogPriority priority, string message, string arg1);
+ }
+}
diff --git a/src/mscorlib/src/Interop/Windows/kernel32/Interop.OutputDebugString.cs b/src/mscorlib/src/Interop/Windows/kernel32/Interop.OutputDebugString.cs
new file mode 100644
index 0000000000..8da50ff8ab
--- /dev/null
+++ b/src/mscorlib/src/Interop/Windows/kernel32/Interop.OutputDebugString.cs
@@ -0,0 +1,14 @@
+// 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.
+
+using System.Runtime.InteropServices;
+
+internal partial class Interop
+{
+ internal partial class Kernel32
+ {
+ [DllImport(Interop.Libraries.Kernel32, CharSet = CharSet.Unicode, EntryPoint = "OutputDebugStringW", ExactSpelling = true)]
+ internal static extern void OutputDebugString(string message);
+ }
+}
diff --git a/src/mscorlib/src/Microsoft/Win32/RegistryKey.cs b/src/mscorlib/src/Microsoft/Win32/RegistryKey.cs
index 6524c2e435..521ea65e10 100644
--- a/src/mscorlib/src/Microsoft/Win32/RegistryKey.cs
+++ b/src/mscorlib/src/Microsoft/Win32/RegistryKey.cs
@@ -48,21 +48,13 @@
*/
-
+using Microsoft.Win32.SafeHandles;
using System;
-using System.Collections;
+using System.Buffers;
using System.Collections.Generic;
-using System.Security;
-using System.Text;
-using System.Threading;
-using System.IO;
-using System.Runtime.Remoting;
-using System.Runtime.InteropServices;
-using Microsoft.Win32.SafeHandles;
-using System.Runtime.Versioning;
-using System.Globalization;
using System.Diagnostics.Contracts;
-using System.Diagnostics.CodeAnalysis;
+using System.IO;
+using System.Text;
namespace Microsoft.Win32
{
@@ -228,7 +220,6 @@ namespace Microsoft.Win32
public void DeleteValue(String name, bool throwOnMissingValue)
{
EnsureWriteable();
- CheckPermission(RegistryInternalCheck.CheckValueWritePermission, name, false, RegistryKeyPermissionCheck.Default);
int errorCode = Win32Native.RegDeleteValue(hkey, name);
//
@@ -299,9 +290,8 @@ namespace Microsoft.Win32
{
ValidateKeyName(name);
EnsureNotDisposed();
- name = FixupName(name); // Fixup multiple slashes to a single slash
+ name = FixupName(name); // Fixup multiple slashes to a single slash
- CheckPermission(RegistryInternalCheck.CheckOpenSubKeyWithWritablePermission, name, writable, RegistryKeyPermissionCheck.Default);
SafeRegistryHandle result = null;
int ret = Win32Native.RegOpenKeyEx(hkey,
name,
@@ -363,144 +353,131 @@ namespace Microsoft.Win32
return OpenSubKey(name, false);
}
- internal int InternalSubKeyCount()
+ /// <summary>
+ /// Retrieves an array of strings containing all the subkey names.
+ /// </summary>
+ public string[] GetSubKeyNames()
{
EnsureNotDisposed();
- int subkeys = 0;
- int junk = 0;
- int ret = Win32Native.RegQueryInfoKey(hkey,
- null,
- null,
- IntPtr.Zero,
- ref subkeys, // subkeys
- null,
- null,
- ref junk, // values
- null,
- null,
- null,
- null);
-
- if (ret != 0)
- Win32Error(ret, null);
- return subkeys;
- }
+ var names = new List<string>();
+ char[] name = ArrayPool<char>.Shared.Rent(MaxKeyLength + 1);
- /**
- * Retrieves an array of strings containing all the subkey names.
- *
- * @return all subkey names.
- */
- public String[] GetSubKeyNames()
- {
- CheckPermission(RegistryInternalCheck.CheckKeyReadPermission, null, false, RegistryKeyPermissionCheck.Default);
- return InternalGetSubKeyNames();
- }
-
- internal unsafe String[] InternalGetSubKeyNames()
- {
- EnsureNotDisposed();
- int subkeys = InternalSubKeyCount();
- String[] names = new String[subkeys]; // Returns 0-length array if empty.
-
- if (subkeys > 0)
+ try
{
- char[] name = new char[MaxKeyLength + 1];
-
- int namelen;
-
- fixed (char* namePtr = &name[0])
+ int result;
+ int nameLength = name.Length;
+
+ while ((result = Win32Native.RegEnumKeyEx(
+ hkey,
+ names.Count,
+ name,
+ ref nameLength,
+ null,
+ null,
+ null,
+ null)) != Interop.Errors.ERROR_NO_MORE_ITEMS)
{
- for (int i = 0; i < subkeys; i++)
+ switch (result)
{
- namelen = name.Length; // Don't remove this. The API's doesn't work if this is not properly initialised.
- int ret = Win32Native.RegEnumKeyEx(hkey,
- i,
- namePtr,
- ref namelen,
- null,
- null,
- null,
- null);
- if (ret != 0)
- Win32Error(ret, null);
- names[i] = new String(namePtr);
+ case Interop.Errors.ERROR_SUCCESS:
+ names.Add(new string(name, 0, nameLength));
+ nameLength = name.Length;
+ break;
+ default:
+ // Throw the error
+ Win32Error(result, null);
+ break;
}
}
}
+ finally
+ {
+ ArrayPool<char>.Shared.Return(name);
+ }
- return names;
+ return names.ToArray();
}
- internal int InternalValueCount()
+ /// <summary>
+ /// Retrieves an array of strings containing all the value names.
+ /// </summary>
+ public unsafe string[] GetValueNames()
{
EnsureNotDisposed();
- int values = 0;
- int junk = 0;
- int ret = Win32Native.RegQueryInfoKey(hkey,
- null,
- null,
- IntPtr.Zero,
- ref junk, // subkeys
- null,
- null,
- ref values, // values
- null,
- null,
- null,
- null);
- if (ret != 0)
- Win32Error(ret, null);
- return values;
- }
+ var names = new List<string>();
- /**
- * Retrieves an array of strings containing all the value names.
- *
- * @return all value names.
- */
- public unsafe String[] GetValueNames()
- {
- CheckPermission(RegistryInternalCheck.CheckKeyReadPermission, null, false, RegistryKeyPermissionCheck.Default);
- EnsureNotDisposed();
+ // Names in the registry aren't usually very long, although they can go to as large
+ // as 16383 characters (MaxValueLength).
+ //
+ // Every call to RegEnumValue will allocate another buffer to get the data from
+ // NtEnumerateValueKey before copying it back out to our passed in buffer. This can
+ // add up quickly- we'll try to keep the memory pressure low and grow the buffer
+ // only if needed.
- int values = InternalValueCount();
- String[] names = new String[values];
+ char[] name = ArrayPool<char>.Shared.Rent(100);
- if (values > 0)
+ try
{
- char[] name = new char[MaxValueLength + 1];
- int namelen;
-
- fixed (char* namePtr = &name[0])
+ int result;
+ int nameLength = name.Length;
+
+ while ((result = Win32Native.RegEnumValue(
+ hkey,
+ names.Count,
+ name,
+ ref nameLength,
+ IntPtr.Zero,
+ null,
+ null,
+ null)) != Interop.Errors.ERROR_NO_MORE_ITEMS)
{
- for (int i = 0; i < values; i++)
+ switch (result)
{
- namelen = name.Length;
-
- int ret = Win32Native.RegEnumValue(hkey,
- i,
- namePtr,
- ref namelen,
- IntPtr.Zero,
- null,
- null,
- null);
-
- if (ret != 0)
- {
- // ignore ERROR_MORE_DATA if we're querying HKEY_PERFORMANCE_DATA
- if (!(IsPerfDataKey() && ret == Win32Native.ERROR_MORE_DATA))
- Win32Error(ret, null);
- }
-
- names[i] = new String(namePtr);
+ // The size is only ever reported back correctly in the case
+ // of ERROR_SUCCESS. It will almost always be changed, however.
+ case Interop.Errors.ERROR_SUCCESS:
+ names.Add(new string(name, 0, nameLength));
+ break;
+ case Interop.Errors.ERROR_MORE_DATA:
+ if (IsPerfDataKey())
+ {
+ // Enumerating the values for Perf keys always returns
+ // ERROR_MORE_DATA, but has a valid name. Buffer does need
+ // to be big enough however. 8 characters is the largest
+ // known name. The size isn't returned, but the string is
+ // null terminated.
+ fixed (char* c = &name[0])
+ {
+ names.Add(new string(c));
+ }
+ }
+ else
+ {
+ char[] oldName = name;
+ int oldLength = oldName.Length;
+ name = null;
+ ArrayPool<char>.Shared.Return(oldName);
+ name = ArrayPool<char>.Shared.Rent(checked(oldLength * 2));
+ }
+ break;
+ default:
+ // Throw the error
+ Win32Error(result, null);
+ break;
}
+
+ // Always set the name length back to the buffer size
+ nameLength = name.Length;
}
}
+ finally
+ {
+ if (name != null)
+ ArrayPool<char>.Shared.Return(name);
+ }
- return names;
+ return names.ToArray();
}
/**
@@ -516,7 +493,6 @@ namespace Microsoft.Win32
*/
public Object GetValue(String name)
{
- CheckPermission(RegistryInternalCheck.CheckValueReadPermission, name, false, RegistryKeyPermissionCheck.Default);
return InternalGetValue(name, null, false, true);
}
@@ -537,7 +513,6 @@ namespace Microsoft.Win32
*/
public Object GetValue(String name, Object defaultValue)
{
- CheckPermission(RegistryInternalCheck.CheckValueReadPermission, name, false, RegistryKeyPermissionCheck.Default);
return InternalGetValue(name, defaultValue, false, true);
}
@@ -548,7 +523,6 @@ namespace Microsoft.Win32
throw new ArgumentException(SR.Format(SR.Arg_EnumIllegalVal, (int)options), nameof(options));
}
bool doNotExpand = (options == RegistryValueOptions.DoNotExpandEnvironmentNames);
- CheckPermission(RegistryInternalCheck.CheckValueReadPermission, name, false, RegistryKeyPermissionCheck.Default);
return InternalGetValue(name, defaultValue, doNotExpand, true);
}
@@ -852,15 +826,6 @@ namespace Microsoft.Win32
EnsureWriteable();
- if (!remoteKey && ContainsRegistryValue(name))
- { // Existing key
- CheckPermission(RegistryInternalCheck.CheckValueWritePermission, name, false, RegistryKeyPermissionCheck.Default);
- }
- else
- { // Creating a new value
- CheckPermission(RegistryInternalCheck.CheckValueCreatePermission, name, false, RegistryKeyPermissionCheck.Default);
- }
-
if (valueKind == RegistryValueKind.Unknown)
{
// this is to maintain compatibility with the old way of autodetecting the type.
@@ -1137,11 +1102,6 @@ namespace Microsoft.Win32
}
}
- private void CheckPermission(RegistryInternalCheck check, string item, bool subKeyWritable, RegistryKeyPermissionCheck subKeyCheck)
- {
- // TODO: Cleanup
- }
-
private bool ContainsRegistryValue(string name)
{
int type = 0;
diff --git a/src/mscorlib/src/Microsoft/Win32/Win32Native.cs b/src/mscorlib/src/Microsoft/Win32/Win32Native.cs
index 840893701c..e751a63b25 100644
--- a/src/mscorlib/src/Microsoft/Win32/Win32Native.cs
+++ b/src/mscorlib/src/Microsoft/Win32/Win32Native.cs
@@ -834,13 +834,13 @@ namespace Microsoft.Win32
[DllImport(ADVAPI32, CharSet = CharSet.Auto, BestFitMapping = false)]
internal unsafe static extern int RegEnumKeyEx(SafeRegistryHandle hKey, int dwIndex,
- char* lpName, ref int lpcbName, int[] lpReserved,
+ char[] lpName, ref int lpcbName, int[] lpReserved,
[Out]StringBuilder lpClass, int[] lpcbClass,
long[] lpftLastWriteTime);
[DllImport(ADVAPI32, CharSet = CharSet.Auto, BestFitMapping = false)]
internal unsafe static extern int RegEnumValue(SafeRegistryHandle hKey, int dwIndex,
- char* lpValueName, ref int lpcbValueName,
+ char[] lpValueName, ref int lpcbValueName,
IntPtr lpReserved_MustBeZero, int[] lpType, byte[] lpData,
int[] lpcbData);
@@ -971,5 +971,15 @@ namespace Microsoft.Win32
#else
private const int BCRYPT_USE_SYSTEM_PREFERRED_RNG = 0x00000002;
#endif
+
+ internal const byte VER_GREATER_EQUAL = 0x3;
+ internal const uint VER_MAJORVERSION = 0x0000002;
+ internal const uint VER_MINORVERSION = 0x0000001;
+ internal const uint VER_SERVICEPACKMAJOR = 0x0000020;
+ internal const uint VER_SERVICEPACKMINOR = 0x0000010;
+ [DllImport("kernel32.dll")]
+ internal static extern bool VerifyVersionInfoW([In, Out] OSVERSIONINFOEX lpVersionInfo, uint dwTypeMask, ulong dwlConditionMask);
+ [DllImport("kernel32.dll")]
+ internal static extern ulong VerSetConditionMask(ulong dwlConditionMask, uint dwTypeBitMask, byte dwConditionMask);
}
}
diff --git a/src/mscorlib/src/System/AppDomain.cs b/src/mscorlib/src/System/AppDomain.cs
index 893389678d..7d2f2ceaf8 100644
--- a/src/mscorlib/src/System/AppDomain.cs
+++ b/src/mscorlib/src/System/AppDomain.cs
@@ -37,63 +37,6 @@ namespace System
using System.Diagnostics.Contracts;
using System.Runtime.ExceptionServices;
- public class ResolveEventArgs : EventArgs
- {
- private String _Name;
- private Assembly _RequestingAssembly;
-
- public String Name
- {
- get
- {
- return _Name;
- }
- }
-
- public Assembly RequestingAssembly
- {
- get
- {
- return _RequestingAssembly;
- }
- }
-
- public ResolveEventArgs(String name)
- {
- _Name = name;
- }
-
- public ResolveEventArgs(String name, Assembly requestingAssembly)
- {
- _Name = name;
- _RequestingAssembly = requestingAssembly;
- }
- }
-
- public class AssemblyLoadEventArgs : EventArgs
- {
- private Assembly _LoadedAssembly;
-
- public Assembly LoadedAssembly
- {
- get
- {
- return _LoadedAssembly;
- }
- }
-
- public AssemblyLoadEventArgs(Assembly loadedAssembly)
- {
- _LoadedAssembly = loadedAssembly;
- }
- }
-
- [Serializable]
- public delegate Assembly ResolveEventHandler(Object sender, ResolveEventArgs args);
-
- [Serializable]
- public delegate void AssemblyLoadEventHandler(Object sender, AssemblyLoadEventArgs args);
-
[Serializable]
internal delegate void AppDomainInitializer(string[] args);
diff --git a/src/mscorlib/src/System/AppDomainManager.cs b/src/mscorlib/src/System/AppDomainManager.cs
index 1c7fb08d98..830de29c16 100644
--- a/src/mscorlib/src/System/AppDomainManager.cs
+++ b/src/mscorlib/src/System/AppDomainManager.cs
@@ -55,10 +55,5 @@ namespace System
return AppDomain.CurrentDomain.DomainManager;
}
}
-
- public virtual bool CheckSecuritySettings(SecurityState state)
- {
- return false;
- }
}
}
diff --git a/src/mscorlib/src/System/AppDomainSetup.cs b/src/mscorlib/src/System/AppDomainSetup.cs
index 2529660670..907ac69e80 100644
--- a/src/mscorlib/src/System/AppDomainSetup.cs
+++ b/src/mscorlib/src/System/AppDomainSetup.cs
@@ -52,7 +52,6 @@ namespace System
// Constants from fusionsetup.h.
private const string LOADER_OPTIMIZATION = "LOADER_OPTIMIZATION";
- private const string CONFIGURATION_EXTENSION = ".config";
private const string ACTAG_APP_BASE_URL = "APPBASE";
@@ -131,7 +130,7 @@ namespace System
else
_AppDomainInitializer = null;
- _ConfigurationBytes = copy.GetConfigurationBytes();
+ _ConfigurationBytes = null;
#if FEATURE_COMINTEROP
_DisableInterfaceCache = copy._DisableInterfaceCache;
#endif // FEATURE_COMINTEROP
@@ -178,7 +177,6 @@ namespace System
else
ApplicationBase = appBase;
}
- ConfigurationFile = ApplicationName + AppDomainSetup.ConfigurationExtension;
}
internal string[] Value
@@ -191,11 +189,6 @@ namespace System
}
}
- internal String GetUnsecureApplicationBase()
- {
- return Value[(int)LoaderInformation.ApplicationBaseValue];
- }
-
public string AppDomainManagerAssembly
{
get { return _AppDomainManagerAssembly; }
@@ -213,246 +206,15 @@ namespace System
[Pure]
get
{
- return VerifyDir(GetUnsecureApplicationBase(), false);
+ return Value[(int)LoaderInformation.ApplicationBaseValue];
}
set
{
- Value[(int)LoaderInformation.ApplicationBaseValue] = NormalizePath(value, false);
+ Value[(int)LoaderInformation.ApplicationBaseValue] = (value == null || value.Length == 0)?null:Path.GetFullPath(value);
}
}
-
- private String NormalizePath(String path, bool useAppBase)
- {
- if (path == null)
- return null;
-
- // If we add very long file name support ("\\?\") to the Path class then this is unnecesary,
- // but we do not plan on doing this for now.
-
- // Long path checks can be quirked, and as loading default quirks too early in the setup of an AppDomain is risky
- // we'll avoid checking path lengths- we'll still fail at MAX_PATH later if we're !useAppBase when we call Path's
- // NormalizePath.
- if (!useAppBase)
- path = Security.Util.URLString.PreProcessForExtendedPathRemoval(
- checkPathLength: false,
- url: path,
- isFileUrl: false);
-
-
- int len = path.Length;
- if (len == 0)
- return null;
-
-#if !PLATFORM_UNIX
- bool UNCpath = false;
-#endif // !PLATFORM_UNIX
-
- if ((len > 7) &&
- (String.Compare(path, 0, "file:", 0, 5, StringComparison.OrdinalIgnoreCase) == 0))
- {
- int trim;
-
- if (path[6] == '\\')
- {
- if ((path[7] == '\\') || (path[7] == '/'))
- {
- // Don't allow "file:\\\\", because we can't tell the difference
- // with it for "file:\\" + "\\server" and "file:\\\" + "\localpath"
- if ((len > 8) &&
- ((path[8] == '\\') || (path[8] == '/')))
- throw new ArgumentException(SR.Argument_InvalidPathChars);
-
- // file:\\\ means local path
- else
-#if !PLATFORM_UNIX
- trim = 8;
-#else
- // For Unix platform, trim the first 7 characters only.
- // Trimming the first 8 characters will cause
- // the root path separator to be trimmed away,
- // and the absolute local path becomes a relative local path.
- trim = 7;
-#endif // !PLATFORM_UNIX
- }
-
- // file:\\ means remote server
- else
- {
- trim = 5;
-#if !PLATFORM_UNIX
- UNCpath = true;
-#endif // !PLATFORM_UNIX
- }
- }
-
- // local path
- else if (path[7] == '/')
-#if !PLATFORM_UNIX
- trim = 8;
-#else
- // For Unix platform, trim the first 7 characters only.
- // Trimming the first 8 characters will cause
- // the root path separator to be trimmed away,
- // and the absolute local path becomes a relative local path.
- trim = 7;
-#endif // !PLATFORM_UNIX
-
- // remote
- else
- {
- // file://\\remote
- if ((len > 8) && (path[7] == '\\') && (path[8] == '\\'))
- trim = 7;
- else
- { // file://remote
- trim = 5;
-#if !PLATFORM_UNIX
- // Create valid UNC path by changing
- // all occurences of '/' to '\\' in path
- System.Text.StringBuilder winPathBuilder =
- new System.Text.StringBuilder(len);
- for (int i = 0; i < len; i++)
- {
- char c = path[i];
- if (c == '/')
- winPathBuilder.Append('\\');
- else
- winPathBuilder.Append(c);
- }
- path = winPathBuilder.ToString();
-#endif // !PLATFORM_UNIX
- }
-#if !PLATFORM_UNIX
- UNCpath = true;
-#endif // !PLATFORM_UNIX
- }
-
- path = path.Substring(trim);
- len -= trim;
- }
-
-#if !PLATFORM_UNIX
- bool localPath;
-
- // UNC
- if (UNCpath ||
- ((len > 1) &&
- ((path[0] == '/') || (path[0] == '\\')) &&
- ((path[1] == '/') || (path[1] == '\\'))))
- localPath = false;
-
- else
- {
- int colon = path.IndexOf(':') + 1;
-
- // protocol other than file:
- if ((colon != 0) &&
- (len > colon + 1) &&
- ((path[colon] == '/') || (path[colon] == '\\')) &&
- ((path[colon + 1] == '/') || (path[colon + 1] == '\\')))
- localPath = false;
-
- else
- localPath = true;
- }
-
- if (localPath)
-#else
- if ( (len == 1) ||
- ( (path[0] != '/') && (path[0] != '\\') ) )
-#endif // !PLATFORM_UNIX
- {
- if (useAppBase &&
- ((len == 1) || (path[1] != ':')))
- {
- String appBase = Value[(int)LoaderInformation.ApplicationBaseValue];
-
- if ((appBase == null) || (appBase.Length == 0))
- throw new MemberAccessException(SR.AppDomain_AppBaseNotSet);
-
- StringBuilder result = StringBuilderCache.Acquire();
-
- bool slash = false;
- if ((path[0] == '/') || (path[0] == '\\'))
- {
- string pathRoot = AppDomain.NormalizePath(appBase, fullCheck: false);
- pathRoot = pathRoot.Substring(0, IO.PathInternal.GetRootLength(pathRoot));
-
- if (pathRoot.Length == 0)
- { // URL
- int index = appBase.IndexOf(":/", StringComparison.Ordinal);
- if (index == -1)
- index = appBase.IndexOf(":\\", StringComparison.Ordinal);
-
- // Get past last slashes of "url:http://"
- int urlLen = appBase.Length;
- for (index += 1;
- (index < urlLen) && ((appBase[index] == '/') || (appBase[index] == '\\'));
- index++) ;
-
- // Now find the next slash to get domain name
- for (; (index < urlLen) && (appBase[index] != '/') && (appBase[index] != '\\');
- index++) ;
-
- pathRoot = appBase.Substring(0, index);
- }
-
- result.Append(pathRoot);
- slash = true;
- }
- else
- result.Append(appBase);
-
- // Make sure there's a slash separator (and only one)
- int aLen = result.Length - 1;
- if ((result[aLen] != '/') &&
- (result[aLen] != '\\'))
- {
- if (!slash)
- {
-#if !PLATFORM_UNIX
- if (appBase.IndexOf(":/", StringComparison.Ordinal) == -1)
- result.Append('\\');
- else
-#endif // !PLATFORM_UNIX
- result.Append('/');
- }
- }
- else if (slash)
- result.Remove(aLen, 1);
-
- result.Append(path);
- path = StringBuilderCache.GetStringAndRelease(result);
- }
- else
- path = AppDomain.NormalizePath(path, fullCheck: true);
- }
-
- return path;
- }
-
- public String ConfigurationFile
- {
- get
- {
- return VerifyDir(Value[(int)LoaderInformation.ConfigurationFileValue], true);
- }
-
- set
- {
- Value[(int)LoaderInformation.ConfigurationFileValue] = value;
- }
- }
-
- public byte[] GetConfigurationBytes()
- {
- if (_ConfigurationBytes == null)
- return null;
-
- return (byte[])_ConfigurationBytes.Clone();
- }
-
+
// only needed by AppDomain.Setup(). Not really needed by users.
internal Dictionary<string, object> GetCompatibilityFlags()
{
@@ -497,22 +259,6 @@ namespace System
}
}
- private String VerifyDir(String dir, bool normalize)
- {
- if (dir != null)
- {
- if (dir.Length == 0)
- dir = null;
- else
- {
- if (normalize)
- dir = NormalizePath(dir, true);
- }
- }
-
- return dir;
- }
-
public String ApplicationName
{
get
@@ -594,14 +340,6 @@ namespace System
}
}
- internal static string ConfigurationExtension
- {
- get
- {
- return CONFIGURATION_EXTENSION;
- }
- }
-
static internal int Locate(String s)
{
if (String.IsNullOrEmpty(s))
diff --git a/src/mscorlib/src/System/ArraySegment.cs b/src/mscorlib/src/System/ArraySegment.cs
index 1e127e3a17..e0118c2cbf 100644
--- a/src/mscorlib/src/System/ArraySegment.cs
+++ b/src/mscorlib/src/System/ArraySegment.cs
@@ -15,6 +15,7 @@
using System.Collections;
using System.Collections.Generic;
+using System.Diagnostics;
using System.Diagnostics.Contracts;
namespace System
diff --git a/src/mscorlib/src/System/CurrentSystemTimeZone.Cache.cs b/src/mscorlib/src/System/CurrentSystemTimeZone.Cache.cs
new file mode 100644
index 0000000000..744c697124
--- /dev/null
+++ b/src/mscorlib/src/System/CurrentSystemTimeZone.Cache.cs
@@ -0,0 +1,35 @@
+// 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.
+
+using System.Collections;
+using System.Globalization;
+
+namespace System
+{
+ internal partial class CurrentSystemTimeZone
+ {
+ private DaylightTime GetCachedDaylightChanges(int year)
+ {
+ Object objYear = (Object)year;
+
+ if (!m_CachedDaylightChanges.Contains(objYear))
+ {
+ DaylightTime currentDaylightChanges = CreateDaylightChanges(year);
+ lock (m_CachedDaylightChanges)
+ {
+ if (!m_CachedDaylightChanges.Contains(objYear))
+ {
+ m_CachedDaylightChanges.Add(objYear, currentDaylightChanges);
+ }
+ }
+ }
+
+ return (DaylightTime)m_CachedDaylightChanges[objYear];
+ }
+
+ // The per-year information is cached in in this instance value. As a result it can
+ // be cleaned up by CultureInfo.ClearCachedData, which will clear the instance of this object
+ private readonly Hashtable m_CachedDaylightChanges = new Hashtable();
+ }
+}
diff --git a/src/mscorlib/src/System/Diagnostics/Debug.Unix.cs b/src/mscorlib/src/System/Diagnostics/Debug.Unix.cs
new file mode 100644
index 0000000000..495f2f713c
--- /dev/null
+++ b/src/mscorlib/src/System/Diagnostics/Debug.Unix.cs
@@ -0,0 +1,95 @@
+// 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.
+
+using Microsoft.Win32.SafeHandles;
+
+namespace System.Diagnostics
+{
+ public static partial class Debug
+ {
+ private static readonly bool s_shouldWriteToStdErr = Environment.GetEnvironmentVariable("COMPlus_DebugWriteToStdErr") == "1";
+
+ private static void ShowAssertDialog(string stackTrace, string message, string detailMessage)
+ {
+ if (Debugger.IsAttached)
+ {
+ Debugger.Break();
+ }
+ else
+ {
+ // In Core, we do not show a dialog.
+ // Fail in order to avoid anyone catching an exception and masking
+ // an assert failure.
+ var ex = new DebugAssertException(message, detailMessage, stackTrace);
+ Environment.FailFast(ex.Message, ex);
+ }
+ }
+
+ private static void WriteCore(string message)
+ {
+ WriteToDebugger(message);
+
+ if (s_shouldWriteToStdErr)
+ {
+ WriteToStderr(message);
+ }
+ }
+
+ private static void WriteToDebugger(string message)
+ {
+ if (Debugger.IsLogging())
+ {
+ Debugger.Log(0, null, message);
+ }
+ else
+ {
+ Interop.Sys.SysLog(Interop.Sys.SysLogPriority.LOG_USER | Interop.Sys.SysLogPriority.LOG_DEBUG, "%s", message);
+ }
+ }
+
+ private static void WriteToStderr(string message)
+ {
+ // We don't want to write UTF-16 to a file like standard error. Ideally we would transcode this
+ // to UTF8, but the downside of that is it pulls in a bunch of stuff into what is ideally
+ // a path with minimal dependencies (as to prevent re-entrency), so we'll take the strategy
+ // of just throwing away any non ASCII characters from the message and writing the rest
+
+ const int BufferLength = 256;
+
+ unsafe
+ {
+ byte* buf = stackalloc byte[BufferLength];
+ int bufCount;
+ int i = 0;
+
+ while (i < message.Length)
+ {
+ for (bufCount = 0; bufCount < BufferLength && i < message.Length; i++)
+ {
+ if (message[i] <= 0x7F)
+ {
+ buf[bufCount] = (byte)message[i];
+ bufCount++;
+ }
+ }
+
+ int totalBytesWritten = 0;
+ while (bufCount > 0)
+ {
+ int bytesWritten = Interop.Sys.Write(2 /* stderr */, buf + totalBytesWritten, bufCount);
+ if (bytesWritten < 0)
+ {
+ // On error, simply stop writing the debug output. This could commonly happen if stderr
+ // was piped to a program that ended before this program did, resulting in EPIPE errors.
+ return;
+ }
+
+ bufCount -= bytesWritten;
+ totalBytesWritten += bytesWritten;
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/src/mscorlib/src/System/Diagnostics/Debug.Windows.cs b/src/mscorlib/src/System/Diagnostics/Debug.Windows.cs
new file mode 100644
index 0000000000..095e9b6985
--- /dev/null
+++ b/src/mscorlib/src/System/Diagnostics/Debug.Windows.cs
@@ -0,0 +1,63 @@
+// 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.
+
+namespace System.Diagnostics
+{
+ public static partial class Debug
+ {
+ private static void ShowAssertDialog(string stackTrace, string message, string detailMessage)
+ {
+ if (Debugger.IsAttached)
+ {
+ Debugger.Break();
+ }
+ else
+ {
+ // In Core, we do not show a dialog.
+ // Fail in order to avoid anyone catching an exception and masking
+ // an assert failure.
+ var ex = new DebugAssertException(message, detailMessage, stackTrace);
+ Environment.FailFast(ex.Message, ex);
+ }
+ }
+
+ private static void WriteCore(string message)
+ {
+ // really huge messages mess up both VS and dbmon, so we chop it up into
+ // reasonable chunks if it's too big. This is the number of characters
+ // that OutputDebugstring chunks at.
+ const int WriteChunkLength = 4091;
+
+ // We don't want output from multiple threads to be interleaved.
+ lock (s_ForLock)
+ {
+ if (message == null || message.Length <= WriteChunkLength)
+ {
+ WriteToDebugger(message);
+ }
+ else
+ {
+ int offset;
+ for (offset = 0; offset < message.Length - WriteChunkLength; offset += WriteChunkLength)
+ {
+ WriteToDebugger(message.Substring(offset, WriteChunkLength));
+ }
+ WriteToDebugger(message.Substring(offset));
+ }
+ }
+ }
+
+ private static void WriteToDebugger(string message)
+ {
+ if (Debugger.IsLogging())
+ {
+ Debugger.Log(0, null, message);
+ }
+ else
+ {
+ Interop.Kernel32.OutputDebugString(message ?? string.Empty);
+ }
+ }
+ }
+}
diff --git a/src/mscorlib/src/System/Diagnostics/Debug.cs b/src/mscorlib/src/System/Diagnostics/Debug.cs
new file mode 100644
index 0000000000..59f3c378da
--- /dev/null
+++ b/src/mscorlib/src/System/Diagnostics/Debug.cs
@@ -0,0 +1,323 @@
+// 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.
+
+// Do not remove this, it is needed to retain calls to these conditional methods in release builds
+#define DEBUG
+
+namespace System.Diagnostics
+{
+ /// <summary>
+ /// Provides a set of properties and methods for debugging code.
+ /// </summary>
+ public static partial class Debug
+ {
+ private static readonly object s_lock = new object();
+
+ public static bool AutoFlush { get { return true; } set { } }
+
+ [ThreadStatic]
+ private static int s_indentLevel;
+ public static int IndentLevel
+ {
+ get
+ {
+ return s_indentLevel;
+ }
+ set
+ {
+ s_indentLevel = value < 0 ? 0 : value;
+ }
+ }
+
+ private static int s_indentSize = 4;
+ public static int IndentSize
+ {
+ get
+ {
+ return s_indentSize;
+ }
+ set
+ {
+ s_indentSize = value < 0 ? 0 : value;
+ }
+ }
+
+ [System.Diagnostics.Conditional("DEBUG")]
+ public static void Close() { }
+
+ [System.Diagnostics.Conditional("DEBUG")]
+ public static void Flush() { }
+
+ [System.Diagnostics.Conditional("DEBUG")]
+ public static void Indent()
+ {
+ IndentLevel++;
+ }
+
+ [System.Diagnostics.Conditional("DEBUG")]
+ public static void Unindent()
+ {
+ IndentLevel--;
+ }
+
+ [System.Diagnostics.Conditional("DEBUG")]
+ public static void Print(string message)
+ {
+ Write(message);
+ }
+
+ [System.Diagnostics.Conditional("DEBUG")]
+ public static void Print(string format, params object[] args)
+ {
+ Write(string.Format(null, format, args));
+ }
+
+ private static readonly object s_ForLock = new Object();
+
+ [System.Diagnostics.Conditional("DEBUG")]
+ public static void Assert(bool condition)
+ {
+ Assert(condition, string.Empty, string.Empty);
+ }
+
+ [System.Diagnostics.Conditional("DEBUG")]
+ public static void Assert(bool condition, string message)
+ {
+ Assert(condition, message, string.Empty);
+ }
+
+ [System.Diagnostics.Conditional("DEBUG")]
+ public static void Assert(bool condition, string message, string detailMessage)
+ {
+ if (!condition)
+ {
+ string stackTrace;
+
+ try
+ {
+ stackTrace = Internal.Runtime.Augments.EnvironmentAugments.StackTrace;
+ }
+ catch
+ {
+ stackTrace = "";
+ }
+
+ WriteLine(FormatAssert(stackTrace, message, detailMessage));
+ s_ShowAssertDialog(stackTrace, message, detailMessage);
+ }
+ }
+
+ [System.Diagnostics.Conditional("DEBUG")]
+ public static void Fail(string message)
+ {
+ Assert(false, message, string.Empty);
+ }
+
+ [System.Diagnostics.Conditional("DEBUG")]
+ public static void Fail(string message, string detailMessage)
+ {
+ Assert(false, message, detailMessage);
+ }
+
+ private static string FormatAssert(string stackTrace, string message, string detailMessage)
+ {
+ string newLine = GetIndentString() + Environment.NewLine;
+ return SR.DebugAssertBanner + newLine
+ + SR.DebugAssertShortMessage + newLine
+ + message + newLine
+ + SR.DebugAssertLongMessage + newLine
+ + detailMessage + newLine
+ + stackTrace;
+ }
+
+ [System.Diagnostics.Conditional("DEBUG")]
+ public static void Assert(bool condition, string message, string detailMessageFormat, params object[] args)
+ {
+ Assert(condition, message, string.Format(detailMessageFormat, args));
+ }
+
+ [System.Diagnostics.Conditional("DEBUG")]
+ public static void WriteLine(string message)
+ {
+ Write(message + Environment.NewLine);
+ }
+
+ [System.Diagnostics.Conditional("DEBUG")]
+ public static void Write(string message)
+ {
+ lock (s_lock)
+ {
+ if (message == null)
+ {
+ s_WriteCore(string.Empty);
+ return;
+ }
+ if (s_needIndent)
+ {
+ message = GetIndentString() + message;
+ s_needIndent = false;
+ }
+ s_WriteCore(message);
+ if (message.EndsWith(Environment.NewLine))
+ {
+ s_needIndent = true;
+ }
+ }
+ }
+
+ [System.Diagnostics.Conditional("DEBUG")]
+ public static void WriteLine(object value)
+ {
+ WriteLine(value?.ToString());
+ }
+
+ [System.Diagnostics.Conditional("DEBUG")]
+ public static void WriteLine(object value, string category)
+ {
+ WriteLine(value?.ToString(), category);
+ }
+
+ [System.Diagnostics.Conditional("DEBUG")]
+ public static void WriteLine(string format, params object[] args)
+ {
+ WriteLine(string.Format(null, format, args));
+ }
+
+ [System.Diagnostics.Conditional("DEBUG")]
+ public static void WriteLine(string message, string category)
+ {
+ if (category == null)
+ {
+ WriteLine(message);
+ }
+ else
+ {
+ WriteLine(category + ":" + message);
+ }
+ }
+
+ [System.Diagnostics.Conditional("DEBUG")]
+ public static void Write(object value)
+ {
+ Write(value?.ToString());
+ }
+
+ [System.Diagnostics.Conditional("DEBUG")]
+ public static void Write(string message, string category)
+ {
+ if (category == null)
+ {
+ Write(message);
+ }
+ else
+ {
+ Write(category + ":" + message);
+ }
+ }
+
+ [System.Diagnostics.Conditional("DEBUG")]
+ public static void Write(object value, string category)
+ {
+ Write(value?.ToString(), category);
+ }
+
+ [System.Diagnostics.Conditional("DEBUG")]
+ public static void WriteIf(bool condition, string message)
+ {
+ if (condition)
+ {
+ Write(message);
+ }
+ }
+
+ [System.Diagnostics.Conditional("DEBUG")]
+ public static void WriteIf(bool condition, object value)
+ {
+ if (condition)
+ {
+ Write(value);
+ }
+ }
+
+ [System.Diagnostics.Conditional("DEBUG")]
+ public static void WriteIf(bool condition, string message, string category)
+ {
+ if (condition)
+ {
+ Write(message, category);
+ }
+ }
+
+ [System.Diagnostics.Conditional("DEBUG")]
+ public static void WriteIf(bool condition, object value, string category)
+ {
+ if (condition)
+ {
+ Write(value, category);
+ }
+ }
+
+ [System.Diagnostics.Conditional("DEBUG")]
+ public static void WriteLineIf(bool condition, object value)
+ {
+ if (condition)
+ {
+ WriteLine(value);
+ }
+ }
+
+ [System.Diagnostics.Conditional("DEBUG")]
+ public static void WriteLineIf(bool condition, object value, string category)
+ {
+ if (condition)
+ {
+ WriteLine(value, category);
+ }
+ }
+
+ [System.Diagnostics.Conditional("DEBUG")]
+ public static void WriteLineIf(bool condition, string message)
+ {
+ if (condition)
+ {
+ WriteLine(message);
+ }
+ }
+
+ [System.Diagnostics.Conditional("DEBUG")]
+ public static void WriteLineIf(bool condition, string message, string category)
+ {
+ if (condition)
+ {
+ WriteLine(message, category);
+ }
+ }
+
+ private static bool s_needIndent;
+
+ private static string s_indentString;
+
+ private static string GetIndentString()
+ {
+ int indentCount = IndentSize * IndentLevel;
+ if (s_indentString?.Length == indentCount)
+ {
+ return s_indentString;
+ }
+ return s_indentString = new string(' ', indentCount);
+ }
+
+ private sealed class DebugAssertException : Exception
+ {
+ internal DebugAssertException(string message, string detailMessage, string stackTrace) :
+ base(message + Environment.NewLine + detailMessage + Environment.NewLine + stackTrace)
+ {
+ }
+ }
+
+ // internal and not readonly so that the tests can swap this out.
+ internal static Action<string, string, string> s_ShowAssertDialog = ShowAssertDialog;
+ internal static Action<string> s_WriteCore = WriteCore;
+ }
+}
diff --git a/src/mscorlib/src/System/Diagnostics/Eventing/EventSource.cs b/src/mscorlib/src/System/Diagnostics/Eventing/EventSource.cs
index 3668d8cb64..1d5830ceb6 100644
--- a/src/mscorlib/src/System/Diagnostics/Eventing/EventSource.cs
+++ b/src/mscorlib/src/System/Diagnostics/Eventing/EventSource.cs
@@ -1470,8 +1470,7 @@ namespace System.Diagnostics.Tracing
#if (!ES_BUILD_STANDALONE && !PROJECTN)
// API available on OS >= Win 8 and patched Win 7.
// Disable only for FrameworkEventSource to avoid recursion inside exception handling.
- var osVer = Environment.OSVersion.Version.Major * 10 + Environment.OSVersion.Version.Minor;
- if (this.Name != "System.Diagnostics.Eventing.FrameworkEventSource" || osVer >= 62)
+ if (this.Name != "System.Diagnostics.Eventing.FrameworkEventSource" || Environment.IsWindows8OrAbove)
#endif
{
int setInformationResult;
diff --git a/src/mscorlib/src/System/Enum.cs b/src/mscorlib/src/System/Enum.cs
index 2403b6ad73..489f36739c 100644
--- a/src/mscorlib/src/System/Enum.cs
+++ b/src/mscorlib/src/System/Enum.cs
@@ -688,7 +688,7 @@ namespace System
char formatCh = format[0];
if (formatCh == 'G' || formatCh == 'g')
- return GetEnumName(rtType, ToUInt64(value));
+ return GetEnumName(rtType, ToUInt64(value)) ?? value.ToString();
if (formatCh == 'D' || formatCh == 'd')
return value.ToString();
diff --git a/src/mscorlib/src/System/Environment.cs b/src/mscorlib/src/System/Environment.cs
index 453583b888..062e5d95d6 100644
--- a/src/mscorlib/src/System/Environment.cs
+++ b/src/mscorlib/src/System/Environment.cs
@@ -361,69 +361,38 @@ namespace System
}
}
- /*==================================OSVersion===================================
- **Action:
- **Returns:
- **Arguments:
- **Exceptions:
- ==============================================================================*/
- internal static OperatingSystem OSVersion
- {
- get
- {
- Contract.Ensures(Contract.Result<OperatingSystem>() != null);
-
- if (m_os == null)
- { // We avoid the lock since we don't care if two threads will set this at the same time.
- Microsoft.Win32.Win32Native.OSVERSIONINFO osvi = new Microsoft.Win32.Win32Native.OSVERSIONINFO();
- if (!GetVersion(osvi))
- {
- throw new InvalidOperationException(SR.InvalidOperation_GetVersion);
- }
-
- Microsoft.Win32.Win32Native.OSVERSIONINFOEX osviEx = new Microsoft.Win32.Win32Native.OSVERSIONINFOEX();
- if (!GetVersionEx(osviEx))
- throw new InvalidOperationException(SR.InvalidOperation_GetVersion);
-
-#if PLATFORM_UNIX
- PlatformID id = PlatformID.Unix;
-#else
- PlatformID id = PlatformID.Win32NT;
-#endif // PLATFORM_UNIX
-
- Version v = new Version(osvi.MajorVersion, osvi.MinorVersion, osvi.BuildNumber, (osviEx.ServicePackMajor << 16) | osviEx.ServicePackMinor);
- m_os = new OperatingSystem(id, v, osvi.CSDVersion);
- }
- Debug.Assert(m_os != null, "m_os != null");
- return m_os;
- }
- }
-
-
- internal static bool IsWindows8OrAbove
- {
- get
- {
- return true;
- }
- }
-
+#if !FEATURE_PAL
+ private static Lazy<bool> s_IsWindows8OrAbove = new Lazy<bool>(() =>
+ {
+ ulong conditionMask = Win32Native.VerSetConditionMask(0, Win32Native.VER_MAJORVERSION, Win32Native.VER_GREATER_EQUAL);
+ conditionMask = Win32Native.VerSetConditionMask(conditionMask, Win32Native.VER_MINORVERSION, Win32Native.VER_GREATER_EQUAL);
+ conditionMask = Win32Native.VerSetConditionMask(conditionMask, Win32Native.VER_SERVICEPACKMAJOR, Win32Native.VER_GREATER_EQUAL);
+ conditionMask = Win32Native.VerSetConditionMask(conditionMask, Win32Native.VER_SERVICEPACKMINOR, Win32Native.VER_GREATER_EQUAL);
+
+ // Windows 8 version is 6.2
+ var version = new Win32Native.OSVERSIONINFOEX { MajorVersion = 6, MinorVersion = 2, ServicePackMajor = 0, ServicePackMinor = 0 };
+
+ return Win32Native.VerifyVersionInfoW(version,
+ Win32Native.VER_MAJORVERSION | Win32Native.VER_MINORVERSION | Win32Native.VER_SERVICEPACKMAJOR | Win32Native.VER_SERVICEPACKMINOR,
+ conditionMask);
+ });
+ internal static bool IsWindows8OrAbove => s_IsWindows8OrAbove.Value;
+#endif
+
#if FEATURE_COMINTEROP
- internal static bool IsWinRTSupported
+ // Does the current version of Windows have Windows Runtime suppport?
+ private static Lazy<bool> s_IsWinRTSupported = new Lazy<bool>(() =>
{
- get
- {
- return true;
- }
- }
-#endif // FEATURE_COMINTEROP
-
+ return WinRTSupported();
+ });
- [MethodImplAttribute(MethodImplOptions.InternalCall)]
- internal static extern bool GetVersion(Microsoft.Win32.Win32Native.OSVERSIONINFO osVer);
+ internal static bool IsWinRTSupported => s_IsWinRTSupported.Value;
- [MethodImplAttribute(MethodImplOptions.InternalCall)]
- internal static extern bool GetVersionEx(Microsoft.Win32.Win32Native.OSVERSIONINFOEX osVer);
+ [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
+ [SuppressUnmanagedCodeSecurity]
+ [return: MarshalAs(UnmanagedType.Bool)]
+ private static extern bool WinRTSupported();
+#endif // FEATURE_COMINTEROP
/*==================================StackTrace==================================
diff --git a/src/mscorlib/src/System/Globalization/Calendar.cs b/src/mscorlib/src/System/Globalization/Calendar.cs
index 422b72a46b..c23e1088c1 100644
--- a/src/mscorlib/src/System/Globalization/Calendar.cs
+++ b/src/mscorlib/src/System/Globalization/Calendar.cs
@@ -839,7 +839,7 @@ namespace System.Globalization
CultureInfo.InvariantCulture,
SR.Format(SR.ArgumentOutOfRange_Range, 0, MillisPerSecond - 1)));
}
- return InternalGloablizationHelper.TimeToTicks(hour, minute, second) + millisecond * TicksPerMillisecond;
+ return InternalGlobalizationHelper.TimeToTicks(hour, minute, second) + millisecond * TicksPerMillisecond;
}
throw new ArgumentOutOfRangeException(null, SR.ArgumentOutOfRange_BadHourMinuteSecond);
}
diff --git a/src/mscorlib/src/System/Globalization/CalendarData.Windows.cs b/src/mscorlib/src/System/Globalization/CalendarData.Windows.cs
index 206d0779f3..51a2727c7d 100644
--- a/src/mscorlib/src/System/Globalization/CalendarData.Windows.cs
+++ b/src/mscorlib/src/System/Globalization/CalendarData.Windows.cs
@@ -3,6 +3,7 @@
// See the LICENSE file in the project root for more information.
using System;
+using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Runtime.CompilerServices;
using System.Diagnostics.Contracts;
diff --git a/src/mscorlib/src/System/Globalization/CultureInfo.Unix.cs b/src/mscorlib/src/System/Globalization/CultureInfo.Unix.cs
index 4d98dd62b7..7a8a9fd08d 100644
--- a/src/mscorlib/src/System/Globalization/CultureInfo.Unix.cs
+++ b/src/mscorlib/src/System/Globalization/CultureInfo.Unix.cs
@@ -2,6 +2,7 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
+using System.Diagnostics;
using System.Threading;
namespace System.Globalization
diff --git a/src/mscorlib/src/System/Globalization/CultureInfo.Windows.cs b/src/mscorlib/src/System/Globalization/CultureInfo.Windows.cs
index 827330b45d..e33874e760 100644
--- a/src/mscorlib/src/System/Globalization/CultureInfo.Windows.cs
+++ b/src/mscorlib/src/System/Globalization/CultureInfo.Windows.cs
@@ -2,6 +2,8 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
+using System.Diagnostics;
+
#if ENABLE_WINRT
using Internal.Runtime.Augments;
#endif
diff --git a/src/mscorlib/src/System/Globalization/CultureTypes.cs b/src/mscorlib/src/System/Globalization/CultureTypes.cs
deleted file mode 100644
index 10d92465d1..0000000000
--- a/src/mscorlib/src/System/Globalization/CultureTypes.cs
+++ /dev/null
@@ -1,28 +0,0 @@
-// 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.
-
-// The enumeration constants used in CultureInfo.GetCultures().
-// On Linux platforms, the only enum values used there is NeutralCultures and SpecificCultures
-// the rest are obsolete or not valid on Linux
-
-namespace System.Globalization
-{
- [Serializable]
- [Flags]
- public enum CultureTypes
- {
- NeutralCultures = 0x0001, // Neutral cultures are cultures like "en", "de", "zh", etc, for enumeration this includes ALL neutrals regardless of other flags
- SpecificCultures = 0x0002, // Non-netural cultuers. Examples are "en-us", "zh-tw", etc., for enumeration this includes ALL specifics regardless of other flags
- InstalledWin32Cultures = 0x0004, // Win32 installed cultures in the system and exists in the framework too., this is effectively all cultures
-
- AllCultures = NeutralCultures | SpecificCultures | InstalledWin32Cultures,
-
- UserCustomCulture = 0x0008, // User defined custom culture
- ReplacementCultures = 0x0010, // User defined replacement custom culture.
- [Obsolete("This value has been deprecated. Please use other values in CultureTypes.")]
- WindowsOnlyCultures = 0x0020, // this will always return empty list.
- [Obsolete("This value has been deprecated. Please use other values in CultureTypes.")]
- FrameworkCultures = 0x0040, // will return only the v2 cultures marked as Framework culture.
- }
-}
diff --git a/src/mscorlib/src/System/Globalization/GregorianCalendarHelper.cs b/src/mscorlib/src/System/Globalization/GregorianCalendarHelper.cs
index ee8ba13894..bdc35f0734 100644
--- a/src/mscorlib/src/System/Globalization/GregorianCalendarHelper.cs
+++ b/src/mscorlib/src/System/Globalization/GregorianCalendarHelper.cs
@@ -315,7 +315,7 @@ namespace System.Globalization
0,
MillisPerSecond - 1));
}
- return (InternalGloablizationHelper.TimeToTicks(hour, minute, second) + millisecond * TicksPerMillisecond); ;
+ return (InternalGlobalizationHelper.TimeToTicks(hour, minute, second) + millisecond * TicksPerMillisecond); ;
}
throw new ArgumentOutOfRangeException(null, SR.ArgumentOutOfRange_BadHourMinuteSecond);
}
diff --git a/src/mscorlib/src/System/Globalization/IdnMapping.Unix.cs b/src/mscorlib/src/System/Globalization/IdnMapping.Unix.cs
index aab957a62a..f1ad6f1d0a 100644
--- a/src/mscorlib/src/System/Globalization/IdnMapping.Unix.cs
+++ b/src/mscorlib/src/System/Globalization/IdnMapping.Unix.cs
@@ -2,6 +2,8 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
+using System.Diagnostics;
+
namespace System.Globalization
{
sealed partial class IdnMapping
diff --git a/src/mscorlib/src/System/Globalization/IdnMapping.cs b/src/mscorlib/src/System/Globalization/IdnMapping.cs
index 1f6bd9b505..4320e3abf5 100644
--- a/src/mscorlib/src/System/Globalization/IdnMapping.cs
+++ b/src/mscorlib/src/System/Globalization/IdnMapping.cs
@@ -24,6 +24,7 @@
// RFC 3491 - Nameprep: A Stringprep Profile for Internationalized Domain Names (IDN)
// RFC 3492 - Punycode: A Bootstring encoding of Unicode for Internationalized Domain Names in Applications (IDNA)
+using System.Diagnostics;
using System.Diagnostics.Contracts;
using System.Text;
diff --git a/src/mscorlib/src/System/Globalization/JapaneseCalendar.Unix.cs b/src/mscorlib/src/System/Globalization/JapaneseCalendar.Unix.cs
index 6f8e0bad35..51ff8095a3 100644
--- a/src/mscorlib/src/System/Globalization/JapaneseCalendar.Unix.cs
+++ b/src/mscorlib/src/System/Globalization/JapaneseCalendar.Unix.cs
@@ -3,6 +3,7 @@
// See the LICENSE file in the project root for more information.
using System.Collections.Generic;
+using System.Diagnostics;
namespace System.Globalization
{
diff --git a/src/mscorlib/src/System/Guid.cs b/src/mscorlib/src/System/Guid.cs
index c7e6220f8b..f64211d5d0 100644
--- a/src/mscorlib/src/System/Guid.cs
+++ b/src/mscorlib/src/System/Guid.cs
@@ -1285,35 +1285,40 @@ namespace System
return ToString(format, null);
}
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
private static char HexToChar(int a)
{
a = a & 0xf;
return (char)((a > 9) ? a - 10 + 0x61 : a + 0x30);
}
- unsafe private static int HexsToChars(char* guidChars, int offset, int a, int b)
+ unsafe private static int HexsToChars(char* guidChars, int a, int b)
{
- return HexsToChars(guidChars, offset, a, b, false);
+ guidChars[0] = HexToChar(a >> 4);
+ guidChars[1] = HexToChar(a);
+
+ guidChars[2] = HexToChar(b >> 4);
+ guidChars[3] = HexToChar(b);
+
+ return 4;
}
- unsafe private static int HexsToChars(char* guidChars, int offset, int a, int b, bool hex)
+ unsafe private static int HexsToCharsHexOutput(char* guidChars, int a, int b)
{
- if (hex)
- {
- guidChars[offset++] = '0';
- guidChars[offset++] = 'x';
- }
- guidChars[offset++] = HexToChar(a >> 4);
- guidChars[offset++] = HexToChar(a);
- if (hex)
- {
- guidChars[offset++] = ',';
- guidChars[offset++] = '0';
- guidChars[offset++] = 'x';
- }
- guidChars[offset++] = HexToChar(b >> 4);
- guidChars[offset++] = HexToChar(b);
- return offset;
+ guidChars[0] = '0';
+ guidChars[1] = 'x';
+
+ guidChars[2] = HexToChar(a >> 4);
+ guidChars[3] = HexToChar(a);
+
+ guidChars[4] = ',';
+ guidChars[5] = '0';
+ guidChars[6] = 'x';
+
+ guidChars[7] = HexToChar(b >> 4);
+ guidChars[8] = HexToChar(b);
+
+ return 9;
}
// IFormattable interface
@@ -1396,42 +1401,42 @@ namespace System
// {0xdddddddd,0xdddd,0xdddd,{0xdd,0xdd,0xdd,0xdd,0xdd,0xdd,0xdd,0xdd}}
guidChars[offset++] = '0';
guidChars[offset++] = 'x';
- offset = HexsToChars(guidChars, offset, _a >> 24, _a >> 16);
- offset = HexsToChars(guidChars, offset, _a >> 8, _a);
+ offset += HexsToChars(guidChars + offset, _a >> 24, _a >> 16);
+ offset += HexsToChars(guidChars + offset, _a >> 8, _a);
guidChars[offset++] = ',';
guidChars[offset++] = '0';
guidChars[offset++] = 'x';
- offset = HexsToChars(guidChars, offset, _b >> 8, _b);
+ offset += HexsToChars(guidChars + offset, _b >> 8, _b);
guidChars[offset++] = ',';
guidChars[offset++] = '0';
guidChars[offset++] = 'x';
- offset = HexsToChars(guidChars, offset, _c >> 8, _c);
+ offset += HexsToChars(guidChars + offset, _c >> 8, _c);
guidChars[offset++] = ',';
guidChars[offset++] = '{';
- offset = HexsToChars(guidChars, offset, _d, _e, true);
+ offset += HexsToCharsHexOutput(guidChars + offset, _d, _e);
guidChars[offset++] = ',';
- offset = HexsToChars(guidChars, offset, _f, _g, true);
+ offset += HexsToCharsHexOutput(guidChars + offset, _f, _g);
guidChars[offset++] = ',';
- offset = HexsToChars(guidChars, offset, _h, _i, true);
+ offset += HexsToCharsHexOutput(guidChars + offset, _h, _i);
guidChars[offset++] = ',';
- offset = HexsToChars(guidChars, offset, _j, _k, true);
+ offset += HexsToCharsHexOutput(guidChars + offset, _j, _k);
guidChars[offset++] = '}';
}
else
{
// [{|(]dddddddd[-]dddd[-]dddd[-]dddd[-]dddddddddddd[}|)]
- offset = HexsToChars(guidChars, offset, _a >> 24, _a >> 16);
- offset = HexsToChars(guidChars, offset, _a >> 8, _a);
+ offset += HexsToChars(guidChars + offset, _a >> 24, _a >> 16);
+ offset += HexsToChars(guidChars + offset, _a >> 8, _a);
if (dash) guidChars[offset++] = '-';
- offset = HexsToChars(guidChars, offset, _b >> 8, _b);
+ offset += HexsToChars(guidChars + offset, _b >> 8, _b);
if (dash) guidChars[offset++] = '-';
- offset = HexsToChars(guidChars, offset, _c >> 8, _c);
+ offset += HexsToChars(guidChars + offset, _c >> 8, _c);
if (dash) guidChars[offset++] = '-';
- offset = HexsToChars(guidChars, offset, _d, _e);
+ offset += HexsToChars(guidChars + offset, _d, _e);
if (dash) guidChars[offset++] = '-';
- offset = HexsToChars(guidChars, offset, _f, _g);
- offset = HexsToChars(guidChars, offset, _h, _i);
- offset = HexsToChars(guidChars, offset, _j, _k);
+ offset += HexsToChars(guidChars + offset, _f, _g);
+ offset += HexsToChars(guidChars + offset, _h, _i);
+ offset += HexsToChars(guidChars + offset, _j, _k);
}
}
}
diff --git a/src/mscorlib/src/System/Reflection/LocalVariableInfo.cs b/src/mscorlib/src/System/Reflection/LocalVariableInfo.cs
index 41d7477f99..241a3c4de6 100644
--- a/src/mscorlib/src/System/Reflection/LocalVariableInfo.cs
+++ b/src/mscorlib/src/System/Reflection/LocalVariableInfo.cs
@@ -2,6 +2,8 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
+using System.Diagnostics;
+
namespace System.Reflection
{
public class LocalVariableInfo
diff --git a/src/mscorlib/src/System/Reflection/RuntimeEventInfo.cs b/src/mscorlib/src/System/Reflection/RuntimeEventInfo.cs
index e2faf8340a..930e1820bd 100644
--- a/src/mscorlib/src/System/Reflection/RuntimeEventInfo.cs
+++ b/src/mscorlib/src/System/Reflection/RuntimeEventInfo.cs
@@ -3,6 +3,7 @@
// See the LICENSE file in the project root for more information.
using System.Collections.Generic;
+using System.Diagnostics;
using System.Diagnostics.Contracts;
using System.Runtime.Serialization;
using RuntimeTypeCache = System.RuntimeType.RuntimeTypeCache;
diff --git a/src/mscorlib/src/System/Reflection/RuntimeParameterInfo.cs b/src/mscorlib/src/System/Reflection/RuntimeParameterInfo.cs
index 77a56b4fe2..a8d62408eb 100644
--- a/src/mscorlib/src/System/Reflection/RuntimeParameterInfo.cs
+++ b/src/mscorlib/src/System/Reflection/RuntimeParameterInfo.cs
@@ -3,6 +3,7 @@
// See the LICENSE file in the project root for more information.
using System.Collections.Generic;
+using System.Diagnostics;
using System.Diagnostics.Contracts;
using System.Runtime.Serialization;
using System.Runtime.CompilerServices;
diff --git a/src/mscorlib/src/System/Runtime/CompilerServices/ConditionalWeakTable.cs b/src/mscorlib/src/System/Runtime/CompilerServices/ConditionalWeakTable.cs
index 9e4673b624..f32cc2b510 100644
--- a/src/mscorlib/src/System/Runtime/CompilerServices/ConditionalWeakTable.cs
+++ b/src/mscorlib/src/System/Runtime/CompilerServices/ConditionalWeakTable.cs
@@ -61,6 +61,7 @@
using System.Collections;
using System.Collections.Generic;
+using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Threading;
diff --git a/src/mscorlib/src/System/Runtime/Serialization/FormatterServices.cs b/src/mscorlib/src/System/Runtime/Serialization/FormatterServices.cs
index 5f07c3a5ce..18139324a3 100644
--- a/src/mscorlib/src/System/Runtime/Serialization/FormatterServices.cs
+++ b/src/mscorlib/src/System/Runtime/Serialization/FormatterServices.cs
@@ -29,6 +29,8 @@ using System.Diagnostics.Contracts;
namespace System.Runtime.Serialization
{
+ // This class duplicates a class on CoreFX. We are keeping it here -- just this one method --
+ // as it was widely invoked by reflection to workaround it being missing in .NET Core 1.0
internal static class FormatterServices
{
// Gets a new instance of the object. The entire object is initalized to 0 and no
@@ -56,28 +58,6 @@ namespace System.Runtime.Serialization
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private static extern Object nativeGetUninitializedObject(RuntimeType type);
- private static Binder s_binder = Type.DefaultBinder;
-
- /*============================LoadAssemblyFromString============================
- **Action: Loads an assembly from a given string. The current assembly loading story
- ** is quite confusing. If the assembly is in the fusion cache, we can load it
- ** using the stringized-name which we transmitted over the wire. If that fails,
- ** we try for a lookup of the assembly using the simple name which is the first
- ** part of the assembly name. If we can't find it that way, we'll return null
- ** as our failure result.
- **Returns: The loaded assembly or null if it can't be found.
- **Arguments: assemblyName -- The stringized assembly name.
- **Exceptions: None
- ==============================================================================*/
- internal static Assembly LoadAssemblyFromString(String assemblyName)
- {
- //
- // Try using the stringized assembly name to load from the fusion cache.
- //
- BCLDebug.Trace("SER", "[LoadAssemblyFromString]Looking for assembly: ", assemblyName);
- Assembly found = Assembly.Load(assemblyName);
- return found;
- }
}
}
diff --git a/src/mscorlib/src/System/Security/SecurityState.cs b/src/mscorlib/src/System/Security/SecurityState.cs
deleted file mode 100644
index 5f42011094..0000000000
--- a/src/mscorlib/src/System/Security/SecurityState.cs
+++ /dev/null
@@ -1,25 +0,0 @@
-// 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.
-
-using System;
-using System.Security;
-
-namespace System.Security
-{
- internal abstract class SecurityState
- {
- protected SecurityState() { }
-
- public bool IsStateAvailable()
- {
- AppDomainManager domainManager = AppDomainManager.CurrentAppDomainManager;
-
- // CheckSecuritySettings only when appdomainManager is present. So if there is no
- // appDomain Manager return true as by default coreclr runs in fulltrust.
- return domainManager != null ? domainManager.CheckSecuritySettings(this) : true;
- }
- // override this function and throw the appropriate
- public abstract void EnsureState();
- }
-}
diff --git a/src/mscorlib/src/System/Security/Util/URLString.cs b/src/mscorlib/src/System/Security/Util/URLString.cs
deleted file mode 100644
index 33aac6f034..0000000000
--- a/src/mscorlib/src/System/Security/Util/URLString.cs
+++ /dev/null
@@ -1,138 +0,0 @@
-// 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.
-
-// URLString
-//
-//
-// Implementation of membership condition for zones
-//
-
-namespace System.Security.Util
-{
- using System;
- using System.Collections;
- using System.Collections.Generic;
- using System.Runtime.CompilerServices;
- using System.Runtime.InteropServices;
- using System.Runtime.Versioning;
- using System.Runtime.Serialization;
- using System.Globalization;
- using System.Text;
- using System.IO;
- using System.Diagnostics.Contracts;
-
- internal static class URLString
- {
- internal static string PreProcessForExtendedPathRemoval(bool checkPathLength, string url, bool isFileUrl)
- {
- bool isUncShare = false;
- return PreProcessForExtendedPathRemoval(checkPathLength: checkPathLength, url: url, isFileUrl: isFileUrl, isUncShare: ref isUncShare);
- }
-
- // Keeping this signature to avoid reflection breaks
- private static string PreProcessForExtendedPathRemoval(string url, bool isFileUrl, ref bool isUncShare)
- {
- return PreProcessForExtendedPathRemoval(checkPathLength: true, url: url, isFileUrl: isFileUrl, isUncShare: ref isUncShare);
- }
-
- private static string PreProcessForExtendedPathRemoval(bool checkPathLength, string url, bool isFileUrl, ref bool isUncShare)
- {
- // This is the modified URL that we will return
- StringBuilder modifiedUrl = new StringBuilder(url);
-
- // ITEM 1 - remove extended path characters.
- {
- // Keep track of where we are in both the comparison and altered strings.
- int curCmpIdx = 0;
- int curModIdx = 0;
-
- // If all the '\' have already been converted to '/', just check for //?/ or //./
- if ((url.Length - curCmpIdx) >= 4 &&
- (String.Compare(url, curCmpIdx, "//?/", 0, 4, StringComparison.OrdinalIgnoreCase) == 0 ||
- String.Compare(url, curCmpIdx, "//./", 0, 4, StringComparison.OrdinalIgnoreCase) == 0))
- {
- modifiedUrl.Remove(curModIdx, 4);
- curCmpIdx += 4;
- }
- else
- {
- if (isFileUrl)
- {
- // We need to handle an indefinite number of leading front slashes for file URLs since we could
- // get something like:
- // file://\\?\
- // file:/\\?\
- // file:\\?\
- // etc...
- while (url[curCmpIdx] == '/')
- {
- curCmpIdx++;
- curModIdx++;
- }
- }
-
- // Remove the extended path characters
- if ((url.Length - curCmpIdx) >= 4 &&
- (String.Compare(url, curCmpIdx, "\\\\?\\", 0, 4, StringComparison.OrdinalIgnoreCase) == 0 ||
- String.Compare(url, curCmpIdx, "\\\\?/", 0, 4, StringComparison.OrdinalIgnoreCase) == 0 ||
- String.Compare(url, curCmpIdx, "\\\\.\\", 0, 4, StringComparison.OrdinalIgnoreCase) == 0 ||
- String.Compare(url, curCmpIdx, "\\\\./", 0, 4, StringComparison.OrdinalIgnoreCase) == 0))
- {
- modifiedUrl.Remove(curModIdx, 4);
- curCmpIdx += 4;
- }
- }
- }
-
- // ITEM 2 - convert all slashes to forward slashes, and strip leading slashes.
- if (isFileUrl)
- {
- int slashCount = 0;
- bool seenFirstBackslash = false;
-
- while (slashCount < modifiedUrl.Length && (modifiedUrl[slashCount] == '/' || modifiedUrl[slashCount] == '\\'))
- {
- // Look for sets of consecutive backslashes. We can't just look for these at the start
- // of the string, since file:// might come first. Instead, once we see the first \, look
- // for a second one following it.
- if (!seenFirstBackslash && modifiedUrl[slashCount] == '\\')
- {
- seenFirstBackslash = true;
- if (slashCount + 1 < modifiedUrl.Length && modifiedUrl[slashCount + 1] == '\\')
- isUncShare = true;
- }
-
- slashCount++;
- }
-
- modifiedUrl.Remove(0, slashCount);
- modifiedUrl.Replace('\\', '/');
- }
-
- // ITEM 3 - If the path is greater than or equal (due to terminating NULL in windows) MAX_PATH, we throw.
- if (checkPathLength)
- {
- // This needs to be a separate method to avoid hitting the static constructor on AppContextSwitches
- CheckPathTooLong(modifiedUrl);
- }
-
- // Create the result string from the StringBuilder
- return modifiedUrl.ToString();
- }
-
- [MethodImpl(MethodImplOptions.NoInlining)]
- private static void CheckPathTooLong(StringBuilder path)
- {
- if (path.Length >= (
-#if PLATFORM_UNIX
- Interop.Sys.MaxPath))
-#else
- PathInternal.MaxLongPath))
-#endif
- {
- throw new PathTooLongException(SR.IO_PathTooLong);
- }
- }
- }
-}
diff --git a/src/mscorlib/src/System/Span.cs b/src/mscorlib/src/System/Span.cs
index 51ed0f23f0..4211083def 100644
--- a/src/mscorlib/src/System/Span.cs
+++ b/src/mscorlib/src/System/Span.cs
@@ -503,56 +503,13 @@ namespace System
/// <exception cref="System.ArgumentNullException">Thrown when <paramref name="text"/> is a null
/// reference (Nothing in Visual Basic).</exception>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static ReadOnlySpan<char> Slice(this string text)
+ public static ReadOnlySpan<char> AsSpan(this string text)
{
if (text == null)
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.text);
return new ReadOnlySpan<char>(ref text.GetFirstCharRef(), text.Length);
}
-
- /// <summary>
- /// Creates a new readonly span over the portion of the target string, beginning at 'start'.
- /// </summary>
- /// <param name="text">The target string.</param>
- /// <param name="start">The index at which to begin this slice.</param>
- /// <exception cref="System.ArgumentNullException">Thrown when <paramref name="text"/> is a null
- /// reference (Nothing in Visual Basic).</exception>
- /// <exception cref="System.ArgumentOutOfRangeException">
- /// Thrown when the specified <paramref name="start"/> index is not in range (&lt;0 or &gt;Length).
- /// </exception>
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static ReadOnlySpan<char> Slice(this string text, int start)
- {
- if (text == null)
- ThrowHelper.ThrowArgumentNullException(ExceptionArgument.text);
- if ((uint)start > (uint)text.Length)
- ThrowHelper.ThrowArgumentOutOfRangeException();
-
- return new ReadOnlySpan<char>(ref Unsafe.Add(ref text.GetFirstCharRef(), start), text.Length - start);
- }
-
- /// <summary>
- /// Creates a new readonly span over the portion of the target string, beginning at <paramref name="start"/>, of given <paramref name="length"/>.
- /// </summary>
- /// <param name="text">The target string.</param>
- /// <param name="start">The index at which to begin this slice.</param>
- /// <param name="length">The number of items in the span.</param>
- /// <exception cref="System.ArgumentNullException">Thrown when <paramref name="text"/> is a null
- /// reference (Nothing in Visual Basic).</exception>
- /// <exception cref="System.ArgumentOutOfRangeException">
- /// Thrown when the specified <paramref name="start"/> or end index is not in range (&lt;0 or &gt;&eq;Length).
- /// </exception>
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static ReadOnlySpan<char> Slice(this string text, int start, int length)
- {
- if (text == null)
- ThrowHelper.ThrowArgumentNullException(ExceptionArgument.text);
- if ((uint)start > (uint)text.Length || (uint)length > (uint)(text.Length - start))
- ThrowHelper.ThrowArgumentOutOfRangeException();
-
- return new ReadOnlySpan<char>(ref Unsafe.Add(ref text.GetFirstCharRef(), start), length);
- }
}
internal static class SpanHelper
diff --git a/src/mscorlib/src/System/ThrowHelper.cs b/src/mscorlib/src/System/ThrowHelper.cs
index 445ea318bb..4dcf8d4511 100644
--- a/src/mscorlib/src/System/ThrowHelper.cs
+++ b/src/mscorlib/src/System/ThrowHelper.cs
@@ -38,6 +38,7 @@
using System.Collections.Generic;
using System.Runtime.CompilerServices;
using System.Runtime.Serialization;
+using System.Diagnostics;
using System.Diagnostics.Contracts;
namespace System
diff --git a/src/mscorlib/src/System/TimeZoneInfo.Win32.cs b/src/mscorlib/src/System/TimeZoneInfo.Win32.cs
index 5107fee333..f359a2a2a3 100644
--- a/src/mscorlib/src/System/TimeZoneInfo.Win32.cs
+++ b/src/mscorlib/src/System/TimeZoneInfo.Win32.cs
@@ -3,6 +3,7 @@
// See the LICENSE file in the project root for more information.
using System.Collections.Generic;
+using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Security;
diff --git a/src/mscorlib/src/System/TimeZoneInfo.cs b/src/mscorlib/src/System/TimeZoneInfo.cs
index 3dd0aec913..29ea33a8ad 100644
--- a/src/mscorlib/src/System/TimeZoneInfo.cs
+++ b/src/mscorlib/src/System/TimeZoneInfo.cs
@@ -4,6 +4,7 @@
using System.Collections.Generic;
using System.Collections.ObjectModel;
+using System.Diagnostics;
using System.Diagnostics.Contracts;
using System.Globalization;
using System.Runtime.Serialization;
diff --git a/src/pal/inc/pal.h b/src/pal/inc/pal.h
index c51dc4459e..8430ea9899 100644
--- a/src/pal/inc/pal.h
+++ b/src/pal/inc/pal.h
@@ -4748,18 +4748,6 @@ typedef POSVERSIONINFOEXA POSVERSIONINFOEX;
typedef LPOSVERSIONINFOEXA LPOSVERSIONINFOEX;
#endif
-PALIMPORT
-BOOL
-PALAPI
-GetVersionExW(
- IN OUT LPOSVERSIONINFOW lpVersionInformation);
-
-#ifdef UNICODE
-#define GetVersionEx GetVersionExW
-#else
-#define GetVersionEx GetVersionExA
-#endif
-
#define IMAGE_FILE_MACHINE_I386 0x014c
#define IMAGE_FILE_MACHINE_ARM64 0xAA64 // ARM64 Little-Endian
diff --git a/src/pal/inc/palprivate.h b/src/pal/inc/palprivate.h
index 2677dd6bdd..554a5028ad 100644
--- a/src/pal/inc/palprivate.h
+++ b/src/pal/inc/palprivate.h
@@ -293,12 +293,6 @@ FreeEnvironmentStringsA(
PALIMPORT
BOOL
PALAPI
-GetVersionExA(
- IN OUT LPOSVERSIONINFOA lpVersionInformation);
-
-PALIMPORT
-BOOL
-PALAPI
RemoveDirectoryA(
IN LPCSTR lpPathName);
diff --git a/src/pal/src/CMakeLists.txt b/src/pal/src/CMakeLists.txt
index f21c9dbf8f..5314cdf86b 100644
--- a/src/pal/src/CMakeLists.txt
+++ b/src/pal/src/CMakeLists.txt
@@ -181,7 +181,6 @@ set(SOURCES
misc/sysinfo.cpp
misc/time.cpp
misc/utils.cpp
- misc/version.cpp
objmgr/palobjbase.cpp
objmgr/shmobject.cpp
objmgr/shmobjectmanager.cpp
diff --git a/src/pal/src/arch/i386/exceptionhelper.S b/src/pal/src/arch/i386/exceptionhelper.S
index f0bf8f8ef9..bf44124479 100644
--- a/src/pal/src/arch/i386/exceptionhelper.S
+++ b/src/pal/src/arch/i386/exceptionhelper.S
@@ -20,10 +20,13 @@
LEAF_ENTRY ThrowExceptionFromContextInternal, _TEXT
push ebp
mov ecx, [esp + 12] // ecx: PAL_SEHException * (first argument for ThrowExceptionHelper)
- mov ebx, [esp + 8] // ebx: CONTEXT *
+ mov eax, [esp + 8] // ebx: CONTEXT *
- mov ebp, [ebx + CONTEXT_Ebp]
- mov esp, [ebx + CONTEXT_ResumeEsp]
+ mov ebp, [eax + CONTEXT_Ebp]
+ mov esp, [eax + CONTEXT_ResumeEsp]
+ mov ebx, [eax + CONTEXT_Ebx]
+ mov esi, [eax + CONTEXT_Esi]
+ mov edi, [eax + CONTEXT_Edi]
// The ESP is re-initialized as the target frame's value, so the current function's
// CFA is now right at the ESP.
@@ -34,7 +37,8 @@ LEAF_ENTRY ThrowExceptionFromContextInternal, _TEXT
.cfi_restore ebp
// Store return address to the stack
- mov ebx, [ebx + CONTEXT_Eip]
- push ebx
+ mov eax, [eax + CONTEXT_Eip]
+ push eax
jmp EXTERNAL_C_FUNC(ThrowExceptionHelper)
+
LEAF_END ThrowExceptionFromContextInternal, _TEXT
diff --git a/src/pal/src/cruntime/misctls.cpp b/src/pal/src/cruntime/misctls.cpp
index e46582ec17..2df32fe115 100644
--- a/src/pal/src/cruntime/misctls.cpp
+++ b/src/pal/src/cruntime/misctls.cpp
@@ -128,6 +128,11 @@ done:
return retval;
}
+UINT GetExponent(double d)
+{
+ return (*((UINT*)&d + 1) >> 20) & 0x000007ff;
+}
+
/**
Function:
@@ -150,250 +155,143 @@ NOTES:
char * __cdecl
_ecvt( double value, int count, int * dec, int * sign )
{
- CONST CHAR * FORMAT_STRING = "%.348e";
- CHAR TempBuffer[ ECVT_MAX_BUFFER_SIZE ];
- CPalThread *pThread = NULL;
- LPSTR lpReturnBuffer = NULL;
- LPSTR lpStartOfReturnBuffer = NULL;
- LPSTR lpTempBuffer = NULL;
- LPSTR lpEndOfTempBuffer = NULL;
- INT nTempBufferLength = 0;
- CHAR ExponentBuffer[ 6 ];
- INT nExponentValue = 0;
- INT LoopIndex = 0;
-
PERF_ENTRY(_ecvt);
ENTRY( "_ecvt( value=%.30g, count=%d, dec=%p, sign=%p )\n",
value, count, dec, sign );
+
+ _ASSERTE(dec != nullptr && sign != nullptr);
+ CPalThread *pThread = InternalGetCurrentThread();
+ LPSTR lpStartOfReturnBuffer = pThread->crtInfo.ECVTBuffer;
- /* Get the per-thread buffer from the thread structure. */
- pThread = InternalGetCurrentThread();
-
- lpStartOfReturnBuffer = lpReturnBuffer = pThread->crtInfo.ECVTBuffer;
-
- /* Sanity checks */
- if ( !dec || !sign )
- {
- ERROR( "dec and sign have to be valid pointers.\n" );
- *lpReturnBuffer = '\0';
- goto done;
- }
- else
+ if (count > ECVT_MAX_COUNT_SIZE)
{
- *dec = *sign = 0;
+ count = ECVT_MAX_COUNT_SIZE;
}
- if ( value < 0.0 )
- {
- *sign = 1;
- }
+ // the caller of _ecvt should already checked the Infinity and NAN values
+ _ASSERTE(GetExponent(value) != 0x7ff);
- if ( count > ECVT_MAX_COUNT_SIZE )
+ CHAR TempBuffer[ECVT_MAX_BUFFER_SIZE];
+
+ *dec = *sign = 0;
+
+ if (value < 0.0)
{
- count = ECVT_MAX_COUNT_SIZE;
+ *sign = 1;
}
-
- /* Get the string to work with. */
- sprintf_s( TempBuffer, sizeof(TempBuffer), FORMAT_STRING, value );
-
- /* Check to see if value was a valid number. */
- if ( strcmp( "NaN", TempBuffer ) == 0 || strcmp( "-NaN", TempBuffer ) == 0 )
+
{
- TRACE( "value was not a number!\n" );
- if (strcpy_s( lpStartOfReturnBuffer, ECVT_MAX_BUFFER_SIZE, "1#QNAN0" ) != SAFECRT_SUCCESS)
+ // we have issue #10290 tracking fixing the sign of 0.0 across the platforms
+ if (value == 0.0)
{
- ERROR( "strcpy_s failed!\n" );
- *lpStartOfReturnBuffer = '\0';
+ for (int j = 0; j < count; j++)
+ {
+ lpStartOfReturnBuffer[j] = '0';
+ }
+ lpStartOfReturnBuffer[count] = '\0';
goto done;
+ }
+
+ int tempBufferLength = snprintf(TempBuffer, ECVT_MAX_BUFFER_SIZE, "%.40e", value);
+ _ASSERTE(tempBufferLength > 0 && ECVT_MAX_BUFFER_SIZE > tempBufferLength);
+
+ //
+ // Calculate the exponent value
+ //
+
+ int exponentIndex = strrchr(TempBuffer, 'e') - TempBuffer;
+ _ASSERTE(exponentIndex > 0 && (exponentIndex < tempBufferLength - 1));
+
+ int i = exponentIndex + 1;
+ int exponentSign = 1;
+ if (TempBuffer[i] == '-')
+ {
+ exponentSign = -1;
+ i++;
}
-
- *dec = 1;
- goto done;
- }
-
- /* Check to see if it is infinite. */
- if ( strcmp( "Inf", TempBuffer ) == 0 || strcmp( "-Inf", TempBuffer ) == 0 )
- {
- TRACE( "value is infinite!\n" );
- if (strcpy_s( lpStartOfReturnBuffer, ECVT_MAX_BUFFER_SIZE, "1#INF00" ) != SAFECRT_SUCCESS)
+ else if (TempBuffer[i] == '+')
{
- ERROR( "strcpy_s failed!\n" );
- *lpStartOfReturnBuffer = '\0';
- goto done;
+ i++;
}
- *dec = 1;
- if ( *TempBuffer == '-' )
+ int exponentValue = 0;
+ while (i < tempBufferLength)
{
- *sign = 1;
+ _ASSERTE(TempBuffer[i] >= '0' && TempBuffer[i] <= '9');
+ exponentValue = exponentValue * 10 + ((BYTE) TempBuffer[i] - (BYTE) '0');
+ i++;
}
- goto done;
- }
-
- nTempBufferLength = strlen( TempBuffer );
- lpEndOfTempBuffer = &(TempBuffer[ nTempBufferLength ]);
-
- /* Extract the exponent, and convert it to integer. */
- while ( *lpEndOfTempBuffer != 'e' && nTempBufferLength > 0 )
- {
- nTempBufferLength--;
- lpEndOfTempBuffer--;
- }
-
- ExponentBuffer[ 0 ] = '\0';
- if (strncat_s( ExponentBuffer, sizeof(ExponentBuffer), lpEndOfTempBuffer + 1, 5 ) != SAFECRT_SUCCESS)
- {
- ERROR( "strncat_s failed!\n" );
- *lpStartOfReturnBuffer = '\0';
- goto done;
- }
-
- nExponentValue = atoi( ExponentBuffer );
+ exponentValue *= exponentSign;
+
+ //
+ // Determine decimal location.
+ //
- /* End the string at the 'e' */
- *lpEndOfTempBuffer = '\0';
- nTempBufferLength--;
+ if (exponentValue == 0)
+ {
+ *dec = 1;
+ }
+ else
+ {
+ *dec = exponentValue + 1;
+ }
+
+ //
+ // Copy the string from the temp buffer upto precision characters, removing the sign, and decimal as required.
+ //
+
+ i = 0;
+ int mantissaIndex = 0;
+ while (i < count && mantissaIndex < exponentIndex)
+ {
+ if (TempBuffer[mantissaIndex] >= '0' && TempBuffer[mantissaIndex] <= '9')
+ {
+ lpStartOfReturnBuffer[i] = TempBuffer[mantissaIndex];
+ i++;
+ }
+ mantissaIndex++;
+ }
- /* Determine decimal location. */
- if ( nExponentValue == 0 )
- {
- *dec = 1;
- }
- else
- {
- *dec = nExponentValue + 1;
- }
+ while (i < count)
+ {
+ lpStartOfReturnBuffer[i] = '0'; // append zeros as needed
+ i++;
+ }
- if ( value == 0.0 )
- {
- *dec = 0;
- }
- /* Copy the string from the temp buffer upto count characters,
- removing the sign, and decimal as required. */
- lpTempBuffer = TempBuffer;
- *lpReturnBuffer = '0';
- lpReturnBuffer++;
+ lpStartOfReturnBuffer[i] = '\0';
+
+ //
+ // Round if needed
+ //
- while ( LoopIndex < ECVT_MAX_COUNT_SIZE )
- {
- if ( isdigit(*lpTempBuffer) )
+ if (mantissaIndex >= exponentIndex || TempBuffer[mantissaIndex] < '5')
{
- *lpReturnBuffer = *lpTempBuffer;
- LoopIndex++;
- lpReturnBuffer++;
+ goto done;
}
- lpTempBuffer++;
- if ( LoopIndex == count + 1 )
+ i = count - 1;
+ while (lpStartOfReturnBuffer[i] == '9' && i > 0)
{
- break;
+ lpStartOfReturnBuffer[i] = '0';
+ i--;
}
- }
- *lpReturnBuffer = '\0';
-
- /* Round if needed. If count is less then 0
- then windows does not round for some reason.*/
- nTempBufferLength = strlen( lpStartOfReturnBuffer ) - 1;
-
- /* Add one for the preceeding zero. */
- lpReturnBuffer = ( lpStartOfReturnBuffer + 1 );
-
- if ( nTempBufferLength >= count && count >= 0 )
- {
- /* Determine whether I need to round up. */
- if ( *(lpReturnBuffer + count) >= '5' )
+ if (i == 0 && lpStartOfReturnBuffer[i] == '9')
{
- CHAR cNumberToBeRounded;
- if ( count != 0 )
- {
- cNumberToBeRounded = *(lpReturnBuffer + count - 1);
- }
- else
- {
- cNumberToBeRounded = *lpReturnBuffer;
- }
-
- if ( cNumberToBeRounded < '9' )
- {
- if ( count > 0 )
- {
- /* Add one to the character. */
- (*(lpReturnBuffer + count - 1))++;
- }
- else
- {
- if ( cNumberToBeRounded >= '5' )
- {
- (*dec)++;
- }
- }
- }
- else
- {
- LPSTR lpRounding = NULL;
-
- if ( count > 0 )
- {
- lpRounding = lpReturnBuffer + count - 1;
- }
- else
- {
- lpRounding = lpReturnBuffer + count;
- }
-
- while ( cNumberToBeRounded == '9' )
- {
- cNumberToBeRounded = *lpRounding;
-
- if ( cNumberToBeRounded == '9' )
- {
- *lpRounding = '0';
- lpRounding--;
- }
- }
-
- if ( lpRounding == lpStartOfReturnBuffer )
- {
- /* Overflow. number is a whole number now. */
- *lpRounding = '1';
- memset( ++lpRounding, '0', count);
-
- /* The decimal has moved. */
- (*dec)++;
- }
- else
- {
- *lpRounding = ++cNumberToBeRounded;
- }
- }
+ lpStartOfReturnBuffer[i] = '1';
+ (*dec)++;
}
else
{
- /* Get rid of the preceding 0 */
- lpStartOfReturnBuffer++;
- }
- }
-
- if ( *lpStartOfReturnBuffer == '0' )
- {
- lpStartOfReturnBuffer++;
- }
-
- if ( count >= 0 )
- {
- *(lpStartOfReturnBuffer + count) = '\0';
- }
- else
- {
- *lpStartOfReturnBuffer = '\0';
+ lpStartOfReturnBuffer[i]++;
+ }
}
done:
LOGEXIT( "_ecvt returning %p (%s)\n", lpStartOfReturnBuffer , lpStartOfReturnBuffer );
PERF_EXIT(_ecvt);
-
+
return lpStartOfReturnBuffer;
}
diff --git a/src/pal/src/misc/environ.cpp b/src/pal/src/misc/environ.cpp
index fed7b69f38..9fc13467c5 100644
--- a/src/pal/src/misc/environ.cpp
+++ b/src/pal/src/misc/environ.cpp
@@ -218,7 +218,13 @@ GetEnvironmentVariableW(
}
else if (size == 0)
{
- // handle error in GetEnvironmentVariableA
+ // If size is 0, it either means GetEnvironmentVariableA failed, or that
+ // it succeeded and the value of the variable is empty. Check GetLastError
+ // to determine which. If the call failed, we won't touch the buffer.
+ if (GetLastError() == ERROR_SUCCESS)
+ {
+ *lpBuffer = '\0';
+ }
}
else
{
diff --git a/src/pal/src/misc/errorstrings.cpp b/src/pal/src/misc/errorstrings.cpp
index 22443114ee..2c5243945c 100644
--- a/src/pal/src/misc/errorstrings.cpp
+++ b/src/pal/src/misc/errorstrings.cpp
@@ -76,7 +76,7 @@ ErrorString palErrorStrings[] =
{ ERROR_SEM_TIMEOUT, W("The semaphore timeout period has expired.\n") },
{ ERROR_INSUFFICIENT_BUFFER, W("The data area passed to a system call is too small.\n") },
{ ERROR_INVALID_NAME, W("The filename, directory name, or volume label syntax is incorrect.\n") },
- { ERROR_MOD_NOT_FOUND, W("The specified module could not be found.\n") },
+ { ERROR_MOD_NOT_FOUND, W("The specified module or one of its dependencies could not be found.\n") },
{ ERROR_PROC_NOT_FOUND, W("The specified procedure could not be found.\n") },
{ ERROR_WAIT_NO_CHILDREN, W("There are no child processes to wait for.\n") },
{ ERROR_NEGATIVE_SEEK, W("An attempt was made to move the file pointer before the beginning of the file.\n") },
diff --git a/src/pal/src/misc/version.cpp b/src/pal/src/misc/version.cpp
deleted file mode 100644
index 7a9f90a320..0000000000
--- a/src/pal/src/misc/version.cpp
+++ /dev/null
@@ -1,119 +0,0 @@
-// 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.
-
-/*++
-
-
-
-Module Name:
-
- version.c
-
-Abstract:
-
- Implementation of functions for getting platform.OS versions.
-
-Revision History:
-
-
-
---*/
-
-#include "pal/palinternal.h"
-#include "pal/dbgmsg.h"
-
-SET_DEFAULT_DEBUG_CHANNEL(MISC);
-
-/*++
-Function:
- GetVersionExA
-
-
-
-GetVersionEx
-
-The GetVersionEx function obtains extended information about the
-version of the operating system that is currently running.
-
-Parameters
-
-lpVersionInfo
- [in/out] Pointer to an OSVERSIONINFO data structure that the
- function fills with operating system version information.
-
- Before calling the GetVersionEx function, set the
- dwOSVersionInfoSize member of the OSVERSIONINFO data structure
- to sizeof(OSVERSIONINFO).
-
-Return Values
-
-If the function succeeds, the return value is a nonzero value.
-
-If the function fails, the return value is zero. To get extended error
-information, call GetLastError. The function fails if you specify an
-invalid value for the dwOSVersionInfoSize member of the OSVERSIONINFO
-structure.
-
---*/
-BOOL
-PALAPI
-GetVersionExA(
- IN OUT LPOSVERSIONINFOA lpVersionInformation)
-{
- BOOL bRet = TRUE;
- PERF_ENTRY(GetVersionExA);
- ENTRY("GetVersionExA (lpVersionInformation=%p)\n", lpVersionInformation);
-
- if (lpVersionInformation->dwOSVersionInfoSize == sizeof(OSVERSIONINFOA))
- {
- lpVersionInformation->dwMajorVersion = 5; /* same as WIN2000 */
- lpVersionInformation->dwMinorVersion = 0; /* same as WIN2000 */
- lpVersionInformation->dwBuildNumber = 0;
- lpVersionInformation->dwPlatformId = VER_PLATFORM_UNIX;
- lpVersionInformation->szCSDVersion[0] = '\0'; /* no service pack */
- }
- else
- {
- SetLastError(ERROR_INVALID_PARAMETER);
- bRet = FALSE;
- }
- LOGEXIT("GetVersionExA returning BOOL %d\n", bRet);
- PERF_EXIT(GetVersionExA);
- return bRet;
-}
-
-
-/*++
-Function:
- GetVersionExW
-
-See GetVersionExA
---*/
-BOOL
-PALAPI
-GetVersionExW(
- IN OUT LPOSVERSIONINFOW lpVersionInformation)
-{
- BOOL bRet = TRUE;
-
- PERF_ENTRY(GetVersionExW);
- ENTRY("GetVersionExW (lpVersionInformation=%p)\n", lpVersionInformation);
-
- if (lpVersionInformation->dwOSVersionInfoSize == sizeof(OSVERSIONINFOW))
- {
- lpVersionInformation->dwMajorVersion = 5; /* same as WIN2000 */
- lpVersionInformation->dwMinorVersion = 0; /* same as WIN2000 */
- lpVersionInformation->dwBuildNumber = 0;
- lpVersionInformation->dwPlatformId = VER_PLATFORM_UNIX;
- lpVersionInformation->szCSDVersion[0] = '\0'; /* no service pack */
- }
- else
- {
- SetLastError(ERROR_INVALID_PARAMETER);
- bRet = FALSE;
- }
- LOGEXIT("GetVersionExW returning BOOL %d\n", bRet);
- PERF_EXIT(GetVersionExW);
- return bRet;
-}
diff --git a/src/pal/tests/palsuite/miscellaneous/GetVersionExA/CMakeLists.txt b/src/pal/tests/palsuite/miscellaneous/GetVersionExA/CMakeLists.txt
deleted file mode 100644
index f6aa0cb2d9..0000000000
--- a/src/pal/tests/palsuite/miscellaneous/GetVersionExA/CMakeLists.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-cmake_minimum_required(VERSION 2.8.12.2)
-
-add_subdirectory(test1)
-
diff --git a/src/pal/tests/palsuite/miscellaneous/GetVersionExA/test1/CMakeLists.txt b/src/pal/tests/palsuite/miscellaneous/GetVersionExA/test1/CMakeLists.txt
deleted file mode 100644
index 1e512f3c2f..0000000000
--- a/src/pal/tests/palsuite/miscellaneous/GetVersionExA/test1/CMakeLists.txt
+++ /dev/null
@@ -1,17 +0,0 @@
-cmake_minimum_required(VERSION 2.8.12.2)
-
-set(CMAKE_INCLUDE_CURRENT_DIR ON)
-
-set(SOURCES
- test.cpp
-)
-
-add_executable(paltest_getversionexa_test1
- ${SOURCES}
-)
-
-add_dependencies(paltest_getversionexa_test1 coreclrpal)
-
-target_link_libraries(paltest_getversionexa_test1
- ${COMMON_TEST_LIBRARIES}
-)
diff --git a/src/pal/tests/palsuite/miscellaneous/GetVersionExA/test1/test.cpp b/src/pal/tests/palsuite/miscellaneous/GetVersionExA/test1/test.cpp
deleted file mode 100644
index 5dd20c6576..0000000000
--- a/src/pal/tests/palsuite/miscellaneous/GetVersionExA/test1/test.cpp
+++ /dev/null
@@ -1,83 +0,0 @@
-// 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.
-
-/*============================================================
-**
-** Source : test.c
-**
-** Purpose: Test for GetVersionExA() function
-**
-**
-**=========================================================*/
-
-#include <palsuite.h>
-
-int __cdecl main(int argc, char *argv[]) {
-
- OSVERSIONINFO TheVersionInfo;
- OSVERSIONINFO* pVersionInfo = &TheVersionInfo;
-
- /*
- * Initialize the PAL and return FAILURE if this fails
- */
-
- if(0 != (PAL_Initialize(argc, argv)))
- {
- return FAIL;
- }
-
-
- /* This needs to be done before using GetVersionEx */
- pVersionInfo->dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
-
- /* If GetVersionEx fails, then the test fails */
- if(GetVersionEx(pVersionInfo) == 0)
- {
- Fail("ERROR: The GetVersionEx function returned 0, which indicates "
- "failure.");
- }
-
- /* These values are fixed, ensure they're set properly */
- if(pVersionInfo->dwMajorVersion != 5)
- {
- Fail("ERROR: The fixed value of dwMajorVersion shoud be 5, "
- "but is really %d.",pVersionInfo->dwMajorVersion);
- }
-
- /* The minor version values for Win2k and XP are different
- for Win2k minor version equals 0 and for XP minor version
- equals 1. Both values are excepted here. */
- if((pVersionInfo->dwMinorVersion != 0) &&
- (pVersionInfo->dwMinorVersion != 1))
- {
- Fail("ERROR: The fixed value of dwMinorVersion shoud be 0 or 1, "
- "but is really %d.",pVersionInfo->dwMinorVersion);
- }
- if(pVersionInfo->dwBuildNumber_PAL_Undefined < 0)
- {
- Fail("ERROR: The value of dwBuildNumber shoud be at least 0, but "
- "is really %d.",pVersionInfo->dwBuildNumber_PAL_Undefined);
- }
-
-#if !WIN32
- /* Under BSD, the PlatformID should be UNIX and the Service Pack
- version should be set to "".
- */
-
- if(pVersionInfo->dwPlatformId != VER_PLATFORM_UNIX ||
- pVersionInfo->szCSDVersion_PAL_Undefined[0] != 0)
- {
- Fail("ERROR: The dwPlatformId should be %d but is really %d. And the "
- "szCSDVerion should be NULL.",
- VER_PLATFORM_UNIX,pVersionInfo->dwPlatformId);
- }
-#endif
-
-
- PAL_Terminate();
- return PASS;
-}
-
-
-
diff --git a/src/pal/tests/palsuite/miscellaneous/GetVersionExA/test1/testinfo.dat b/src/pal/tests/palsuite/miscellaneous/GetVersionExA/test1/testinfo.dat
deleted file mode 100644
index 1e9c570c60..0000000000
--- a/src/pal/tests/palsuite/miscellaneous/GetVersionExA/test1/testinfo.dat
+++ /dev/null
@@ -1,16 +0,0 @@
-# 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.
-
-Version = 1.0
-Section = Miscellaneous
-Function = GetVersionExA
-Name = Positive Test for GetVersionExA
-TYPE = DEFAULT
-EXE1 = test
-Description
-= Test that all the values in the OSVERSION structure are set properly
-= for the current environment.
-
-
-
diff --git a/src/pal/tests/palsuite/miscellaneous/GetVersionExW/CMakeLists.txt b/src/pal/tests/palsuite/miscellaneous/GetVersionExW/CMakeLists.txt
deleted file mode 100644
index f6aa0cb2d9..0000000000
--- a/src/pal/tests/palsuite/miscellaneous/GetVersionExW/CMakeLists.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-cmake_minimum_required(VERSION 2.8.12.2)
-
-add_subdirectory(test1)
-
diff --git a/src/pal/tests/palsuite/miscellaneous/GetVersionExW/test1/CMakeLists.txt b/src/pal/tests/palsuite/miscellaneous/GetVersionExW/test1/CMakeLists.txt
deleted file mode 100644
index 4ef820c479..0000000000
--- a/src/pal/tests/palsuite/miscellaneous/GetVersionExW/test1/CMakeLists.txt
+++ /dev/null
@@ -1,17 +0,0 @@
-cmake_minimum_required(VERSION 2.8.12.2)
-
-set(CMAKE_INCLUDE_CURRENT_DIR ON)
-
-set(SOURCES
- test.cpp
-)
-
-add_executable(paltest_getversionexw_test1
- ${SOURCES}
-)
-
-add_dependencies(paltest_getversionexw_test1 coreclrpal)
-
-target_link_libraries(paltest_getversionexw_test1
- ${COMMON_TEST_LIBRARIES}
-)
diff --git a/src/pal/tests/palsuite/miscellaneous/GetVersionExW/test1/test.cpp b/src/pal/tests/palsuite/miscellaneous/GetVersionExW/test1/test.cpp
deleted file mode 100644
index 69aae54bcf..0000000000
--- a/src/pal/tests/palsuite/miscellaneous/GetVersionExW/test1/test.cpp
+++ /dev/null
@@ -1,88 +0,0 @@
-// 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.
-
-/*============================================================
-**
-** Source : test.c
-**
-** Purpose: Test for GetVersionExW() function
-**
-**
-**=========================================================*/
-
-#define UNICODE
-
-#include <palsuite.h>
-
-int __cdecl main(int argc, char *argv[])
-{
-
- OSVERSIONINFO TheVersionInfo;
- OSVERSIONINFO* pVersionInfo = &TheVersionInfo;
-
- /*
- * Initialize the PAL and return FAILURE if this fails
- */
-
- if(0 != (PAL_Initialize(argc, argv)))
- {
- return FAIL;
- }
-
- /* This needs to be done before using GetVersionEx */
- pVersionInfo->dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
-
- /* If GetVersionEx fails, then the test fails */
- if(GetVersionEx(pVersionInfo) == 0)
- {
- Fail("ERROR: The GetVersionEx function returned 0, which indicates "
- "failure.");
- }
-
- /* These values are fixed, ensure they're set properly */
- if(pVersionInfo->dwMajorVersion != 5)
- {
- Fail("ERROR: The fixed value of dwMajorVersion shoud be 5, but is "
- " really %d.",pVersionInfo->dwMajorVersion);
- }
-
- /* The minor version values for Win2k and XP are different
- for Win2k minor version equals 0 and for XP minor version
- equals 1. Both values are excepted here. */
- if((pVersionInfo->dwMinorVersion != 0) &&
- (pVersionInfo->dwMinorVersion != 1))
- {
- Fail("ERROR: The fixed value of dwMinorVersion shoud be 0 or 1, "
- "but is really %d.",pVersionInfo->dwMinorVersion);
- }
-
- if(pVersionInfo->dwBuildNumber_PAL_Undefined < 0)
- {
- Fail("ERROR: The value of dwBuildNumber shoud be at least 0, but is "
- "really %d.",pVersionInfo->dwBuildNumber_PAL_Undefined);
- }
-
-#if !WIN32
-
-
- /* Under BSD, the PlatformID should be UNIX and the Service Pack
- version should be set to "".
- */
-
- if(pVersionInfo->dwPlatformId != VER_PLATFORM_UNIX ||
- pVersionInfo->szCSDVersion_PAL_Undefined[0] != 0)
- {
- Fail("ERROR: The dwPlatformId should be %d but is really %d. And the "
- "szCSDVerion should be NULL.",VER_PLATFORM_UNIX,
- pVersionInfo->dwPlatformId);
- }
-#endif
-
-
- PAL_Terminate();
- return PASS;
-}
-
-
-
diff --git a/src/pal/tests/palsuite/miscellaneous/GetVersionExW/test1/testinfo.dat b/src/pal/tests/palsuite/miscellaneous/GetVersionExW/test1/testinfo.dat
deleted file mode 100644
index 7773245b3f..0000000000
--- a/src/pal/tests/palsuite/miscellaneous/GetVersionExW/test1/testinfo.dat
+++ /dev/null
@@ -1,16 +0,0 @@
-# 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.
-
-Version = 1.0
-Section = Miscellaneous
-Function = GetVersionExW
-Name = Positive Test for GetVersionExW
-TYPE = DEFAULT
-EXE1 = test
-Description
-= Test that all the values in the OSVERSION structure are set properly
-= for the current environment.
-
-
-
diff --git a/src/pal/tests/palsuite/paltestlist_to_be_reviewed.txt b/src/pal/tests/palsuite/paltestlist_to_be_reviewed.txt
index f7a293a69c..3f9469d254 100644
--- a/src/pal/tests/palsuite/paltestlist_to_be_reviewed.txt
+++ b/src/pal/tests/palsuite/paltestlist_to_be_reviewed.txt
@@ -144,8 +144,6 @@ miscellaneous/GetDateFormatW/GetDateFormatW_neg1/paltest_getdateformatw_getdatef
miscellaneous/GetDateFormatW/GetDateFormatW_neg2/paltest_getdateformatw_getdateformatw_neg2
miscellaneous/GetDateFormatW/test1/paltest_getdateformatw_test1
miscellaneous/GetUserNameW/test1/paltest_getusernamew_test1
-miscellaneous/GetVersionExA/test1/paltest_getversionexa_test1
-miscellaneous/GetVersionExW/test1/paltest_getversionexw_test1
miscellaneous/InterLockedExchangeAdd/test1/paltest_interlockedexchangeadd_test1
miscellaneous/IsBadCodePtr/test1/paltest_isbadcodeptr_test1
miscellaneous/IsBadReadPtr/test1/paltest_isbadreadptr_test1
diff --git a/src/pal/tools/gen-buildsys-clang.sh b/src/pal/tools/gen-buildsys-clang.sh
index 6c264cbc84..924a365af9 100755
--- a/src/pal/tools/gen-buildsys-clang.sh
+++ b/src/pal/tools/gen-buildsys-clang.sh
@@ -139,6 +139,17 @@ if [[ -n "$CROSSCOMPILE" ]]; then
fi
cmake_extra_defines="$cmake_extra_defines -C $CONFIG_DIR/tryrun.cmake"
cmake_extra_defines="$cmake_extra_defines -DCMAKE_TOOLCHAIN_FILE=$CONFIG_DIR/toolchain.cmake"
+ cmake_extra_defines="$cmake_extra_defines -DCLR_UNIX_CROSS_BUILD=1"
+fi
+if [ $OS == "Linux" ]; then
+ linux_id_file="/etc/os-release"
+ if [[ -n "$CROSSCOMPILE" ]]; then
+ linux_id_file="$ROOTFS_DIR/$linux_id_file"
+ fi
+ if [[ -e $linux_id_file ]]; then
+ source $linux_id_file
+ cmake_extra_defines="$cmake_extra_defines -DCLR_CMAKE_LINUX_ID=$ID"
+ fi
fi
if [ "$build_arch" == "armel" ]; then
cmake_extra_defines="$cmake_extra_defines -DARM_SOFTFP=1"
diff --git a/src/unwinder/i386/unwinder_i386.cpp b/src/unwinder/i386/unwinder_i386.cpp
index 2c184d1e66..5ce6e16524 100644
--- a/src/unwinder/i386/unwinder_i386.cpp
+++ b/src/unwinder/i386/unwinder_i386.cpp
@@ -76,7 +76,7 @@ OOPStackUnwinderX86::VirtualUnwind(
FillRegDisplay(&rd, ContextRecord);
- rd.SP = ContextRecord->ResumeEsp;
+ rd.SP = ContextRecord->Esp;
rd.PCTAddr = (UINT_PTR)&(ContextRecord->Eip);
if (ContextPointers)
diff --git a/src/utilcode/CMakeLists.txt b/src/utilcode/CMakeLists.txt
index 27b7a4a006..dfe830d5c0 100644
--- a/src/utilcode/CMakeLists.txt
+++ b/src/utilcode/CMakeLists.txt
@@ -1,10 +1,6 @@
set(CMAKE_INCLUDE_CURRENT_DIR ON)
-if(WIN32)
- add_compile_options(/wd4996)
-endif(WIN32)
-
set(UTILCODE_COMMON_SOURCES
clrhost_nodependencies.cpp
ccomprc.cpp
diff --git a/src/vm/arm64/asmhelpers.asm b/src/vm/arm64/asmhelpers.asm
index d760765885..e8b16ded6a 100644
--- a/src/vm/arm64/asmhelpers.asm
+++ b/src/vm/arm64/asmhelpers.asm
@@ -159,6 +159,7 @@
RestoreRegMS 26, X26
RestoreRegMS 27, X27
RestoreRegMS 28, X28
+ RestoreRegMS 29, X29
Done
; Its imperative that the return value of HelperMethodFrameRestoreState is zero
@@ -991,16 +992,6 @@ UM2MThunk_WrapperHelper_RegArgumentsSetup
; This helper enables us to call into a funclet after restoring Fp register
NESTED_ENTRY CallEHFunclet
-
- ; Using below prolog instead of PROLOG_SAVE_REG_PAIR fp,lr, #-16!
- ; is intentional. Above statement would also emit instruction to save
- ; sp in fp. If sp is saved in fp in prolog then it is not expected that fp can change in the body
- ; of method. However, this method needs to be able to change fp before calling funclet.
- ; This is required to access locals in funclet.
- PROLOG_SAVE_REG_PAIR x19,x20, #-16!
- PROLOG_SAVE_REG fp, #0
- PROLOG_SAVE_REG lr, #8
-
; On entry:
;
; X0 = throwable
@@ -1008,17 +999,42 @@ UM2MThunk_WrapperHelper_RegArgumentsSetup
; X2 = address of X19 register in CONTEXT record; used to restore the non-volatile registers of CrawlFrame
; X3 = address of the location where the SP of funclet's caller (i.e. this helper) should be saved.
;
+
+ ; Using below prolog instead of PROLOG_SAVE_REG_PAIR fp,lr, #-16!
+ ; is intentional. Above statement would also emit instruction to save
+ ; sp in fp. If sp is saved in fp in prolog then it is not expected that fp can change in the body
+ ; of method. However, this method needs to be able to change fp before calling funclet.
+ ; This is required to access locals in funclet.
+ PROLOG_SAVE_REG_PAIR_NO_FP fp,lr, #-96!
+
+ ; Spill callee saved registers
+ PROLOG_SAVE_REG_PAIR x19, x20, 16
+ PROLOG_SAVE_REG_PAIR x21, x22, 32
+ PROLOG_SAVE_REG_PAIR x23, x24, 48
+ PROLOG_SAVE_REG_PAIR x25, x26, 64
+ PROLOG_SAVE_REG_PAIR x27, x28, 80
+
; Save the SP of this function. We cannot store SP directly.
mov fp, sp
str fp, [x3]
+ ldp x19, x20, [x2, #0]
+ ldp x21, x22, [x2, #16]
+ ldp x23, x24, [x2, #32]
+ ldp x25, x26, [x2, #48]
+ ldp x27, x28, [x2, #64]
ldr fp, [x2, #80] ; offset of fp in CONTEXT relative to X19
; Invoke the funclet
blr x1
nop
- EPILOG_RESTORE_REG_PAIR fp, lr, #16!
+ EPILOG_RESTORE_REG_PAIR x19, x20, 16
+ EPILOG_RESTORE_REG_PAIR x21, x22, 32
+ EPILOG_RESTORE_REG_PAIR x23, x24, 48
+ EPILOG_RESTORE_REG_PAIR x25, x26, 64
+ EPILOG_RESTORE_REG_PAIR x27, x28, 80
+ EPILOG_RESTORE_REG_PAIR fp, lr, #96!
EPILOG_RETURN
NESTED_END CallEHFunclet
diff --git a/src/vm/baseassemblyspec.cpp b/src/vm/baseassemblyspec.cpp
index fdaa981523..4d6ba26e40 100644
--- a/src/vm/baseassemblyspec.cpp
+++ b/src/vm/baseassemblyspec.cpp
@@ -266,9 +266,9 @@ BOOL BaseAssemblySpec::CompareRefToDef(const BaseAssemblySpec *pRef, const BaseA
}
//
- // flags are non-optional, except processor architecture and content type
+ // flags are non-optional, except processor architecture, content type, and debuggable attribute bits
//
- DWORD dwFlagsMask = ~(afPA_FullMask | afContentType_Mask);
+ DWORD dwFlagsMask = ~(afPA_FullMask | afContentType_Mask | afDebuggableAttributeMask);
if ((pRef->m_dwFlags & dwFlagsMask) != (pDef->m_dwFlags & dwFlagsMask))
return FALSE;
diff --git a/src/vm/ceemain.cpp b/src/vm/ceemain.cpp
index 1caed49296..dd8438e7db 100644
--- a/src/vm/ceemain.cpp
+++ b/src/vm/ceemain.cpp
@@ -485,6 +485,7 @@ void InitializeStartupFlags()
InitializeHeapType((flags & STARTUP_SERVER_GC) != 0);
+ g_heap_type = (flags & STARTUP_SERVER_GC) == 0 ? GC_HEAP_WKS : GC_HEAP_SVR;
#ifdef FEATURE_LOADER_OPTIMIZATION
g_dwGlobalSharePolicy = (flags&STARTUP_LOADER_OPTIMIZATION_MASK)>>1;
@@ -3408,24 +3409,4 @@ void ContractRegressionCheck()
#endif // ENABLE_CONTRACTS_IMPL
-
#endif // CROSSGEN_COMPILE
-
-
-//
-// GetOSVersion - Gets the real OS version bypassing the OS compatibility shim
-// Mscoree.dll resides in System32 dir and is always excluded from compat shim.
-// This function calls mscoree!shim function via mscoreei ICLRRuntimeHostInternal interface
-// to get the OS version. We do not do this PAL or coreclr..we direclty call the OS
-// in that case.
-//
-BOOL GetOSVersion(LPOSVERSIONINFO lposVer)
-{
-// Fix for warnings when building against WinBlue build 9444.0.130614-1739
-// warning C4996: 'GetVersionExW': was declared deprecated
-// externalapis\windows\winblue\sdk\inc\sysinfoapi.h(442)
-// Deprecated. Use VerifyVersionInfo* or IsWindows* macros from VersionHelpers.
-#pragma warning( disable : 4996 )
- return WszGetVersionEx(lposVer);
-#pragma warning( default : 4996 )
-}
diff --git a/src/vm/codeman.cpp b/src/vm/codeman.cpp
index ad4c5196b1..c2632f7f8a 100644
--- a/src/vm/codeman.cpp
+++ b/src/vm/codeman.cpp
@@ -985,6 +985,13 @@ PTR_VOID GetUnwindDataBlob(TADDR moduleBase, PTR_RUNTIME_FUNCTION pRuntimeFuncti
return pUnwindInfo;
+#elif defined(_TARGET_X86_) && defined(FEATURE_PAL)
+ PTR_UNWIND_INFO pUnwindInfo(dac_cast<PTR_UNWIND_INFO>(moduleBase + RUNTIME_FUNCTION__GetUnwindInfoAddress(pRuntimeFunction)));
+
+ *pSize = ALIGN_UP(sizeof(UNWIND_INFO), sizeof(DWORD));
+
+ return pUnwindInfo;
+
#elif defined(_TARGET_ARM_)
// if this function uses packed unwind data then at least one of the two least significant bits
diff --git a/src/vm/crossgencompile.cpp b/src/vm/crossgencompile.cpp
index c29d3cc60b..b106ecc918 100644
--- a/src/vm/crossgencompile.cpp
+++ b/src/vm/crossgencompile.cpp
@@ -133,9 +133,7 @@ BOOL g_fEEComActivatedStartup=FALSE;
GVAL_IMPL_INIT(DWORD, g_fHostConfig, 0);
-#ifdef FEATURE_SVR_GC
-SVAL_IMPL_INIT(uint32_t,IGCHeap,gcHeapType,IGCHeap::GC_HEAP_WKS);
-#endif
+GVAL_IMPL_INIT(GCHeapType, g_heap_type, GC_HEAP_WKS);
void UpdateGCSettingFromHost()
{
diff --git a/src/vm/domainfile.cpp b/src/vm/domainfile.cpp
index 253ebbbd52..2193c5a28d 100644
--- a/src/vm/domainfile.cpp
+++ b/src/vm/domainfile.cpp
@@ -2418,14 +2418,11 @@ void DomainAssembly::GetCurrentVersionInfo(CORCOMPILE_VERSION_INFO *pNativeVersi
&fForceProfiling,
&fForceInstrument);
- OSVERSIONINFOW osInfo;
- osInfo.dwOSVersionInfoSize = sizeof(osInfo);
- if (!GetOSVersion(&osInfo))
- _ASSERTE(!"GetOSVersion failed");
-
- _ASSERTE(osInfo.dwMajorVersion < 999);
- _ASSERTE(osInfo.dwMinorVersion < 999);
- pNativeVersionInfo->wOSPlatformID = (WORD) osInfo.dwPlatformId;
+#ifndef FEATURE_PAL
+ pNativeVersionInfo->wOSPlatformID = VER_PLATFORM_WIN32_NT;
+#else
+ pNativeVersionInfo->wOSPlatformID = VER_PLATFORM_UNIX;
+#endif
// The native images should be OS-version agnostic. Do not store the actual OS version for determinism.
// pNativeVersionInfo->wOSMajorVersion = (WORD) osInfo.dwMajorVersion;
diff --git a/src/vm/ecalllist.h b/src/vm/ecalllist.h
index ad73135f63..415926eafa 100644
--- a/src/vm/ecalllist.h
+++ b/src/vm/ecalllist.h
@@ -170,8 +170,6 @@ FCFuncStart(gDateTimeFuncs)
FCFuncEnd()
FCFuncStart(gEnvironmentFuncs)
- FCFuncElement("GetVersion", SystemNative::GetOSVersion)
- FCFuncElement("GetVersionEx", SystemNative::GetOSVersionEx)
FCFuncElement("get_TickCount", SystemNative::GetTickCount)
QCFuncElement("_Exit", SystemNative::Exit)
FCFuncElement("set_ExitCode", SystemNative::SetExitCode)
@@ -181,7 +179,7 @@ FCFuncStart(gEnvironmentFuncs)
FCFuncElement("GetCommandLineArgsNative", SystemNative::GetCommandLineArgs)
FCFuncElement("get_CurrentProcessorNumber", SystemNative::GetCurrentProcessorNumber)
-#if defined(FEATURE_COMINTEROP) && !defined(FEATURE_CORESYSTEM)
+#if defined(FEATURE_COMINTEROP)
QCFuncElement("WinRTSupported", SystemNative::WinRTSupported)
#endif // FEATURE_COMINTEROP
FCFuncElementSig("FailFast", &gsig_SM_Str_RetVoid, SystemNative::FailFast)
diff --git a/src/vm/eetwain.cpp b/src/vm/eetwain.cpp
index 18bc24ae39..aff2507489 100644
--- a/src/vm/eetwain.cpp
+++ b/src/vm/eetwain.cpp
@@ -3815,7 +3815,10 @@ bool UnwindEbpDoubleAlignFrame(
// TODO Currently we assume that ESP of funclet frames is always fixed but actually it could change.
if (pCodeInfo->IsFunclet())
{
- baseSP = curESP + 12; // padding for 16byte stack alignment allocated in genFuncletProlog()
+ // Set baseSP as initial SP
+ baseSP = pContext->pCurrentContext->ResumeEsp;
+ // 16-byte stack alignment padding (allocated in genFuncletProlog)
+ baseSP += 12;
pContext->PCTAddr = baseSP;
pContext->ControlPC = *PTR_PCODE(pContext->PCTAddr);
@@ -4163,6 +4166,14 @@ bool EECodeManager::EnumGcRefs( PREGDISPLAY pContext,
GC_NOTRIGGER;
} CONTRACTL_END;
+#ifdef WIN64EXCEPTIONS
+ if (flags & ParentOfFuncletStackFrame)
+ {
+ LOG((LF_GCROOTS, LL_INFO100000, "Not reporting this frame because it was already reported via another funclet.\n"));
+ return true;
+ }
+#endif // WIN64EXCEPTIONS
+
GCInfoToken gcInfoToken = pCodeInfo->GetGCInfoToken();
unsigned curOffs = pCodeInfo->GetRelOffset();
@@ -4752,6 +4763,18 @@ bool EECodeManager::EnumGcRefs( PREGDISPLAY pContext,
_ASSERTE(*castto(table, unsigned short *)++ == 0xBABE);
#endif
+#ifdef WIN64EXCEPTIONS // funclets
+ //
+ // If we're in a funclet, we do not want to report the incoming varargs. This is
+ // taken care of by the parent method and the funclet should access those arguments
+ // by way of the parent method's stack frame.
+ //
+ if(pCodeInfo->IsFunclet())
+ {
+ return true;
+ }
+#endif // WIN64EXCEPTIONS
+
/* Are we a varargs function, if so we have to report all args
except 'this' (note that the GC tables created by the x86 jit
do not contain ANY arguments except 'this' (even if they
diff --git a/src/vm/eventtrace.cpp b/src/vm/eventtrace.cpp
index b708f17e34..1eb89385a6 100644
--- a/src/vm/eventtrace.cpp
+++ b/src/vm/eventtrace.cpp
@@ -4310,27 +4310,6 @@ HRESULT ETW::CEtwTracer::Register()
{
WRAPPER_NO_CONTRACT;
-#ifndef FEATURE_CORESYSTEM
- OSVERSIONINFO osVer;
- osVer.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
-
- if (GetOSVersion(&osVer) == FALSE) {
- return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED);
- }
- else if (osVer.dwMajorVersion < ETW_SUPPORTED_MAJORVER) {
- return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED);
- }
-
- // if running on OS < Longhorn, skip registration unless reg key is set
- // since ETW reg is expensive (in both time and working set) on older OSes
- if (osVer.dwMajorVersion < ETW_ENABLED_MAJORVER && !g_fEnableETW && !CLRConfig::GetConfigValue(CLRConfig::EXTERNAL_PreVistaETWEnabled))
- return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED);
-
- // If running on OS >= Longhorn, skip registration if ETW is not enabled
- if (osVer.dwMajorVersion >= ETW_ENABLED_MAJORVER && !g_fEnableETW && !CLRConfig::GetConfigValue(CLRConfig::EXTERNAL_VistaAndAboveETWEnabled))
- return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED);
-#endif
-
EventRegisterMicrosoft_Windows_DotNETRuntime();
EventRegisterMicrosoft_Windows_DotNETRuntimePrivate();
EventRegisterMicrosoft_Windows_DotNETRuntimeRundown();
diff --git a/src/vm/exinfo.h b/src/vm/exinfo.h
index 6b34e71116..4a6c3e5dcc 100644
--- a/src/vm/exinfo.h
+++ b/src/vm/exinfo.h
@@ -134,7 +134,7 @@ public:
return m_pPrevNestedInfo;
}
- // Returns the throwble associated with the tracker
+ // Returns the throwable associated with the tracker
inline OBJECTREF GetThrowable()
{
LIMITED_METHOD_CONTRACT;
diff --git a/src/vm/gcenv.ee.cpp b/src/vm/gcenv.ee.cpp
index e8619953ff..f11b8f9aba 100644
--- a/src/vm/gcenv.ee.cpp
+++ b/src/vm/gcenv.ee.cpp
@@ -29,6 +29,15 @@
#include "comcallablewrapper.h"
#endif // FEATURE_COMINTEROP
+// the method table for the WeakReference class
+extern MethodTable* pWeakReferenceMT;
+
+// The canonical method table for WeakReference<T>
+extern MethodTable* pWeakReferenceOfTCanonMT;
+
+// Finalizes a weak reference directly.
+extern void FinalizeWeakReference(Object* obj);
+
void GCToEEInterface::SuspendEE(SUSPEND_REASON reason)
{
WRAPPER_NO_CONTRACT;
@@ -1016,6 +1025,7 @@ void GCProfileWalkHeapWorker(BOOL fProfilerPinned, BOOL fShouldWalkHeapRootsForE
{
{
ProfilingScanContext SC(fProfilerPinned);
+ unsigned max_generation = GCHeapUtilities::GetGCHeap()->GetMaxGeneration();
// **** Scan roots: Only scan roots if profiling API wants them or ETW wants them.
if (fProfilerPinned || fShouldWalkHeapRootsForEtw)
@@ -1349,3 +1359,38 @@ void GCToEEInterface::HandleFatalError(unsigned int exitCode)
{
EEPOLICY_HANDLE_FATAL_ERROR(exitCode);
}
+
+bool GCToEEInterface::ShouldFinalizeObjectForUnload(AppDomain* pDomain, Object* obj)
+{
+ // CoreCLR does not have appdomains, so this code path is dead. Other runtimes may
+ // choose to inspect the object being finalized here.
+ // [DESKTOP TODO] Desktop looks for "agile and finalizable" objects and may choose
+ // to move them to a new app domain instead of finalizing them here.
+ return true;
+}
+
+bool GCToEEInterface::ForceFullGCToBeBlocking()
+{
+ // In theory, there is nothing fundamental that requires an AppDomain unload to induce
+ // a blocking GC. In the past, this workaround was done to fix an Stress AV, but the root
+ // cause of the AV was never discovered and this workaround remains in place.
+ //
+ // It would be nice if this were not necessary. However, it's not clear if the aformentioned
+ // stress bug is still lurking and will return if this workaround is removed. We should
+ // do some experiments: remove this workaround and see if the stress bug still repros.
+ // If so, we should find the root cause instead of relying on this.
+ return !!SystemDomain::System()->RequireAppDomainCleanup();
+}
+
+bool GCToEEInterface::EagerFinalized(Object* obj)
+{
+ MethodTable* pMT = obj->GetGCSafeMethodTable();
+ if (pMT == pWeakReferenceMT ||
+ pMT->GetCanonicalMethodTable() == pWeakReferenceOfTCanonMT)
+ {
+ FinalizeWeakReference(obj);
+ return true;
+ }
+
+ return false;
+}
diff --git a/src/vm/gcenv.ee.h b/src/vm/gcenv.ee.h
index e3ced6c65a..3eca755761 100644
--- a/src/vm/gcenv.ee.h
+++ b/src/vm/gcenv.ee.h
@@ -45,6 +45,10 @@ public:
void EnableFinalization(bool foundFinalizers);
void HandleFatalError(unsigned int exitCode);
+ bool ShouldFinalizeObjectForUnload(AppDomain* pDomain, Object* obj);
+ bool ShouldElevateForAppDomainCleanup();
+ bool ForceFullGCToBeBlocking();
+ bool EagerFinalized(Object* obj);
};
#endif // FEATURE_STANDALONE_GC
diff --git a/src/vm/gcheaputilities.cpp b/src/vm/gcheaputilities.cpp
index aa90341159..91640d30a2 100644
--- a/src/vm/gcheaputilities.cpp
+++ b/src/vm/gcheaputilities.cpp
@@ -4,6 +4,8 @@
#include "common.h"
#include "gcheaputilities.h"
+#include "appdomain.hpp"
+
// These globals are variables used within the GC and maintained
// by the EE for use in write barriers. It is the responsibility
@@ -12,6 +14,7 @@
GPTR_IMPL_INIT(uint32_t, g_card_table, nullptr);
GPTR_IMPL_INIT(uint8_t, g_lowest_address, nullptr);
GPTR_IMPL_INIT(uint8_t, g_highest_address, nullptr);
+GVAL_IMPL_INIT(GCHeapType, g_heap_type, GC_HEAP_INVALID);
uint8_t* g_ephemeral_low = (uint8_t*)1;
uint8_t* g_ephemeral_high = (uint8_t*)~0;
@@ -36,3 +39,37 @@ bool g_sw_ww_enabled_for_gc_heap = false;
gc_alloc_context g_global_alloc_context = {};
+// Debug-only validation for handle.
+void ValidateHandleAndAppDomain(OBJECTHANDLE handle)
+{
+#ifdef _DEBUG_IMPL
+ OBJECTREF objRef = ObjectToOBJECTREF(*(Object**)handle);
+ VALIDATEOBJECTREF(objRef);
+
+ IGCHandleTable *pHandleTable = GCHeapUtilities::GetGCHandleTable();
+
+ void* handleTable = pHandleTable->GetHandleTableForHandle(handle);
+ DWORD context = (DWORD)pHandleTable->GetHandleTableContext(handleTable);
+
+ ADIndex appDomainIndex = ADIndex(context);
+ AppDomain *domain = SystemDomain::GetAppDomainAtIndex(appDomainIndex);
+
+ // Access to a handle in an unloaded domain is not allowed
+ assert(domain != nullptr);
+ assert(!domain->NoAccessToHandleTable());
+
+#if CHECK_APP_DOMAIN_LEAKS
+ if (g_pConfig->AppDomainLeaks() && objRef != NULL)
+ {
+ if (appDomainIndex.m_dwIndex)
+ {
+ objRef->TryAssignAppDomain(domain);
+ }
+ else
+ {
+ objRef->TrySetAppDomainAgile();
+ }
+ }
+#endif // CHECK_APP_DOMAIN_LEAKS
+#endif // _DEBUG_IMPL
+}
diff --git a/src/vm/gcheaputilities.h b/src/vm/gcheaputilities.h
index 1e920127fe..baa2558b8e 100644
--- a/src/vm/gcheaputilities.h
+++ b/src/vm/gcheaputilities.h
@@ -16,6 +16,7 @@ extern "C" {
GPTR_DECL(uint8_t,g_lowest_address);
GPTR_DECL(uint8_t,g_highest_address);
GPTR_DECL(uint32_t,g_card_table);
+GVAL_DECL(GCHeapType, g_heap_type);
#ifndef DACCESS_COMPILE
}
#endif // !DACCESS_COMPILE
@@ -120,10 +121,11 @@ public:
inline static bool IsServerHeap()
{
LIMITED_METHOD_CONTRACT;
+
#ifdef FEATURE_SVR_GC
- _ASSERTE(IGCHeap::gcHeapType != IGCHeap::GC_HEAP_INVALID);
- return (IGCHeap::gcHeapType == IGCHeap::GC_HEAP_SVR);
-#else // FEATURE_SVR_GC
+ _ASSERTE(g_heap_type != GC_HEAP_INVALID);
+ return g_heap_type == GC_HEAP_SVR;
+#else
return false;
#endif // FEATURE_SVR_GC
}
@@ -209,5 +211,22 @@ private:
GCHeapUtilities() = delete;
};
+// Handle-related utilities.
+
+void ValidateHandleAndAppDomain(OBJECTHANDLE handle);
+
+// Given a handle, returns an OBJECTREF for the object it refers to.
+inline OBJECTREF ObjectFromHandle(OBJECTHANDLE handle)
+{
+ _ASSERTE(handle);
+
+#ifdef _DEBUG_IMPL
+ ValidateHandleAndAppDomain(handle);
+#endif // _DEBUG_IMPL
+
+ // Wrap the raw OBJECTREF and return it
+ return UNCHECKED_OBJECTREF_TO_OBJECTREF(*PTR_UNCHECKED_OBJECTREF(handle));
+}
+
#endif // _GCHEAPUTILITIES_H_
diff --git a/src/vm/gdbjit.cpp b/src/vm/gdbjit.cpp
index 30a6a38d7c..1f2bedf39a 100644
--- a/src/vm/gdbjit.cpp
+++ b/src/vm/gdbjit.cpp
@@ -398,7 +398,10 @@ HRESULT FunctionMember::GetLocalsDebugInfo(NotifyGdb::PTK_TypeInfoMap pTypeMap,
{
if (FindNativeInfoInILVariable(0, startNativeOffset, &locals.pVars, locals.countVars, &nativeVar) == S_OK)
{
- vars[0].m_var_type = GetTypeInfoFromTypeHandle(TypeHandle(md->GetMethodTable()), pTypeMap, method);
+ TypeHandle th = TypeHandle(md->GetMethodTable());
+ if (th.IsValueType())
+ th = th.MakePointer();
+ vars[0].m_var_type = GetTypeInfoFromTypeHandle(th, pTypeMap, method);
vars[0].m_var_name = new char[strlen("this") + 1];
strcpy(vars[0].m_var_name, "this");
vars[0].m_il_index = 0;
diff --git a/src/vm/i386/asmhelpers.S b/src/vm/i386/asmhelpers.S
index a19d2a8f5e..0ab23f1572 100644
--- a/src/vm/i386/asmhelpers.S
+++ b/src/vm/i386/asmhelpers.S
@@ -966,6 +966,14 @@ DYNAMICHELPER (DynamicHelperFrameFlags_ObjectArg | DynamicHelperFrameFlags_Objec
#endif // FEATURE_READYTORUN
+//
+// Entry stack:
+// dispatch token
+// siteAddrForRegisterIndirect (used only if this is a RegisterIndirect dispatch call)
+// return address of caller to stub
+//
+// Please see vm/i386/virtualcallstubcpu.hpp for details
+//
NESTED_ENTRY ResolveWorkerAsmStub, _TEXT, NoHandler
//
// The stub arguments are where we want to setup the TransitionBlock. We will
@@ -987,32 +995,40 @@ NESTED_ENTRY ResolveWorkerAsmStub, _TEXT, NoHandler
mov esi, esp
+ #define STACK_ALIGN_PADDING 8
+
+ sub esp, STACK_ALIGN_PADDING
push [esi + 4*4] // dispatch token
push [esi + 5*4] // siteAddrForRegisterIndirect
push esi // pTransitionBlock
// Setup up proper EBP frame now that the stub arguments can be trashed
- mov [esi + 4*4],ebx
- mov [esi + 5*4],ebp
+ mov [esi + 4*4], ebx
+ mov [esi + 5*4], ebp
lea ebp, [esi + 5*4]
// Make the call
+ CHECK_STACK_ALIGNMENT
call C_FUNC(VSD_ResolveWorker)
+ add esp, STACK_ALIGN_PADDING
+
+ #undef STACK_ALIGN_PADDING
+
// From here on, mustn't trash eax
// pop ArgumentRegisters
- pop edx
- pop ecx
+ pop edx
+ pop ecx
// pop CalleeSavedRegisters
- pop edi
- pop esi
- pop ebx
- pop ebp
+ pop edi
+ pop esi
+ pop ebx
+ pop ebp
// Now jump to the target
- jmp eax // continue on into the method
+ jmp eax // continue on into the method
NESTED_END ResolveWorkerAsmStub, _TEXT
#ifdef FEATURE_STUBS_AS_IL
diff --git a/src/vm/jitinterface.cpp b/src/vm/jitinterface.cpp
index 248deac04d..338c274014 100644
--- a/src/vm/jitinterface.cpp
+++ b/src/vm/jitinterface.cpp
@@ -8719,7 +8719,6 @@ CORINFO_METHOD_HANDLE CEEInfo::resolveVirtualMethodHelper(CORINFO_METHOD_HANDLE
CORINFO_CONTEXT_HANDLE ownerType)
{
CONTRACTL {
- SO_TOLERANT;
THROWS;
GC_TRIGGERS;
MODE_PREEMPTIVE;
@@ -9917,15 +9916,12 @@ void CEEInfo::getEEInfo(CORINFO_EE_INFO *pEEInfoOut)
pEEInfoOut->maxUncheckedOffsetForNullObject = MAX_UNCHECKED_OFFSET_FOR_NULL_OBJECT;
pEEInfoOut->targetAbi = CORINFO_CORECLR_ABI;
- OSVERSIONINFO sVerInfo;
- sVerInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
- GetOSVersion(&sVerInfo);
-
pEEInfoOut->osType = CORINFO_WINNT;
- pEEInfoOut->osMajor = sVerInfo.dwMajorVersion;
- pEEInfoOut->osMinor = sVerInfo.dwMinorVersion;
- pEEInfoOut->osBuild = sVerInfo.dwBuildNumber;
+ // hardcode OS version to 0.0.0. These fields can be removed from JITEE interface
+ pEEInfoOut->osMajor = 0;
+ pEEInfoOut->osMinor = 0;
+ pEEInfoOut->osBuild = 0;
EE_TO_JIT_TRANSITION();
}
diff --git a/src/vm/prestub.cpp b/src/vm/prestub.cpp
index e6467710dd..67639e99b2 100644
--- a/src/vm/prestub.cpp
+++ b/src/vm/prestub.cpp
@@ -285,7 +285,7 @@ PCODE MethodDesc::MakeJitWorker(COR_ILMETHOD_DECODER* ILHeader, CORJIT_FLAGS fla
bool fBackgroundThread = flags.IsSet(CORJIT_FLAGS::CORJIT_FLAG_MCJIT_BACKGROUND);
#endif
- // If this is the first stage of a tiered compilation progression, use min-opt, otherwise
+ // If this is the first stage of a tiered compilation progression, use tier0, otherwise
// use default compilation options
#ifdef FEATURE_TIERED_COMPILATION
if (!IsEligibleForTieredCompilation())
@@ -295,7 +295,7 @@ PCODE MethodDesc::MakeJitWorker(COR_ILMETHOD_DECODER* ILHeader, CORJIT_FLAGS fla
else
{
fStable = FALSE;
- flags.Add(CORJIT_FLAGS(CORJIT_FLAGS::CORJIT_FLAG_MIN_OPT));
+ flags.Add(CORJIT_FLAGS(CORJIT_FLAGS::CORJIT_FLAG_TIER0));
}
#endif
diff --git a/src/vm/readytoruninfo.cpp b/src/vm/readytoruninfo.cpp
index 623556d793..b85cf9a9c3 100644
--- a/src/vm/readytoruninfo.cpp
+++ b/src/vm/readytoruninfo.cpp
@@ -53,7 +53,7 @@ MethodDesc * ReadyToRunInfo::GetMethodDescForEntryPoint(PCODE entryPoint)
}
CONTRACTL_END;
-#ifdef _TARGET_AMD64_
+#if defined(_TARGET_AMD64_) || (defined(_TARGET_X86_) && defined(FEATURE_PAL))
// A normal method entry point is always 8 byte aligned, but a funclet can start at an odd address.
// Since PtrHashMap can't handle odd pointers, check for this case and return NULL.
if ((entryPoint & 0x1) != 0)
diff --git a/src/vm/rexcep.h b/src/vm/rexcep.h
index 0417bef5be..b4a8318d92 100644
--- a/src/vm/rexcep.h
+++ b/src/vm/rexcep.h
@@ -109,8 +109,7 @@
//
DEFINE_EXCEPTION(g_ReflectionNS, AmbiguousMatchException, false, COR_E_AMBIGUOUSMATCH)
-// ApplicationException is removed in CoreCLR
-#define kApplicationException kException
+DEFINE_EXCEPTION(g_SystemNS, ApplicationException, false, COR_E_APPLICATION)
DEFINE_EXCEPTION(g_SystemNS, AppDomainUnloadedException, false, COR_E_APPDOMAINUNLOADED)
DEFINE_EXCEPTION(g_SystemNS, ArithmeticException, false, COR_E_ARITHMETIC)
diff --git a/src/vm/threads.cpp b/src/vm/threads.cpp
index da805bdd46..68a81bf606 100644
--- a/src/vm/threads.cpp
+++ b/src/vm/threads.cpp
@@ -5750,6 +5750,7 @@ void ThreadStore::InitThreadStore()
}
s_DeadThreadGCTriggerPeriodMilliseconds =
CLRConfig::GetConfigValue(CLRConfig::INTERNAL_Thread_DeadThreadGCTriggerPeriodMilliseconds);
+ s_DeadThreadGenerationCounts = nullptr;
}
// Enter and leave the critical section around the thread store. Clients should
@@ -5986,6 +5987,7 @@ void ThreadStore::TransferStartedThread(Thread *thread, BOOL bRequiresTSL)
LONG ThreadStore::s_DeadThreadCountThresholdForGCTrigger = 0;
DWORD ThreadStore::s_DeadThreadGCTriggerPeriodMilliseconds = 0;
+SIZE_T *ThreadStore::s_DeadThreadGenerationCounts = nullptr;
void ThreadStore::IncrementDeadThreadCountForGCTrigger()
{
@@ -6012,7 +6014,7 @@ void ThreadStore::IncrementDeadThreadCountForGCTrigger()
return;
}
- SIZE_T gcLastMilliseconds = gcHeap->GetLastGCStartTime(max_generation);
+ SIZE_T gcLastMilliseconds = gcHeap->GetLastGCStartTime(gcHeap->GetMaxGeneration());
SIZE_T gcNowMilliseconds = gcHeap->GetNow();
if (gcNowMilliseconds - gcLastMilliseconds < s_DeadThreadGCTriggerPeriodMilliseconds)
{
@@ -6088,11 +6090,22 @@ void ThreadStore::TriggerGCForDeadThreadsIfNecessary()
return;
}
- int gcGenerationToTrigger = 0;
+ unsigned gcGenerationToTrigger = 0;
IGCHeap *gcHeap = GCHeapUtilities::GetGCHeap();
_ASSERTE(gcHeap != nullptr);
SIZE_T generationCountThreshold = static_cast<SIZE_T>(s_DeadThreadCountThresholdForGCTrigger) / 2;
- SIZE_T newDeadThreadGenerationCounts[max_generation + 1] = {0};
+ unsigned maxGeneration = gcHeap->GetMaxGeneration();
+ if (!s_DeadThreadGenerationCounts)
+ {
+ // initialize this field on first use with an entry for every table.
+ s_DeadThreadGenerationCounts = new (nothrow) SIZE_T[maxGeneration + 1];
+ if (!s_DeadThreadGenerationCounts)
+ {
+ return;
+ }
+ }
+
+ memset(s_DeadThreadGenerationCounts, 0, sizeof(SIZE_T) * (maxGeneration + 1));
{
ThreadStoreLockHolder threadStoreLockHolder;
GCX_COOP();
@@ -6114,12 +6127,12 @@ void ThreadStore::TriggerGCForDeadThreadsIfNecessary()
continue;
}
- int exposedObjectGeneration = gcHeap->WhichGeneration(exposedObject);
- SIZE_T newDeadThreadGenerationCount = ++newDeadThreadGenerationCounts[exposedObjectGeneration];
+ unsigned exposedObjectGeneration = gcHeap->WhichGeneration(exposedObject);
+ SIZE_T newDeadThreadGenerationCount = ++s_DeadThreadGenerationCounts[exposedObjectGeneration];
if (exposedObjectGeneration > gcGenerationToTrigger && newDeadThreadGenerationCount >= generationCountThreshold)
{
gcGenerationToTrigger = exposedObjectGeneration;
- if (gcGenerationToTrigger >= max_generation)
+ if (gcGenerationToTrigger >= maxGeneration)
{
break;
}
@@ -6153,8 +6166,8 @@ void ThreadStore::TriggerGCForDeadThreadsIfNecessary()
continue;
}
- if (gcGenerationToTrigger < max_generation &&
- static_cast<int>(gcHeap->WhichGeneration(exposedObject)) > gcGenerationToTrigger)
+ if (gcGenerationToTrigger < maxGeneration &&
+ gcHeap->WhichGeneration(exposedObject) > gcGenerationToTrigger)
{
continue;
}
diff --git a/src/vm/threads.h b/src/vm/threads.h
index f34066feb3..697ffea454 100644
--- a/src/vm/threads.h
+++ b/src/vm/threads.h
@@ -5555,6 +5555,7 @@ private:
private:
static LONG s_DeadThreadCountThresholdForGCTrigger;
static DWORD s_DeadThreadGCTriggerPeriodMilliseconds;
+ static SIZE_T *s_DeadThreadGenerationCounts;
public:
diff --git a/src/vm/tieredcompilation.cpp b/src/vm/tieredcompilation.cpp
index 64378dbfc2..2032e66f1b 100644
--- a/src/vm/tieredcompilation.cpp
+++ b/src/vm/tieredcompilation.cpp
@@ -300,7 +300,7 @@ PCODE TieredCompilationManager::CompileMethod(MethodDesc* pMethod)
EX_TRY
{
CORJIT_FLAGS flags = CORJIT_FLAGS(CORJIT_FLAGS::CORJIT_FLAG_MCJIT_BACKGROUND);
- flags.Add(CORJIT_FLAGS(CORJIT_FLAGS::CORJIT_FLAG_SPEED_OPT));
+ flags.Add(CORJIT_FLAGS(CORJIT_FLAGS::CORJIT_FLAG_TIER1));
if (pMethod->IsDynamicMethod())
{
diff --git a/src/zap/zapcode.cpp b/src/zap/zapcode.cpp
index e54e884bc2..ead385d5e0 100644
--- a/src/zap/zapcode.cpp
+++ b/src/zap/zapcode.cpp
@@ -1202,6 +1202,30 @@ void ZapUnwindData::Save(ZapWriter * pZapWriter)
#endif //REDHAWK
}
+#elif defined(_TARGET_X86_) && defined(FEATURE_PAL)
+
+UINT ZapUnwindData::GetAlignment()
+{
+ return sizeof(BYTE);
+}
+
+DWORD ZapUnwindData::GetSize()
+{
+ DWORD dwSize = ZapBlob::GetSize();
+
+ return dwSize;
+}
+
+void ZapUnwindData::Save(ZapWriter * pZapWriter)
+{
+ ZapImage * pImage = ZapImage::GetImage(pZapWriter);
+
+ PVOID pData = GetData();
+ DWORD dwSize = GetBlobSize();
+
+ pZapWriter->Write(pData, dwSize);
+}
+
#elif defined(_TARGET_ARM_) || defined(_TARGET_ARM64_)
UINT ZapUnwindData::GetAlignment()
diff --git a/src/zap/zapimage.cpp b/src/zap/zapimage.cpp
index 457b82e1fd..cb69ba9f96 100644
--- a/src/zap/zapimage.cpp
+++ b/src/zap/zapimage.cpp
@@ -1089,14 +1089,14 @@ HANDLE ZapImage::SaveImage(LPCWSTR wszOutputFileName, CORCOMPILE_NGEN_SIGNATURE
OutputTables();
- // Create a empty export table. This makes tools like symchk not think
- // that native images are resoure-only DLLs. It is important to NOT
- // be a resource-only DLL because those DLL's PDBS are not put up on the
- // symbol server and we want NEN PDBS to be placed there.
- ZapPEExports* exports = new(GetHeap()) ZapPEExports(wszOutputFileName);
- m_pDebugSection->Place(exports);
- SetDirectoryEntry(IMAGE_DIRECTORY_ENTRY_EXPORT, exports);
-
+ // Create a empty export table. This makes tools like symchk not think
+ // that native images are resoure-only DLLs. It is important to NOT
+ // be a resource-only DLL because those DLL's PDBS are not put up on the
+ // symbol server and we want NEN PDBS to be placed there.
+ ZapPEExports* exports = new(GetHeap()) ZapPEExports(wszOutputFileName);
+ m_pDebugSection->Place(exports);
+ SetDirectoryEntry(IMAGE_DIRECTORY_ENTRY_EXPORT, exports);
+
ComputeRVAs();
if (!IsReadyToRunCompilation())
@@ -1588,13 +1588,53 @@ ZapImage::CompileStatus ZapImage::CompileProfileDataWorker(mdToken token, unsign
return TryCompileMethodDef(token, methodProfilingDataFlags);
}
-void ZapImage::CompileProfileData()
+// ProfileDisableInlining
+// Before we start compiling any methods we may need to suppress the inlining
+// of certain methods based upon our profile data.
+// This method will arrange to disable this inlining.
+//
+void ZapImage::ProfileDisableInlining()
{
+ // We suppress the inlining of any Hot methods that have the ExcludeHotMethodCode flag.
+ // We want such methods to be Jitted at runtime rather than compiled in the AOT native image.
+ // The inlining of such a method also need to be suppressed.
+ //
+ ProfileDataSection* methodProfileData = &(m_profileDataSections[MethodProfilingData]);
+ if (methodProfileData->tableSize > 0)
+ {
+ for (DWORD i = 0; i < methodProfileData->tableSize; i++)
+ {
+ CORBBTPROF_TOKEN_INFO * pTokenInfo = &(methodProfileData->pTable[i]);
+ unsigned methodProfilingDataFlags = pTokenInfo->flags;
+
+ // Hot methods can be marked to be excluded from the AOT native image.
+ // We also need to disable inlining of such methods.
+ //
+ if ((methodProfilingDataFlags & (1 << DisableInlining)) != 0)
+ {
+ // Disable the inlining of this method
+ //
+ // @ToDo: Figure out how to disable inlining for this method.
+ }
+ }
+ }
+}
+
+// CompileHotRegion
+// Performs the compilation and placement for all methods in the the "Hot" code region
+// Methods placed in this region typically correspond to all of the methods that were
+// executed during any of the profiling scenarios.
+//
+void ZapImage::CompileHotRegion()
+{
+ // Compile all of the methods that were executed during profiling into the "Hot" code region.
+ //
BeginRegion(CORINFO_REGION_HOT);
CorProfileData* pProfileData = GetProfileData();
- if (m_profileDataSections[MethodProfilingData].tableSize > 0)
+ ProfileDataSection* methodProfileData = &(m_profileDataSections[MethodProfilingData]);
+ if (methodProfileData->tableSize > 0)
{
// record the start of hot IBC methods.
m_iIBCMethod = m_MethodCompilationOrder.GetCount();
@@ -1602,19 +1642,21 @@ void ZapImage::CompileProfileData()
//
// Compile the hot methods in the order specified in the MethodProfilingData
//
- for (DWORD i = 0; i < m_profileDataSections[MethodProfilingData].tableSize; i++)
+ for (DWORD i = 0; i < methodProfileData->tableSize; i++)
{
- unsigned methodProfilingDataFlags = m_profileDataSections[MethodProfilingData].pTable[i].flags;
- _ASSERTE(methodProfilingDataFlags != 0);
+ CompileStatus compileResult = NOT_COMPILED;
+ CORBBTPROF_TOKEN_INFO * pTokenInfo = &(methodProfileData->pTable[i]);
- mdToken token = m_profileDataSections[MethodProfilingData].pTable[i].token;
+ mdToken token = pTokenInfo->token;
+ unsigned methodProfilingDataFlags = pTokenInfo->flags;
+ _ASSERTE(methodProfilingDataFlags != 0);
if (TypeFromToken(token) == mdtMethodDef)
{
//
// Compile a non-generic method
//
- CompileProfileDataWorker(token, methodProfilingDataFlags);
+ compileResult = CompileProfileDataWorker(token, methodProfilingDataFlags);
}
else if (TypeFromToken(token) == ibcMethodSpec)
{
@@ -1638,10 +1680,14 @@ void ZapImage::CompileProfileData()
{
m_pPreloader->AddMethodToTransitiveClosureOfInstantiations(pMethod);
- TryCompileInstantiatedMethod(pMethod, methodProfilingDataFlags);
+ compileResult = TryCompileInstantiatedMethod(pMethod, methodProfilingDataFlags);
}
}
}
+
+ // Update the 'flags' and 'compileResult' saved in the profileDataHashTable hash table.
+ //
+ hashBBUpdateFlagsAndCompileResult(token, methodProfilingDataFlags, compileResult);
}
// record the start of hot Generics methods.
m_iGenericsMethod = m_MethodCompilationOrder.GetCount();
@@ -1653,72 +1699,92 @@ void ZapImage::CompileProfileData()
EndRegion(CORINFO_REGION_HOT);
}
-void ZapImage::Compile()
+// CompileColdRegion
+// Performs the compilation and placement for all methods in the the "Cold" code region
+// Methods placed in this region typically correspond to all of the methods that were
+// NOT executed during any of the profiling scenarios.
+//
+void ZapImage::CompileColdRegion()
{
+ // Compile all of the methods that were NOT executed during profiling into the "Cold" code region.
//
- // First, compile methods in the load order array.
- //
- bool doNothingNgen = false;
-#ifdef _DEBUG
- static ConfigDWORD fDoNothingNGen;
- doNothingNgen = !!fDoNothingNGen.val(CLRConfig::INTERNAL_ZapDoNothing);
-#endif
- if (!doNothingNgen)
+ BeginRegion(CORINFO_REGION_COLD);
+
+ IMDInternalImport * pMDImport = m_pMDImport;
+
+ HENUMInternalHolder hEnum(pMDImport);
+ hEnum.EnumAllInit(mdtMethodDef);
+
+ mdMethodDef md;
+ while (pMDImport->EnumNext(&hEnum, &md))
{
//
- // Compile the methods specified by the IBC profile data
- //
- CompileProfileData();
-
- BeginRegion(CORINFO_REGION_COLD);
-
-
- IMDInternalImport * pMDImport = m_pMDImport;
-
- HENUMInternalHolder hEnum(pMDImport);
- hEnum.EnumAllInit(mdtMethodDef);
-
- mdMethodDef md;
- while (pMDImport->EnumNext(&hEnum, &md))
- {
- if (m_pILMetaData != NULL)
- {
- // Copy IL for all methods. We treat errors during copying IL
- // over as fatal error. These errors are typically caused by
- // corrupted IL images.
- //
- m_pILMetaData->EmitMethodIL(md);
- }
+ // Compile the remaining methods that weren't compiled during the CompileHotRegion phase
+ //
+ TryCompileMethodDef(md, 0);
+ }
- //
- // Compile the remaining methods that weren't compiled during the CompileProfileData phase
- //
- TryCompileMethodDef(md, 0);
- }
+ // Compile any generic code which lands in this LoaderModule
+ // that resulted from the above compilations
+ CORINFO_METHOD_HANDLE handle = m_pPreloader->NextUncompiledMethod();
+ while (handle != NULL)
+ {
+ TryCompileInstantiatedMethod(handle, 0);
+ handle = m_pPreloader->NextUncompiledMethod();
+ }
+
+ EndRegion(CORINFO_REGION_COLD);
+}
- // Compile any generic code which lands in this LoaderModule
- // that resulted from the above compilations
- CORINFO_METHOD_HANDLE handle = m_pPreloader->NextUncompiledMethod();
- while (handle != NULL)
+// PlaceMethodIL
+// Copy the IL for all method into the AOT native image
+//
+void ZapImage::PlaceMethodIL()
+{
+ // Place the IL for all of the methods
+ //
+ IMDInternalImport * pMDImport = m_pMDImport;
+ HENUMInternalHolder hEnum(pMDImport);
+ hEnum.EnumAllInit(mdtMethodDef);
+
+ mdMethodDef md;
+ while (pMDImport->EnumNext(&hEnum, &md))
+ {
+ if (m_pILMetaData != NULL)
{
- TryCompileInstantiatedMethod(handle, 0);
- handle = m_pPreloader->NextUncompiledMethod();
+ // Copy IL for all methods. We treat errors during copying IL
+ // over as fatal error. These errors are typically caused by
+ // corrupted IL images.
+ //
+ m_pILMetaData->EmitMethodIL(md);
}
+ }
+}
- EndRegion(CORINFO_REGION_COLD);
+void ZapImage::Compile()
+{
+ //
+ // Compile all of the methods for our AOT native image
+ //
- // If we want ngen to fail when we create partial ngen images we can
- // throw an NGEN failure HRESULT here.
-#if 0
- if (m_zapper->m_failed)
- {
- ThrowHR(NGEN_E_TP_PARTIAL_IMAGE);
- }
+ bool doNothingNgen = false;
+#ifdef _DEBUG
+ static ConfigDWORD fDoNothingNGen;
+ doNothingNgen = !!fDoNothingNGen.val(CLRConfig::INTERNAL_ZapDoNothing);
#endif
+ ProfileDisableInlining();
+
+ if (!doNothingNgen)
+ {
+ CompileHotRegion();
+
+ CompileColdRegion();
}
+ PlaceMethodIL();
+
// Compute a preferred class layout order based on analyzing the graph
// of which classes contain calls to other classes.
ComputeClassLayoutOrder();
@@ -2022,20 +2088,64 @@ ZapImage::CompileStatus ZapImage::TryCompileMethodWorker(CORINFO_METHOD_HANDLE h
}
#endif
+ // Do we have a profile entry for this method?
+ //
if (methodProfilingDataFlags != 0)
{
// Report the profiling data flags for layout of the EE datastructures
m_pPreloader->SetMethodProfilingFlags(handle, methodProfilingDataFlags);
- // Only proceed with compilation if the code is hot
+ // Hot methods can be marked to be excluded from the AOT native image.
+ // A Jitted method executes faster than a ReadyToRun compiled method.
+ //
+ if ((methodProfilingDataFlags & (1 << ExcludeHotMethodCode)) != 0)
+ {
+ // returning COMPILE_HOT_EXCLUDED excludes this method from the AOT native image
+ return COMPILE_HOT_EXCLUDED;
+ }
+
+ // Cold methods can be marked to be excluded from the AOT native image.
+ // We can reduced the size of the AOT native image by selectively
+ // excluding the code for some of the cold methods.
+ //
+ if ((methodProfilingDataFlags & (1 << ExcludeColdMethodCode)) != 0)
+ {
+ // returning COMPILE_COLD_EXCLUDED excludes this method from the AOT native image
+ return COMPILE_COLD_EXCLUDED;
+ }
+
+ // If the code was never executed based on the profile data
+ // then don't compile this method now. Wait until until later
+ // when we are compiling the methods in the cold section.
//
if ((methodProfilingDataFlags & (1 << ReadMethodCode)) == 0)
+ {
+ // returning NOT_COMPILED will defer until later the compilation of this method
return NOT_COMPILED;
+ }
}
- else
+ else // we are compiling methods for the cold region
{
+ // When Partial Ngen is specified we will omit the AOT native code for every
+ // method that was not executed based on the profile data.
+ //
if (m_zapper->m_pOpt->m_fPartialNGen)
- return COMPILE_EXCLUDED;
+ {
+ // returning COMPILE_COLD_EXCLUDED excludes this method from the AOT native image
+ return COMPILE_COLD_EXCLUDED;
+ }
+
+ // Retrieve any information that we have about a previous compilation attempt of this method
+ const ProfileDataHashEntry* pEntry = profileDataHashTable.LookupPtr(md);
+
+ if (pEntry != nullptr)
+ {
+ if ((pEntry->status == COMPILE_HOT_EXCLUDED) || (pEntry->status == COMPILE_COLD_EXCLUDED))
+ {
+ // returning COMPILE_HOT_EXCLUDED excludes this method from the AOT native image
+ return pEntry->status;
+ }
+ }
}
// Have we already compiled it?
@@ -3207,6 +3317,8 @@ HRESULT ZapImage::hashBBProfileData ()
READ(methodHeader,CORBBTPROF_METHOD_HEADER);
newEntry.md = methodHeader->method.token;
newEntry.size = methodHeader->size;
+ newEntry.flags = 0;
+ newEntry.status = NOT_COMPILED;
// Add the new entry to the table
profileDataHashTable.Add(newEntry);
@@ -3219,6 +3331,33 @@ HRESULT ZapImage::hashBBProfileData ()
return S_OK;
}
+void ZapImage::hashBBUpdateFlagsAndCompileResult(mdToken token, unsigned methodProfilingDataFlags, ZapImage::CompileStatus compileResult)
+{
+ // SHash only supports replacing an entry so we setup our newEntry and then perform a lookup
+ //
+ ProfileDataHashEntry newEntry;
+ newEntry.md = token;
+ newEntry.flags = methodProfilingDataFlags;
+ newEntry.status = compileResult;
+
+ const ProfileDataHashEntry* pEntry = profileDataHashTable.LookupPtr(token);
+ if (pEntry != nullptr)
+ {
+ assert(pEntry->md == newEntry.md);
+ assert(pEntry->flags == 0); // the flags should not be set at this point.
+
+ // Copy and keep the two fleids that were previously set
+ newEntry.size = pEntry->size;
+ newEntry.pos = pEntry->pos;
+ }
+ else // We have a method that doesn't have basic block counts
+ {
+ newEntry.size = 0;
+ newEntry.pos = 0;
+ }
+ profileDataHashTable.AddOrReplace(newEntry);
+}
+
void ZapImage::LoadProfileData()
{
HRESULT hr = E_FAIL;
diff --git a/src/zap/zapimage.h b/src/zap/zapimage.h
index f014fd249a..f0bcbcb033 100644
--- a/src/zap/zapimage.h
+++ b/src/zap/zapimage.h
@@ -336,12 +336,33 @@ private:
COUNT_T m_cRawProfileData;
CorProfileData * m_pCorProfileData;
- // ProfileData hash table
+public:
+ enum CompileStatus {
+ // Failure status values are negative
+ LOOKUP_FAILED = -2,
+ COMPILE_FAILED = -1,
+
+ // Info status values are [0..9]
+ NOT_COMPILED = 0,
+ COMPILE_EXCLUDED = 1,
+ COMPILE_HOT_EXCLUDED = 2,
+ COMPILE_COLD_EXCLUDED = 3,
+
+ // Successful status values are 10 or greater
+ COMPILE_SUCCEED = 10,
+ ALREADY_COMPILED = 11
+ };
+
+private:
+ // A hash table entry that contains the profile infomation and the CompileStatus for a given method
struct ProfileDataHashEntry
{
- mdMethodDef md; // A copy of the method.token of the profile data
- DWORD size; // A copy of the size of the profile data
- ULONG pos;
+ mdMethodDef md; // The method.token, also used as the key for the ProfileDataHashTable
+ DWORD size; // The size of the CORBBTPROF_BLOCK_DATA region, set by ZapImage::hashBBProfileData()
+ ULONG pos; // the offset to the CORBBTPROF_BLOCK_DATA region, set by ZapImage::hashBBProfileData()
+
+ unsigned flags; // The methodProfilingDataFlags, set by ZapImage::CompileHotRegion()
+ CompileStatus status; // The compileResult, set by ZapImage::CompileHotRegion()
};
class ProfileDataHashTraits : public NoRemoveSHashTraits< DefaultSHashTraits<ProfileDataHashEntry> >
@@ -365,8 +386,24 @@ private:
return (count_t)k;
}
- static const element_t Null() { LIMITED_METHOD_CONTRACT; ProfileDataHashEntry e; e.pos = 0; e.size = 0; e.md = 0; return e; } // Assuming method profile data cannot start from position 0.
- static bool IsNull(const element_t &e) { LIMITED_METHOD_CONTRACT; return e.pos == 0; }
+ static const element_t Null()
+ {
+ LIMITED_METHOD_CONTRACT;
+ ProfileDataHashEntry e;
+ e.md = 0;
+ e.size = 0;
+ e.pos = 0;
+ e.flags = 0;
+ e.status = NOT_COMPILED;
+ return e;
+ }
+
+ static bool IsNull(const element_t &e)
+ {
+ LIMITED_METHOD_CONTRACT;
+ // returns true if both md and pos are zero
+ return (e.md == 0) && (e.pos == 0);
+ }
};
typedef SHash<ProfileDataHashTraits> ProfileDataHashTable;
@@ -653,11 +690,6 @@ public:
return m_CompiledMethods.Lookup(handle);
}
-
- enum CompileStatus { LOOKUP_FAILED = -2, COMPILE_FAILED = -1, // Failure
- NOT_COMPILED = 0, COMPILE_EXCLUDED = 1, // Info
- COMPILE_SUCCEED = 10, ALREADY_COMPILED = 11}; // Success
-
static void __stdcall TryCompileMethodStub(LPVOID pContext, CORINFO_METHOD_HANDLE hStub, CORJIT_FLAGS jitFlags);
BOOL IsVTableGapMethod(mdMethodDef md);
@@ -813,6 +845,7 @@ public:
void RehydrateBlobStream();
HRESULT RehydrateProfileData();
HRESULT hashBBProfileData ();
+ void hashBBUpdateFlagsAndCompileResult(mdToken token, unsigned methodProfilingDataFlags, CompileStatus compileResult);
void LoadProfileData();
CorProfileData * NewProfileData();
@@ -820,7 +853,11 @@ public:
bool CanConvertIbcData();
CompileStatus CompileProfileDataWorker(mdToken token, unsigned methodProfilingDataFlags);
- void CompileProfileData();
+
+ void ProfileDisableInlining();
+ void CompileHotRegion();
+ void CompileColdRegion();
+ void PlaceMethodIL();
};
class BinaryWriter
diff --git a/src/zap/zapinfo.cpp b/src/zap/zapinfo.cpp
index 9713ce57ea..af0c41c4e4 100644
--- a/src/zap/zapinfo.cpp
+++ b/src/zap/zapinfo.cpp
@@ -1009,12 +1009,19 @@ HRESULT ZapInfo::getBBProfileData (
}
// The md must match.
- _ASSERTE(foundEntry->md == md);
+ _ASSERTE(foundEntry->md == md);
+ if (foundEntry->pos == 0)
+ {
+ // We might not have profile data and instead only have CompileStatus and flags
+ assert(foundEntry->size == 0);
+ return E_FAIL;
+ }
+
+ //
//
// We found the md. Let's retrieve the profile data.
//
- _ASSERTE(foundEntry->pos > 0); // The target position cannot be 0.
_ASSERTE(foundEntry->size >= sizeof(CORBBTPROF_METHOD_HEADER)); // The size must at least this
ProfileReader profileReader(DataSection_MethodBlockCounts->pData, DataSection_MethodBlockCounts->dataSize);