Merge pull request #8588 from litian2025/AVX_SSE
authorSivarv <sivarv@microsoft.com>
Thu, 12 Jan 2017 07:11:05 +0000 (23:11 -0800)
committerGitHub <noreply@github.com>
Thu, 12 Jan 2017 07:11:05 +0000 (23:11 -0800)
Remove AVX/SSE transition penalties

171 files changed:
.gitignore
BuildToolsVersion.txt
Documentation/botr/clr-abi.md
Documentation/design-docs/finally-optimizations.md [new file with mode: 0644]
clrdefinitions.cmake
dependencies.props
netci.groovy
perf.groovy
src/.nuget/Microsoft.NETCore.Native/Microsoft.NETCore.Native.builds [new file with mode: 0644]
src/.nuget/Microsoft.NETCore.Native/Microsoft.NETCore.Native.pkgproj [new file with mode: 0644]
src/.nuget/Microsoft.NETCore.Native/alpine/3.4.3/Microsoft.NETCore.Native.pkgproj [new file with mode: 0644]
src/.nuget/Microsoft.NETCore.Native/debian/Microsoft.NETCore.Native.pkgproj [new file with mode: 0644]
src/.nuget/Microsoft.NETCore.Native/fedora/23/Microsoft.NETCore.Native.pkgproj [new file with mode: 0644]
src/.nuget/Microsoft.NETCore.Native/fedora/24/Microsoft.NETCore.Native.pkgproj [new file with mode: 0644]
src/.nuget/Microsoft.NETCore.Native/linux/Microsoft.NETCore.Native.pkgproj [new file with mode: 0644]
src/.nuget/Microsoft.NETCore.Native/opensuse/13.2/Microsoft.NETCore.Native.pkgproj [new file with mode: 0644]
src/.nuget/Microsoft.NETCore.Native/opensuse/42.1/Microsoft.NETCore.Native.pkgproj [new file with mode: 0644]
src/.nuget/Microsoft.NETCore.Native/osx/Microsoft.NETCore.Native.pkgproj [new file with mode: 0644]
src/.nuget/Microsoft.NETCore.Native/rhel/Microsoft.NETCore.Native.pkgproj [new file with mode: 0644]
src/.nuget/Microsoft.NETCore.Native/ubuntu/14.04/Microsoft.NETCore.Native.pkgproj [new file with mode: 0644]
src/.nuget/Microsoft.NETCore.Native/ubuntu/16.04/Microsoft.NETCore.Native.pkgproj [new file with mode: 0644]
src/.nuget/Microsoft.NETCore.Native/ubuntu/16.10/Microsoft.NETCore.Native.pkgproj [new file with mode: 0644]
src/.nuget/descriptions.json
src/.nuget/packages.builds
src/ToolBox/SOS/Strike/disasmARM.cpp
src/ToolBox/SOS/Strike/eeheap.cpp
src/ToolBox/SOS/lldbplugin/CMakeLists.txt
src/corefx/System.Globalization.Native/CMakeLists.txt
src/debug/daccess/dacfn.cpp
src/debug/daccess/enummem.cpp
src/debug/di/rspriv.h
src/debug/di/rsthread.cpp
src/debug/ee/amd64/amd64walker.cpp
src/debug/inc/dbgipcevents.h
src/inc/clrconfigvalues.h
src/inc/clrnt.h
src/inc/corcompile.h
src/inc/corinfo.h
src/inc/daccess.h
src/inc/eetwain.h
src/inc/gcinfodecoder.h
src/inc/jithelpers.h
src/inc/readytorun.h
src/inc/regdisp.h
src/inc/switches.h
src/jit/block.cpp
src/jit/block.h
src/jit/codegenxarch.cpp
src/jit/compiler.cpp
src/jit/compiler.h
src/jit/compphases.h
src/jit/emitxarch.cpp
src/jit/flowgraph.cpp
src/jit/gentree.cpp
src/jit/gschecks.cpp
src/jit/gtlist.h
src/jit/importer.cpp
src/jit/jitconfigvalues.h
src/jit/jiteh.cpp
src/jit/jiteh.h
src/jit/lir.cpp
src/jit/liveness.cpp
src/jit/lower.cpp
src/jit/lowerxarch.cpp
src/jit/morph.cpp
src/jit/rationalize.cpp
src/jit/ssabuilder.cpp
src/jit/target.h
src/mscorlib/System.Private.CoreLib.csproj
src/mscorlib/corefx/Interop/Windows/Interop.Errors.cs [new file with mode: 0644]
src/mscorlib/corefx/Interop/Windows/kernel32/Interop.CancelIoEx.cs [moved from src/mscorlib/corefx/Interop/Windows/mincore/Interop.CancelIoEx.cs with 70% similarity]
src/mscorlib/corefx/Interop/Windows/kernel32/Interop.CloseHandle.cs [moved from src/mscorlib/corefx/Interop/Windows/mincore/Interop.CloseHandle.cs with 81% similarity]
src/mscorlib/corefx/Interop/Windows/kernel32/Interop.CreateFile.cs [moved from src/mscorlib/corefx/Interop/Windows/mincore/Interop.CreateFile.cs with 89% similarity]
src/mscorlib/corefx/Interop/Windows/kernel32/Interop.FileOperations.cs [moved from src/mscorlib/corefx/Interop/Windows/mincore/Interop.FileOperations.cs with 97% similarity]
src/mscorlib/corefx/Interop/Windows/kernel32/Interop.FileTypes.cs [moved from src/mscorlib/corefx/Interop/Windows/mincore/Interop.FileTypes.cs with 93% similarity]
src/mscorlib/corefx/Interop/Windows/kernel32/Interop.FlushFileBuffers.cs [moved from src/mscorlib/corefx/Interop/Windows/mincore/Interop.FlushFileBuffers.cs with 82% similarity]
src/mscorlib/corefx/Interop/Windows/kernel32/Interop.FormatMessage.cs [moved from src/mscorlib/corefx/Interop/Windows/mincore/Interop.FormatMessage.cs with 96% similarity]
src/mscorlib/corefx/Interop/Windows/kernel32/Interop.GetFileInformationByHandleEx.cs [moved from src/mscorlib/corefx/Interop/Windows/mincore/Interop.GetFileInformationByHandleEx.cs with 89% similarity]
src/mscorlib/corefx/Interop/Windows/kernel32/Interop.GetFileType_SafeHandle.cs [moved from src/mscorlib/corefx/Interop/Windows/mincore/Interop.GetFileType_SafeHandle.cs with 79% similarity]
src/mscorlib/corefx/Interop/Windows/kernel32/Interop.GetFullPathNameW.cs [moved from src/mscorlib/corefx/Interop/Windows/mincore/Interop.GetFullPathNameW.cs with 77% similarity]
src/mscorlib/corefx/Interop/Windows/kernel32/Interop.GetLongPathNameW.cs [moved from src/mscorlib/corefx/Interop/Windows/mincore/Interop.GetLongPathNameW.cs with 77% similarity]
src/mscorlib/corefx/Interop/Windows/kernel32/Interop.GetTempFileNameW.cs [moved from src/mscorlib/corefx/Interop/Windows/mincore/Interop.GetTempFileNameW.cs with 76% similarity]
src/mscorlib/corefx/Interop/Windows/kernel32/Interop.GetTempPathW.cs [moved from src/mscorlib/corefx/Interop/Windows/mincore/Interop.GetTempPathW.cs with 77% similarity]
src/mscorlib/corefx/Interop/Windows/kernel32/Interop.LockFile.cs [moved from src/mscorlib/corefx/Interop/Windows/mincore/Interop.LockFile.cs with 79% similarity]
src/mscorlib/corefx/Interop/Windows/kernel32/Interop.ReadFile_SafeHandle_IntPtr.cs [moved from src/mscorlib/corefx/Interop/Windows/mincore/Interop.ReadFile_SafeHandle_IntPtr.cs with 76% similarity]
src/mscorlib/corefx/Interop/Windows/kernel32/Interop.ReadFile_SafeHandle_NativeOverlapped.cs [moved from src/mscorlib/corefx/Interop/Windows/mincore/Interop.ReadFile_SafeHandle_NativeOverlapped.cs with 78% similarity]
src/mscorlib/corefx/Interop/Windows/kernel32/Interop.SECURITY_ATTRIBUTES.cs [moved from src/mscorlib/corefx/Interop/Windows/mincore/Interop.SECURITY_ATTRIBUTES.cs with 94% similarity]
src/mscorlib/corefx/Interop/Windows/kernel32/Interop.SafeCreateFile.cs [moved from src/mscorlib/corefx/Interop/Windows/mincore/Interop.SafeCreateFile.cs with 85% similarity]
src/mscorlib/corefx/Interop/Windows/kernel32/Interop.SecurityOptions.cs [moved from src/mscorlib/corefx/Interop/Windows/mincore/Interop.SecurityOptions.cs with 94% similarity]
src/mscorlib/corefx/Interop/Windows/kernel32/Interop.SetEndOfFile.cs [moved from src/mscorlib/corefx/Interop/Windows/mincore/Interop.SetEndOfFile.cs with 80% similarity]
src/mscorlib/corefx/Interop/Windows/kernel32/Interop.SetErrorMode.cs [moved from src/mscorlib/corefx/Interop/Windows/mincore/Interop.SetErrorMode.cs with 69% similarity]
src/mscorlib/corefx/Interop/Windows/kernel32/Interop.SetFileInformationByHandle.cs [moved from src/mscorlib/corefx/Interop/Windows/mincore/Interop.SetFileInformationByHandle.cs with 94% similarity]
src/mscorlib/corefx/Interop/Windows/kernel32/Interop.SetFilePointerEx.cs [moved from src/mscorlib/corefx/Interop/Windows/mincore/Interop.SetFilePointerEx.cs with 82% similarity]
src/mscorlib/corefx/Interop/Windows/kernel32/Interop.UnsafeCreateFile.cs [moved from src/mscorlib/corefx/Interop/Windows/mincore/Interop.UnsafeCreateFile.cs with 87% similarity]
src/mscorlib/corefx/Interop/Windows/kernel32/Interop.WideCharToMultiByte.cs [moved from src/mscorlib/corefx/Interop/Windows/mincore/Interop.WideCharToMultiByte.cs with 89% similarity]
src/mscorlib/corefx/Interop/Windows/kernel32/Interop.WriteFile_SafeHandle_IntPtr.cs [moved from src/mscorlib/corefx/Interop/Windows/mincore/Interop.WriteFile_SafeHandle_IntPtr.cs with 84% similarity]
src/mscorlib/corefx/Interop/Windows/kernel32/Interop.WriteFile_SafeHandle_NativeOverlapped.cs [moved from src/mscorlib/corefx/Interop/Windows/mincore/Interop.WriteFile_SafeHandle_NativeOverlapped.cs with 85% similarity]
src/mscorlib/corefx/Interop/Windows/mincore/Interop.Errors.cs [deleted file]
src/mscorlib/corefx/Interop/Windows/mincore/Interop.Idna.cs [deleted file]
src/mscorlib/corefx/Interop/Windows/mincore/Interop.ThreadPoolIO.cs [deleted file]
src/mscorlib/corefx/Microsoft/Win32/SafeHandles/SafeFileHandle.Windows.cs
src/mscorlib/corefx/System/IO/FileStream.Win32.cs
src/mscorlib/corefx/System/IO/FileStreamCompletionSource.Win32.cs
src/mscorlib/corefx/System/IO/Path.Windows.cs
src/mscorlib/corefx/System/IO/PathHelper.Windows.cs
src/mscorlib/corefx/System/IO/Win32Marshal.cs
src/mscorlib/corefx/System/Security/SecureString.Windows.cs
src/mscorlib/facade/mscorlib.csproj
src/mscorlib/model.xml
src/mscorlib/mscorlib.shared.sources.props
src/mscorlib/ref/mscorlib.cs
src/mscorlib/src/System/ByReference.cs
src/mscorlib/src/System/Runtime/InteropServices/WindowsRuntime/NativeMethods.cs
src/mscorlib/src/System/String.Manipulation.cs
src/mscorlib/src/System/Threading/CancellationTokenSource.cs
src/mscorlib/src/System/Threading/Tasks/Task.cs
src/pal/inc/pal.h
src/vm/CMakeLists.txt
src/vm/argdestination.h
src/vm/arm/asmhelpers.S
src/vm/codeman.cpp
src/vm/codeman.h
src/vm/eetwain.cpp
src/vm/excep.cpp
src/vm/excep.h
src/vm/exceptionhandling.cpp
src/vm/exinfo.cpp
src/vm/exstate.cpp
src/vm/exstatecommon.h
src/vm/frames.h
src/vm/gcenv.ee.cpp
src/vm/i386/cgencpu.h
src/vm/i386/cgenx86.cpp
src/vm/i386/excepcpu.h
src/vm/i386/excepx86.cpp
src/vm/i386/jithelp.S
src/vm/i386/unixstubs.cpp
src/vm/jitinterface.cpp
src/vm/jitinterface.h
src/vm/method.cpp
src/vm/prestub.cpp
src/vm/siginfo.cpp
src/vm/stackwalk.cpp
src/vm/stubmgr.h
src/vm/threads.h
src/vm/threadsuspend.cpp
src/zap/common.h
src/zap/zapcode.cpp
tests/src/CLRTest.Jit.targets
tests/src/Common/build_against_pkg_dependencies/project.json
tests/src/Common/netcoreapp/project.json
tests/src/Common/targeting_pack_ref/project.json
tests/src/Common/test_dependencies/project.json
tests/src/Common/test_runtime/project.json
tests/src/GC/API/GC/TotalMemory.cs
tests/src/JIT/Performance/CodeQuality/BenchmarksGame/binarytrees/binarytrees.csharp.cs
tests/src/JIT/Performance/CodeQuality/BenchmarksGame/binarytrees/binarytrees.csharp3.cs [new file with mode: 0644]
tests/src/JIT/Performance/CodeQuality/BenchmarksGame/binarytrees/binarytrees.csproj
tests/src/JIT/Performance/CodeQuality/BenchmarksGame/binarytrees/binarytrees3.csproj [new file with mode: 0644]
tests/src/JIT/Performance/CodeQuality/SIMD/SeekUnroll/SeekUnroll.cs
tests/src/JIT/Regression/VS-ia64-JIT/V2.0-RTM/b539509/b539509.cs
tests/src/JIT/config/benchmark+roslyn/project.json
tests/src/JIT/config/benchmark+serialize/project.json
tests/src/JIT/config/benchmark/project.json
tests/src/JIT/config/extra/project.json
tests/src/JIT/config/minimal/project.json
tests/src/JIT/config/threading+thread/project.json
tests/src/JIT/config/threading/project.json
tests/src/JIT/jit64/opt/cse/hugeexpr1.csproj
tests/src/JIT/jit64/regress/vsw/539509/test1.cs
tests/src/performance/project.json

index 702c37d..5ebba36 100644 (file)
@@ -24,6 +24,7 @@ build/
 bld/
 [Bb]in/
 [Oo]bj/
+localpkg/
 msbuild.log
 
 # add back architecture directories ignored in 'Build results'
index 4c6fcde..49acdc6 100644 (file)
@@ -1 +1 @@
-1.0.27-prerelease-01205-03
\ No newline at end of file
+1.0.27-prerelease-01209-01
index caa5c7a..1a60344 100644 (file)
@@ -149,7 +149,9 @@ For x86, all handlers are generated within the method body, typically in lexical
 
 JIT64 attempts to speed the normal control flow by 'inlining' a called finally along the 'normal' control flow (i.e., leaving a try body in a non-exceptional manner via C# fall-through). Because the VM semantics for non-rude Thread.Abort dictate that handlers will not be aborted, the JIT must mark these 'inlined' finally bodies. These show up as special entries at the end of the EH tables and are marked with `COR_ILEXCEPTION_CLAUSE_FINALLY | COR_ILEXCEPTION_CLAUSE_DUPLICATED`, and the try_start, try_end, and handler_start are all the same: the start of the cloned finally.
 
-JIT32 and RyuJIT currently do not implement finally cloning.
+RyuJit also implements finally cloning, for all supported architectures. However, the implementation does not yet handle the thread abort case; cloned finally bodies are not guaranteed to remain intact and are not reported to the runtime. Because of this, finally cloning is disabled for VMs that support thread abort (desktop clr).
+
+JIT32 does not implement finally cloning.
 
 ## Invoking Finallys/Non-local exits
 
diff --git a/Documentation/design-docs/finally-optimizations.md b/Documentation/design-docs/finally-optimizations.md
new file mode 100644 (file)
index 0000000..ddc6dbd
--- /dev/null
@@ -0,0 +1,451 @@
+Finally Optimizations
+=====================
+
+In MSIL, a try-finally is a construct where a block of code
+(the finally) is guaranteed to be executed after control leaves a
+protected region of code (the try) either normally or via an
+exception.
+
+In RyuJit a try-finally is currently implemented by transforming the
+finally into a local function that is invoked via jitted code at normal
+exits from the try block and is invoked via the runtime for exceptional
+exits from the try block.
+
+For x86 the local function is simply a part of the method and shares
+the same stack frame with the method. For other architectures the
+local function is promoted to a potentially separable "funclet"
+which is almost like a regular function with a prolog and epilog. A
+custom calling convention gives the funclet access to the parent stack
+frame.
+
+In this proposal we outline two optimizations for finallys: removing
+empty finallys and finally cloning.
+
+Empty Finally Removal
+---------------------
+
+An empty finally is one that has no observable effect. These often
+arise from `foreach` or `using` constructs (which induce a
+try-finally) where the cleanup method called in the finally does
+nothing. Often, after inlining, the empty finally is readily apparent.
+
+For example, this snippet of C# code
+```C#
+static int Sum(List<int> x) {
+    int sum = 0;
+    foreach(int i in x) {
+        sum += i;
+    }
+    return sum;
+}
+```
+produces the following jitted code:
+```asm
+; Successfully inlined Enumerator[Int32][System.Int32]:Dispose():this
+;    (1 IL bytes) (depth 1) [below ALWAYS_INLINE size]
+G_M60484_IG01:
+       55                   push     rbp
+       57                   push     rdi
+       56                   push     rsi
+       4883EC50             sub      rsp, 80
+       488D6C2460           lea      rbp, [rsp+60H]
+       488BF1               mov      rsi, rcx
+       488D7DD0             lea      rdi, [rbp-30H]
+       B906000000           mov      ecx, 6
+       33C0                 xor      rax, rax
+       F3AB                 rep stosd
+       488BCE               mov      rcx, rsi
+       488965C0             mov      qword ptr [rbp-40H], rsp
+
+G_M60484_IG02:
+       33C0                 xor      eax, eax
+       8945EC               mov      dword ptr [rbp-14H], eax
+       8B01                 mov      eax, dword ptr [rcx]
+       8B411C               mov      eax, dword ptr [rcx+28]
+       33D2                 xor      edx, edx
+       48894DD0             mov      gword ptr [rbp-30H], rcx
+       8955D8               mov      dword ptr [rbp-28H], edx
+       8945DC               mov      dword ptr [rbp-24H], eax
+       8955E0               mov      dword ptr [rbp-20H], edx
+
+G_M60484_IG03:
+       488D4DD0             lea      rcx, bword ptr [rbp-30H]
+       E89B35665B           call     Enumerator[Int32][System.Int32]:MoveNext():bool:this
+       85C0                 test     eax, eax
+       7418                 je       SHORT G_M60484_IG05
+
+; Body of foreach loop
+
+G_M60484_IG04:
+       8B4DE0               mov      ecx, dword ptr [rbp-20H]
+       8B45EC               mov      eax, dword ptr [rbp-14H]
+       03C1                 add      eax, ecx
+       8945EC               mov      dword ptr [rbp-14H], eax
+       488D4DD0             lea      rcx, bword ptr [rbp-30H]
+       E88335665B           call     Enumerator[Int32][System.Int32]:MoveNext():bool:this
+       85C0                 test     eax, eax
+       75E8                 jne      SHORT G_M60484_IG04
+
+; Normal exit from the implicit try region created by `foreach`
+; Calls the finally to dispose of the iterator
+
+G_M60484_IG05:
+       488BCC               mov      rcx, rsp
+       E80C000000           call     G_M60484_IG09      // call to finally
+
+G_M60484_IG06:
+       90                   nop
+
+G_M60484_IG07:
+       8B45EC               mov      eax, dword ptr [rbp-14H]
+
+G_M60484_IG08:
+       488D65F0             lea      rsp, [rbp-10H]
+       5E                   pop      rsi
+       5F                   pop      rdi
+       5D                   pop      rbp
+       C3                   ret
+
+; Finally funclet. Note it simply sets up and then tears down a stack
+; frame. The dispose method was inlined and is empty.
+
+G_M60484_IG09:
+       55                   push     rbp
+       57                   push     rdi
+       56                   push     rsi
+       4883EC30             sub      rsp, 48
+       488B6920             mov      rbp, qword ptr [rcx+32]
+       48896C2420           mov      qword ptr [rsp+20H], rbp
+       488D6D60             lea      rbp, [rbp+60H]
+
+G_M60484_IG10:
+       4883C430             add      rsp, 48
+       5E                   pop      rsi
+       5F                   pop      rdi
+       5D                   pop      rbp
+       C3                   ret
+```
+
+In such cases the try-finally can be removed, leading to code like the following:
+```asm
+G_M60484_IG01:
+       57                   push     rdi
+       56                   push     rsi
+       4883EC38             sub      rsp, 56
+       488BF1               mov      rsi, rcx
+       488D7C2420           lea      rdi, [rsp+20H]
+       B906000000           mov      ecx, 6
+       33C0                 xor      rax, rax
+       F3AB                 rep stosd
+       488BCE               mov      rcx, rsi
+
+G_M60484_IG02:
+       33F6                 xor      esi, esi
+       8B01                 mov      eax, dword ptr [rcx]
+       8B411C               mov      eax, dword ptr [rcx+28]
+       48894C2420           mov      gword ptr [rsp+20H], rcx
+       89742428             mov      dword ptr [rsp+28H], esi
+       8944242C             mov      dword ptr [rsp+2CH], eax
+       89742430             mov      dword ptr [rsp+30H], esi
+
+G_M60484_IG03:
+       488D4C2420           lea      rcx, bword ptr [rsp+20H]
+       E8A435685B           call     Enumerator[Int32][System.Int32]:MoveNext():bool:this
+       85C0                 test     eax, eax
+       7414                 je       SHORT G_M60484_IG05
+
+G_M60484_IG04:
+       8B4C2430             mov      ecx, dword ptr [rsp+30H]
+       03F1                 add      esi, ecx
+       488D4C2420           lea      rcx, bword ptr [rsp+20H]
+       E89035685B           call     Enumerator[Int32][System.Int32]:MoveNext():bool:this
+       85C0                 test     eax, eax
+       75EC                 jne      SHORT G_M60484_IG04
+
+G_M60484_IG05:
+       8BC6                 mov      eax, esi
+
+G_M60484_IG06:
+       4883C438             add      rsp, 56
+       5E                   pop      rsi
+       5F                   pop      rdi
+       C3                   ret
+```
+
+Empty finally removal is unconditionally profitable: it should always
+reduce code size and improve code speed.
+
+Finally Cloning
+---------------
+
+Finally cloning is an optimization where the jit duplicates the code
+in the finally for one or more of the normal exit paths from the try,
+and has those exit points branch to the duplicated code directly,
+rather than calling the finally.  This transformation allows for
+improved performance and optimization of the common case where the try
+completes without an exception.
+
+Finally cloning also allows hot/cold splitting of finally bodies: the
+cloned finally code covers the normal try exit paths (the hot cases)
+and can be placed in the main method region, and the original finally,
+now used largely or exclusively for exceptional cases (the cold cases)
+spilt off into the cold code region. Without cloning, RyuJit
+would always treat the finally as cold code.
+
+Finally cloning will increase code size, though often the size
+increase is mitigated somewhat by more compact code generation in the
+try body and streamlined invocation of the cloned finallys.
+
+Try-finally regions may have multiple normal exit points. For example
+the following `try` has two: one at the `return 3` and one at the try
+region end:
+
+```C#
+try {
+   if (p) return 3;
+   ...
+}
+finally {
+   ...
+}
+return 4;
+```
+
+Here the finally must be executed no matter how the try exits. So
+there are to two normal exit paths from the try, both of which pass
+through the finally but which then diverge. The fact that some try
+regions can have multiple exits opens the potential for substantial
+code growth from finally cloning, and so leads to a choice point in
+the implementation:
+
+* Share the clone along all exit paths
+* Share the clone along some exit paths
+* Clone along all exit paths
+* Clone along some exit paths
+* Only clone along one exit path
+* Only clone when there is one exit path
+
+The shared clone option must essentially recreate or simulate the
+local call mechanism for the finally, though likely somewhat more
+efficiently. Each exit point must designate where control should
+resume once the shared finally has finished.  For instance the jit
+could introduce a new local per try-finally to determine where the
+cloned finally should resume, and enumerate the possibilities using a
+small integer. The end of the cloned finally would then use a switch
+to determine what code to execute next. This has the downside of
+introducing unrealizable paths into the control flow graph.
+
+Cloning along all exit paths can potentially lead to large amounts of
+code growth.
+
+Cloning along some paths or only one path implies that some normal
+exit paths won't be as well optimized. Nonetheless cloning along one
+path was the choice made by JIT64 and the one we recommend for
+implementation. In particular we suggest only cloning along the end of
+try region exit path, so that any early exit will continue to invoke
+the funclet for finally cleanup (unless that exit happens to have the
+same post-finally continuation as the end try region exit, in which
+case it can simply jump to the cloned finally).
+
+One can imagine adaptive strategies. The size of the finally can
+be roughly estimated and the number of clones needed for full cloning
+readily computed. Selective cloning can be based on profile
+feedback or other similar mechanisms for choosing the profitable
+cases.
+
+The current implementation will clone the finally and retarget the
+last (largest IL offset) leave in the try region to the clone. Any
+other leave that ultimately transfers control to the same post-finally
+offset will also be modified to jump to the clone.
+
+Empirical studies have shown that most finallys are small. Thus to
+avoid excessive code growth, a crude size estimate is formed by
+counting the number of statements in the blocks that make up the
+finally. Any finally larger that 15 statements is not cloned. In our
+study this disqualifed about 0.5% of all finallys from cloning.
+
+### EH Nesting Considerations
+
+Finally cloning is also more complicated when the finally encloses
+other EH regions, since the clone will introduce copies of all these
+regions. While it is possible to implement cloning in such cases we
+propose to defer for now.
+
+Finally cloning is also a bit more complicated if the finally is
+enclosed by another finally region, so we likewise propose deferring
+support for this.  (Seems like a rare enough thing but maybe not too
+hard to handle -- though possibly not worth it if we're not going to
+support the enclosing case).
+
+### Control-Flow and Other Considerations
+
+If the try never exits normally, then the finally can only be invoked
+in exceptional cases. There is no benefit to cloning since the cloned
+finally would be unreachable. We can detect a subset of such cases
+because there will be no call finally blocks.
+
+JIT64 does not clone finallys that contained switch. We propose to
+do likewise. (Initially I did not include this restriction but
+hit a failing test case where the finally contained a switch. Might be
+worth a deeper look, though such cases are presumably rare.)
+
+If the finally never exits normally, then we presume it is cold code,
+and so will not clone.
+
+If the finally is marked as run rarely, we will not clone.
+
+Implementation Proposal
+-----------------------
+
+We propose that empty finally removal and finally cloning be run back
+to back, spliced into the phase list just after fgInline and
+fgAddInternal, and just before implicit by-ref and struct
+promotion. We want to run these early before a lot of structural
+invariants regarding EH are put in place, and before most
+other optimization, but run them after inlining
+(so empty finallys can be more readily identified) and after the
+addition of implicit try-finallys created by the jit.  Empty finallys
+may arise later because of optimization, but this seems relatively
+uncommon.
+
+We will remove empty finallys first, then clone.
+
+Neither optimization will run when the jit is generating debuggable
+code or operating in min opts mode.
+
+### Empty Finally Removal (Sketch)
+
+Skip over methods that have no EH, are compiled with min opts, or
+where the jit is generating debuggable code.
+
+Walk the handler table, looking for try-finally (we could also look
+for and remove try-faults with empty faults, but those are presumably
+rare).
+
+If the finally is a single block and contains only a `retfilter`
+statement, then:
+
+* Retarget the callfinally(s) to jump always to the continuation blocks.
+* Remove the paired jump always block(s) (note we expect all finally
+calls to be paired since the empty finally returns).
+* For funclet EH models with finally target bits, clear the finally
+target from the continuations.
+* For non-funclet EH models only, clear out the GT_END_LFIN statement
+in the finally continuations.
+* Remove the handler block.
+* Reparent all directly contained try blocks to the enclosing try region
+or to the method region if there is no enclosing try.
+* Remove the try-finally from the EH table via `fgRemoveEHTableEntry`.
+
+After the walk, if any empty finallys were removed, revalidate the
+integrity of the handler table.
+
+### Finally Cloning (Sketch)
+
+Skip over all methods, if the runtime suports thread abort. More on
+this below.
+
+Skip over methods that have no EH, are compiled with min opts, or
+where the jit is generating debuggable code.
+
+Walk the handler table, looking for try-finally. If the finally is
+enclosed in a handler or encloses another handler, skip.
+
+Walk the finally body blocks. If any is BBJ_SWITCH, or if none
+is BBJ_EHFINALLYRET, skip cloning. If all blocks are RunRarely
+skip cloning. If the finally has more that 15 statements, skip
+cloning.
+
+Walk the try region from back to front (from largest to smallest IL
+offset). Find the last block in the try that invokes the finally. That
+will be the path that will invoke the clone.
+
+If the EH model requires callfinally thunks, and there are multiple
+thunks that invoke the finally, and the callfinally thunk along the
+clone path is not the first, move it to the front (this helps avoid
+extra jumps).
+
+Set the insertion point to just after the callfinally in the path (for
+thunk models) or the end of the try (for non-thunk models).  Set up a
+block map. Clone the finally body using `fgNewBBinRegion` and
+`fgNewBBafter` to make the first and subsequent blocks, and
+`CloneBlockState` to fill in the block contents. Clear the handler
+region on the cloned blocks. Bail out if cloning fails. Mark the first
+and last cloned blocks with appropriate BBF flags. Patch up inter-clone
+branches and convert the returns into jumps to the continuation.
+
+Walk the callfinallys, retargeting the ones that return to the
+continuation so that they invoke the clone. Remove the paired always
+blocks. Clear the finally target bit and any GT_END_LFIN from the
+continuation.
+
+If all call finallys are converted, modify the region to be try/fault
+(interally EH_HANDLER_FAULT_WAS_FINALLY, so we can distinguish it
+later from "organic" try/faults).  Otherwise leave it as a
+try/finally.
+
+Clear the catch type on the clone entry.
+
+### Thread Abort
+
+For runtimes that support thread abort (desktop), more work is
+required:
+
+* The cloned finally must be reported to the runtime. Likely this
+can trigger off of the BBF_CLONED_FINALLY_BEGIN/END flags.
+* The jit must maintain the integrity of the clone by not losing
+track of the blocks involved, and not allowing code to move in our
+out of the cloned region
+
+Code Size Impact
+----------------
+
+Code size impact from finally cloning was measured for CoreCLR on
+Windows x64.
+
+```
+Total bytes of diff: 16158 (0.12 % of base)
+    diff is a regression.
+Total byte diff includes 0 bytes from reconciling methods
+        Base had    0 unique methods,        0 unique bytes
+        Diff had    0 unique methods,        0 unique bytes
+Top file regressions by size (bytes):
+        3518 : Microsoft.CodeAnalysis.CSharp.dasm (0.16 % of base)
+        1895 : System.Linq.Expressions.dasm (0.32 % of base)
+        1626 : Microsoft.CodeAnalysis.VisualBasic.dasm (0.07 % of base)
+        1428 : System.Threading.Tasks.Parallel.dasm (4.66 % of base)
+        1248 : System.Linq.Parallel.dasm (0.20 % of base)
+Top file improvements by size (bytes):
+       -4529 : System.Private.CoreLib.dasm (-0.14 % of base)
+        -975 : System.Reflection.Metadata.dasm (-0.28 % of base)
+        -239 : System.Private.Uri.dasm (-0.27 % of base)
+        -104 : System.Runtime.InteropServices.RuntimeInformation.dasm (-3.36 % of base)
+         -99 : System.Security.Cryptography.Encoding.dasm (-0.61 % of base)
+57 total files with size differences.
+Top method regessions by size (bytes):
+         645 : System.Diagnostics.Process.dasm - System.Diagnostics.Process:StartCore(ref):bool:this
+         454 : Microsoft.CSharp.dasm - Microsoft.CSharp.RuntimeBinder.Semantics.ExpressionBinder:AdjustCallArgumentsForParams(ref,ref,ref,ref,ref,byref):this
+         447 : System.Threading.Tasks.Dataflow.dasm - System.Threading.Tasks.Dataflow.Internal.SpscTargetCore`1[__Canon][System.__Canon]:ProcessMessagesLoopCore():this
+         421 : Microsoft.CodeAnalysis.VisualBasic.dasm - Microsoft.CodeAnalysis.VisualBasic.Symbols.ImplementsHelper:FindExplicitlyImplementedMember(ref,ref,ref,ref,ref,ref,byref):ref
+         358 : System.Private.CoreLib.dasm - System.Threading.TimerQueueTimer:Change(int,int):bool:this
+Top method improvements by size (bytes):
+       -2512 : System.Private.CoreLib.dasm - DomainNeutralILStubClass:IL_STUB_CLRtoWinRT():ref:this (68 methods)
+        -824 : Microsoft.CodeAnalysis.dasm - Microsoft.Cci.PeWriter:WriteHeaders(ref,ref,ref,ref,byref):this
+        -663 : System.Private.CoreLib.dasm - DomainNeutralILStubClass:IL_STUB_CLRtoWinRT(ref):int:this (17 methods)
+        -627 : System.Private.CoreLib.dasm - System.Diagnostics.Tracing.ManifestBuilder:CreateManifestString():ref:this
+        -546 : System.Private.CoreLib.dasm - DomainNeutralILStubClass:IL_STUB_WinRTtoCLR(long):int:this (67 methods)
+3014 total methods with size differences.
+```
+
+The largest growth is seen in `Process:StartCore`, which has 4
+try-finally constructs.
+
+Diffs generally show improved codegen in the try bodies with cloned
+finallys. However some of this improvement comes from more aggressive
+use of callee save registers, and this causes size inflation in the
+funclets (note finally cloning does not alter the number of
+funclets). So if funclet save/restore could be contained to registers
+used in the funclet, the size impact would be slightly smaller.
+
+There are also some instances where cloning relatively small finallys
+leads to large code size increases. xxx is one example.
index acca50a..7719450 100644 (file)
@@ -57,6 +57,8 @@ if (CLR_CMAKE_PLATFORM_UNIX)
     add_definitions(-DUNIX_AMD64_ABI)
   elseif (CLR_CMAKE_PLATFORM_UNIX_ARM)
     add_definitions(-DUNIX_ARM_ABI)
+  elseif (CLR_CMAKE_PLATFORM_UNIX_X86)
+    add_definitions(-DUNIX_X86_ABI)
   endif()
 
 endif(CLR_CMAKE_PLATFORM_UNIX)
index 99cb396..6879329 100644 (file)
@@ -1,18 +1,18 @@
 <Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
   <!-- Source of truth for dependency tooling: the commit hash of the dotnet/versions master branch as of the last auto-upgrade. -->
   <PropertyGroup>
-    <CoreFxCurrentRef>ef2f3c2b059e208ac188399cc10204861f9dfb70</CoreFxCurrentRef>
-    <CoreClrCurrentRef>ef2f3c2b059e208ac188399cc10204861f9dfb70</CoreClrCurrentRef>
+    <CoreFxCurrentRef>50316aab6400fcb2894d608f997d6483962b6642</CoreFxCurrentRef>
+    <CoreClrCurrentRef>50316aab6400fcb2894d608f997d6483962b6642</CoreClrCurrentRef>
   </PropertyGroup>
 
   <!-- Auto-upgraded properties for each build info dependency. -->
   <PropertyGroup>
-    <CoreFxExpectedPrerelease>beta-24906-02</CoreFxExpectedPrerelease>
+    <CoreFxExpectedPrerelease>beta-24911-08</CoreFxExpectedPrerelease>
   </PropertyGroup>
 
   <!-- Full package version strings that are used in other parts of the build. -->
   <PropertyGroup>
-    <CoreClrPackageVersion>1.2.0-beta-24906-01</CoreClrPackageVersion>
+    <CoreClrPackageVersion>1.2.0-beta-24911-02</CoreClrPackageVersion>
     <XunitPackageVersion>2.2.0-beta2-build3300</XunitPackageVersion>
   </PropertyGroup>
 
index aefc0a1..94104b5 100755 (executable)
@@ -1216,6 +1216,10 @@ def static addTriggers(def job, def branch, def isPR, def architecture, def os,
                     if (configuration == 'Checked') {
                         Utilities.addGithubPRTriggerForBranch(job, branch, "${os} ${architecture} ${configuration} Build and Test")
                     }
+                    else if (configuration == 'Release') {
+                        Utilities.addGithubPRTriggerForBranch(job, branch, "${os} ${architecture} ${configuration} Build and Test",
+                            "(?i).*test\\W+${os}\\W+${architecture}\\W+${configuration}.*")
+                    }
                     break
                 case 'pri1':
                     if (configuration == 'Release') {
@@ -1877,7 +1881,7 @@ def static calculateBuildCommands(def newJob, def scenario, def branch, def isPR
                         }
                         if (scenario == 'gcstress15_pri1r2r')
                         {
-                           gcstressStr = 'gcstresslevel 0xF'
+                            gcstressStr = 'gcstresslevel 0xF'
                         }
 
                         if (scenario == 'jitdiff')
@@ -1934,7 +1938,7 @@ def static calculateBuildCommands(def newJob, def scenario, def branch, def isPR
                         // 10s of thousands of files around.
                         buildCommands += "powershell -Command \"Add-Type -Assembly 'System.IO.Compression.FileSystem'; [System.IO.Compression.ZipFile]::CreateFromDirectory('.\\bin\\tests\\${osGroup}.${arch}.${configuration}', '.\\bin\\tests\\tests.zip')\"";
 
-                        if (!Constants.jitStressModeScenarios.containsKey(scenario) && scenario != 'jitdiff') {
+                        if (!Constants.jitStressModeScenarios.containsKey(scenario)) {
                             // For windows, pull full test results and test drops for x86/x64.
                             // No need to pull for stress mode scenarios (downstream builds use the default scenario)
                             Utilities.addArchival(newJob, "bin/Product/**,bin/tests/tests.zip")
@@ -2113,7 +2117,7 @@ def static calculateBuildCommands(def newJob, def scenario, def branch, def isPR
                         --mountPath=${armrootfs_mountpath} \\
                         --buildConfig=${lowerConfiguration} \\
                         --testRootDir=./bin/tests/Windows_NT.x64.${configuration} \\
-                        --coreFxNativeBinDir=./bin/Linux.arm-softfp.${configuration} \\
+                        --coreFxNativeBinDir=./bin/Linux.armel.${configuration} \\
                         --coreFxBinDir=\"./bin/Linux.AnyCPU.${configuration};./bin/Unix.AnyCPU.${configuration};./bin/AnyOS.AnyCPU.${configuration}\" \\
                         --testDirFile=./tests/testsRunningInsideARM.txt"""
 
index d7eb783..b2dfedd 100644 (file)
@@ -41,7 +41,7 @@ def static getOSGroup(def os) {
                        {
                                parameters
                                {
-                                       stringParam('BenchviewCommitName', '%ghprbPullTitle%', 'The name that you will be used to build the full title of a run in Benchview.  The final name will be of the form <branch> private BenchviewCommitName')
+                                       stringParam('BenchviewCommitName', '\${ghprbPullTitle}', 'The name that you will be used to build the full title of a run in Benchview.  The final name will be of the form <branch> private BenchviewCommitName')
                                }
                        }
                        def configuration = 'Release'
@@ -107,7 +107,7 @@ def static getOSGroup(def os) {
                        {
                                parameters
                                {
-                                       stringParam('BenchviewCommitName', '\$ghprbPullTitle', 'The name that you will be used to build the full title of a run in Benchview.  The final name will be of the form <branch> private BenchviewCommitName')
+                                       stringParam('BenchviewCommitName', '\${ghprbPullTitle}', 'The name that you will be used to build the full title of a run in Benchview.  The final name will be of the form <branch> private BenchviewCommitName')
                                }
                        }
                        def osGroup = getOSGroup(os)
diff --git a/src/.nuget/Microsoft.NETCore.Native/Microsoft.NETCore.Native.builds b/src/.nuget/Microsoft.NETCore.Native/Microsoft.NETCore.Native.builds
new file mode 100644 (file)
index 0000000..a178ddb
--- /dev/null
@@ -0,0 +1,65 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
+
+  <PropertyGroup>
+    <!-- This property must be set to the same value as $(PackageOutputPath) for the nuspecs and nupkgs to be binplaced to the intended location. -->
+    <OutputPath>$(PackageOutputPath)</OutputPath>
+  </PropertyGroup>
+
+  <!-- We always build the identity/redirection package. However, the platform specific runtime-*.nupkg is built based upon the target OS we are building the product for. -->
+  <ItemGroup>
+    <Project Include="Microsoft.NETCore.Native.pkgproj">
+    </Project>
+    <Project Condition="'$(TargetsLinux)' == 'true' and '$(DistroRid)' == 'linux-x64'" Include="linux/Microsoft.NETCore.Native.pkgproj">
+      <OSGroup>Linux</OSGroup>
+      <Platform>amd64</Platform>
+    </Project>
+    <Project Condition="'$(TargetsLinux)' == 'true' and '$(DistroRid)' == 'debian.8-x64'" Include="debian/Microsoft.NETCore.Native.pkgproj">
+      <OSGroup>Linux</OSGroup>
+      <Platform>amd64</Platform>
+    </Project>
+    <Project Condition="'$(TargetsLinux)' == 'true' and '$(DistroRid)' == 'fedora.23-x64'" Include="fedora/23/Microsoft.NETCore.Native.pkgproj">
+      <OSGroup>Linux</OSGroup>
+      <Platform>amd64</Platform>
+    </Project>
+    <Project Condition="'$(TargetsLinux)' == 'true' and '$(DistroRid)' == 'fedora.24-x64'" Include="fedora/24/Microsoft.NETCore.Native.pkgproj">
+      <OSGroup>Linux</OSGroup>
+      <Platform>amd64</Platform>
+    </Project>
+    <Project Condition="'$(TargetsLinux)' == 'true' and '$(DistroRid)' == 'opensuse.13.2-x64'" Include="opensuse/13.2/Microsoft.NETCore.Native.pkgproj">
+      <OSGroup>Linux</OSGroup>
+      <Platform>amd64</Platform>
+    </Project>
+    <Project Condition="'$(TargetsLinux)' == 'true' and '$(DistroRid)' == 'opensuse.42.1-x64'" Include="opensuse/42.1/Microsoft.NETCore.Native.pkgproj">
+      <OSGroup>Linux</OSGroup>
+      <Platform>amd64</Platform>
+    </Project>
+    <Project Condition="'$(TargetsLinux)' == 'true' and $(DistroRid.StartsWith('rhel.7'))" Include="rhel/Microsoft.NETCore.Native.pkgproj">
+      <OSGroup>Linux</OSGroup>
+      <Platform>amd64</Platform>
+    </Project>
+    <Project Condition="'$(TargetsLinux)' == 'true' and '$(DistroRid)' == 'ubuntu.14.04-x64'" Include="ubuntu/14.04/Microsoft.NETCore.Native.pkgproj">
+      <OSGroup>Linux</OSGroup>
+      <Platform>amd64</Platform>
+    </Project>
+    <Project Condition="'$(TargetsLinux)' == 'true' and '$(DistroRid)' == 'ubuntu.16.04-x64'" Include="ubuntu/16.04/Microsoft.NETCore.Native.pkgproj">
+      <OSGroup>Linux</OSGroup>
+      <Platform>amd64</Platform>
+    </Project>
+    <Project Condition="'$(TargetsLinux)' == 'true' and '$(DistroRid)' == 'ubuntu.16.10-x64'" Include="ubuntu/16.10/Microsoft.NETCore.Native.pkgproj">
+      <OSGroup>Linux</OSGroup>
+      <Platform>amd64</Platform>
+    </Project>
+    <Project Condition="'$(TargetsLinux)' == 'true' and '$(DistroRid)' == 'alpine.3.4.3-x64'" Include="alpine/3.4.3/Microsoft.NETCore.Native.pkgproj">
+      <OSGroup>Linux</OSGroup>
+      <Platform>amd64</Platform>
+    </Project>
+    <Project Condition="'$(TargetsOSX)' == 'true'" Include="osx/Microsoft.NETCore.Native.pkgproj">
+      <OSGroup>OSX</OSGroup>
+      <Platform>amd64</Platform>
+    </Project>
+  </ItemGroup>
+
+  <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.traversal.targets))\dir.traversal.targets" />
+</Project>
diff --git a/src/.nuget/Microsoft.NETCore.Native/Microsoft.NETCore.Native.pkgproj b/src/.nuget/Microsoft.NETCore.Native/Microsoft.NETCore.Native.pkgproj
new file mode 100644 (file)
index 0000000..51b524a
--- /dev/null
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
+  <PropertyGroup>
+    <SkipPackageFileCheck>true</SkipPackageFileCheck>
+    <SkipValidatePackage>true</SkipValidatePackage>
+    <PackagePlatforms>x64;x86;arm64;arm;</PackagePlatforms>
+    <OutputPath>$(PackagesOutputPath)</OutputPath>
+    <IncludeRuntimeJson>true</IncludeRuntimeJson>
+  </PropertyGroup>
+  <ItemGroup>
+    <ProjectReference Include="linux\Microsoft.NETCore.Native.pkgproj">
+      <Platform>amd64</Platform>
+    </ProjectReference>
+    <ProjectReference Include="debian\Microsoft.NETCore.Native.pkgproj">
+      <Platform>amd64</Platform>
+    </ProjectReference>
+    <ProjectReference Include="fedora\23\Microsoft.NETCore.Native.pkgproj">
+      <Platform>amd64</Platform>
+    </ProjectReference>
+    <ProjectReference Include="fedora\24\Microsoft.NETCore.Native.pkgproj">
+      <Platform>amd64</Platform>
+    </ProjectReference>
+    <ProjectReference Include="opensuse\13.2\Microsoft.NETCore.Native.pkgproj">
+      <Platform>amd64</Platform>
+    </ProjectReference>
+    <ProjectReference Include="opensuse\42.1\Microsoft.NETCore.Native.pkgproj">
+      <Platform>amd64</Platform>
+    </ProjectReference>
+    <ProjectReference Include="rhel\Microsoft.NETCore.Native.pkgproj">
+      <Platform>amd64</Platform>
+    </ProjectReference>
+    <ProjectReference Include="ubuntu\14.04\Microsoft.NETCore.Native.pkgproj">
+      <Platform>amd64</Platform>
+    </ProjectReference>
+    <ProjectReference Include="ubuntu\16.04\Microsoft.NETCore.Native.pkgproj">
+      <Platform>amd64</Platform>
+    </ProjectReference>
+    <ProjectReference Include="ubuntu\16.10\Microsoft.NETCore.Native.pkgproj">
+      <Platform>amd64</Platform>
+    </ProjectReference>
+    <ProjectReference Include="alpine\3.4.3\Microsoft.NETCore.Native.pkgproj">
+      <Platform>amd64</Platform>
+    </ProjectReference>
+    <ProjectReference Include="osx\Microsoft.NETCore.Native.pkgproj">
+      <Platform>amd64</Platform>
+    </ProjectReference>
+  </ItemGroup>
+  <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
+</Project>
diff --git a/src/.nuget/Microsoft.NETCore.Native/alpine/3.4.3/Microsoft.NETCore.Native.pkgproj b/src/.nuget/Microsoft.NETCore.Native/alpine/3.4.3/Microsoft.NETCore.Native.pkgproj
new file mode 100644 (file)
index 0000000..90545a9
--- /dev/null
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
+  <PropertyGroup>
+    <SkipPackageFileCheck>true</SkipPackageFileCheck>
+    <PackageTargetRuntime>alpine.3.4.3-$(PackagePlatform)</PackageTargetRuntime>
+    <!-- only build for x64 -->
+    <PackagePlatforms>x64;</PackagePlatforms>
+  </PropertyGroup>
+  <ItemGroup>
+    <NativeBinary Include="$(BinDir)libSystem.Globalization.Native.a" />
+    <NativeSplittableBinary Include="$(BinDir)System.Globalization.Native.so" />
+    <ArchitectureSpecificNativeFile Include="@(NativeSplittableBinary)" />
+    <File Include="@(ArchitectureSpecificNativeFile);@(NativeBinary)">
+      <TargetPath>runtimes/$(PackageTargetRuntime)/native</TargetPath>
+    </File>
+  </ItemGroup>
+  <ItemGroup Condition="'$(__BuildType)' == 'Release'">
+    <ArchitectureSpecificNativeSymbol Include="@(NativeSplittableBinary -> '%(Identity).dbg')" />
+    <AdditionalLibPackageExcludes Include="%2A%2A\%2A.dbg" />
+    <AdditionalSymbolPackageExcludes Include="%2A%2A\%2A.so" />
+    <AdditionalSymbolPackageExcludes Include="%2A%2A\%2A.dll" />
+    <ArchitectureSpecificNativeSymbol Include="..\..\..\_.pdb" />
+    <File Include="@(ArchitectureSpecificNativeSymbol)">
+      <TargetPath>runtimes/$(PackageTargetRuntime)/native</TargetPath>
+      <IsSymbolFile>true</IsSymbolFile>
+    </File>
+  </ItemGroup>
+  <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
+</Project>
diff --git a/src/.nuget/Microsoft.NETCore.Native/debian/Microsoft.NETCore.Native.pkgproj b/src/.nuget/Microsoft.NETCore.Native/debian/Microsoft.NETCore.Native.pkgproj
new file mode 100644 (file)
index 0000000..c136a2c
--- /dev/null
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
+  <PropertyGroup>
+    <SkipPackageFileCheck>true</SkipPackageFileCheck>
+    <PackageTargetRuntime>debian.8-$(PackagePlatform)</PackageTargetRuntime>
+    <!-- only build for x64 -->
+    <PackagePlatforms>x64;</PackagePlatforms>
+  </PropertyGroup>
+  <ItemGroup>
+    <NativeBinary Include="$(BinDir)libSystem.Globalization.Native.a" />
+    <NativeSplittableBinary Include="$(BinDir)System.Globalization.Native.so" />
+    <ArchitectureSpecificNativeFile Include="@(NativeSplittableBinary)" />
+    <File Include="@(ArchitectureSpecificNativeFile);@(NativeBinary)">
+      <TargetPath>runtimes/$(PackageTargetRuntime)/native</TargetPath>
+    </File>
+  </ItemGroup>
+  <ItemGroup Condition="'$(__BuildType)' == 'Release'">
+    <ArchitectureSpecificNativeSymbol Include="@(NativeSplittableBinary -> '%(Identity).dbg')" />
+    <AdditionalLibPackageExcludes Include="%2A%2A\%2A.dbg" />
+    <AdditionalSymbolPackageExcludes Include="%2A%2A\%2A.so" />
+    <AdditionalSymbolPackageExcludes Include="%2A%2A\%2A.dll" />
+    <ArchitectureSpecificNativeSymbol Include="..\..\_.pdb" />
+    <File Include="@(ArchitectureSpecificNativeSymbol)">
+      <TargetPath>runtimes/$(PackageTargetRuntime)/native</TargetPath>
+      <IsSymbolFile>true</IsSymbolFile>
+    </File>
+  </ItemGroup>
+  <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
+</Project>
diff --git a/src/.nuget/Microsoft.NETCore.Native/fedora/23/Microsoft.NETCore.Native.pkgproj b/src/.nuget/Microsoft.NETCore.Native/fedora/23/Microsoft.NETCore.Native.pkgproj
new file mode 100644 (file)
index 0000000..8547114
--- /dev/null
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
+  <PropertyGroup>
+    <SkipPackageFileCheck>true</SkipPackageFileCheck>
+    <PackageTargetRuntime>fedora.23-$(PackagePlatform)</PackageTargetRuntime>
+    <!-- only build for x64 -->
+    <PackagePlatforms>x64;</PackagePlatforms>
+  </PropertyGroup>
+  <ItemGroup>
+    <NativeBinary Include="$(BinDir)libSystem.Globalization.Native.a" />
+    <NativeSplittableBinary Include="$(BinDir)System.Globalization.Native.so" />
+    <ArchitectureSpecificNativeFile Include="@(NativeSplittableBinary)" />
+    <File Include="@(ArchitectureSpecificNativeFile);@(NativeBinary)">
+      <TargetPath>runtimes/$(PackageTargetRuntime)/native</TargetPath>
+    </File>
+  </ItemGroup>
+  <ItemGroup Condition="'$(__BuildType)' == 'Release'">
+    <ArchitectureSpecificNativeSymbol Include="@(NativeSplittableBinary -> '%(Identity).dbg')" />
+    <AdditionalLibPackageExcludes Include="%2A%2A\%2A.dbg" />
+    <AdditionalSymbolPackageExcludes Include="%2A%2A\%2A.so" />
+    <AdditionalSymbolPackageExcludes Include="%2A%2A\%2A.dll" />
+    <ArchitectureSpecificNativeSymbol Include="..\..\..\_.pdb" />
+    <File Include="@(ArchitectureSpecificNativeSymbol)">
+      <TargetPath>runtimes/$(PackageTargetRuntime)/native</TargetPath>
+      <IsSymbolFile>true</IsSymbolFile>
+    </File>
+  </ItemGroup>
+  <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
+</Project>
diff --git a/src/.nuget/Microsoft.NETCore.Native/fedora/24/Microsoft.NETCore.Native.pkgproj b/src/.nuget/Microsoft.NETCore.Native/fedora/24/Microsoft.NETCore.Native.pkgproj
new file mode 100644 (file)
index 0000000..f4987de
--- /dev/null
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
+  <PropertyGroup>
+    <SkipPackageFileCheck>true</SkipPackageFileCheck>
+    <PackageTargetRuntime>fedora.24-$(PackagePlatform)</PackageTargetRuntime>
+    <!-- only build for x64 -->
+    <PackagePlatforms>x64;</PackagePlatforms>
+  </PropertyGroup>
+  <ItemGroup>
+    <NativeBinary Include="$(BinDir)libSystem.Globalization.Native.a" />
+    <NativeSplittableBinary Include="$(BinDir)System.Globalization.Native.so" />
+    <ArchitectureSpecificNativeFile Include="@(NativeSplittableBinary)" />
+    <File Include="@(ArchitectureSpecificNativeFile);@(NativeBinary)">
+      <TargetPath>runtimes/$(PackageTargetRuntime)/native</TargetPath>
+    </File>
+  </ItemGroup>
+  <ItemGroup Condition="'$(__BuildType)' == 'Release'">
+    <ArchitectureSpecificNativeSymbol Include="@(NativeSplittableBinary -> '%(Identity).dbg')" />
+    <AdditionalLibPackageExcludes Include="%2A%2A\%2A.dbg" />
+    <AdditionalSymbolPackageExcludes Include="%2A%2A\%2A.so" />
+    <AdditionalSymbolPackageExcludes Include="%2A%2A\%2A.dll" />
+    <ArchitectureSpecificNativeSymbol Include="..\..\..\_.pdb" />
+    <File Include="@(ArchitectureSpecificNativeSymbol)">
+      <TargetPath>runtimes/$(PackageTargetRuntime)/native</TargetPath>
+      <IsSymbolFile>true</IsSymbolFile>
+    </File>
+  </ItemGroup>
+  <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
+</Project>
diff --git a/src/.nuget/Microsoft.NETCore.Native/linux/Microsoft.NETCore.Native.pkgproj b/src/.nuget/Microsoft.NETCore.Native/linux/Microsoft.NETCore.Native.pkgproj
new file mode 100644 (file)
index 0000000..8b1064f
--- /dev/null
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
+  <PropertyGroup>
+    <SkipPackageFileCheck>true</SkipPackageFileCheck>
+    <PackageTargetRuntime>linux-$(PackagePlatform)</PackageTargetRuntime>
+    <!-- only build for x64 -->
+    <PackagePlatforms>x64;</PackagePlatforms>
+  </PropertyGroup>
+  <ItemGroup>
+    <NativeBinary Include="$(BinDir)libSystem.Globalization.Native.a" />
+    <NativeSplittableBinary Include="$(BinDir)System.Globalization.Native.so" />
+    <ArchitectureSpecificNativeFile Include="@(NativeSplittableBinary)" />
+    <File Include="@(ArchitectureSpecificNativeFile);@(NativeBinary)">
+      <TargetPath>runtimes/$(PackageTargetRuntime)/native</TargetPath>
+    </File>
+  </ItemGroup>
+  <ItemGroup Condition="'$(__BuildType)' == 'Release'">
+    <ArchitectureSpecificNativeSymbol Include="@(NativeSplittableBinary -> '%(Identity).dbg')" />
+    <AdditionalLibPackageExcludes Include="%2A%2A\%2A.dbg" />
+    <AdditionalSymbolPackageExcludes Include="%2A%2A\%2A.so" />
+    <AdditionalSymbolPackageExcludes Include="%2A%2A\%2A.dll" />
+    <ArchitectureSpecificNativeSymbol Include="..\..\_.pdb" />
+    <File Include="@(ArchitectureSpecificNativeSymbol)">
+      <TargetPath>runtimes/$(PackageTargetRuntime)/native</TargetPath>
+      <IsSymbolFile>true</IsSymbolFile>
+    </File>
+  </ItemGroup>
+  <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
+</Project>
diff --git a/src/.nuget/Microsoft.NETCore.Native/opensuse/13.2/Microsoft.NETCore.Native.pkgproj b/src/.nuget/Microsoft.NETCore.Native/opensuse/13.2/Microsoft.NETCore.Native.pkgproj
new file mode 100644 (file)
index 0000000..bf8307a
--- /dev/null
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
+  <PropertyGroup>
+    <SkipPackageFileCheck>true</SkipPackageFileCheck>
+    <PackageTargetRuntime>opensuse.13.2-$(PackagePlatform)</PackageTargetRuntime>
+    <!-- only build for x64 -->
+    <PackagePlatforms>x64;</PackagePlatforms>
+  </PropertyGroup>
+  <ItemGroup>
+    <NativeBinary Include="$(BinDir)libSystem.Globalization.Native.a" />
+    <NativeSplittableBinary Include="$(BinDir)System.Globalization.Native.so" />
+    <ArchitectureSpecificNativeFile Include="@(NativeSplittableBinary)" />
+    <File Include="@(ArchitectureSpecificNativeFile);@(NativeBinary)">
+      <TargetPath>runtimes/$(PackageTargetRuntime)/native</TargetPath>
+    </File>
+  </ItemGroup>
+  <ItemGroup Condition="'$(__BuildType)' == 'Release'">
+    <ArchitectureSpecificNativeSymbol Include="@(NativeSplittableBinary -> '%(Identity).dbg')" />
+    <AdditionalLibPackageExcludes Include="%2A%2A\%2A.dbg" />
+    <AdditionalSymbolPackageExcludes Include="%2A%2A\%2A.so" />
+    <AdditionalSymbolPackageExcludes Include="%2A%2A\%2A.dll" />
+    <ArchitectureSpecificNativeSymbol Include="..\..\..\_.pdb" />
+    <File Include="@(ArchitectureSpecificNativeSymbol)">
+      <TargetPath>runtimes/$(PackageTargetRuntime)/native</TargetPath>
+      <IsSymbolFile>true</IsSymbolFile>
+    </File>
+  </ItemGroup>
+  <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
+</Project>
diff --git a/src/.nuget/Microsoft.NETCore.Native/opensuse/42.1/Microsoft.NETCore.Native.pkgproj b/src/.nuget/Microsoft.NETCore.Native/opensuse/42.1/Microsoft.NETCore.Native.pkgproj
new file mode 100644 (file)
index 0000000..19ac91c
--- /dev/null
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
+  <PropertyGroup>
+    <SkipPackageFileCheck>true</SkipPackageFileCheck>
+    <PackageTargetRuntime>opensuse.42.1-$(PackagePlatform)</PackageTargetRuntime>
+    <!-- only build for x64 -->
+    <PackagePlatforms>x64;</PackagePlatforms>
+  </PropertyGroup>
+  <ItemGroup>
+    <NativeBinary Include="$(BinDir)libSystem.Globalization.Native.a" />
+    <NativeSplittableBinary Include="$(BinDir)System.Globalization.Native.so" />
+    <ArchitectureSpecificNativeFile Include="@(NativeSplittableBinary)" />
+    <File Include="@(ArchitectureSpecificNativeFile);@(NativeBinary)">
+      <TargetPath>runtimes/$(PackageTargetRuntime)/native</TargetPath>
+    </File>
+  </ItemGroup>
+  <ItemGroup Condition="'$(__BuildType)' == 'Release'">
+    <ArchitectureSpecificNativeSymbol Include="@(NativeSplittableBinary -> '%(Identity).dbg')" />
+    <AdditionalLibPackageExcludes Include="%2A%2A\%2A.dbg" />
+    <AdditionalSymbolPackageExcludes Include="%2A%2A\%2A.so" />
+    <AdditionalSymbolPackageExcludes Include="%2A%2A\%2A.dll" />
+    <ArchitectureSpecificNativeSymbol Include="..\..\..\_.pdb" />
+    <File Include="@(ArchitectureSpecificNativeSymbol)">
+      <TargetPath>runtimes/$(PackageTargetRuntime)/native</TargetPath>
+      <IsSymbolFile>true</IsSymbolFile>
+    </File>
+  </ItemGroup>
+  <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
+</Project>
diff --git a/src/.nuget/Microsoft.NETCore.Native/osx/Microsoft.NETCore.Native.pkgproj b/src/.nuget/Microsoft.NETCore.Native/osx/Microsoft.NETCore.Native.pkgproj
new file mode 100644 (file)
index 0000000..b358c86
--- /dev/null
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
+  <PropertyGroup>
+    <SkipPackageFileCheck>true</SkipPackageFileCheck>
+    <PackageTargetRuntime>osx.10.10-$(PackagePlatform)</PackageTargetRuntime>
+    <!-- only build for x64 -->
+    <PackagePlatforms>x64;</PackagePlatforms>
+  </PropertyGroup>
+  <ItemGroup>
+    <NativeBinary Include="$(BinDir)libSystem.Globalization.Native.a" />
+    <NativeSplittableBinary Include="$(BinDir)System.Globalization.Native.dylib" />
+    <ArchitectureSpecificNativeFile Include="@(NativeSplittableBinary)" />
+    <File Include="@(ArchitectureSpecificNativeFile);@(NativeBinary)">
+      <TargetPath>runtimes/$(PackageTargetRuntime)/native</TargetPath>
+    </File>
+  </ItemGroup>
+  <ItemGroup Condition="'$(__BuildType)' == 'Release'">
+    <ArchitectureSpecificNativeSymbol Include="@(NativeSplittableBinary -> '%(Identity).dwarf')" />
+    <AdditionalLibPackageExcludes Include="%2A%2A\%2A.dwarf" />
+    <AdditionalSymbolPackageExcludes Include="%2A%2A\%2A.dylib" />
+    <AdditionalSymbolPackageExcludes Include="%2A%2A\%2A.dll" />
+    <ArchitectureSpecificNativeSymbol Include="..\..\_.pdb" />
+    <File Include="@(ArchitectureSpecificNativeSymbol)">
+      <TargetPath>runtimes/$(PackageTargetRuntime)/native</TargetPath>
+      <IsSymbolFile>true</IsSymbolFile>
+    </File>
+  </ItemGroup>
+  <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
+</Project>
diff --git a/src/.nuget/Microsoft.NETCore.Native/rhel/Microsoft.NETCore.Native.pkgproj b/src/.nuget/Microsoft.NETCore.Native/rhel/Microsoft.NETCore.Native.pkgproj
new file mode 100644 (file)
index 0000000..f9dc309
--- /dev/null
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
+  <PropertyGroup>
+    <SkipPackageFileCheck>true</SkipPackageFileCheck>
+    <PackageTargetRuntime>rhel.7-$(PackagePlatform)</PackageTargetRuntime>
+    <!-- only build for x64 -->
+    <PackagePlatforms>x64;</PackagePlatforms>
+  </PropertyGroup>
+  <ItemGroup>
+    <NativeBinary Include="$(BinDir)libSystem.Globalization.Native.a" />
+    <NativeSplittableBinary Include="$(BinDir)System.Globalization.Native.so" />
+    <ArchitectureSpecificNativeFile Include="@(NativeSplittableBinary)" />
+    <File Include="@(ArchitectureSpecificNativeFile);@(NativeBinary)">
+      <TargetPath>runtimes/$(PackageTargetRuntime)/native</TargetPath>
+    </File>
+  </ItemGroup>
+  <ItemGroup Condition="'$(__BuildType)' == 'Release'">
+    <ArchitectureSpecificNativeSymbol Include="@(NativeSplittableBinary -> '%(Identity).dbg')" />
+    <AdditionalLibPackageExcludes Include="%2A%2A\%2A.dbg" />
+    <AdditionalSymbolPackageExcludes Include="%2A%2A\%2A.so" />
+    <AdditionalSymbolPackageExcludes Include="%2A%2A\%2A.dll" />
+    <ArchitectureSpecificNativeSymbol Include="..\..\_.pdb" />
+    <File Include="@(ArchitectureSpecificNativeSymbol)">
+      <TargetPath>runtimes/$(PackageTargetRuntime)/native</TargetPath>
+      <IsSymbolFile>true</IsSymbolFile>
+    </File>
+  </ItemGroup>
+  <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
+</Project>
diff --git a/src/.nuget/Microsoft.NETCore.Native/ubuntu/14.04/Microsoft.NETCore.Native.pkgproj b/src/.nuget/Microsoft.NETCore.Native/ubuntu/14.04/Microsoft.NETCore.Native.pkgproj
new file mode 100644 (file)
index 0000000..d1c5be7
--- /dev/null
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
+  <PropertyGroup>
+    <SkipPackageFileCheck>true</SkipPackageFileCheck>
+    <PackageTargetRuntime>ubuntu.14.04-$(PackagePlatform)</PackageTargetRuntime>
+    <!-- only build for x64 -->
+    <PackagePlatforms>x64;</PackagePlatforms>
+  </PropertyGroup>
+  <ItemGroup>
+    <NativeBinary Include="$(BinDir)libSystem.Globalization.Native.a" />
+    <NativeSplittableBinary Include="$(BinDir)System.Globalization.Native.so" />
+    <ArchitectureSpecificNativeFile Include="@(NativeSplittableBinary)" />
+    <File Include="@(ArchitectureSpecificNativeFile);@(NativeBinary)">
+      <TargetPath>runtimes/$(PackageTargetRuntime)/native</TargetPath>
+    </File>
+  </ItemGroup>
+  <ItemGroup Condition="'$(__BuildType)' == 'Release'">
+    <ArchitectureSpecificNativeSymbol Include="@(NativeSplittableBinary -> '%(Identity).dbg')" />
+    <AdditionalLibPackageExcludes Include="%2A%2A\%2A.dbg" />
+    <AdditionalSymbolPackageExcludes Include="%2A%2A\%2A.so" />
+    <AdditionalSymbolPackageExcludes Include="%2A%2A\%2A.dll" />
+    <ArchitectureSpecificNativeSymbol Include="..\..\..\_.pdb" />
+    <File Include="@(ArchitectureSpecificNativeSymbol)">
+      <TargetPath>runtimes/$(PackageTargetRuntime)/native</TargetPath>
+      <IsSymbolFile>true</IsSymbolFile>
+    </File>
+  </ItemGroup>
+  <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
+</Project>
diff --git a/src/.nuget/Microsoft.NETCore.Native/ubuntu/16.04/Microsoft.NETCore.Native.pkgproj b/src/.nuget/Microsoft.NETCore.Native/ubuntu/16.04/Microsoft.NETCore.Native.pkgproj
new file mode 100644 (file)
index 0000000..b2b0f96
--- /dev/null
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
+  <PropertyGroup>
+    <SkipPackageFileCheck>true</SkipPackageFileCheck>
+    <PackageTargetRuntime>ubuntu.16.04-$(PackagePlatform)</PackageTargetRuntime>
+    <!-- only build for x64 -->
+    <PackagePlatforms>x64;</PackagePlatforms>
+  </PropertyGroup>
+  <ItemGroup>
+    <NativeBinary Include="$(BinDir)libSystem.Globalization.Native.a" />
+    <NativeSplittableBinary Include="$(BinDir)System.Globalization.Native.so" />
+    <ArchitectureSpecificNativeFile Include="@(NativeSplittableBinary)" />
+    <File Include="@(ArchitectureSpecificNativeFile);@(NativeBinary)">
+      <TargetPath>runtimes/$(PackageTargetRuntime)/native</TargetPath>
+    </File>
+  </ItemGroup>
+  <ItemGroup Condition="'$(__BuildType)' == 'Release'">
+    <ArchitectureSpecificNativeSymbol Include="@(NativeSplittableBinary -> '%(Identity).dbg')" />
+    <AdditionalLibPackageExcludes Include="%2A%2A\%2A.dbg" />
+    <AdditionalSymbolPackageExcludes Include="%2A%2A\%2A.so" />
+    <AdditionalSymbolPackageExcludes Include="%2A%2A\%2A.dll" />
+    <ArchitectureSpecificNativeSymbol Include="..\..\..\_.pdb" />
+    <File Include="@(ArchitectureSpecificNativeSymbol)">
+      <TargetPath>runtimes/$(PackageTargetRuntime)/native</TargetPath>
+      <IsSymbolFile>true</IsSymbolFile>
+    </File>
+  </ItemGroup>
+  <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
+</Project>
diff --git a/src/.nuget/Microsoft.NETCore.Native/ubuntu/16.10/Microsoft.NETCore.Native.pkgproj b/src/.nuget/Microsoft.NETCore.Native/ubuntu/16.10/Microsoft.NETCore.Native.pkgproj
new file mode 100644 (file)
index 0000000..da4a03d
--- /dev/null
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
+  <PropertyGroup>
+    <SkipPackageFileCheck>true</SkipPackageFileCheck>
+    <PackageTargetRuntime>ubuntu.16.10-$(PackagePlatform)</PackageTargetRuntime>
+    <!-- only build for x64 -->
+    <PackagePlatforms>x64;</PackagePlatforms>
+  </PropertyGroup>
+  <ItemGroup>
+    <NativeBinary Include="$(BinDir)libSystem.Globalization.Native.a" />
+    <NativeSplittableBinary Include="$(BinDir)System.Globalization.Native.so" />
+    <ArchitectureSpecificNativeFile Include="@(NativeSplittableBinary)" />
+    <File Include="@(ArchitectureSpecificNativeFile);@(NativeBinary)">
+      <TargetPath>runtimes/$(PackageTargetRuntime)/native</TargetPath>
+    </File>
+  </ItemGroup>
+  <ItemGroup Condition="'$(__BuildType)' == 'Release'">
+    <ArchitectureSpecificNativeSymbol Include="@(NativeSplittableBinary -> '%(Identity).dbg')" />
+    <AdditionalLibPackageExcludes Include="%2A%2A\%2A.dbg" />
+    <AdditionalSymbolPackageExcludes Include="%2A%2A\%2A.so" />
+    <AdditionalSymbolPackageExcludes Include="%2A%2A\%2A.dll" />
+    <ArchitectureSpecificNativeSymbol Include="..\..\..\_.pdb" />
+    <File Include="@(ArchitectureSpecificNativeSymbol)">
+      <TargetPath>runtimes/$(PackageTargetRuntime)/native</TargetPath>
+      <IsSymbolFile>true</IsSymbolFile>
+    </File>
+  </ItemGroup>
+  <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
+</Project>
index 640ff02..ccb6af8 100644 (file)
         "Name": "Microsoft.NETCore.TestHost",
         "Description": "CoreCLR application host for test applications",
         "CommonTypes": [ ]
+    },
+    {
+       "Name": "Microsoft.NETCore.Native",
+       "Description": "Native shims for .NET Core runtime",
+       "CommonTypes": [ ]
     }
 ]
index 7458c8e..5d1d025 100644 (file)
@@ -18,6 +18,7 @@
   <ItemGroup Condition="'$(__SkipNativeBuild)'==''">
     <Project Include="Microsoft.NETCore.Jit\Microsoft.NETCore.Jit.builds" />     
     <Project Include="Microsoft.NETCore.TestHost\Microsoft.NETCore.TestHost.builds" />     
+    <Project Include="Microsoft.NETCore.Native\Microsoft.NETCore.Native.builds" />     
   </ItemGroup>
 
   <ItemGroup>
index 8217355..cc80d77 100644 (file)
@@ -28,6 +28,7 @@
 namespace ARMGCDump
 {
 #undef _TARGET_X86_
+#define WIN64EXCEPTIONS
 #undef LIMITED_METHOD_CONTRACT
 #define LIMITED_METHOD_DAC_CONTRACT
 #define SUPPORTS_DAC
index ac41e2d..5a5680f 100644 (file)
@@ -1614,9 +1614,9 @@ void LoaderHeapTraverse(CLRDATA_ADDRESS blockData,size_t blockSize,BOOL blockIsC
 \**********************************************************************/
 void PrintHeapSize(DWORD_PTR total, DWORD_PTR wasted)
 {
-    ExtOut("Size: 0x%" POINTERSIZE_TYPE "x (%" POINTERSIZE_TYPE "lu) bytes", total, total);
+    ExtOut("Size: 0x%" POINTERSIZE_TYPE "x (%" POINTERSIZE_TYPE "u) bytes", total, total);
     if (wasted)
-        ExtOut(" total, 0x%" POINTERSIZE_TYPE "x (%" POINTERSIZE_TYPE "lu) bytes wasted", wasted,  wasted);    
+        ExtOut(" total, 0x%" POINTERSIZE_TYPE "x (%" POINTERSIZE_TYPE "u) bytes wasted", wasted,  wasted);    
     ExtOut(".\n");
 }
 
index 7f1fa77..8ae2c9b 100644 (file)
@@ -49,8 +49,8 @@ if(NOT ENABLE_LLDBPLUGIN)
 endif()
 
 # Check for LLDB library
-find_library(LLDB NAMES LLDB lldb lldb-3.8 lldb-3.6 lldb-3.5 PATHS "${WITH_LLDB_LIBS}" PATH_SUFFIXES llvm NO_DEFAULT_PATH)
-find_library(LLDB NAMES LLDB lldb lldb-3.8 lldb-3.6 lldb-3.5 PATH_SUFFIXES llvm)
+find_library(LLDB NAMES LLDB lldb lldb-3.8 lldb-3.7 lldb-3.6 lldb-3.5 PATHS "${WITH_LLDB_LIBS}" PATH_SUFFIXES llvm NO_DEFAULT_PATH)
+find_library(LLDB NAMES LLDB lldb lldb-3.8 lldb-3.7 lldb-3.6 lldb-3.5 PATH_SUFFIXES llvm)
 if(LLDB STREQUAL LLDB-NOTFOUND)
     if(REQUIRE_LLDBPLUGIN)
         message(FATAL_ERROR "Cannot find lldb-3.5, lldb-3.6 or lldb-3.8. Try installing lldb-3.6-dev (or the appropriate package for your platform)")
@@ -69,18 +69,21 @@ find_path(LLDB_H "lldb/API/LLDB.h")
 if(LLDB_H STREQUAL LLDB_H-NOTFOUND)
     find_path(LLDB_H "lldb/API/LLDB.h" PATHS "/usr/lib/llvm-3.8/include")
     if(LLDB_H STREQUAL LLDB_H-NOTFOUND)
-        find_path(LLDB_H "lldb/API/LLDB.h" PATHS "/usr/lib/llvm-3.6/include")
-        if(LLDB_H STREQUAL LLDB_H-NOTFOUND)
-            find_path(LLDB_H "lldb/API/LLDB.h" PATHS "/usr/lib/llvm-3.5/include")
-            if(LLDB_H STREQUAL LLDB_H-NOTFOUND)
-                if(REQUIRE_LLDBPLUGIN)
-                    message(FATAL_ERROR "Cannot find LLDB.h. Try installing lldb-3.6-dev (or the appropriate package for your platform)")
-                else()
-                    message(WARNING "Cannot find LLDB.h Try installing lldb-3.6-dev (or the appropriate package for your platform)")
-                endif()
-                return()
-            endif()
-        endif()
+               find_path(LLDB_H "lldb/API/LLDB.h" PATHS "/usr/lib/llvm-3.7/include")
+       if(LLDB_H STREQUAL LLDB_H-NOTFOUND)
+                       find_path(LLDB_H "lldb/API/LLDB.h" PATHS "/usr/lib/llvm-3.6/include")
+                       if(LLDB_H STREQUAL LLDB_H-NOTFOUND)
+                               find_path(LLDB_H "lldb/API/LLDB.h" PATHS "/usr/lib/llvm-3.5/include")
+                               if(LLDB_H STREQUAL LLDB_H-NOTFOUND)
+                                       if(REQUIRE_LLDBPLUGIN)
+                                               message(FATAL_ERROR "Cannot find LLDB.h. Try installing lldb-3.6-dev (or the appropriate package for your platform)")
+                                       else()
+                                               message(WARNING "Cannot find LLDB.h Try installing lldb-3.6-dev (or the appropriate package for your platform)")
+                                       endif()
+                                       return()
+                               endif()
+                       endif()
+               endif()
     endif()
 endif()
 
index 90f5067..9ecb0e0 100644 (file)
@@ -67,6 +67,14 @@ _add_library(System.Globalization.Native
     ${NATIVEGLOBALIZATION_SOURCES}
 )
 
+_add_library(System.Globalization.Native_Static
+    STATIC
+    ${NATIVEGLOBALIZATION_SOURCES}
+)
+
+# Remove the _Static postfix from the static library name
+set_target_properties(System.Globalization.Native_Static PROPERTIES OUTPUT_NAME System.Globalization.Native)
+
 # Disable the "lib" prefix.
 set_target_properties(System.Globalization.Native PROPERTIES PREFIX "")
 
@@ -80,10 +88,17 @@ if(NOT CLR_CMAKE_PLATFORM_DARWIN)
             ${ICUUC}
             ${ICUI18N}
         )
+        target_link_libraries(System.Globalization.Native_Static
+            ${ICUUC}
+            ${ICUI18N}
+        )
     elseif(NOT CMAKE_SYSTEM_NAME STREQUAL FreeBSD AND NOT CMAKE_SYSTEM_NAME STREQUAL NetBSD)
         target_link_libraries(System.Globalization.Native
             dl
         )
+        target_link_libraries(System.Globalization.Native_Static
+            dl
+        )
     endif()
 else()
     target_link_libraries(System.Globalization.Native
@@ -100,4 +115,5 @@ verify_dependencies(
 
 # add the install targets
 install_clr(System.Globalization.Native)
+install(TARGETS System.Globalization.Native_Static DESTINATION .)
 
index d8bae77..33dfa10 100644 (file)
@@ -219,7 +219,7 @@ DacWriteAll(TADDR addr, PVOID buffer, ULONG32 size, bool throwEx)
 
 #ifdef FEATURE_PAL
 HRESULT 
-DacVirtualUnwind(DWORD threadId, PCONTEXT context, PT_KNONVOLATILE_CONTEXT_POINTERS contextPointers)
+DacVirtualUnwind(DWORD threadId, PT_CONTEXT context, PT_KNONVOLATILE_CONTEXT_POINTERS contextPointers)
 {
     if (!g_dacImpl)
     {
index d66af05..0f38aa5 100644 (file)
@@ -970,7 +970,7 @@ HRESULT ClrDataAccess::EnumMemWalkStackHelper(CLRDataEnumMemoryFlags flags,
                             // Pulls in sequence points and local variable info
                             DebugInfoManager::EnumMemoryRegionsForMethodDebugInfo(flags, pMethodDesc);
 
-#ifdef WIN64EXCEPTIONS
+#if defined(WIN64EXCEPTIONS) && defined(USE_GC_INFO_DECODER)
                           
                             if (addr != NULL)
                             {
@@ -988,7 +988,7 @@ HRESULT ClrDataAccess::EnumMemWalkStackHelper(CLRDataEnumMemoryFlags flags,
                                     DacEnumMemoryRegion(dac_cast<TADDR>(pGCInfo), gcDecoder.GetNumBytesRead(), true);
                                 }
                             }
-#endif // WIN64EXCEPTIONS
+#endif // WIN64EXCEPTIONS && USE_GC_INFO_DECODER
                         }
                         pMethodDefinition.Clear();
                     }
index 18920ad..8f369b7 100644 (file)
@@ -6929,11 +6929,11 @@ public:
     // new-style constructor
     CordbMiscFrame(DebuggerIPCE_JITFuncData * pJITFuncData);
 
-#if defined(DBG_TARGET_WIN64) || defined(DBG_TARGET_ARM)
+#ifdef WIN64EXCEPTIONS
     SIZE_T             parentIP;
     FramePointer       fpParentOrSelf;
     bool               fIsFilterFunclet;
-#endif // DBG_TARGET_WIN64 || DBG_TARGET_ARM
+#endif // WIN64EXCEPTIONS
 };
 
 
index a4660be..02fae00 100644 (file)
@@ -5849,11 +5849,11 @@ CordbMiscFrame::CordbMiscFrame()
 // the real constructor which stores the funclet-related information in the CordbMiscFrame
 CordbMiscFrame::CordbMiscFrame(DebuggerIPCE_JITFuncData * pJITFuncData)
 {
-#if defined(DBG_TARGET_WIN64) || defined(DBG_TARGET_ARM)
+#ifdef WIN64EXCEPTIONS
     this->parentIP       = pJITFuncData->parentNativeOffset;
     this->fpParentOrSelf = pJITFuncData->fpParentOrSelf;
     this->fIsFilterFunclet = (pJITFuncData->fIsFilterFrame == TRUE);
-#endif // DBG_TARGET_WIN64 || DBG_TARGET_ARM
+#endif // WIN64EXCEPTIONS
 }
 
 /* ------------------------------------------------------------------------- *
index 836d214..39e9784 100644 (file)
@@ -131,10 +131,11 @@ void NativeWalker::Decode()
     {
         case 0xff:
         {
-
             BYTE modrm = *ip++;
 
-            _ASSERT(modrm != NULL);
+            // Ignore "inc dword ptr [reg]" instructions
+            if (modrm == 0)
+                break;
             
             BYTE mod = (modrm & 0xC0) >> 6;
             BYTE reg = (modrm & 0x38) >> 3;
index 6ace36e..1b4dec7 100644 (file)
@@ -1355,11 +1355,11 @@ struct MSLAYOUT DebuggerIPCE_JITFuncData
     LSPTR_DJI   nativeCodeJITInfoToken;
     VMPTR_MethodDesc vmNativeCodeMethodDescToken;
 
-#if defined(DBG_TARGET_WIN64) || defined(DBG_TARGET_ARM)
+#ifdef WIN64EXCEPTIONS
     BOOL         fIsFilterFrame;
     SIZE_T       parentNativeOffset;
     FramePointer fpParentOrSelf;
-#endif // DBG_TARGET_WIN64 || DBG_TARGET_ARM
+#endif // WIN64EXCEPTIONS
 
     // indicates if the MethodDesc is a generic function or a method inside a generic class (or
     // both!).
index a0183d2..cf71e46 100644 (file)
@@ -338,7 +338,7 @@ RETAIL_CONFIG_DWORD_INFO_DIRECT_ACCESS(UNSUPPORTED_GCprnLvl, W("GCprnLvl"), "Spe
 RETAIL_CONFIG_DWORD_INFO(UNSUPPORTED_GCRetainVM, W("GCRetainVM"), 0, "When set we put the segments that should be deleted on a standby list (instead of releasing them back to the OS) which will be considered to satisfy new segment requests (note that the same thing can be specified via API which is the supported way)")
 RETAIL_CONFIG_DWORD_INFO_DIRECT_ACCESS(UNSUPPORTED_GCSegmentSize, W("GCSegmentSize"), "Specifies the managed heap segment size")
 RETAIL_CONFIG_DWORD_INFO_DIRECT_ACCESS(UNSUPPORTED_GCLOHCompact, W("GCLOHCompact"), "Specifies the LOH compaction mode")
-RETAIL_CONFIG_DWORD_INFO(EXTERNAL_gcAllowVeryLargeObjects, W("gcAllowVeryLargeObjects"), 0, "allow allocation of 2GB+ objects on GC heap")
+RETAIL_CONFIG_DWORD_INFO(EXTERNAL_gcAllowVeryLargeObjects, W("gcAllowVeryLargeObjects"), 1, "allow allocation of 2GB+ objects on GC heap")
 RETAIL_CONFIG_DWORD_INFO_EX(EXTERNAL_GCStress, W("GCStress"), 0, "trigger GCs at regular intervals", CLRConfig::REGUTIL_default)
 CONFIG_DWORD_INFO_EX(INTERNAL_GcStressOnDirectCalls, W("GcStressOnDirectCalls"), 0, "whether to trigger a GC on direct calls", CLRConfig::REGUTIL_default)
 RETAIL_CONFIG_DWORD_INFO(EXTERNAL_GCStressStart, W("GCStressStart"), 0, "start GCStress after N stress GCs have been attempted")
index 0e082c7..9a4601e 100644 (file)
@@ -837,6 +837,13 @@ RtlVirtualUnwind_Unsafe(
 
 #ifdef _TARGET_X86_
 #ifndef FEATURE_PAL
+//
+// x86 ABI does not define RUNTIME_FUNCTION. Define our own to allow unification between x86 and other platforms.
+//
+typedef struct _RUNTIME_FUNCTION {
+    DWORD BeginAddress;
+    DWORD UnwindData;
+} RUNTIME_FUNCTION, *PRUNTIME_FUNCTION;
 
 typedef struct _DISPATCHER_CONTEXT {
     _EXCEPTION_REGISTRATION_RECORD* RegistrationPointer;
@@ -845,6 +852,43 @@ typedef struct _DISPATCHER_CONTEXT {
 #endif // !FEATURE_PAL
 
 #define RUNTIME_FUNCTION__BeginAddress(prf)             (prf)->BeginAddress
+#define RUNTIME_FUNCTION__SetBeginAddress(prf,addr)     ((prf)->BeginAddress = (addr))
+
+#ifdef WIN64EXCEPTIONS
+EXTERN_C ULONG
+RtlpGetFunctionEndAddress (
+    __in PT_RUNTIME_FUNCTION FunctionEntry,
+    __in ULONG ImageBase
+    );
+
+#define RUNTIME_FUNCTION__EndAddress(prf, ImageBase)   RtlpGetFunctionEndAddress(prf, ImageBase)
+
+#define RUNTIME_FUNCTION__GetUnwindInfoAddress(prf)    (prf)->UnwindData
+#define RUNTIME_FUNCTION__SetUnwindInfoAddress(prf, addr) do { (prf)->UnwindData = (addr); } while(0)
+
+#define UNW_FLAG_NHANDLER               0x0             /* any handler */
+#define UNW_FLAG_EHANDLER               0x1             /* filter handler */
+#define UNW_FLAG_UHANDLER               0x2             /* unwind handler */
+
+typedef struct _UNWIND_INFO {
+    // dummy
+} UNWIND_INFO, *PUNWIND_INFO;
+
+EXTERN_C
+NTSYSAPI
+PEXCEPTION_ROUTINE
+NTAPI
+RtlVirtualUnwind (
+    __in DWORD HandlerType,
+    __in DWORD ImageBase,
+    __in DWORD ControlPc,
+    __in PRUNTIME_FUNCTION FunctionEntry,
+    __inout PT_CONTEXT ContextRecord,
+    __out PVOID *HandlerData,
+    __out PDWORD EstablisherFrame,
+    __inout_opt PT_KNONVOLATILE_CONTEXT_POINTERS ContextPointers
+    );
+#endif // WIN64EXCEPTIONS
 
 #endif // _TARGET_X86_
 
index 3b517ae..7346314 100644 (file)
 #error FEATURE_PREJIT is required for this file
 #endif // FEATURE_PREJIT
 
-#if !defined(_TARGET_X86_)
+#if !defined(_TARGET_X86_) || defined(FEATURE_PAL)
 #ifndef WIN64EXCEPTIONS
 #define WIN64EXCEPTIONS
 #endif
-#endif  // !_TARGET_X86_
+#endif  // !_TARGET_X86_ || FEATURE_PAL
 
 #include <cor.h>
 #include <corhdr.h>
@@ -72,16 +72,6 @@ typedef DPTR(struct CORCOMPILE_IMPORT_SECTION)
     PTR_CORCOMPILE_IMPORT_SECTION;
 
 #ifdef _TARGET_X86_
-#ifndef FEATURE_PAL
-//
-// x86 ABI does not define RUNTIME_FUNCTION. Define our own to allow unification between x86 and other platforms.
-//
-typedef struct _RUNTIME_FUNCTION {
-    DWORD BeginAddress;
-    DWORD UnwindData;
-} RUNTIME_FUNCTION, *PRUNTIME_FUNCTION;
-
-#endif // !FEATURE_PAL
 
 typedef DPTR(RUNTIME_FUNCTION) PTR_RUNTIME_FUNCTION;
 
index e899a23..f515fcb 100644 (file)
@@ -988,6 +988,8 @@ enum CorInfoIntrinsics
     CORINFO_INTRINSIC_MemoryBarrier,
     CORINFO_INTRINSIC_GetCurrentManagedThread,
     CORINFO_INTRINSIC_GetManagedThreadId,
+    CORINFO_INTRINSIC_ByReference_Ctor,
+    CORINFO_INTRINSIC_ByReference_Value,
 
     CORINFO_INTRINSIC_Count,
     CORINFO_INTRINSIC_Illegal = -1,         // Not a true intrinsic,
index 6d9fb32..3e3a62c 100644 (file)
@@ -784,7 +784,7 @@ BOOL DacUnwindStackFrame(T_CONTEXT * pContext, T_KNONVOLATILE_CONTEXT_POINTERS*
 
 #if defined(FEATURE_PAL)
 // call back through data target to unwind out-of-process
-HRESULT DacVirtualUnwind(ULONG32 threadId, PCONTEXT context, PT_KNONVOLATILE_CONTEXT_POINTERS contextPointers);
+HRESULT DacVirtualUnwind(ULONG32 threadId, PT_CONTEXT context, PT_KNONVOLATILE_CONTEXT_POINTERS contextPointers);
 #endif // FEATURE_PAL
 
 #ifdef FEATURE_MINIMETADATA_IN_TRIAGEDUMPS
index 502d181..55cc905 100644 (file)
@@ -602,7 +602,7 @@ HRESULT FixContextForEnC(PCONTEXT        pCtx,
 
 #endif // #ifndef DACCESS_COMPILE
 
-#ifndef _TARGET_X86_
+#ifdef WIN64EXCEPTIONS
     static void EnsureCallerContextIsValid( PREGDISPLAY pRD, StackwalkCacheEntry* pCacheEntry, EECodeInfo * pCodeInfo = NULL );
     static size_t GetCallerSp( PREGDISPLAY  pRD );
 #endif
index 6d4850a..5151616 100644 (file)
@@ -451,6 +451,7 @@ private:
     GcSlotDesc* m_pLastSlot;
 };
 
+#ifdef USE_GC_INFO_DECODER
 class GcInfoDecoder
 {
 public:
@@ -678,6 +679,7 @@ private:
         }
     }
 };
+#endif // USE_GC_INFO_DECODER
 
 
 #endif // _GC_INFO_DECODER_
index f84db91..89d4be7 100644 (file)
     JITHELPER(CORINFO_HELP_FIELD_ACCESS_EXCEPTION,JIT_ThrowFieldAccessException, CORINFO_HELP_SIG_REG_ONLY)
     JITHELPER(CORINFO_HELP_CLASS_ACCESS_EXCEPTION,JIT_ThrowClassAccessException, CORINFO_HELP_SIG_REG_ONLY)
 
-#ifdef WIN64EXCEPTIONS
+// UNIXTODO: Disable JIT_EndCatch after revising the jitter not to use this (for x86/Linux)
+#ifndef _TARGET_X86_
     JITHELPER(CORINFO_HELP_ENDCATCH,            NULL,               CORINFO_HELP_SIG_CANNOT_USE_ALIGN_STUB)
 #else
     JITHELPER(CORINFO_HELP_ENDCATCH,            JIT_EndCatch,       CORINFO_HELP_SIG_CANNOT_USE_ALIGN_STUB)
index 9204862..ebc557b 100644 (file)
@@ -279,7 +279,7 @@ enum ReadyToRunHelper
     READYTORUN_HELPER_DblRound                  = 0xE2,
     READYTORUN_HELPER_FltRound                  = 0xE3,
 
-#ifndef _TARGET_X86_
+#ifdef WIN64EXCEPTIONS
     // Personality rountines
     READYTORUN_HELPER_PersonalityRoutine        = 0xF0,
     READYTORUN_HELPER_PersonalityRoutineFilterFunclet = 0xF1,
index 09a6a38..8114346 100644 (file)
@@ -18,10 +18,33 @@ struct REGDISPLAY {
                           // returned by GetContext or provided
                           // at exception time.
 
+#ifndef WIN64EXCEPTIONS
     // TODO: Unify with pCurrentContext / pCallerContext used on 64-bit
     PCONTEXT pContextForUnwind; // scratch context for unwinding
                                 // used to preserve context saved in the frame that 
                                 // could be otherwise wiped by the unwinding
+#else // !WIN64EXCEPTIONS
+    PT_CONTEXT pCurrentContext;   // [trashed] points to current Context of stackwalk
+    PT_CONTEXT pCallerContext;    // [trashed] points to the Context of the caller during stackwalk -- used for GC crawls
+
+    // [trashed] points to current context pointers of stackwalk
+    T_KNONVOLATILE_CONTEXT_POINTERS *pCurrentContextPointers;
+    // [trashed] points to the context pointers of the caller during stackwalk -- used for GC crawls
+    T_KNONVOLATILE_CONTEXT_POINTERS *pCallerContextPointers;
+
+    BOOL IsCallerContextValid;  // TRUE if pCallerContext really contains the caller's context
+    BOOL IsCallerSPValid;       // Don't add usage of this field.  This is only temporary.
+
+    T_CONTEXT  ctxOne;    // used by stackwalk
+    T_CONTEXT  ctxTwo;    // used by stackwalk
+
+    T_KNONVOLATILE_CONTEXT_POINTERS ctxPtrsOne;  // used by stackwalk
+    T_KNONVOLATILE_CONTEXT_POINTERS ctxPtrsTwo;  // used by stackwalk
+
+#ifdef DEBUG_REGDISPLAY
+    Thread *_pThread;
+#endif // DEBUG_REGDISPLAY
+#endif // !WIN64EXCEPTIONS
 
     DWORD * pEdi;
     DWORD * pEsi;
@@ -166,18 +189,6 @@ inline PCODE GetControlPC(REGDISPLAY *display) {
 void CheckRegDisplaySP (REGDISPLAY *pRD);
 #endif // DEBUG_REGDISPLAY
 
-inline void SyncRegDisplayToCurrentContext(REGDISPLAY* pRD)
-{
-    LIMITED_METHOD_CONTRACT;
-
-    pRD->SP         = (INT_PTR)GetSP(pRD->pCurrentContext);
-
-#ifdef DEBUG_REGDISPLAY
-    CheckRegDisplaySP(pRD);
-#endif // DEBUG_REGDISPLAY
-
-    pRD->ControlPC  = INT_PTR(GetIP(pRD->pCurrentContext));
-}
 
 // This function tells us if the given stack pointer is in one of the frames of the functions called by the given frame
 inline BOOL IsInCalleesFrames(REGDISPLAY *display, LPVOID stackPointer)
@@ -204,20 +215,6 @@ inline TADDR GetRegdisplayStackMark(REGDISPLAY *display)
 #endif // _TARGET_AMD64_
 }
 
-// This needs to be implemented for platforms that have funclets.
-inline LPVOID GetRegdisplayReturnValue(REGDISPLAY *display)
-{
-    LIMITED_METHOD_CONTRACT;
-
-#if defined(_TARGET_AMD64_)
-    return (LPVOID)display->pCurrentContext->Rax;
-#elif defined(_TARGET_ARM64_)
-    return (LPVOID)display->pCurrentContext->X0;
-#else
-    PORTABILITY_ASSERT("GetRegdisplayReturnValue NYI for this platform (Regdisp.h)");
-    return NULL;
-#endif
-}
 
 #elif defined(_TARGET_ARM_)
 
@@ -307,20 +304,7 @@ inline TADDR GetRegdisplayStackMark(REGDISPLAY *display) {
     return GetSP(display->pCallerContext);
 }
 
-inline void SyncRegDisplayToCurrentContext(REGDISPLAY* pRD)
-{
-    LIMITED_METHOD_CONTRACT;
-    pRD->SP         = (DWORD)GetSP(pRD->pCurrentContext);
-    pRD->ControlPC  = (DWORD)GetIP(pRD->pCurrentContext);
-}
-
-// This needs to be implemented for platforms that have funclets.
-inline LPVOID GetRegdisplayReturnValue(REGDISPLAY *display)
-{
-    LIMITED_METHOD_CONTRACT;
 
-    return (LPVOID)display->pCurrentContext->R0;
-}
 
 #else // none of the above processors
 
@@ -359,6 +343,50 @@ inline LPVOID GetRegdisplayStackMark(REGDISPLAY *display) {
 
 #endif
 
+#if defined(_WIN64) || defined(_TARGET_ARM_) || (defined(_TARGET_X86_) && defined(WIN64EXCEPTIONS))
+// This needs to be implemented for platforms that have funclets.
+inline LPVOID GetRegdisplayReturnValue(REGDISPLAY *display)
+{
+    LIMITED_METHOD_CONTRACT;
+
+#if defined(_TARGET_AMD64_)
+    return (LPVOID)display->pCurrentContext->Rax;
+#elif defined(_TARGET_ARM64_)
+    return (LPVOID)display->pCurrentContext->X0;
+#elif defined(_TARGET_ARM_)
+    return (LPVOID)display->pCurrentContext->R0;
+#elif defined(_TARGET_X86_)
+    return (LPVOID)display->pCurrentContext->Eax;
+#else
+    PORTABILITY_ASSERT("GetRegdisplayReturnValue NYI for this platform (Regdisp.h)");
+    return NULL;
+#endif
+}
+
+inline void SyncRegDisplayToCurrentContext(REGDISPLAY* pRD)
+{
+    LIMITED_METHOD_CONTRACT;
+
+#if defined(_WIN64)
+    pRD->SP         = (INT_PTR)GetSP(pRD->pCurrentContext);
+
+#ifdef DEBUG_REGDISPLAY
+    CheckRegDisplaySP(pRD);
+#endif // DEBUG_REGDISPLAY
+
+    pRD->ControlPC  = INT_PTR(GetIP(pRD->pCurrentContext));
+#elif defined(_TARGET_ARM_) // _WIN64
+    pRD->SP         = (DWORD)GetSP(pRD->pCurrentContext);
+    pRD->ControlPC  = (DWORD)GetIP(pRD->pCurrentContext);
+#elif defined(_TARGET_X86_) // _TARGET_ARM_
+    pRD->Esp        = (DWORD)GetSP(pRD->pCurrentContext);
+    pRD->ControlPC  = (DWORD)GetIP(pRD->pCurrentContext);
+#else // _TARGET_X86_
+    PORTABILITY_ASSERT("SyncRegDisplayToCurrentContext");
+#endif // _TARGET_ARM_ || _TARGET_X86_
+}
+#endif // _WIN64 || _TARGET_ARM_ || (_TARGET_X86_ && WIN64EXCEPTIONS)
+
 typedef REGDISPLAY *PREGDISPLAY;
 
 
@@ -368,6 +396,7 @@ inline void FillRegDisplay(const PREGDISPLAY pRD, PT_CONTEXT pctx, PT_CONTEXT pC
 
     SUPPORTS_DAC;
 
+#ifndef WIN64EXCEPTIONS
 #ifdef _TARGET_X86_
     pRD->pContext = pctx;
     pRD->pContextForUnwind = NULL;
@@ -381,57 +410,38 @@ inline void FillRegDisplay(const PREGDISPLAY pRD, PT_CONTEXT pctx, PT_CONTEXT pC
     pRD->Esp  = pctx->Esp;
     pRD->ControlPC = (PCODE)(pctx->Eip);
     pRD->PCTAddr = (UINT_PTR)&(pctx->Eip);
-#elif defined(_WIN64)
+#else // _TARGET_X86_
+    PORTABILITY_ASSERT("FillRegDisplay");
+#endif // _TARGET_???_ (ELSE)
+
+#else // !WIN64EXCEPTIONS
     pRD->pContext   = pctx;
 #ifdef _TARGET_AMD64_
     for (int i = 0; i < 16; i++)
     {
         *(&pRD->ctxPtrsOne.Rax + i) = (&pctx->Rax + i);
     }
-#elif defined(_TARGET_ARM64_)
+#elif defined(_TARGET_ARM64_) // _TARGET_AMD64_
     for (int i = 0; i < 12; i++)
     {
         *(&pRD->ctxPtrsOne.X19 + i) = (&pctx->X19 + i);
     }
-#endif // _TARGET_AMD64_
-
-    pRD->pCurrentContextPointers = &pRD->ctxPtrsOne;
-    pRD->pCallerContextPointers = &pRD->ctxPtrsTwo;
-
-    pRD->pCurrentContext = &(pRD->ctxOne);
-    pRD->pCallerContext  = &(pRD->ctxTwo);
-
-    // copy the active context to initialize our stackwalk
-    *(pRD->pCurrentContext)     = *(pctx);
-
-    // copy the caller context as well if it's specified
-    if (pCallerCtx == NULL)
-    {
-        pRD->IsCallerContextValid = FALSE;
-        pRD->IsCallerSPValid      = FALSE;        // Don't add usage of this field.  This is only temporary.
-    }
-    else
-    {
-        *(pRD->pCallerContext)    = *(pCallerCtx);
-        pRD->IsCallerContextValid = TRUE;
-        pRD->IsCallerSPValid      = TRUE;        // Don't add usage of this field.  This is only temporary.
-    }
-
-#ifdef DEBUG_REGDISPLAY
-    pRD->_pThread = NULL;
-#endif // DEBUG_REGDISPLAY
-
-    SyncRegDisplayToCurrentContext(pRD);
-#elif defined(_TARGET_ARM_)
-    pRD->pContext = pctx;
-
+#elif defined(_TARGET_ARM_) // _TARGET_ARM64_
     // Copy over the nonvolatile integer registers (R4-R11)
     for (int i = 0; i < 8; i++)
     {
         *(&pRD->ctxPtrsOne.R4 + i) = (&pctx->R4 + i);
     }
 
-    pRD->ctxPtrsOne.Lr = &pctx->Lr; 
+    pRD->ctxPtrsOne.Lr = &pctx->Lr;
+#elif defined(_TARGET_X86_) // _TARGET_ARM_
+    for (int i = 0; i < 4; ++i)
+    {
+        *(&pRD->ctxPtrsOne.Ebx + i) = (&pctx->Ebx + i);
+    }
+#else // _TARGET_X86_
+    PORTABILITY_ASSERT("FillRegDisplay");
+#endif // _TARGET_???_ (ELSE)
 
     // Setup the references
     pRD->pCurrentContextPointers = &pRD->ctxPtrsOne;
@@ -456,7 +466,9 @@ inline void FillRegDisplay(const PREGDISPLAY pRD, PT_CONTEXT pctx, PT_CONTEXT pC
         pRD->IsCallerSPValid      = TRUE;        // Don't add usage of this field.  This is only temporary.
     }
 
+#ifdef _TARGET_ARM_
     pRD->pPC = &pRD->pCurrentContext->Pc;
+#endif
 
 #ifdef DEBUG_REGDISPLAY
     pRD->_pThread = NULL;
@@ -464,9 +476,7 @@ inline void FillRegDisplay(const PREGDISPLAY pRD, PT_CONTEXT pctx, PT_CONTEXT pC
 
     // This will setup the PC and SP
     SyncRegDisplayToCurrentContext(pRD);
-#else
-    PORTABILITY_ASSERT("@NYI Platform - InitRegDisplay (Threads.cpp)");
-#endif
+#endif // !WIN64EXCEPTIONS
 }
 
 // Initialize a new REGDISPLAY/CONTEXT pair from an existing valid REGDISPLAY.
index f52f24b..bb3ca28 100644 (file)
@@ -37,7 +37,7 @@
     #define LOGGING
 #endif
 
-#if !defined(_TARGET_X86_)
+#if !defined(_TARGET_X86_) || defined(FEATURE_PAL)
 #define WIN64EXCEPTIONS
 #endif
 
index 47f1052..bb6a57c 100644 (file)
@@ -365,6 +365,14 @@ void BasicBlock::dspFlags()
     {
         printf("KEEP ");
     }
+    if (bbFlags & BBF_CLONED_FINALLY_BEGIN)
+    {
+        printf("cfb ");
+    }
+    if (bbFlags & BBF_CLONED_FINALLY_END)
+    {
+        printf("cfe ");
+    }
 }
 
 /*****************************************************************************
@@ -664,7 +672,7 @@ bool BasicBlock::IsLIR()
 // Return Value:
 //    The first statement in the block's bbTreeList.
 //
-GenTreeStmt* BasicBlock::firstStmt()
+GenTreeStmt* BasicBlock::firstStmt() const
 {
     if (bbTreeList == nullptr)
     {
@@ -683,7 +691,7 @@ GenTreeStmt* BasicBlock::firstStmt()
 // Return Value:
 //    The last statement in the block's bbTreeList.
 //
-GenTreeStmt* BasicBlock::lastStmt()
+GenTreeStmt* BasicBlock::lastStmt() const
 {
     if (bbTreeList == nullptr)
     {
index add5451..cb02afd 100644 (file)
@@ -353,15 +353,18 @@ struct BasicBlock : private LIR::Range
                                        // BBJ_CALLFINALLY block, as well as, on x86, the final step block out of a
                                        // finally.
 
+#define BBF_CLONED_FINALLY_BEGIN 0x100000000 // First block of a cloned finally region
+#define BBF_CLONED_FINALLY_END 0x200000000   // Last block of a cloned finally region
+
 // Flags that relate blocks to loop structure.
 
 #define BBF_LOOP_FLAGS (BBF_LOOP_PREHEADER | BBF_LOOP_HEAD | BBF_LOOP_CALL0 | BBF_LOOP_CALL1)
 
-    bool isRunRarely()
+    bool isRunRarely() const
     {
         return ((bbFlags & BBF_RUN_RARELY) != 0);
     }
-    bool isLoopHead()
+    bool isLoopHead() const
     {
         return ((bbFlags & BBF_LOOP_HEAD) != 0);
     }
@@ -388,7 +391,7 @@ struct BasicBlock : private LIR::Range
 // For example, the top block might or might not have BBF_GC_SAFE_POINT,
 // but we assume it does not have BBF_GC_SAFE_POINT any more.
 
-#define BBF_SPLIT_LOST (BBF_GC_SAFE_POINT | BBF_HAS_JMP | BBF_KEEP_BBJ_ALWAYS)
+#define BBF_SPLIT_LOST (BBF_GC_SAFE_POINT | BBF_HAS_JMP | BBF_KEEP_BBJ_ALWAYS | BBF_CLONED_FINALLY_END)
 
 // Flags gained by the bottom block when a block is split.
 // Note, this is a conservative guess.
@@ -399,7 +402,7 @@ struct BasicBlock : private LIR::Range
 
 #define BBF_SPLIT_GAINED                                                                                               \
     (BBF_DONT_REMOVE | BBF_HAS_LABEL | BBF_HAS_JMP | BBF_BACKWARD_JUMP | BBF_HAS_IDX_LEN | BBF_HAS_NEWARRAY |          \
-     BBF_PROF_WEIGHT | BBF_HAS_NEWOBJ | BBF_KEEP_BBJ_ALWAYS)
+     BBF_PROF_WEIGHT | BBF_HAS_NEWOBJ | BBF_KEEP_BBJ_ALWAYS | BBF_CLONED_FINALLY_END)
 
 #ifndef __GNUC__ // GCC doesn't like C_ASSERT at global scope
     static_assert_no_msg((BBF_SPLIT_NONEXIST & BBF_SPLIT_LOST) == 0);
@@ -818,33 +821,15 @@ struct BasicBlock : private LIR::Range
     // lclVar, and thus has no local #, we can't use a GenTreePhiArg.  Instead, we use this struct.
     struct HeapPhiArg
     {
-        bool m_isSsaNum; // If true, the phi arg is an SSA # for an internal try block heap state, being
-                         // added to the phi of a catch block.  If false, it's a pred block.
-        union {
-            BasicBlock* m_predBB; // Predecessor block from which the SSA # flows.
-            unsigned    m_ssaNum; // SSA# for internal block heap state.
-        };
+        unsigned    m_ssaNum;  // SSA# for incoming value.
         HeapPhiArg* m_nextArg; // Next arg in the list, else NULL.
 
         unsigned GetSsaNum()
         {
-            if (m_isSsaNum)
-            {
-                return m_ssaNum;
-            }
-            else
-            {
-                assert(m_predBB != nullptr);
-                return m_predBB->bbHeapSsaNumOut;
-            }
+            return m_ssaNum;
         }
 
-        HeapPhiArg(BasicBlock* predBB, HeapPhiArg* nextArg = nullptr)
-            : m_isSsaNum(false), m_predBB(predBB), m_nextArg(nextArg)
-        {
-        }
-        HeapPhiArg(unsigned ssaNum, HeapPhiArg* nextArg = nullptr)
-            : m_isSsaNum(true), m_ssaNum(ssaNum), m_nextArg(nextArg)
+        HeapPhiArg(unsigned ssaNum, HeapPhiArg* nextArg = nullptr) : m_ssaNum(ssaNum), m_nextArg(nextArg)
         {
         }
 
@@ -980,8 +965,8 @@ struct BasicBlock : private LIR::Range
         return bbNum - 1;
     }
 
-    GenTreeStmt* firstStmt();
-    GenTreeStmt* lastStmt();
+    GenTreeStmt* firstStmt() const;
+    GenTreeStmt* lastStmt() const;
     GenTreeStmt* lastTopLevelStmt();
 
     GenTree* firstNode();
index 3241c88..855b9b0 100644 (file)
@@ -4616,8 +4616,7 @@ void CodeGen::genStoreInd(GenTreePtr node)
                     assert(rmwSrc == data->gtGetOp2());
                     genCodeForShiftRMW(storeInd);
                 }
-                else if (!compiler->opts.compDbgCode && data->OperGet() == GT_ADD &&
-                         (rmwSrc->IsIntegralConst(1) || rmwSrc->IsIntegralConst(-1)))
+                else if (data->OperGet() == GT_ADD && (rmwSrc->IsIntegralConst(1) || rmwSrc->IsIntegralConst(-1)))
                 {
                     // Generate "inc/dec [mem]" instead of "add/sub [mem], 1".
                     //
@@ -4858,11 +4857,6 @@ void CodeGen::genCallInstruction(GenTreePtr node)
         if (arg->OperGet() != GT_ARGPLACE && !(arg->gtFlags & GTF_LATE_ARG))
         {
 #if defined(_TARGET_X86_)
-            assert((arg->OperGet() == GT_PUTARG_STK) || (arg->OperGet() == GT_LONG));
-            if (arg->OperGet() == GT_LONG)
-            {
-                assert((arg->gtGetOp1()->OperGet() == GT_PUTARG_STK) && (arg->gtGetOp2()->OperGet() == GT_PUTARG_STK));
-            }
             if ((arg->OperGet() == GT_PUTARG_STK) && (arg->gtGetOp1()->OperGet() == GT_FIELD_LIST))
             {
                 fgArgTabEntryPtr curArgTabEntry = compiler->gtArgEntryByNode(call, arg);
@@ -7796,9 +7790,9 @@ void CodeGen::genPutArgStk(GenTreePutArgStk* putArgStk)
 
     GenTreePtr data = putArgStk->gtOp1;
 
-    // On a 32-bit target, all of the long arguments have been decomposed into
-    // a separate putarg_stk for each of the upper and lower halves.
-    noway_assert(targetType != TYP_LONG);
+    // On a 32-bit target, all of the long arguments are handled with GT_FIELD_LIST,
+    // and the type of the putArgStk is TYP_VOID.
+    assert(targetType != TYP_LONG);
 
     const unsigned argSize = putArgStk->getArgSize();
     assert((argSize % TARGET_POINTER_SIZE) == 0);
@@ -8395,6 +8389,14 @@ void CodeGen::genCreateAndStoreGCInfoX64(unsigned codeSize, unsigned prologSize
         gcInfoEncoder->SetSizeOfEditAndContinuePreservedArea(preservedAreaSize);
     }
 
+    if (compiler->opts.IsReversePInvoke())
+    {
+        unsigned reversePInvokeFrameVarNumber = compiler->lvaReversePInvokeFrameVar;
+        assert(reversePInvokeFrameVarNumber != BAD_VAR_NUM && reversePInvokeFrameVarNumber < compiler->lvaRefCount);
+        LclVarDsc& reversePInvokeFrameVar = compiler->lvaTable[reversePInvokeFrameVarNumber];
+        gcInfoEncoder->SetReversePInvokeFrameSlot(reversePInvokeFrameVar.lvStkOffs);
+    }
+
     gcInfoEncoder->Build();
 
     // GC Encoder automatically puts the GC info in the right spot using ICorJitInfo::allocGCInfo(size_t)
index 47d3c35..34844e8 100644 (file)
@@ -3297,8 +3297,6 @@ void Compiler::compInitOptions(JitFlags* jitFlags)
     }
 #endif
 
-    opts.compMustInlinePInvokeCalli = jitFlags->IsSet(JitFlags::JIT_FLAG_IL_STUB);
-
     opts.compScopeInfo = opts.compDbgInfo;
 
 #ifdef LATE_DISASM
index b69d574..2a5c561 100644 (file)
@@ -2785,7 +2785,7 @@ protected:
 
     void impImportNewObjArray(CORINFO_RESOLVED_TOKEN* pResolvedToken, CORINFO_CALL_INFO* pCallInfo);
 
-    bool impCanPInvokeInline(BasicBlock* block);
+    bool impCanPInvokeInline();
     bool impCanPInvokeInlineCallSite(BasicBlock* block);
     void impCheckForPInvokeCall(
         GenTreePtr call, CORINFO_METHOD_HANDLE methHnd, CORINFO_SIG_INFO* sig, unsigned mflags, BasicBlock* block);
@@ -2836,7 +2836,8 @@ protected:
 
     void impImportLeave(BasicBlock* block);
     void impResetLeaveBlock(BasicBlock* block, unsigned jmpAddr);
-    GenTreePtr impIntrinsic(CORINFO_CLASS_HANDLE  clsHnd,
+    GenTreePtr impIntrinsic(GenTreePtr            newobjThis,
+                            CORINFO_CLASS_HANDLE  clsHnd,
                             CORINFO_METHOD_HANDLE method,
                             CORINFO_SIG_INFO*     sig,
                             int                   memberRef,
@@ -3500,6 +3501,10 @@ public:
 
     void fgInline();
 
+    void fgRemoveEmptyFinally();
+
+    void fgCloneFinally();
+
     GenTreePtr fgGetCritSectOfStaticMethod();
 
 #if !defined(_TARGET_X86_)
@@ -4271,6 +4276,7 @@ public:
     void fgDebugCheckNodeLinks(BasicBlock* block, GenTreePtr stmt);
     void fgDebugCheckFlags(GenTreePtr tree);
     void fgDebugCheckFlagsHelper(GenTreePtr tree, unsigned treeFlags, unsigned chkFlags);
+    void fgDebugCheckTryFinallyExits();
 #endif
 
 #ifdef LEGACY_BACKEND
@@ -7625,8 +7631,6 @@ public:
         static const bool compNoPInvokeInlineCB;
 #endif
 
-        bool compMustInlinePInvokeCalli; // Unmanaged CALLI in IL stubs must be inlined
-
 #ifdef DEBUG
         bool compGcChecks;         // Check arguments and return values to ensure they are sane
         bool compStackCheckOnRet;  // Check ESP on return to ensure it is correct
index ac1bb63..655170f 100644 (file)
 // corresponding array of string names of those phases.  This include file undefines CompPhaseNameMacro
 // after the last use.
 // The arguments are:
-//   CompPhaseNameMacro(enumName, stringName, hasChildren, parent)
+//   CompPhaseNameMacro(enumName, stringName, shortName, hasChildren, parent)
 //     "enumName" is an Enumeration-style all-caps name.
 //     "stringName" is a self-explanatory.
+//     "shortName" is an abbreviated form for stringName
 //     "hasChildren" is true if this phase is broken out into subphases.
 //         (We should never do EndPhase on a phase that has children, only on 'leaf phases.')
 //     "parent" is -1 for leaf phases, otherwise it is the "enumName" of the parent phase.
@@ -97,6 +98,9 @@ CompPhaseNameMacro(PHASE_EMIT_GCEH,              "Emit GC+EH tables",
 // for calls through ICorJitInfo across all "real" phases.
 CompPhaseNameMacro(PHASE_CLR_API,                "CLR API calls",                  "CLR-API",  false, -1)
 #endif
+
+CompPhaseNameMacro(PHASE_EMPTY_FINALLY,          "Remove empty finally",           "EMPTYFIN",  false, -1)
+CompPhaseNameMacro(PHASE_CLONE_FINALLY,          "Clone finally",                  "CLONEFIN",  false, -1)
 // clang-format on
 
 #undef CompPhaseNameMacro
index b6bacfa..a914c21 100644 (file)
@@ -898,7 +898,8 @@ bool emitter::emitInsCanOnlyWriteSSE2OrAVXReg(instrDesc* id)
     // The following SSE2 instructions write to a general purpose integer register.
     if (!IsSSEOrAVXInstruction(ins) || ins == INS_mov_xmm2i || ins == INS_cvttsd2si
 #ifndef LEGACY_BACKEND
-        || ins == INS_cvttss2si || ins == INS_cvtsd2si || ins == INS_cvtss2si
+        || ins == INS_cvttss2si || ins == INS_cvtsd2si || ins == INS_cvtss2si || ins == INS_pmovmskb ||
+        ins == INS_pextrw
 #endif // !LEGACY_BACKEND
         )
     {
@@ -8055,10 +8056,7 @@ DONE:
     }
     else
     {
-        if (emitInsCanOnlyWriteSSE2OrAVXReg(id))
-        {
-        }
-        else
+        if (!emitInsCanOnlyWriteSSE2OrAVXReg(id))
         {
             switch (id->idInsFmt())
             {
@@ -8450,10 +8448,7 @@ BYTE* emitter::emitOutputSV(BYTE* dst, instrDesc* id, code_t code, CnsVal* addc)
     }
     else
     {
-        if (emitInsCanOnlyWriteSSE2OrAVXReg(id))
-        {
-        }
-        else
+        if (!emitInsCanOnlyWriteSSE2OrAVXReg(id))
         {
             switch (id->idInsFmt())
             {
@@ -8883,10 +8878,7 @@ BYTE* emitter::emitOutputCV(BYTE* dst, instrDesc* id, code_t code, CnsVal* addc)
     }
     else
     {
-        if (emitInsCanOnlyWriteSSE2OrAVXReg(id))
-        {
-        }
-        else
+        if (!emitInsCanOnlyWriteSSE2OrAVXReg(id))
         {
             switch (id->idInsFmt())
             {
@@ -9428,10 +9420,7 @@ BYTE* emitter::emitOutputRR(BYTE* dst, instrDesc* id)
     }
     else
     {
-        if (emitInsCanOnlyWriteSSE2OrAVXReg(id))
-        {
-        }
-        else
+        if (!emitInsCanOnlyWriteSSE2OrAVXReg(id))
         {
             switch (id->idInsFmt())
             {
@@ -10832,6 +10821,12 @@ size_t emitter::emitOutputInstr(insGroup* ig, instrDesc* id, BYTE** dp)
 
             dst += emitOutputByte(dst, emitGetInsSC(id));
             sz = emitSizeOfInsDsc(id);
+
+            // Kill any GC ref in the destination register if necessary.
+            if (!emitInsCanOnlyWriteSSE2OrAVXReg(id))
+            {
+                emitGCregDeadUpd(id->idReg1(), dst);
+            }
             break;
 
         /********************************************************************/
index 441569c..50c2621 100644 (file)
@@ -8550,8 +8550,12 @@ void Compiler::fgAddInternal()
 GenTreeStmt* Compiler::fgNewStmtFromTree(GenTreePtr tree, BasicBlock* block, IL_OFFSETX offs)
 {
     GenTreeStmt* stmt = gtNewStmt(tree, offs);
-    gtSetStmtInfo(stmt);
-    fgSetStmtSeq(stmt);
+
+    if (fgStmtListThreaded)
+    {
+        gtSetStmtInfo(stmt);
+        fgSetStmtSeq(stmt);
+    }
 
 #if DEBUG
     if (block != nullptr)
@@ -12946,6 +12950,12 @@ bool Compiler::fgOptimizeBranchToEmptyUnconditional(BasicBlock* block, BasicBloc
         optimizeJump = false;
     }
 
+    // Don't optimize a jump to a cloned finally
+    if (bDest->bbFlags & BBF_CLONED_FINALLY_BEGIN)
+    {
+        optimizeJump = false;
+    }
+
 #if FEATURE_EH_FUNCLETS && defined(_TARGET_ARM_)
     // Don't optimize a jump to a finally target. For BB1->BB2->BB3, where
     // BB2 is a finally target, if we changed BB1 to jump directly to BB3,
@@ -22471,3 +22481,1026 @@ void Compiler::fgLclFldAssign(unsigned lclNum)
         lvaSetVarDoNotEnregister(lclNum DEBUGARG(DNER_LocalField));
     }
 }
+
+//------------------------------------------------------------------------
+// fgRemoveEmptyFinally: Remove try/finallys where the finally is empty
+//
+// Notes:
+//    Removes all try/finallys in the method with empty finallys.
+//    These typically arise from inlining empty Dispose methods.
+//
+//    Converts callfinally to a jump to the finally continuation.
+//    Removes the finally, and reparents all blocks in the try to the
+//    enclosing try or method region.
+//
+//    Currently limited to trivially empty finallys: those with one basic
+//    block containing only single RETFILT statement. It is possible but
+//    not likely that more complex-looking finallys will eventually become
+//    empty (from say subsequent optimization). An SPMI run with
+//    just the "detection" part of this phase run after optimization
+//    found only one example where a new empty finally was detected.
+
+void Compiler::fgRemoveEmptyFinally()
+{
+    JITDUMP("\n*************** In fgRemoveEmptyFinally()\n");
+
+    if (compHndBBtabCount == 0)
+    {
+        JITDUMP("No EH in this method, nothing to remove.\n");
+        return;
+    }
+
+    if (opts.MinOpts())
+    {
+        JITDUMP("Method compiled with minOpts, no removal.\n");
+        return;
+    }
+
+    if (opts.compDbgCode)
+    {
+        JITDUMP("Method compiled with debug codegen, no removal.\n");
+        return;
+    }
+
+#ifdef DEBUG
+    if (verbose)
+    {
+        printf("\n*************** Before fgRemoveEmptyFinally()\n");
+        fgDispBasicBlocks();
+        fgDispHandlerTab();
+        printf("\n");
+    }
+#endif // DEBUG
+
+    // Look for finallys or faults that are empty.
+    unsigned finallyCount = 0;
+    unsigned emptyCount   = 0;
+    unsigned XTnum        = 0;
+    while (XTnum < compHndBBtabCount)
+    {
+        EHblkDsc* const HBtab = &compHndBBtab[XTnum];
+
+        // Check if this is a try/finally.  We could also look for empty
+        // try/fault but presumably those are rare.
+        if (!HBtab->HasFinallyHandler())
+        {
+            JITDUMP("EH#%u is not a try-finally; skipping.\n", XTnum);
+            XTnum++;
+            continue;
+        }
+
+        finallyCount++;
+
+        // Look at blocks involved.
+        BasicBlock* const firstBlock = HBtab->ebdHndBeg;
+        BasicBlock* const lastBlock  = HBtab->ebdHndLast;
+
+        // Limit for now to finallys that are single blocks.
+        if (firstBlock != lastBlock)
+        {
+            JITDUMP("EH#%u finally has multiple basic blocks; skipping.\n", XTnum);
+            XTnum++;
+            continue;
+        }
+
+        // Limit for now to finallys that contain only a GT_RETFILT.
+        bool isEmpty = true;
+
+        for (GenTreeStmt* stmt = firstBlock->firstStmt(); stmt != nullptr; stmt = stmt->gtNextStmt)
+        {
+            GenTreePtr stmtExpr = stmt->gtStmtExpr;
+
+            if (stmtExpr->gtOper != GT_RETFILT)
+            {
+                isEmpty = false;
+                break;
+            }
+        }
+
+        if (!isEmpty)
+        {
+            JITDUMP("EH#%u finally is not empty; skipping.\n", XTnum);
+            XTnum++;
+            continue;
+        }
+
+        JITDUMP("EH#%u has empty finally, removing the region.\n", XTnum);
+
+        // Find all the call finallys that invoke this finally,
+        // and modify them to jump to the return point.
+        BasicBlock* firstCallFinallyRangeBlock = nullptr;
+        BasicBlock* endCallFinallyRangeBlock   = nullptr;
+        ehGetCallFinallyBlockRange(XTnum, &firstCallFinallyRangeBlock, &endCallFinallyRangeBlock);
+
+        BasicBlock* currentBlock = firstCallFinallyRangeBlock;
+
+        while (currentBlock != endCallFinallyRangeBlock)
+        {
+            BasicBlock* nextBlock = currentBlock->bbNext;
+
+            if ((currentBlock->bbJumpKind == BBJ_CALLFINALLY) && (currentBlock->bbJumpDest == firstBlock))
+            {
+                // Retarget the call finally to jump to the return
+                // point.
+                //
+                // We don't expect to see retless finallys here, since
+                // the finally is empty.
+                noway_assert(currentBlock->isBBCallAlwaysPair());
+
+                BasicBlock* const leaveBlock          = currentBlock->bbNext;
+                BasicBlock* const postTryFinallyBlock = leaveBlock->bbJumpDest;
+
+                noway_assert(leaveBlock->bbJumpKind == BBJ_ALWAYS);
+
+                currentBlock->bbJumpDest = postTryFinallyBlock;
+                currentBlock->bbJumpKind = BBJ_ALWAYS;
+
+                // Ref count updates.
+                fgAddRefPred(postTryFinallyBlock, currentBlock);
+                // fgRemoveRefPred(firstBlock, currentBlock);
+
+                // Delete the leave block, which should be marked as
+                // keep always.
+                assert((leaveBlock->bbFlags & BBF_KEEP_BBJ_ALWAYS) != 0);
+                nextBlock = leaveBlock->bbNext;
+
+                leaveBlock->bbFlags &= ~BBF_KEEP_BBJ_ALWAYS;
+                fgRemoveBlock(leaveBlock, true);
+
+                // The postTryFinallyBlock may be a finalStep block.
+                // It is now a normal block, so clear the special keep
+                // always flag.
+                postTryFinallyBlock->bbFlags &= ~BBF_KEEP_BBJ_ALWAYS;
+
+#if FEATURE_EH_FUNCLETS && defined(_TARGET_ARM_)
+                // Also, clear the finally target bit for arm
+                fgClearFinallyTargetBit(postTryFinallyBlock);
+#endif // FEATURE_EH_FUNCLETS && defined(_TARGET_ARM_)
+
+#if !FEATURE_EH_FUNCLETS
+                // Remove the GT_END_LFIN from the post-try-finally block.
+                // remove it since there is no finally anymore.
+                GenTreeStmt* endFinallyStmt = postTryFinallyBlock->lastStmt();
+                GenTreePtr   endFinallyExpr = endFinallyStmt->gtStmtExpr;
+                assert(endFinallyExpr->gtOper == GT_END_LFIN);
+                fgRemoveStmt(postTryFinallyBlock, endFinallyStmt);
+#endif // !FEATURE_EH_FUNCLETS
+
+                // Make sure iteration isn't going off the deep end.
+                assert(leaveBlock != endCallFinallyRangeBlock);
+            }
+
+            currentBlock = nextBlock;
+        }
+
+        // Handler block should now be unreferenced, since the only
+        // explicit references to it were in call finallys.
+        firstBlock->bbRefs = 0;
+
+        // Remove the handler block.
+        const bool unreachable = true;
+        firstBlock->bbFlags &= ~BBF_DONT_REMOVE;
+        fgRemoveBlock(firstBlock, unreachable);
+
+        // Find enclosing try region for the try, if any, and update
+        // the try region. Note the handler region (if any) won't
+        // change.
+        BasicBlock* const firstTryBlock = HBtab->ebdTryBeg;
+        BasicBlock* const lastTryBlock  = HBtab->ebdTryLast;
+        assert(firstTryBlock->getTryIndex() == XTnum);
+
+        for (BasicBlock* block = firstTryBlock; block != nullptr; block = block->bbNext)
+        {
+            // Look for blocks directly contained in this try, and
+            // update the try region appropriately.
+            //
+            // Try region for blocks transitively contained (say in a
+            // child try) will get updated by the subsequent call to
+            // fgRemoveEHTableEntry.
+            if (block->getTryIndex() == XTnum)
+            {
+                if (firstBlock->hasTryIndex())
+                {
+                    block->setTryIndex(firstBlock->getTryIndex());
+                }
+                else
+                {
+                    block->clearTryIndex();
+                }
+            }
+
+            if (block == firstTryBlock)
+            {
+                assert((block->bbFlags & BBF_TRY_BEG) != 0);
+                block->bbFlags &= ~BBF_TRY_BEG;
+            }
+
+            if (block == lastTryBlock)
+            {
+                break;
+            }
+        }
+
+        // Remove the try-finally EH region. This will compact the EH table
+        // so XTnum now points at the next entry.
+        fgRemoveEHTableEntry(XTnum);
+
+        emptyCount++;
+    }
+
+    if (emptyCount > 0)
+    {
+        JITDUMP("fgRemoveEmptyFinally() removed %u try-finally clauses from %u finallys\n", emptyCount, finallyCount);
+
+#ifdef DEBUG
+        if (verbose)
+        {
+            printf("\n*************** After fgRemoveEmptyFinally()\n");
+            fgDispBasicBlocks();
+            fgDispHandlerTab();
+            printf("\n");
+        }
+
+        fgVerifyHandlerTab();
+        fgDebugCheckBBlist(false, false);
+
+#endif // DEBUG
+    }
+}
+
+//------------------------------------------------------------------------
+// fgCloneFinally: Optimize normal exit path from a try/finally
+//
+// Notes:
+//    Handles finallys that are not enclosed by or enclosing other
+//    handler regions.
+//
+//    Converts the "normal exit" callfinally to a jump to a cloned copy
+//    of the finally, which in turn jumps to the finally continuation.
+//
+//    If all callfinallys for a given finally are converted to jump to
+//    the clone, the try-finally is modified into a try-fault,
+//    distingushable from organic try-faults by handler type
+//    EH_HANDLER_FAULT_WAS_FINALLY vs the organic EH_HANDLER_FAULT.
+//
+//    Does not yet handle thread abort. The open issues here are how
+//    to maintain the proper description of the cloned finally blocks
+//    as a handler (for thread abort purposes), how to prevent code
+//    motion in or out of these blocks, and how to report this cloned
+//    handler to the runtime. Some building blocks for thread abort
+//    exist (see below) but more work needed.
+//
+//    The first and last blocks of the cloned finally are marked with
+//    BBF_CLONED_FINALLY_BEGIN and BBF_CLONED_FINALLY_END. However
+//    these markers currently can get lost during subsequent
+//    optimizations.
+
+void Compiler::fgCloneFinally()
+{
+    JITDUMP("\n*************** In fgCloneFinally()\n");
+
+#if FEATURE_CORECLR
+    bool enableCloning = true;
+#else
+    // Finally cloning currently doesn't provide sufficient protection
+    // for the cloned code in the presence of thread abort.
+    bool enableCloning = false;
+#endif // FEATURE_CORECLR
+
+#if DEBUG
+    // Allow override to enable/disable.
+    enableCloning = (JitConfig.JitEnableFinallyCloning() == 1);
+#endif // DEBUG
+
+    if (!enableCloning)
+    {
+        JITDUMP("Finally cloning disabled.\n");
+        return;
+    }
+
+    if (compHndBBtabCount == 0)
+    {
+        JITDUMP("No EH in this method, no cloning.\n");
+        return;
+    }
+
+    if (opts.MinOpts())
+    {
+        JITDUMP("Method compiled with minOpts, no cloning.\n");
+        return;
+    }
+
+    if (opts.compDbgCode)
+    {
+        JITDUMP("Method compiled with debug codegen, no cloning.\n");
+        return;
+    }
+
+#ifdef DEBUG
+    if (verbose)
+    {
+        printf("\n*************** Before fgCloneFinally()\n");
+        fgDispBasicBlocks();
+        fgDispHandlerTab();
+        printf("\n");
+    }
+
+    // Verify try-finally exits look good before we start.
+    fgDebugCheckTryFinallyExits();
+
+#endif // DEBUG
+
+    // Look for finallys that are not contained within other handlers,
+    // and which do not themselves contain EH.
+    //
+    // Note these cases potentially could be handled, but are less
+    // obviously profitable and require modification of the handler
+    // table.
+    unsigned  XTnum      = 0;
+    EHblkDsc* HBtab      = compHndBBtab;
+    unsigned  cloneCount = 0;
+    for (; XTnum < compHndBBtabCount; XTnum++, HBtab++)
+    {
+        // Check if this is a try/finally
+        if (!HBtab->HasFinallyHandler())
+        {
+            JITDUMP("EH#%u is not a try-finally; skipping.\n", XTnum);
+            continue;
+        }
+
+        // Check if enclosed by another handler.
+        const unsigned enclosingHandlerRegion = ehGetEnclosingHndIndex(XTnum);
+
+        if (enclosingHandlerRegion != EHblkDsc::NO_ENCLOSING_INDEX)
+        {
+            JITDUMP("EH#%u is enclosed by handler EH#%u; skipping.\n", XTnum, enclosingHandlerRegion);
+            continue;
+        }
+
+        bool     containsEH                   = false;
+        unsigned exampleEnclosedHandlerRegion = 0;
+
+        // Only need to look at lower numbered regions because the
+        // handler table is ordered by nesting.
+        for (unsigned i = 0; i < XTnum; i++)
+        {
+            if (ehGetEnclosingHndIndex(i) == XTnum)
+            {
+                exampleEnclosedHandlerRegion = i;
+                containsEH                   = true;
+                break;
+            }
+        }
+
+        if (containsEH)
+        {
+            JITDUMP("Finally for EH#%u encloses handler EH#%u; skipping.\n", XTnum, exampleEnclosedHandlerRegion);
+            continue;
+        }
+
+        // Look at blocks involved.
+        BasicBlock* const firstBlock = HBtab->ebdHndBeg;
+        BasicBlock* const lastBlock  = HBtab->ebdHndLast;
+        assert(firstBlock != nullptr);
+        assert(lastBlock != nullptr);
+        BasicBlock* nextBlock       = lastBlock->bbNext;
+        unsigned    regionBBCount   = 0;
+        unsigned    regionStmtCount = 0;
+        bool        hasFinallyRet   = false;
+        bool        isAllRare       = true;
+        bool        hasSwitch       = false;
+
+        for (const BasicBlock* block = firstBlock; block != nextBlock; block = block->bbNext)
+        {
+            if (block->bbJumpKind == BBJ_SWITCH)
+            {
+                hasSwitch = true;
+                break;
+            }
+
+            regionBBCount++;
+
+            // Should we compute statement cost here, or is it
+            // premature...? For now just count statements I guess.
+            for (GenTreeStmt* stmt = block->firstStmt(); stmt != nullptr; stmt = stmt->gtNextStmt)
+            {
+                regionStmtCount++;
+            }
+
+            hasFinallyRet = hasFinallyRet || (block->bbJumpKind == BBJ_EHFINALLYRET);
+            isAllRare     = isAllRare && block->isRunRarely();
+        }
+
+        // Skip cloning if the finally has a switch.
+        if (hasSwitch)
+        {
+            JITDUMP("Finally in EH#%u has a switch; skipping.\n", XTnum);
+            continue;
+        }
+
+        // Skip cloning if the finally must throw.
+        if (!hasFinallyRet)
+        {
+            JITDUMP("Finally in EH#%u does not return; skipping.\n", XTnum);
+            continue;
+        }
+
+        // Skip cloning if the finally is rarely run code.
+        if (isAllRare)
+        {
+            JITDUMP("Finally in EH#%u is run rarely; skipping.\n", XTnum);
+            continue;
+        }
+
+        // Empirical studies from CoreCLR and CoreFX show that less
+        // that 1% of finally regions have more than 15
+        // statements. So, to avoid potentially excessive code growth,
+        // only clone finallys that have 15 or fewer statements.
+        const unsigned stmtCountLimit = 15;
+        if (regionStmtCount > stmtCountLimit)
+        {
+            JITDUMP("Finally in EH#%u has %u statements, limit is %u; skipping.\n", XTnum, regionStmtCount,
+                    stmtCountLimit);
+            continue;
+        }
+
+        JITDUMP("EH#%u is a candidate for finally cloning:"
+                " %u blocks, %u statements\n",
+                XTnum, regionBBCount, regionStmtCount);
+
+        // Walk the try region backwards looking for the last block
+        // that transfers control to a callfinally.
+        BasicBlock* const firstTryBlock = HBtab->ebdTryBeg;
+        BasicBlock* const lastTryBlock  = HBtab->ebdTryLast;
+        assert(firstTryBlock->getTryIndex() == XTnum);
+        assert(lastTryBlock->getTryIndex() == XTnum);
+        BasicBlock* const beforeTryBlock = firstTryBlock->bbPrev;
+
+        BasicBlock* normalCallFinallyBlock   = nullptr;
+        BasicBlock* normalCallFinallyReturn  = nullptr;
+        BasicBlock* cloneInsertAfter         = HBtab->ebdTryLast;
+        bool        tryToRelocateCallFinally = false;
+
+        for (BasicBlock* block = lastTryBlock; block != beforeTryBlock; block = block->bbPrev)
+        {
+#if FEATURE_EH_CALLFINALLY_THUNKS
+            // Look for blocks that are always jumps to a call finally
+            // pair that targets our finally.
+            if (block->bbJumpKind != BBJ_ALWAYS)
+            {
+                continue;
+            }
+
+            BasicBlock* const jumpDest = block->bbJumpDest;
+
+            if (!jumpDest->isBBCallAlwaysPair() || (jumpDest->bbJumpDest != firstBlock))
+            {
+                continue;
+            }
+#else
+            // Look for call finally pair directly within the try
+            if (!block->isBBCallAlwaysPair() || (block->bbJumpDest != firstBlock))
+            {
+                continue;
+            }
+
+            BasicBlock* const jumpDest = block;
+#endif // FEATURE_EH_CALLFINALLY_THUNKS
+
+            // Found our block.
+            BasicBlock* const finallyReturnBlock  = jumpDest->bbNext;
+            BasicBlock* const postTryFinallyBlock = finallyReturnBlock->bbJumpDest;
+
+            normalCallFinallyBlock  = jumpDest;
+            normalCallFinallyReturn = postTryFinallyBlock;
+
+#if FEATURE_EH_CALLFINALLY_THUNKS
+            // When there are callfinally thunks, we don't expect to see the
+            // callfinally within a handler region either.
+            assert(!jumpDest->hasHndIndex());
+
+            // Update the clone insertion point to just after the
+            // call always pair.
+            cloneInsertAfter = finallyReturnBlock;
+
+            // We will consider moving the callfinally so we can fall
+            // through from the try into the clone.
+            tryToRelocateCallFinally = true;
+
+            JITDUMP("Chose path to clone: try block BB%02u jumps to callfinally at BB%02u;"
+                    " the call returns to BB%02u which jumps to BB%02u\n",
+                    block->bbNum, jumpDest->bbNum, finallyReturnBlock->bbNum, postTryFinallyBlock->bbNum);
+#else
+            JITDUMP("Chose path to clone: try block BB%02u is a callfinally;"
+                    " the call returns to BB%02u which jumps to BB%02u\n",
+                    block->bbNum, finallyReturnBlock->bbNum, postTryFinallyBlock->bbNum);
+#endif // FEATURE_EH_CALLFINALLY_THUNKS
+
+            break;
+        }
+
+        // If there is no call to the finally, don't clone.
+        if (normalCallFinallyBlock == nullptr)
+        {
+            JITDUMP("EH#%u: no calls from the try to the finally, skipping.\n", XTnum);
+            continue;
+        }
+
+        JITDUMP("Will update callfinally block BB%02u to jump to the clone;"
+                " clone will jump to BB%02u\n",
+                normalCallFinallyBlock->bbNum, normalCallFinallyReturn->bbNum);
+
+        // If there are multiple callfinallys and we're in the
+        // callfinally thunk model, all the callfinallys are placed
+        // just outside the try region. We'd like our chosen
+        // callfinally to come first after the try, so we can fall out of the try
+        // into the clone.
+        BasicBlock* firstCallFinallyRangeBlock = nullptr;
+        BasicBlock* endCallFinallyRangeBlock   = nullptr;
+        ehGetCallFinallyBlockRange(XTnum, &firstCallFinallyRangeBlock, &endCallFinallyRangeBlock);
+
+        if (tryToRelocateCallFinally)
+        {
+            BasicBlock* firstCallFinallyBlock = nullptr;
+
+            for (BasicBlock* block = firstCallFinallyRangeBlock; block != endCallFinallyRangeBlock;
+                 block             = block->bbNext)
+            {
+                if (block->isBBCallAlwaysPair())
+                {
+                    if (block->bbJumpDest == firstBlock)
+                    {
+                        firstCallFinallyBlock = block;
+                        break;
+                    }
+                }
+            }
+
+            // We better have found at least one call finally.
+            assert(firstCallFinallyBlock != nullptr);
+
+            // If there is more than one callfinally, move the one we are
+            // going to retarget to be first in the callfinally range.
+            if (firstCallFinallyBlock != normalCallFinallyBlock)
+            {
+                JITDUMP("Moving callfinally BB%02u to be first in line, before BB%02u\n", normalCallFinallyBlock->bbNum,
+                        firstCallFinallyBlock->bbNum);
+
+                BasicBlock* const firstToMove      = normalCallFinallyBlock;
+                BasicBlock* const lastToMove       = normalCallFinallyBlock->bbNext;
+                BasicBlock* const placeToMoveAfter = firstCallFinallyBlock->bbPrev;
+
+                fgUnlinkRange(firstToMove, lastToMove);
+                fgMoveBlocksAfter(firstToMove, lastToMove, placeToMoveAfter);
+
+#ifdef DEBUG
+                // Sanity checks
+                fgDebugCheckBBlist(false, false);
+                fgVerifyHandlerTab();
+#endif // DEBUG
+
+                assert(nextBlock == lastBlock->bbNext);
+
+                // Update where the callfinally range begins, since we might
+                // have altered this with callfinally rearrangement, and/or
+                // the range begin might have been pretty loose to begin with.
+                firstCallFinallyRangeBlock = normalCallFinallyBlock;
+            }
+        }
+
+        // Clone the finally and retarget the normal return path and
+        // any other path that happens to share that same return
+        // point. For instance a construct like:
+        //
+        //  try { } catch { } finally { }
+        //
+        // will have two call finally blocks, one for the normal exit
+        // from the try, and the the other for the exit from the
+        // catch. They'll both pass the same return point which is the
+        // statement after the finally, so they can share the clone.
+        //
+        // Clone the finally body, and splice it into the flow graph
+        // within in the parent region of the try.
+        const unsigned  finallyTryIndex = firstBlock->bbTryIndex;
+        BasicBlock*     insertAfter     = nullptr;
+        BlockToBlockMap blockMap(getAllocator());
+        bool            clonedOk     = true;
+        unsigned        cloneBBCount = 0;
+
+        for (BasicBlock* block = firstBlock; block != nextBlock; block = block->bbNext)
+        {
+            BasicBlock* newBlock;
+
+            if (block == firstBlock)
+            {
+                // Put first cloned finally block into the approprate
+                // region, somewhere within or after the range of
+                // callfinallys, depending on the EH implementation.
+                const unsigned    hndIndex = 0;
+                BasicBlock* const nearBlk  = cloneInsertAfter;
+                newBlock                   = fgNewBBinRegion(block->bbJumpKind, finallyTryIndex, hndIndex, nearBlk);
+
+                // If the clone ends up just after the finally, adjust
+                // the stopping point for finally traversal.
+                if (newBlock->bbNext == nextBlock)
+                {
+                    assert(newBlock->bbPrev == lastBlock);
+                    nextBlock = newBlock;
+                }
+            }
+            else
+            {
+                // Put subsequent blocks in the same region...
+                const bool extendRegion = true;
+                newBlock                = fgNewBBafter(block->bbJumpKind, insertAfter, extendRegion);
+            }
+
+            cloneBBCount++;
+            assert(cloneBBCount <= regionBBCount);
+
+            insertAfter = newBlock;
+            blockMap.Set(block, newBlock);
+
+            clonedOk = BasicBlock::CloneBlockState(this, newBlock, block);
+
+            if (!clonedOk)
+            {
+                break;
+            }
+
+            // Update block flags. Note a block can be both first and last.
+            if (block == firstBlock)
+            {
+                // Mark the block as the start of the cloned finally.
+                newBlock->bbFlags |= BBF_CLONED_FINALLY_BEGIN;
+            }
+
+            if (block == lastBlock)
+            {
+                // Mark the block as the end of the cloned finally.
+                newBlock->bbFlags |= BBF_CLONED_FINALLY_END;
+            }
+
+            // Make sure clone block state hasn't munged the try region.
+            assert(newBlock->bbTryIndex == finallyTryIndex);
+
+            // Cloned handler block is no longer within the handler.
+            newBlock->clearHndIndex();
+
+            // Jump dests are set in a post-pass; make sure CloneBlockState hasn't tried to set them.
+            assert(newBlock->bbJumpDest == nullptr);
+        }
+
+        if (!clonedOk)
+        {
+            // TODO: cleanup the partial clone?
+            JITDUMP("Unable to clone the finally; skipping.\n");
+            continue;
+        }
+
+        // We should have cloned all the finally region blocks.
+        assert(cloneBBCount == regionBBCount);
+
+        JITDUMP("Cloned finally blocks are: BB%2u ... BB%2u\n", blockMap[firstBlock]->bbNum,
+                blockMap[lastBlock]->bbNum);
+
+        // Redirect redirect any branches within the newly-cloned
+        // finally, and any finally returns to jump to the return
+        // point.
+        for (BasicBlock* block = firstBlock; block != nextBlock; block = block->bbNext)
+        {
+            BasicBlock* newBlock = blockMap[block];
+
+            if (block->bbJumpKind == BBJ_EHFINALLYRET)
+            {
+                GenTreeStmt* finallyRet     = newBlock->lastStmt();
+                GenTreePtr   finallyRetExpr = finallyRet->gtStmtExpr;
+                assert(finallyRetExpr->gtOper == GT_RETFILT);
+                fgRemoveStmt(newBlock, finallyRet);
+                newBlock->bbJumpKind = BBJ_ALWAYS;
+                newBlock->bbJumpDest = normalCallFinallyReturn;
+
+                fgAddRefPred(normalCallFinallyReturn, newBlock);
+            }
+            else
+            {
+                optCopyBlkDest(block, newBlock);
+                optRedirectBlock(newBlock, &blockMap);
+            }
+        }
+
+        // Modify the targeting call finallys to branch to the cloned
+        // finally. Make a note if we see some calls that can't be
+        // retargeted (since they want to return to other places).
+        BasicBlock* const firstCloneBlock    = blockMap[firstBlock];
+        bool              retargetedAllCalls = true;
+        BasicBlock*       currentBlock       = firstCallFinallyRangeBlock;
+
+        while (currentBlock != endCallFinallyRangeBlock)
+        {
+            BasicBlock* nextBlockToScan = currentBlock->bbNext;
+
+            if (currentBlock->isBBCallAlwaysPair())
+            {
+                if (currentBlock->bbJumpDest == firstBlock)
+                {
+                    BasicBlock* const leaveBlock          = currentBlock->bbNext;
+                    BasicBlock* const postTryFinallyBlock = leaveBlock->bbJumpDest;
+
+                    // Note we must retarget all callfinallies that have this
+                    // continuation, or we can't clean up the continuation
+                    // block properly below, since it will be reachable both
+                    // by the cloned finally and by the called finally.
+                    if (postTryFinallyBlock == normalCallFinallyReturn)
+                    {
+                        // This call returns to the expected spot, so
+                        // retarget it to branch to the clone.
+                        currentBlock->bbJumpDest = firstCloneBlock;
+                        currentBlock->bbJumpKind = BBJ_ALWAYS;
+
+                        // Ref count updates.
+                        fgAddRefPred(firstCloneBlock, currentBlock);
+                        // fgRemoveRefPred(firstBlock, currentBlock);
+
+                        // Delete the leave block, which should be marked as
+                        // keep always.
+                        assert((leaveBlock->bbFlags & BBF_KEEP_BBJ_ALWAYS) != 0);
+                        nextBlock = leaveBlock->bbNext;
+
+                        leaveBlock->bbFlags &= ~BBF_KEEP_BBJ_ALWAYS;
+                        fgRemoveBlock(leaveBlock, true);
+
+                        // Make sure iteration isn't going off the deep end.
+                        assert(leaveBlock != endCallFinallyRangeBlock);
+                    }
+                    else
+                    {
+                        // We can't retarget this call since it
+                        // returns somewhere else.
+                        retargetedAllCalls = false;
+                    }
+                }
+            }
+
+            currentBlock = nextBlockToScan;
+        }
+
+        // If we retargeted all calls, modify EH descriptor to be
+        // try-fault instead of try-finally, and then non-cloned
+        // finally catch type to be fault.
+        if (retargetedAllCalls)
+        {
+            JITDUMP("All callfinallys retargeted; changing finally to fault.\n");
+            HBtab->ebdHandlerType  = EH_HANDLER_FAULT_WAS_FINALLY;
+            firstBlock->bbCatchTyp = BBCT_FAULT;
+        }
+        else
+        {
+            JITDUMP("Some callfinallys *not* retargeted, so region must remain as a finally.\n");
+        }
+
+        // Modify first block of cloned finally to be a "normal" block.
+        BasicBlock* firstClonedBlock = blockMap[firstBlock];
+        firstClonedBlock->bbCatchTyp = BBCT_NONE;
+
+        // The normalCallFinallyReturn may be a finalStep block.  It
+        // is now a normal block, since all the callfinallies that
+        // return to it are now going via the clone, so clear the
+        // special keep always flag.
+        normalCallFinallyReturn->bbFlags &= ~BBF_KEEP_BBJ_ALWAYS;
+
+#if FEATURE_EH_FUNCLETS && defined(_TARGET_ARM_)
+        // Also, clear the finally target bit for arm
+        fgClearFinallyTargetBit(normalCallFinallyReturn);
+#endif // FEATURE_EH_FUNCLETS && defined(_TARGET_ARM_)
+
+#if !FEATURE_EH_FUNCLETS
+        // Remove the GT_END_LFIN from the normalCallFinallyReturn
+        // since no callfinally returns there anymore.
+        GenTreeStmt* endFinallyStmt = normalCallFinallyReturn->lastStmt();
+        GenTreePtr   endFinallyExpr = endFinallyStmt->gtStmtExpr;
+        assert(endFinallyExpr->gtOper == GT_END_LFIN);
+        fgRemoveStmt(normalCallFinallyReturn, endFinallyStmt);
+#endif
+
+        // Todo -- mark cloned blocks as a cloned finally....
+
+        // Done!
+        JITDUMP("\nDone with EH#%u\n\n", XTnum);
+        cloneCount++;
+    }
+
+    if (cloneCount > 0)
+    {
+        JITDUMP("fgCloneFinally() cloned %u finally handlers\n", cloneCount);
+
+#ifdef DEBUG
+        if (verbose)
+        {
+            printf("\n*************** After fgCloneFinally()\n");
+            fgDispBasicBlocks();
+            fgDispHandlerTab();
+            printf("\n");
+        }
+
+        fgVerifyHandlerTab();
+        fgDebugCheckBBlist(false, false);
+        fgDebugCheckTryFinallyExits();
+
+#endif // DEBUG
+    }
+}
+
+#ifdef DEBUG
+
+//------------------------------------------------------------------------
+// fgDebugCheckTryFinallyExits: validate normal flow from try-finally
+// or try-fault-was-finally.
+//
+// Notes:
+//
+// Normal control flow exiting the try block of a try-finally must
+// pass through the finally. This checker attempts to verify that by
+// looking at the control flow graph.
+//
+// Each path that exits the try of a try-finally (including try-faults
+// that were optimized into try-finallys by fgCloneFinally) should
+// thus either execute a callfinally to the associated finally or else
+// jump to a block with the BBF_CLONED_FINALLY_BEGIN flag set.
+//
+// Depending on when this check is done, there may also be an empty
+// block along the path.
+//
+// Depending on the model for invoking finallys, the callfinallies may
+// lie within the try region (callfinally thunks) or in the enclosing
+// region.
+
+void Compiler::fgDebugCheckTryFinallyExits()
+{
+    unsigned  XTnum            = 0;
+    EHblkDsc* HBtab            = compHndBBtab;
+    unsigned  cloneCount       = 0;
+    bool      allTryExitsValid = true;
+    for (; XTnum < compHndBBtabCount; XTnum++, HBtab++)
+    {
+        const EHHandlerType handlerType = HBtab->ebdHandlerType;
+        const bool          isFinally   = (handlerType == EH_HANDLER_FINALLY);
+        const bool          wasFinally  = (handlerType == EH_HANDLER_FAULT_WAS_FINALLY);
+
+        // Screen out regions that are or were not finallys.
+        if (!isFinally && !wasFinally)
+        {
+            continue;
+        }
+
+        // Walk blocks of the try, looking for normal control flow to
+        // an ancestor region.
+
+        BasicBlock* const firstTryBlock = HBtab->ebdTryBeg;
+        BasicBlock* const lastTryBlock  = HBtab->ebdTryLast;
+        assert(firstTryBlock->getTryIndex() <= XTnum);
+        assert(lastTryBlock->getTryIndex() <= XTnum);
+        BasicBlock* const afterTryBlock = lastTryBlock->bbNext;
+        BasicBlock* const finallyBlock  = isFinally ? HBtab->ebdHndBeg : nullptr;
+
+        for (BasicBlock* block = firstTryBlock; block != afterTryBlock; block = block->bbNext)
+        {
+            // Only check the directly contained blocks.
+            assert(block->hasTryIndex());
+
+            if (block->getTryIndex() != XTnum)
+            {
+                continue;
+            }
+
+            // Look at each of the normal control flow possibilities.
+            const unsigned numSuccs = block->NumSucc();
+
+            for (unsigned i = 0; i < numSuccs; i++)
+            {
+                BasicBlock* const succBlock = block->GetSucc(i);
+
+                if (succBlock->hasTryIndex() && succBlock->getTryIndex() <= XTnum)
+                {
+                    // Successor does not exit this try region.
+                    continue;
+                }
+
+#if FEATURE_EH_CALLFINALLY_THUNKS
+
+                // When there are callfinally thunks, callfinallies
+                // logically "belong" to a child region and the exit
+                // path validity will be checked when looking at the
+                // try blocks in that region.
+                if (block->bbJumpKind == BBJ_CALLFINALLY)
+                {
+                    continue;
+                }
+
+#endif // FEATURE_EH_CALLFINALLY_THUNKS
+
+                // Now we know block lies directly within the try of a
+                // try-finally, and succBlock is in an enclosing
+                // region (possibly the method region). So this path
+                // represents flow out of the try and should be
+                // checked.
+                //
+                // There are various ways control can properly leave a
+                // try-finally (or try-fault-was-finally):
+                //
+                // (a1) via a jump to a callfinally (only for finallys, only for call finally thunks)
+                // (a2) via a callfinally (only for finallys, only for !call finally thunks)
+                // (b) via a jump to a begin finally clone block
+                // (c) via a jump to an empty block to (b)
+                // (d) via a fallthrough to an empty block to (b)
+                // (e) via the always half of a callfinally pair
+                // (f) via an always jump clonefinally exit
+                bool isCallToFinally = false;
+
+#if FEATURE_EH_CALLFINALLY_THUNKS
+                if (succBlock->bbJumpKind == BBJ_CALLFINALLY)
+                {
+                    // case (a1)
+                    isCallToFinally = isFinally && (succBlock->bbJumpDest == finallyBlock);
+                }
+#else
+                if (block->bbJumpKind == BBJ_CALLFINALLY)
+                {
+                    // case (a2)
+                    isCallToFinally = isFinally && (block->bbJumpDest == finallyBlock);
+                }
+#endif // FEATURE_EH_CALLFINALLY_THUNKS
+
+                bool isJumpToClonedFinally = false;
+
+                if (succBlock->bbFlags & BBF_CLONED_FINALLY_BEGIN)
+                {
+                    // case (b)
+                    isJumpToClonedFinally = true;
+                }
+                else if (succBlock->bbJumpKind == BBJ_ALWAYS)
+                {
+                    if (succBlock->isEmpty())
+                    {
+                        // case (c)
+                        BasicBlock* const succSuccBlock = succBlock->bbJumpDest;
+
+                        if (succSuccBlock->bbFlags & BBF_CLONED_FINALLY_BEGIN)
+                        {
+                            isJumpToClonedFinally = true;
+                        }
+                    }
+                }
+                else if (succBlock->bbJumpKind == BBJ_NONE)
+                {
+                    if (succBlock->isEmpty())
+                    {
+                        BasicBlock* const succSuccBlock = succBlock->bbNext;
+
+                        // case (d)
+                        if (succSuccBlock->bbFlags & BBF_CLONED_FINALLY_BEGIN)
+                        {
+                            isJumpToClonedFinally = true;
+                        }
+                    }
+                }
+
+                bool isReturnFromFinally = false;
+
+                // Case (e). Ideally we'd have something stronger to
+                // check here -- eg that we are returning from a call
+                // to the right finally -- but there are odd cases
+                // like orphaned second halves of callfinally pairs
+                // that we need to tolerate.
+                if (block->bbFlags & BBF_KEEP_BBJ_ALWAYS)
+                {
+                    isReturnFromFinally = true;
+                }
+
+                // Case (f)
+                if (block->bbFlags & BBF_CLONED_FINALLY_END)
+                {
+                    isReturnFromFinally = true;
+                }
+
+                const bool thisExitValid = isCallToFinally || isJumpToClonedFinally || isReturnFromFinally;
+
+                if (!thisExitValid)
+                {
+                    JITDUMP("fgCheckTryFinallyExitS: EH#%u exit via BB%02u -> BB%02u is invalid\n", XTnum, block->bbNum,
+                            succBlock->bbNum);
+                }
+
+                allTryExitsValid = allTryExitsValid & thisExitValid;
+            }
+        }
+    }
+
+    if (!allTryExitsValid)
+    {
+        JITDUMP("fgCheckTryFinallyExits: method contains invalid try exit paths\n");
+        assert(allTryExitsValid);
+    }
+}
+
+#endif // DEBUG
index 5caec5f..4bf2a00 100644 (file)
@@ -5959,11 +5959,11 @@ void Compiler::gtComputeFPlvls(GenTreePtr tree)
             noway_assert(!isflt);
             break;
 
-#ifdef DEBUG
         default:
+#ifdef DEBUG
             noway_assert(!"Unhandled special operator in gtComputeFPlvls()");
-            break;
 #endif
+            break;
     }
 
 DONE:
index 9255d8f..c3522b8 100644 (file)
@@ -406,6 +406,7 @@ void Compiler::gsParamsToShadows()
 
 #ifdef FEATURE_SIMD
         lvaTable[shadowVar].lvSIMDType            = varDsc->lvSIMDType;
+        lvaTable[shadowVar].lvExactSize           = varDsc->lvExactSize;
         lvaTable[shadowVar].lvUsedInSIMDIntrinsic = varDsc->lvUsedInSIMDIntrinsic;
         if (varDsc->lvSIMDType)
         {
index 92265a7..707ae61 100644 (file)
@@ -269,7 +269,7 @@ GTNODE(EMITNOP          , "emitnop"      ,GenTree            ,0,GTK_LEAF|GTK_NOV
 GTNODE(PINVOKE_PROLOG   ,"pinvoke_prolog",GenTree            ,0,GTK_LEAF|GTK_NOVALUE)   // pinvoke prolog seq
 GTNODE(PINVOKE_EPILOG   ,"pinvoke_epilog",GenTree            ,0,GTK_LEAF|GTK_NOVALUE)   // pinvoke epilog seq
 GTNODE(PUTARG_REG       , "putarg_reg"   ,GenTreeOp          ,0,GTK_UNOP)               // operator that places outgoing arg in register
-GTNODE(PUTARG_STK       , "putarg_stk"   ,GenTreePutArgStk   ,0,GTK_UNOP)               // operator that places outgoing arg in stack
+GTNODE(PUTARG_STK       , "putarg_stk"   ,GenTreePutArgStk   ,0,GTK_UNOP|GTK_NOVALUE)   // operator that places outgoing arg in stack
 GTNODE(RETURNTRAP       , "returnTrap"   ,GenTreeOp          ,0,GTK_UNOP|GTK_NOVALUE)   // a conditional call to wait on gc
 GTNODE(SWAP             , "swap"         ,GenTreeOp          ,0,GTK_BINOP|GTK_NOVALUE)  // op1 and op2 swap (registers)
 GTNODE(IL_OFFSET        , "il_offset"    ,GenTreeStmt        ,0,GTK_LEAF|GTK_NOVALUE)   // marks an IL offset for debugging purposes
index 9351094..1d9144b 100644 (file)
@@ -1489,17 +1489,16 @@ var_types Compiler::impNormStructType(CORINFO_CLASS_HANDLE structHnd,
     const DWORD structFlags = info.compCompHnd->getClassAttribs(structHnd);
     var_types   structType  = TYP_STRUCT;
 
-#ifdef FEATURE_CORECLR
-    const bool hasGCPtrs = (structFlags & CORINFO_FLG_CONTAINS_GC_PTR) != 0;
-#else
-    // Desktop CLR won't report FLG_CONTAINS_GC_PTR for RefAnyClass - need to check explicitly.
-    const bool        isRefAny    = (structHnd == impGetRefAnyClass());
-    const bool        hasGCPtrs   = isRefAny || ((structFlags & CORINFO_FLG_CONTAINS_GC_PTR) != 0);
-#endif
+    // On coreclr the check for GC includes a "may" to account for the special
+    // ByRef like span structs.  The added check for "CONTAINS_STACK_PTR" is the particular bit.
+    // When this is set the struct will contain a ByRef that could be a GC pointer or a native
+    // pointer.
+    const bool mayContainGCPtrs =
+        ((structFlags & CORINFO_FLG_CONTAINS_STACK_PTR) != 0 || ((structFlags & CORINFO_FLG_CONTAINS_GC_PTR) != 0));
 
 #ifdef FEATURE_SIMD
     // Check to see if this is a SIMD type.
-    if (featureSIMD && !hasGCPtrs)
+    if (featureSIMD && !mayContainGCPtrs)
     {
         unsigned originalSize = info.compCompHnd->getClassSize(structHnd);
 
@@ -1532,9 +1531,10 @@ var_types Compiler::impNormStructType(CORINFO_CLASS_HANDLE structHnd,
         // Verify that the quick test up above via the class attributes gave a
         // safe view of the type's GCness.
         //
-        // Note there are cases where hasGCPtrs is true but getClassGClayout
+        // Note there are cases where mayContainGCPtrs is true but getClassGClayout
         // does not report any gc fields.
-        assert(hasGCPtrs || (numGCVars == 0));
+
+        assert(mayContainGCPtrs || (numGCVars == 0));
 
         if (pNumGCVars != nullptr)
         {
@@ -3271,7 +3271,8 @@ GenTreePtr Compiler::impInitializeArrayIntrinsic(CORINFO_SIG_INFO* sig)
 // Returns the GenTree that should be used to do the intrinsic instead of the call.
 // Returns NULL if an intrinsic cannot be used
 
-GenTreePtr Compiler::impIntrinsic(CORINFO_CLASS_HANDLE  clsHnd,
+GenTreePtr Compiler::impIntrinsic(GenTreePtr            newobjThis,
+                                  CORINFO_CLASS_HANDLE  clsHnd,
                                   CORINFO_METHOD_HANDLE method,
                                   CORINFO_SIG_INFO*     sig,
                                   int                   memberRef,
@@ -3283,7 +3284,7 @@ GenTreePtr Compiler::impIntrinsic(CORINFO_CLASS_HANDLE  clsHnd,
 #if COR_JIT_EE_VERSION > 460
     CorInfoIntrinsics intrinsicID = info.compCompHnd->getIntrinsicID(method, &mustExpand);
 #else
-    CorInfoIntrinsics intrinsicID = info.compCompHnd->getIntrinsicID(method);
+    CorInfoIntrinsics intrinsicID                                      = info.compCompHnd->getIntrinsicID(method);
 #endif
     *pIntrinsicID = intrinsicID;
 
@@ -3607,7 +3608,33 @@ GenTreePtr Compiler::impIntrinsic(CORINFO_CLASS_HANDLE  clsHnd,
             retNode = op1;
             break;
 #endif
-
+        // Implement ByReference Ctor.  This wraps the assignment of the ref into a byref-like field
+        // in a value type.  The canonical example of this is Span<T>. In effect this is just a
+        // substitution.  The parameter byref will be assigned into the newly allocated object.
+        case CORINFO_INTRINSIC_ByReference_Ctor:
+        {
+            // Remove call to constructor and directly assign the byref passed
+            // to the call to the first slot of the ByReference struct.
+            op1                                    = impPopStack().val;
+            GenTreePtr           thisptr           = newobjThis;
+            CORINFO_FIELD_HANDLE fldHnd            = info.compCompHnd->getFieldInClass(clsHnd, 0);
+            GenTreePtr           field             = gtNewFieldRef(TYP_BYREF, fldHnd, thisptr, 0, false);
+            GenTreePtr           assign            = gtNewAssignNode(field, op1);
+            GenTreePtr           byReferenceStruct = gtCloneExpr(thisptr->gtGetOp1());
+            assert(byReferenceStruct != nullptr);
+            impPushOnStack(byReferenceStruct, typeInfo(TI_STRUCT, clsHnd));
+            retNode = assign;
+            break;
+        }
+        // Implement ptr value getter for ByReference struct.
+        case CORINFO_INTRINSIC_ByReference_Value:
+        {
+            op1                         = impPopStack().val;
+            CORINFO_FIELD_HANDLE fldHnd = info.compCompHnd->getFieldInClass(clsHnd, 0);
+            GenTreePtr           field  = gtNewFieldRef(TYP_BYREF, fldHnd, op1, 0, false);
+            retNode                     = field;
+            break;
+        }
         default:
             /* Unknown intrinsic */
             break;
@@ -5390,29 +5417,23 @@ GenTreePtr Compiler::impTransformThis(GenTreePtr              thisPtr,
 }
 
 //------------------------------------------------------------------------
-// impCanPInvokeInline: examine information from a call to see if the call
-// qualifies as an inline pinvoke.
-//
-// Arguments:
-//    block      - block contaning the call, or for inlinees, block
-//                 containing the call being inlined
+// impCanPInvokeInline: check whether PInvoke inlining should enabled in current method.
 //
 // Return Value:
-//    true if this call qualifies as an inline pinvoke, false otherwise
+//    true if PInvoke inlining should be enabled in current method, false otherwise
 //
 // Notes:
-//    Checks basic legality and then a number of ambient conditions
-//    where we could pinvoke but choose not to
+//    Checks a number of ambient conditions where we could pinvoke but choose not to
 
-bool Compiler::impCanPInvokeInline(BasicBlock* block)
+bool Compiler::impCanPInvokeInline()
 {
-    return impCanPInvokeInlineCallSite(block) && getInlinePInvokeEnabled() && (!opts.compDbgCode) &&
-           (compCodeOpt() != SMALL_CODE) && (!opts.compNoPInvokeInlineCB) // profiler is preventing inline pinvoke
+    return getInlinePInvokeEnabled() && (!opts.compDbgCode) && (compCodeOpt() != SMALL_CODE) &&
+           (!opts.compNoPInvokeInlineCB) // profiler is preventing inline pinvoke
         ;
 }
 
 //------------------------------------------------------------------------
-// impCanPInvokeInlineSallSite: basic legality checks using information
+// impCanPInvokeInlineCallSite: basic legality checks using information
 // from a call to see if the call qualifies as an inline pinvoke.
 //
 // Arguments:
@@ -5441,6 +5462,17 @@ bool Compiler::impCanPInvokeInline(BasicBlock* block)
 
 bool Compiler::impCanPInvokeInlineCallSite(BasicBlock* block)
 {
+    if (block->hasHndIndex())
+    {
+        return false;
+    }
+
+    // The remaining limitations do not apply to CoreRT
+    if (IsTargetAbi(CORINFO_CORERT_ABI))
+    {
+        return true;
+    }
+
 #ifdef _TARGET_AMD64_
     // On x64, we disable pinvoke inlining inside of try regions.
     // Here is the comment from JIT64 explaining why:
@@ -5462,12 +5494,13 @@ bool Compiler::impCanPInvokeInlineCallSite(BasicBlock* block)
     //
     //   A desktop test case where this seems to matter is
     //   jit\jit64\ebvts\mcpp\sources2\ijw\__clrcall\vector_ctor_dtor.02\deldtor_clr.exe
-    const bool inX64Try = block->hasTryIndex();
-#else
-    const bool inX64Try = false;
+    if (block->hasTryIndex())
+    {
+        return false;
+    }
 #endif // _TARGET_AMD64_
 
-    return !inX64Try && !block->hasHndIndex();
+    return true;
 }
 
 //------------------------------------------------------------------------
@@ -5533,27 +5566,38 @@ void Compiler::impCheckForPInvokeCall(
     }
     optNativeCallCount++;
 
-    if (opts.compMustInlinePInvokeCalli && methHnd == nullptr)
+    if (opts.jitFlags->IsSet(JitFlags::JIT_FLAG_IL_STUB) && methHnd == nullptr)
     {
-        // Always inline pinvoke.
+        // PInvoke CALLI in IL stubs must be inlined
     }
     else
     {
-        // Check legality and profitability.
-        if (!impCanPInvokeInline(block))
+        // Check legality
+        if (!impCanPInvokeInlineCallSite(block))
         {
             return;
         }
 
-        if (info.compCompHnd->pInvokeMarshalingRequired(methHnd, sig))
+        // PInvoke CALL in IL stubs must be inlined on CoreRT. Skip the ambient conditions checks and
+        // profitability checks
+        if (!(opts.jitFlags->IsSet(JitFlags::JIT_FLAG_IL_STUB) && IsTargetAbi(CORINFO_CORERT_ABI)))
         {
-            return;
+            if (impCanPInvokeInline())
+            {
+                return;
+            }
+
+            // Size-speed tradeoff: don't use inline pinvoke at rarely
+            // executed call sites.  The non-inline version is more
+            // compact.
+            if (block->isRunRarely())
+            {
+                return;
+            }
         }
 
-        // Size-speed tradeoff: don't use inline pinvoke at rarely
-        // executed call sites.  The non-inline version is more
-        // compact.
-        if (block->isRunRarely())
+        // The expensive check should be last
+        if (info.compCompHnd->pInvokeMarshalingRequired(methHnd, sig))
         {
             return;
         }
@@ -6220,7 +6264,7 @@ bool Compiler::impIsTailCallILPattern(bool        tailPrefixed,
              ((nextOpcode == CEE_NOP) || ((nextOpcode == CEE_POP) && (++cntPop == 1)))); // Next opcode = nop or exactly
                                                                                          // one pop seen so far.
 #else
-    nextOpcode          = (OPCODE)getU1LittleEndian(codeAddrOfNextOpcode);
+    nextOpcode = (OPCODE)getU1LittleEndian(codeAddrOfNextOpcode);
 #endif
 
     if (isCallPopAndRet)
@@ -6521,7 +6565,7 @@ var_types Compiler::impImportCall(OPCODE                  opcode,
         // <NICE> Factor this into getCallInfo </NICE>
         if ((mflags & CORINFO_FLG_INTRINSIC) && !pConstrainedResolvedToken)
         {
-            call = impIntrinsic(clsHnd, methHnd, sig, pResolvedToken->token, readonlyCall,
+            call = impIntrinsic(newobjThis, clsHnd, methHnd, sig, pResolvedToken->token, readonlyCall,
                                 (canTailCall && (tailCall != 0)), &intrinsicID);
 
             if (call != nullptr)
index 39a2505..8a25af0 100644 (file)
@@ -274,6 +274,14 @@ CONFIG_INTEGER(JitInlinePolicyModel, W("JitInlinePolicyModel"), 0)
 
 CONFIG_INTEGER(JitEECallTimingInfo, W("JitEECallTimingInfo"), 0)
 
+#if defined(DEBUG)
+#if defined(FEATURE_CORECLR)
+CONFIG_INTEGER(JitEnableFinallyCloning, W("JitEnableFinallyCloning"), 1)
+#else
+CONFIG_INTEGER(JitEnableFinallyCloning, W("JitEnableFinallyCloning"), 0)
+#endif // defined(FEATURE_CORECLR)
+#endif // DEBUG
+
 #undef CONFIG_INTEGER
 #undef CONFIG_STRING
 #undef CONFIG_METHODSET
index 01a2fdc..2d0eee3 100644 (file)
@@ -93,7 +93,7 @@ bool EHblkDsc::HasFinallyHandler()
 
 bool EHblkDsc::HasFaultHandler()
 {
-    return ebdHandlerType == EH_HANDLER_FAULT;
+    return (ebdHandlerType == EH_HANDLER_FAULT) || (ebdHandlerType == EH_HANDLER_FAULT_WAS_FINALLY);
 }
 
 bool EHblkDsc::HasFinallyOrFaultHandler()
index 5731162..502d215 100644 (file)
@@ -27,7 +27,8 @@ enum EHHandlerType
     EH_HANDLER_CATCH = 0x1, // Don't use zero (to aid debugging uninitialized memory)
     EH_HANDLER_FILTER,
     EH_HANDLER_FAULT,
-    EH_HANDLER_FINALLY
+    EH_HANDLER_FINALLY,
+    EH_HANDLER_FAULT_WAS_FINALLY
 };
 
 // ToCORINFO_EH_CLAUSE_FLAGS: Convert an internal EHHandlerType to a CORINFO_EH_CLAUSE_FLAGS value
@@ -41,6 +42,7 @@ inline CORINFO_EH_CLAUSE_FLAGS ToCORINFO_EH_CLAUSE_FLAGS(EHHandlerType type)
         case EH_HANDLER_FILTER:
             return CORINFO_EH_CLAUSE_FILTER;
         case EH_HANDLER_FAULT:
+        case EH_HANDLER_FAULT_WAS_FINALLY:
             return CORINFO_EH_CLAUSE_FAULT;
         case EH_HANDLER_FINALLY:
             return CORINFO_EH_CLAUSE_FINALLY;
index 35dd181..6eb8a49 100644 (file)
@@ -1494,9 +1494,13 @@ bool LIR::Range::CheckLIR(Compiler* compiler, bool checkUnusedValues) const
             }
             else if (!def->IsValue())
             {
-                // Calls may contain "uses" of nodes that do not produce a value. This is an artifact of
-                // the HIR and should probably be fixed, but doing so is an unknown amount of work.
-                assert(node->OperGet() == GT_CALL);
+                // Stack arguments do not produce a value, but they are considered children of the call.
+                // It may be useful to remove these from being call operands, but that may also impact
+                // other code that relies on being able to reach all the operands from a call node.
+                // The GT_NOP case is because sometimes we eliminate stack argument stores as dead, but
+                // instead of removing them we replace with a NOP.
+                assert((node->OperGet() == GT_CALL) &&
+                       (def->OperIsStore() || (def->OperGet() == GT_PUTARG_STK) || (def->OperGet() == GT_NOP)));
                 continue;
             }
 
index b73a9fa..0d47716 100644 (file)
@@ -265,10 +265,7 @@ void Compiler::fgPerNodeLocalVarLiveness(GenTree* tree)
                 GenTreePtr           addrArg         = tree->gtOp.gtOp1->gtEffectiveVal(/*commaOnly*/ true);
                 if (!addrArg->DefinesLocalAddr(this, /*width doesn't matter*/ 0, &dummyLclVarTree, &dummyIsEntire))
                 {
-                    if (!fgCurHeapDef)
-                    {
-                        fgCurHeapUse = true;
-                    }
+                    fgCurHeapUse = true;
                 }
                 else
                 {
@@ -1063,181 +1060,216 @@ VARSET_VALRET_TP Compiler::fgGetHandlerLiveVars(BasicBlock* block)
     return liveVars;
 }
 
-/*****************************************************************************
- *
- *  This is the classic algorithm for Live Variable Analysis.
- *  If updateInternalOnly==true, only update BBF_INTERNAL blocks.
- */
-
-void Compiler::fgLiveVarAnalysis(bool updateInternalOnly)
+class LiveVarAnalysis
 {
-    BasicBlock* block;
-    bool        change;
-#ifdef DEBUG
-    VARSET_TP VARSET_INIT_NOCOPY(extraLiveOutFromFinally, VarSetOps::MakeEmpty(this));
-#endif // DEBUG
-    bool keepAliveThis = lvaKeepAliveAndReportThis() && lvaTable[info.compThisArg].lvTracked;
+    Compiler* m_compiler;
 
-    /* Live Variable Analysis - Backward dataflow */
+    bool m_hasPossibleBackEdge;
 
-    bool hasPossibleBackEdge = false;
+    bool      m_heapLiveIn;
+    bool      m_heapLiveOut;
+    VARSET_TP m_liveIn;
+    VARSET_TP m_liveOut;
 
-    do
+    LiveVarAnalysis(Compiler* compiler)
+        : m_compiler(compiler)
+        , m_hasPossibleBackEdge(false)
+        , m_heapLiveIn(false)
+        , m_heapLiveOut(false)
+        , m_liveIn(VarSetOps::MakeEmpty(compiler))
+        , m_liveOut(VarSetOps::MakeEmpty(compiler))
     {
-        change = false;
-
-        /* Visit all blocks and compute new data flow values */
-
-        VARSET_TP VARSET_INIT_NOCOPY(liveIn, VarSetOps::MakeEmpty(this));
-        VARSET_TP VARSET_INIT_NOCOPY(liveOut, VarSetOps::MakeEmpty(this));
-
-        bool heapLiveIn  = false;
-        bool heapLiveOut = false;
+    }
 
-        for (block = fgLastBB; block; block = block->bbPrev)
+    bool PerBlockAnalysis(BasicBlock* block, bool updateInternalOnly, bool keepAliveThis)
+    {
+        /* Compute the 'liveOut' set */
+        VarSetOps::ClearD(m_compiler, m_liveOut);
+        m_heapLiveOut = false;
+        if (block->endsWithJmpMethod(m_compiler))
         {
-            // sometimes block numbers are not monotonically increasing which
-            // would cause us not to identify backedges
-            if (block->bbNext && block->bbNext->bbNum <= block->bbNum)
+            // A JMP uses all the arguments, so mark them all
+            // as live at the JMP instruction
+            //
+            const LclVarDsc* varDscEndParams = m_compiler->lvaTable + m_compiler->info.compArgsCount;
+            for (LclVarDsc* varDsc = m_compiler->lvaTable; varDsc < varDscEndParams; varDsc++)
             {
-                hasPossibleBackEdge = true;
+                noway_assert(!varDsc->lvPromoted);
+                if (varDsc->lvTracked)
+                {
+                    VarSetOps::AddElemD(m_compiler, m_liveOut, varDsc->lvVarIndex);
+                }
             }
+        }
 
-            if (updateInternalOnly)
+        // Additionally, union in all the live-in tracked vars of successors.
+        AllSuccessorIter succsEnd = block->GetAllSuccs(m_compiler).end();
+        for (AllSuccessorIter succs = block->GetAllSuccs(m_compiler).begin(); succs != succsEnd; ++succs)
+        {
+            BasicBlock* succ = (*succs);
+            VarSetOps::UnionD(m_compiler, m_liveOut, succ->bbLiveIn);
+            m_heapLiveOut = m_heapLiveOut || (*succs)->bbHeapLiveIn;
+            if (succ->bbNum <= block->bbNum)
             {
-                /* Only update BBF_INTERNAL blocks as they may be
-                   syntactically out of sequence. */
+                m_hasPossibleBackEdge = true;
+            }
+        }
 
-                noway_assert(opts.compDbgCode && (info.compVarScopesCount > 0));
+        /* For lvaKeepAliveAndReportThis methods, "this" has to be kept alive everywhere
+           Note that a function may end in a throw on an infinite loop (as opposed to a return).
+           "this" has to be alive everywhere even in such methods. */
 
-                if (!(block->bbFlags & BBF_INTERNAL))
-                {
-                    continue;
-                }
-            }
+        if (keepAliveThis)
+        {
+            VarSetOps::AddElemD(m_compiler, m_liveOut, m_compiler->lvaTable[m_compiler->info.compThisArg].lvVarIndex);
+        }
+
+        /* Compute the 'm_liveIn'  set */
+        VarSetOps::Assign(m_compiler, m_liveIn, m_liveOut);
+        VarSetOps::DiffD(m_compiler, m_liveIn, block->bbVarDef);
+        VarSetOps::UnionD(m_compiler, m_liveIn, block->bbVarUse);
 
-            /* Compute the 'liveOut' set */
+        m_heapLiveIn = (m_heapLiveOut && !block->bbHeapDef) || block->bbHeapUse;
+
+        /* Can exceptions from this block be handled (in this function)? */
+
+        if (m_compiler->ehBlockHasExnFlowDsc(block))
+        {
+            VARSET_TP VARSET_INIT_NOCOPY(liveVars, m_compiler->fgGetHandlerLiveVars(block));
 
-            VarSetOps::ClearD(this, liveOut);
-            heapLiveOut = false;
-            if (block->endsWithJmpMethod(this))
+            VarSetOps::UnionD(m_compiler, m_liveIn, liveVars);
+            VarSetOps::UnionD(m_compiler, m_liveOut, liveVars);
+        }
+
+        /* Has there been any change in either live set? */
+
+        bool liveInChanged = !VarSetOps::Equal(m_compiler, block->bbLiveIn, m_liveIn);
+        if (liveInChanged || !VarSetOps::Equal(m_compiler, block->bbLiveOut, m_liveOut))
+        {
+            if (updateInternalOnly)
             {
-                // A JMP uses all the arguments, so mark them all
-                // as live at the JMP instruction
-                //
-                const LclVarDsc* varDscEndParams = lvaTable + info.compArgsCount;
-                for (LclVarDsc* varDsc = lvaTable; varDsc < varDscEndParams; varDsc++)
+                // Only "extend" liveness over BBF_INTERNAL blocks
+
+                noway_assert(block->bbFlags & BBF_INTERNAL);
+
+                liveInChanged =
+                    !VarSetOps::Equal(m_compiler, VarSetOps::Intersection(m_compiler, block->bbLiveIn, m_liveIn),
+                                      m_liveIn);
+                if (liveInChanged ||
+                    !VarSetOps::Equal(m_compiler, VarSetOps::Intersection(m_compiler, block->bbLiveOut, m_liveOut),
+                                      m_liveOut))
                 {
-                    noway_assert(!varDsc->lvPromoted);
-                    if (varDsc->lvTracked)
+#ifdef DEBUG
+                    if (m_compiler->verbose)
                     {
-                        VarSetOps::AddElemD(this, liveOut, varDsc->lvVarIndex);
+                        printf("Scope info: block BB%02u LiveIn+ ", block->bbNum);
+                        dumpConvertedVarSet(m_compiler, VarSetOps::Diff(m_compiler, m_liveIn, block->bbLiveIn));
+                        printf(", LiveOut+ ");
+                        dumpConvertedVarSet(m_compiler, VarSetOps::Diff(m_compiler, m_liveOut, block->bbLiveOut));
+                        printf("\n");
                     }
-                }
-            }
+#endif // DEBUG
 
-            // Additionally, union in all the live-in tracked vars of successors.
-            AllSuccessorIter succsEnd = block->GetAllSuccs(this).end();
-            for (AllSuccessorIter succs = block->GetAllSuccs(this).begin(); succs != succsEnd; ++succs)
-            {
-                BasicBlock* succ = (*succs);
-                VarSetOps::UnionD(this, liveOut, succ->bbLiveIn);
-                heapLiveOut = heapLiveOut || (*succs)->bbHeapLiveIn;
-                if (succ->bbNum <= block->bbNum)
-                {
-                    hasPossibleBackEdge = true;
+                    VarSetOps::UnionD(m_compiler, block->bbLiveIn, m_liveIn);
+                    VarSetOps::UnionD(m_compiler, block->bbLiveOut, m_liveOut);
                 }
             }
-
-            /* For lvaKeepAliveAndReportThis methods, "this" has to be kept alive everywhere
-               Note that a function may end in a throw on an infinite loop (as opposed to a return).
-               "this" has to be alive everywhere even in such methods. */
-
-            if (keepAliveThis)
+            else
             {
-                VarSetOps::AddElemD(this, liveOut, lvaTable[info.compThisArg].lvVarIndex);
+                VarSetOps::Assign(m_compiler, block->bbLiveIn, m_liveIn);
+                VarSetOps::Assign(m_compiler, block->bbLiveOut, m_liveOut);
             }
+        }
 
-            /* Compute the 'liveIn'  set */
+        const bool heapLiveInChanged = (block->bbHeapLiveIn == 1) != m_heapLiveIn;
+        if (heapLiveInChanged || (block->bbHeapLiveOut == 1) != m_heapLiveOut)
+        {
+            block->bbHeapLiveIn  = m_heapLiveIn;
+            block->bbHeapLiveOut = m_heapLiveOut;
+        }
 
-            VarSetOps::Assign(this, liveIn, liveOut);
-            VarSetOps::DiffD(this, liveIn, block->bbVarDef);
-            VarSetOps::UnionD(this, liveIn, block->bbVarUse);
+        return liveInChanged || heapLiveInChanged;
+    }
 
-            heapLiveIn = (heapLiveOut && !block->bbHeapDef) || block->bbHeapUse;
+    void Run(bool updateInternalOnly)
+    {
+        const bool keepAliveThis =
+            m_compiler->lvaKeepAliveAndReportThis() && m_compiler->lvaTable[m_compiler->info.compThisArg].lvTracked;
 
-            /* Can exceptions from this block be handled (in this function)? */
+        /* Live Variable Analysis - Backward dataflow */
+        bool changed;
+        do
+        {
+            changed = false;
 
-            if (ehBlockHasExnFlowDsc(block))
-            {
-                VARSET_TP VARSET_INIT_NOCOPY(liveVars, fgGetHandlerLiveVars(block));
+            /* Visit all blocks and compute new data flow values */
 
-                VarSetOps::UnionD(this, liveIn, liveVars);
-                VarSetOps::UnionD(this, liveOut, liveVars);
-            }
+            VarSetOps::ClearD(m_compiler, m_liveIn);
+            VarSetOps::ClearD(m_compiler, m_liveOut);
 
-            /* Has there been any change in either live set? */
+            m_heapLiveIn  = false;
+            m_heapLiveOut = false;
 
-            if (!VarSetOps::Equal(this, block->bbLiveIn, liveIn) || !VarSetOps::Equal(this, block->bbLiveOut, liveOut))
+            for (BasicBlock* block = m_compiler->fgLastBB; block; block = block->bbPrev)
             {
+                // sometimes block numbers are not monotonically increasing which
+                // would cause us not to identify backedges
+                if (block->bbNext && block->bbNext->bbNum <= block->bbNum)
+                {
+                    m_hasPossibleBackEdge = true;
+                }
+
                 if (updateInternalOnly)
                 {
-                    // Only "extend" liveness over BBF_INTERNAL blocks
+                    /* Only update BBF_INTERNAL blocks as they may be
+                       syntactically out of sequence. */
 
-                    noway_assert(block->bbFlags & BBF_INTERNAL);
+                    noway_assert(m_compiler->opts.compDbgCode && (m_compiler->info.compVarScopesCount > 0));
 
-                    if (!VarSetOps::Equal(this, VarSetOps::Intersection(this, block->bbLiveIn, liveIn), liveIn) ||
-                        !VarSetOps::Equal(this, VarSetOps::Intersection(this, block->bbLiveOut, liveOut), liveOut))
+                    if (!(block->bbFlags & BBF_INTERNAL))
                     {
-#ifdef DEBUG
-                        if (verbose)
-                        {
-                            printf("Scope info: block BB%02u LiveIn+ ", block->bbNum);
-                            dumpConvertedVarSet(this, VarSetOps::Diff(this, liveIn, block->bbLiveIn));
-                            printf(", LiveOut+ ");
-                            dumpConvertedVarSet(this, VarSetOps::Diff(this, liveOut, block->bbLiveOut));
-                            printf("\n");
-                        }
-#endif // DEBUG
-
-                        VarSetOps::UnionD(this, block->bbLiveIn, liveIn);
-                        VarSetOps::UnionD(this, block->bbLiveOut, liveOut);
-                        change = true;
+                        continue;
                     }
                 }
-                else
+
+                if (PerBlockAnalysis(block, updateInternalOnly, keepAliveThis))
                 {
-                    VarSetOps::Assign(this, block->bbLiveIn, liveIn);
-                    VarSetOps::Assign(this, block->bbLiveOut, liveOut);
-                    change = true;
+                    changed = true;
                 }
             }
-
-            if ((block->bbHeapLiveIn == 1) != heapLiveIn || (block->bbHeapLiveOut == 1) != heapLiveOut)
+            // if there is no way we could have processed a block without seeing all of its predecessors
+            // then there is no need to iterate
+            if (!m_hasPossibleBackEdge)
             {
-                block->bbHeapLiveIn  = heapLiveIn;
-                block->bbHeapLiveOut = heapLiveOut;
-                change               = true;
+                break;
             }
-        }
-        // if there is no way we could have processed a block without seeing all of its predecessors
-        // then there is no need to iterate
-        if (!hasPossibleBackEdge)
-        {
-            break;
-        }
-    } while (change);
+        } while (changed);
+    }
 
-//-------------------------------------------------------------------------
+public:
+    static void Run(Compiler* compiler, bool updateInternalOnly)
+    {
+        LiveVarAnalysis analysis(compiler);
+        analysis.Run(updateInternalOnly);
+    }
+};
 
-#ifdef DEBUG
+/*****************************************************************************
+ *
+ *  This is the classic algorithm for Live Variable Analysis.
+ *  If updateInternalOnly==true, only update BBF_INTERNAL blocks.
+ */
 
+void Compiler::fgLiveVarAnalysis(bool updateInternalOnly)
+{
+    LiveVarAnalysis::Run(this, updateInternalOnly);
+
+#ifdef DEBUG
     if (verbose && !updateInternalOnly)
     {
         printf("\nBB liveness after fgLiveVarAnalysis():\n\n");
         fgDispBBLiveness();
     }
-
 #endif // DEBUG
 }
 
index a6e50b3..d1ecf7c 100644 (file)
@@ -757,16 +757,6 @@ GenTreePtr Lowering::NewPutArg(GenTreeCall* call, GenTreePtr arg, fgArgTabEntryP
     GenTreePtr putArg         = nullptr;
     bool       updateArgTable = true;
 
-#if !defined(_TARGET_64BIT_)
-    if (varTypeIsLong(type))
-    {
-        // For TYP_LONG, we leave the GT_LONG as the arg, and put the putArg below it.
-        // Therefore, we don't update the arg table entry.
-        updateArgTable = false;
-        type           = TYP_INT;
-    }
-#endif // !defined(_TARGET_64BIT_)
-
     bool isOnStack = true;
 #ifdef FEATURE_UNIX_AMD64_STRUCT_PASSING
     if (varTypeIsStruct(type))
@@ -1084,25 +1074,22 @@ void Lowering::LowerArg(GenTreeCall* call, GenTreePtr* ppArg)
             NYI("Lowering of long register argument");
         }
 
-        // For longs, we will create two PUTARG_STKs below the GT_LONG. The hi argument needs to
-        // be pushed first, so the hi PUTARG_STK will precede the lo PUTARG_STK in execution order.
+        // For longs, we will replace the GT_LONG with a GT_FIELD_LIST, and put that under a PUTARG_STK.
+        // Although the hi argument needs to be pushed first, that will be handled by the general case,
+        // in which the fields will be reversed.
         noway_assert(arg->OperGet() == GT_LONG);
-        GenTreePtr argLo = arg->gtGetOp1();
-        GenTreePtr argHi = arg->gtGetOp2();
-
-        GenTreePtr putArgLo = NewPutArg(call, argLo, info, type);
-        GenTreePtr putArgHi = NewPutArg(call, argHi, info, type);
-
-        arg->gtOp.gtOp1 = putArgLo;
-        arg->gtOp.gtOp2 = putArgHi;
-
-        BlockRange().InsertBefore(arg, putArgHi, putArgLo);
-
-        // The execution order now looks like this:
-        // argLoPrev <-> argLoFirst ... argLo <-> argHiFirst ... argHi <-> putArgHi <-> putArgLo <-> arg(GT_LONG)
-
-        assert((arg->gtFlags & GTF_REVERSE_OPS) == 0);
-        arg->gtFlags |= GTF_REVERSE_OPS; // We consume the high arg (op2) first.
+        assert(info->numSlots == 2);
+        GenTreePtr        argLo     = arg->gtGetOp1();
+        GenTreePtr        argHi     = arg->gtGetOp2();
+        GenTreeFieldList* fieldList = new (comp, GT_FIELD_LIST) GenTreeFieldList(argLo, 0, TYP_INT, nullptr);
+        // Only the first fieldList node (GTF_FIELD_LIST_HEAD) is in the instruction sequence.
+        (void)new (comp, GT_FIELD_LIST) GenTreeFieldList(argHi, 4, TYP_INT, fieldList);
+        putArg = NewPutArg(call, fieldList, info, TYP_VOID);
+
+        // We can't call ReplaceArgWithPutArgOrCopy here because it presumes that we are keeping the original arg.
+        BlockRange().InsertBefore(arg, fieldList, putArg);
+        BlockRange().Remove(arg);
+        *ppArg = putArg;
     }
     else
 #endif // !defined(_TARGET_64BIT_)
index 3381060..61ab63c 100644 (file)
@@ -1025,7 +1025,7 @@ void Lowering::TreeNodeInfoInitSimple(GenTree* tree)
 {
     TreeNodeInfo* info = &(tree->gtLsraInfo);
     unsigned      kind = tree->OperKind();
-    info->dstCount     = (tree->TypeGet() == TYP_VOID) ? 0 : 1;
+    info->dstCount     = tree->IsValue() ? 1 : 0;
     if (kind & (GTK_CONST | GTK_LEAF))
     {
         info->srcCount = 0;
@@ -1590,53 +1590,38 @@ void Lowering::TreeNodeInfoInitCall(GenTreeCall* call)
         if (!(args->gtFlags & GTF_LATE_ARG))
         {
             TreeNodeInfo* argInfo = &(arg->gtLsraInfo);
-#if !defined(_TARGET_64BIT_)
-            if (arg->TypeGet() == TYP_LONG)
+            if (argInfo->dstCount != 0)
             {
-                assert(arg->OperGet() == GT_LONG);
-                GenTreePtr loArg = arg->gtGetOp1();
-                GenTreePtr hiArg = arg->gtGetOp2();
-                assert((loArg->OperGet() == GT_PUTARG_STK) && (hiArg->OperGet() == GT_PUTARG_STK));
-                assert((loArg->gtLsraInfo.dstCount == 1) && (hiArg->gtLsraInfo.dstCount == 1));
-                loArg->gtLsraInfo.isLocalDefUse = true;
-                hiArg->gtLsraInfo.isLocalDefUse = true;
+                argInfo->isLocalDefUse = true;
             }
-            else
-#endif // !defined(_TARGET_64BIT_)
-            {
-                if (argInfo->dstCount != 0)
-                {
-                    argInfo->isLocalDefUse = true;
-                }
 
-                // If the child of GT_PUTARG_STK is a constant, we don't need a register to
-                // move it to memory (stack location).
-                //
-                // On AMD64, we don't want to make 0 contained, because we can generate smaller code
-                // by zeroing a register and then storing it. E.g.:
-                //      xor rdx, rdx
-                //      mov gword ptr [rsp+28H], rdx
-                // is 2 bytes smaller than:
-                //      mov gword ptr [rsp+28H], 0
-                //
-                // On x86, we push stack arguments; we don't use 'mov'. So:
-                //      push 0
-                // is 1 byte smaller than:
-                //      xor rdx, rdx
-                //      push rdx
-
-                argInfo->dstCount = 0;
-                if (arg->gtOper == GT_PUTARG_STK)
-                {
-                    GenTree* op1 = arg->gtOp.gtOp1;
-                    if (IsContainableImmed(arg, op1)
+            // If the child of GT_PUTARG_STK is a constant, we don't need a register to
+            // move it to memory (stack location).
+            //
+            // On AMD64, we don't want to make 0 contained, because we can generate smaller code
+            // by zeroing a register and then storing it. E.g.:
+            //      xor rdx, rdx
+            //      mov gword ptr [rsp+28H], rdx
+            // is 2 bytes smaller than:
+            //      mov gword ptr [rsp+28H], 0
+            //
+            // On x86, we push stack arguments; we don't use 'mov'. So:
+            //      push 0
+            // is 1 byte smaller than:
+            //      xor rdx, rdx
+            //      push rdx
+
+            argInfo->dstCount = 0;
+            if (arg->gtOper == GT_PUTARG_STK)
+            {
+                GenTree* op1 = arg->gtOp.gtOp1;
+                if (IsContainableImmed(arg, op1)
 #if defined(_TARGET_AMD64_)
-                        && !op1->IsIntegralConst(0)
+                    && !op1->IsIntegralConst(0)
 #endif // _TARGET_AMD64_
-                            )
-                    {
-                        MakeSrcContained(arg, op1);
-                    }
+                        )
+                {
+                    MakeSrcContained(arg, op1);
                 }
             }
         }
index d2a6843..24872de 100644 (file)
@@ -16910,6 +16910,14 @@ void Compiler::fgMorph()
     fgDebugCheckBBlist(false, false);
 #endif // DEBUG
 
+    fgRemoveEmptyFinally();
+
+    EndPhase(PHASE_EMPTY_FINALLY);
+
+    fgCloneFinally();
+
+    EndPhase(PHASE_CLONE_FINALLY);
+
     /* For x64 and ARM64 we need to mark irregular parameters early so that they don't get promoted */
     fgMarkImplicitByRefArgs();
 
index 7c635ca..c648ab2 100644 (file)
@@ -7,6 +7,7 @@
 #pragma hdrstop
 #endif
 
+#ifndef LEGACY_BACKEND
 // state carried over the tree walk, to be used in making
 // a splitting decision.
 struct SplitData
@@ -1054,3 +1055,4 @@ void Rationalizer::DoPhase()
 
     comp->compRationalIRForm = true;
 }
+#endif // LEGACY_BACKEND
index f0ee461..5d553c1 100644 (file)
@@ -1333,17 +1333,18 @@ void SsaBuilder::AssignPhiNodeRhsVariables(BasicBlock* block, SsaRenameState* pR
         {
             if (succ->bbHeapSsaPhiFunc == BasicBlock::EmptyHeapPhiDef)
             {
-                succ->bbHeapSsaPhiFunc = new (m_pCompiler) BasicBlock::HeapPhiArg(block);
+                succ->bbHeapSsaPhiFunc = new (m_pCompiler) BasicBlock::HeapPhiArg(block->bbHeapSsaNumOut);
             }
             else
             {
                 BasicBlock::HeapPhiArg* curArg = succ->bbHeapSsaPhiFunc;
+                unsigned                ssaNum = block->bbHeapSsaNumOut;
                 bool                    found  = false;
                 // This is a quadratic algorithm.  We might need to consider some switch over to a hash table
                 // representation for the arguments of a phi node, to make this linear.
                 while (curArg != nullptr)
                 {
-                    if (curArg->m_predBB == block)
+                    if (curArg->m_ssaNum == ssaNum)
                     {
                         found = true;
                         break;
@@ -1352,7 +1353,7 @@ void SsaBuilder::AssignPhiNodeRhsVariables(BasicBlock* block, SsaRenameState* pR
                 }
                 if (!found)
                 {
-                    succ->bbHeapSsaPhiFunc = new (m_pCompiler) BasicBlock::HeapPhiArg(block, succ->bbHeapSsaPhiFunc);
+                    succ->bbHeapSsaPhiFunc = new (m_pCompiler) BasicBlock::HeapPhiArg(ssaNum, succ->bbHeapSsaPhiFunc);
                 }
             }
             DBG_SSA_JITDUMP("  Added phi arg for Heap from BB%02u in BB%02u.\n", block->bbNum, succ->bbNum);
@@ -1466,20 +1467,18 @@ void SsaBuilder::AssignPhiNodeRhsVariables(BasicBlock* block, SsaRenameState* pR
                 {
                     if (handlerStart->bbHeapSsaPhiFunc == BasicBlock::EmptyHeapPhiDef)
                     {
-                        handlerStart->bbHeapSsaPhiFunc = new (m_pCompiler) BasicBlock::HeapPhiArg(block);
+                        handlerStart->bbHeapSsaPhiFunc =
+                            new (m_pCompiler) BasicBlock::HeapPhiArg(block->bbHeapSsaNumOut);
                     }
                     else
                     {
-#ifdef DEBUG
-                        BasicBlock::HeapPhiArg* curArg = handlerStart->bbHeapSsaPhiFunc;
-                        while (curArg != nullptr)
-                        {
-                            assert(curArg->m_predBB != block);
-                            curArg = curArg->m_nextArg;
-                        }
-#endif // DEBUG
-                        handlerStart->bbHeapSsaPhiFunc =
-                            new (m_pCompiler) BasicBlock::HeapPhiArg(block, handlerStart->bbHeapSsaPhiFunc);
+                        // This path has a potential to introduce redundant phi args, due to multiple
+                        // preds of the same try-begin block having the same live-out heap def, and/or
+                        // due to nested try-begins each having preds with the same live-out heap def.
+                        // Avoid doing quadratic processing on handler phis, and instead live with the
+                        // occasional redundancy.
+                        handlerStart->bbHeapSsaPhiFunc = new (m_pCompiler)
+                            BasicBlock::HeapPhiArg(block->bbHeapSsaNumOut, handlerStart->bbHeapSsaPhiFunc);
                     }
                     DBG_SSA_JITDUMP("  Added phi arg for Heap from BB%02u in BB%02u.\n", block->bbNum,
                                     handlerStart->bbNum);
index 8b448a2..32eb166 100644 (file)
 #endif
 #endif
 
+// If the UNIX_X86_ABI is defined make sure that _TARGET_X86_ is also defined.
+#if defined(UNIX_X86_ABI)
+#if !defined(_TARGET_X86_)
+#error When UNIX_X86_ABI is defined you must define _TARGET_X86_ defined as well.
+#endif
+#endif
+
 #if (defined(FEATURE_CORECLR) && defined(PLATFORM_UNIX))
 #define FEATURE_VARARG 0
 #else // !(defined(FEATURE_CORECLR) && defined(PLATFORM_UNIX))
index 2d3d3fd..d24d0da 100644 (file)
     </EmbeddedResource>
   </ItemGroup>
 
-  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.Targets" />
+  <PropertyGroup Condition="'$(BuildOS)' == 'Windows_NT'">
+    <EnableDotnetAnalyzers Condition="'$(EnableDotnetAnalyzers)'==''">true</EnableDotnetAnalyzers>
+    <UseWin32Apis>true</UseWin32Apis>
+    <OSGroup>Windows_NT</OSGroup>
+  </PropertyGroup>
+  <Import Project="$(ToolsDir)\codeAnalysis.targets" />
+
+  <Import Project="$(ToolsDir)\Microsoft.CSharp.Targets" />
 
   <PropertyGroup>
     <StrongNameSig>Silverlight</StrongNameSig>
diff --git a/src/mscorlib/corefx/Interop/Windows/Interop.Errors.cs b/src/mscorlib/corefx/Interop/Windows/Interop.Errors.cs
new file mode 100644 (file)
index 0000000..7eeb18d
--- /dev/null
@@ -0,0 +1,71 @@
+// 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.
+
+internal partial class Interop
+{
+    internal partial class Errors
+    {
+        internal const int ERROR_SUCCESS = 0x0;
+        internal const int ERROR_INVALID_FUNCTION = 0x1;
+        internal const int ERROR_FILE_NOT_FOUND = 0x2;
+        internal const int ERROR_PATH_NOT_FOUND = 0x3;
+        internal const int ERROR_ACCESS_DENIED = 0x5;
+        internal const int ERROR_INVALID_HANDLE = 0x6;
+        internal const int ERROR_NOT_ENOUGH_MEMORY = 0x8;
+        internal const int ERROR_INVALID_DATA = 0xD;
+        internal const int ERROR_INVALID_DRIVE = 0xF;
+        internal const int ERROR_NO_MORE_FILES = 0x12;
+        internal const int ERROR_NOT_READY = 0x15;
+        internal const int ERROR_BAD_LENGTH = 0x18;
+        internal const int ERROR_SHARING_VIOLATION = 0x20;
+        internal const int ERROR_LOCK_VIOLATION = 0x21;
+        internal const int ERROR_HANDLE_EOF = 0x26;
+        internal const int ERROR_FILE_EXISTS = 0x50;
+        internal const int ERROR_INVALID_PARAMETER = 0x57;
+        internal const int ERROR_BROKEN_PIPE = 0x6D;
+        internal const int ERROR_INSUFFICIENT_BUFFER = 0x7A;
+        internal const int ERROR_INVALID_NAME = 0x7B;
+        internal const int ERROR_NEGATIVE_SEEK = 0x83;
+        internal const int ERROR_DIR_NOT_EMPTY = 0x91;
+        internal const int ERROR_BAD_PATHNAME = 0xA1;
+        internal const int ERROR_LOCK_FAILED = 0xA7;
+        internal const int ERROR_BUSY = 0xAA;
+        internal const int ERROR_ALREADY_EXISTS = 0xB7;
+        internal const int ERROR_BAD_EXE_FORMAT = 0xC1;
+        internal const int ERROR_ENVVAR_NOT_FOUND = 0xCB;
+        internal const int ERROR_FILENAME_EXCED_RANGE = 0xCE;
+        internal const int ERROR_EXE_MACHINE_TYPE_MISMATCH = 0xD8;
+        internal const int ERROR_PIPE_BUSY = 0xE7;
+        internal const int ERROR_NO_DATA = 0xE8;
+        internal const int ERROR_PIPE_NOT_CONNECTED = 0xE9;
+        internal const int ERROR_MORE_DATA = 0xEA;
+        internal const int ERROR_NO_MORE_ITEMS = 0x103;
+        internal const int ERROR_PARTIAL_COPY = 0x12B;
+        internal const int ERROR_ARITHMETIC_OVERFLOW = 0x216;
+        internal const int ERROR_PIPE_CONNECTED = 0x217;
+        internal const int ERROR_PIPE_LISTENING = 0x218;
+        internal const int ERROR_OPERATION_ABORTED = 0x3E3;
+        internal const int ERROR_IO_PENDING = 0x3E5;
+        internal const int ERROR_NO_TOKEN = 0x3f0;
+        internal const int ERROR_DLL_INIT_FAILED = 0x45A;
+        internal const int ERROR_NOT_FOUND = 0x490;
+        internal const int ERROR_NON_ACCOUNT_SID = 0x4E9;
+        internal const int ERROR_NOT_ALL_ASSIGNED = 0x514;
+        internal const int ERROR_UNKNOWN_REVISION = 0x519;
+        internal const int ERROR_INVALID_OWNER = 0x51B;
+        internal const int ERROR_INVALID_PRIMARY_GROUP = 0x51C;
+        internal const int ERROR_NO_SUCH_PRIVILEGE = 0x521;
+        internal const int ERROR_PRIVILEGE_NOT_HELD = 0x522;
+        internal const int ERROR_INVALID_ACL = 0x538;
+        internal const int ERROR_INVALID_SECURITY_DESCR = 0x53A;
+        internal const int ERROR_INVALID_SID = 0x539;
+        internal const int ERROR_BAD_IMPERSONATION_LEVEL = 0x542;
+        internal const int ERROR_CANT_OPEN_ANONYMOUS = 0x543;
+        internal const int ERROR_NO_SECURITY_ON_OBJECT = 0x546;
+        internal const int ERROR_TRUSTED_RELATIONSHIP_FAILURE = 0x6FD;
+        internal const int ERROR_RESOURCE_LANG_NOT_FOUND = 0x717;
+        internal const int EFail = unchecked((int)0x80004005);
+        internal const int E_FILENOTFOUND = unchecked((int)0x80070002);
+    }
+}
@@ -8,9 +8,9 @@ using System.Threading;
 
 internal partial class Interop
 {
-    internal partial class mincore
+    internal partial class Kernel32
     {
-        [DllImport(Libraries.IO, SetLastError = true)]
-        internal static unsafe extern bool CancelIoEx(SafeHandle handle, NativeOverlapped* lpOverlapped);
+        [DllImport(Libraries.Kernel32, SetLastError = true)]
+        internal static extern unsafe bool CancelIoEx(SafeHandle handle, NativeOverlapped* lpOverlapped);
     }
 }
@@ -7,9 +7,9 @@ using System.Runtime.InteropServices;
 
 internal partial class Interop
 {
-    internal partial class mincore
+    internal partial class Kernel32
     {
-        [DllImport(Libraries.Handle, SetLastError = true)]
+        [DllImport(Libraries.Kernel32, SetLastError = true)]
         [return: MarshalAs(UnmanagedType.Bool)]
         internal static extern bool CloseHandle(IntPtr handle);
     }
@@ -9,12 +9,12 @@ using System.Runtime.InteropServices;
 
 internal partial class Interop
 {
-    internal partial class mincore
+    internal partial class Kernel32
     {
         /// <summary>
         /// WARNING: This method does not implicitly handle long paths. Use CreateFile.
         /// </summary>
-        [DllImport(Libraries.CoreFile_L1, EntryPoint = "CreateFileW", SetLastError = true, CharSet = CharSet.Unicode, BestFitMapping = false)]
+        [DllImport(Libraries.Kernel32, EntryPoint = "CreateFileW", SetLastError = true, CharSet = CharSet.Unicode, BestFitMapping = false)]
         private static extern SafeFileHandle CreateFilePrivate(
             string lpFileName,
             int dwDesiredAccess,
@@ -4,7 +4,7 @@
 
 internal partial class Interop
 {
-    internal partial class mincore
+    internal partial class Kernel32
     {
         internal partial class IOReparseOptions
         {
@@ -4,7 +4,7 @@
 
 internal partial class Interop
 {
-    internal partial class mincore
+    internal partial class Kernel32
     {
         internal partial class FileTypes
         {
@@ -8,9 +8,9 @@ using System.Runtime.InteropServices;
 
 internal partial class Interop
 {
-    internal partial class mincore
+    internal partial class Kernel32
     {
-        [DllImport(Libraries.CoreFile_L1, SetLastError = true)]
+        [DllImport(Libraries.Kernel32, SetLastError = true)]
         [return: MarshalAs(UnmanagedType.Bool)]
         internal static extern bool FlushFileBuffers(SafeHandle hHandle);
     }
@@ -8,7 +8,7 @@ using System.Runtime.InteropServices;
 
 internal partial class Interop
 {
-    internal partial class mincore
+    internal partial class Kernel32
     {
         private const int FORMAT_MESSAGE_IGNORE_INSERTS = 0x00000200;
         private const int FORMAT_MESSAGE_FROM_HMODULE = 0x00000800;
@@ -18,7 +18,7 @@ internal partial class Interop
 
         private const int ERROR_INSUFFICIENT_BUFFER = 0x7A;
 
-        [DllImport(Libraries.Localization, CharSet = CharSet.Unicode, EntryPoint = "FormatMessageW", SetLastError = true, BestFitMapping = true)]
+        [DllImport(Libraries.Kernel32, CharSet = CharSet.Unicode, EntryPoint = "FormatMessageW", SetLastError = true, BestFitMapping = true)]
         private static extern int FormatMessage(
             int dwFlags,
             IntPtr lpSource,
@@ -8,9 +8,9 @@ using System.Runtime.InteropServices;
 
 internal partial class Interop
 {
-    internal partial class mincore
+    internal partial class Kernel32
     {
-        [DllImport(Libraries.CoreFile_L2, SetLastError = true)]
+        [DllImport(Libraries.Kernel32, SetLastError = true)]
         internal static extern bool GetFileInformationByHandleEx(SafeFileHandle hFile, FILE_INFO_BY_HANDLE_CLASS FileInformationClass, out FILE_STANDARD_INFO lpFileInformation, uint dwBufferSize);
 
         internal partial struct FILE_STANDARD_INFO
@@ -7,9 +7,9 @@ using System.Runtime.InteropServices;
 
 internal partial class Interop
 {
-    internal partial class mincore
+    internal partial class Kernel32
     {
-        [DllImport(Libraries.CoreFile_L1, SetLastError = true)]
+        [DllImport(Libraries.Kernel32, SetLastError = true)]
         internal extern static int GetFileType(SafeHandle hFile);
     }
 }
@@ -7,12 +7,12 @@ using System.Runtime.InteropServices;
 
 internal partial class Interop
 {
-    internal partial class mincore
+    internal partial class Kernel32
     {
         /// <summary>
         /// WARNING: This method does not implicitly handle long paths. Use GetFullPathName or PathHelper.
         /// </summary>
-        [DllImport(Libraries.CoreFile_L1, SetLastError = true, CharSet = CharSet.Unicode, BestFitMapping = false, ExactSpelling = true)]
+        [DllImport(Libraries.Kernel32, SetLastError = true, CharSet = CharSet.Unicode, BestFitMapping = false, ExactSpelling = true)]
         unsafe internal static extern uint GetFullPathNameW(char* path, uint numBufferChars, char[] buffer, IntPtr mustBeZero);
     }
 }
@@ -7,12 +7,12 @@ using System.Runtime.InteropServices;
 
 partial class Interop
 {
-    partial class mincore
+    partial class Kernel32
     {
         /// <summary>
         /// WARNING: This method does not implicitly handle long paths. Use GetFullPath/PathHelper.
         /// </summary>
-        [DllImport(Libraries.CoreFile_L1, SetLastError = true, CharSet = CharSet.Unicode, BestFitMapping = false, ExactSpelling = true)]
+        [DllImport(Libraries.Kernel32, SetLastError = true, CharSet = CharSet.Unicode, BestFitMapping = false, ExactSpelling = true)]
         internal static extern uint GetLongPathNameW(char[] lpszShortPath, char[] lpszLongPath, uint cchBuffer);
     }
 }
@@ -8,9 +8,9 @@ using System.Runtime.InteropServices;
 
 partial class Interop
 {
-    partial class mincore
+    partial class Kernel32
     {
-        [DllImport(Libraries.CoreFile_L1, CharSet = CharSet.Unicode, SetLastError = true, BestFitMapping = false)]
+        [DllImport(Libraries.Kernel32, CharSet = CharSet.Unicode, SetLastError = true, BestFitMapping = false)]
         internal static extern uint GetTempFileNameW(string tmpPath, string prefix, uint uniqueIdOrZero, [Out]StringBuilder tmpFileName);
     }
 }
@@ -8,9 +8,9 @@ using System.Runtime.InteropServices;
 
 partial class Interop
 {
-    partial class mincore
+    partial class Kernel32
     {
-        [DllImport(Libraries.CoreFile_L1_2, CharSet = CharSet.Unicode, BestFitMapping = false)]
+        [DllImport(Libraries.Kernel32, CharSet = CharSet.Unicode, BestFitMapping = false)]
         internal static extern uint GetTempPathW(int bufferLen, [Out]StringBuilder buffer);
     }
 }
@@ -9,12 +9,12 @@ using System.Runtime.InteropServices;
 
 internal partial class Interop
 {
-    internal partial class mincore
+    internal partial class Kernel32
     {
-        [DllImport(Libraries.CoreFile_L1, SetLastError = true)]
+        [DllImport(Libraries.Kernel32, SetLastError = true)]
         internal static extern bool LockFile(SafeFileHandle handle, int offsetLow, int offsetHigh, int countLow, int countHigh);
 
-        [DllImport(Libraries.CoreFile_L1, SetLastError = true)]
+        [DllImport(Libraries.Kernel32, SetLastError = true)]
         internal static extern bool UnlockFile(SafeFileHandle handle, int offsetLow, int offsetHigh, int countLow, int countHigh);
     }
 }
@@ -8,10 +8,10 @@ using System.Runtime.InteropServices;
 
 internal partial class Interop
 {
-    internal partial class mincore
+    internal partial class Kernel32
     {
-        [DllImport(Libraries.CoreFile_L1, SetLastError = true)]
-        unsafe internal static extern int ReadFile(
+        [DllImport(Libraries.Kernel32, SetLastError = true)]
+        internal static extern unsafe int ReadFile(
             SafeHandle handle,
             byte* bytes,
             int numBytesToRead,
@@ -9,10 +9,10 @@ using System.Threading;
 
 internal partial class Interop
 {
-    internal partial class mincore
+    internal partial class Kernel32
     {
-        [DllImport(Libraries.CoreFile_L1, SetLastError = true)]
-        unsafe internal static extern int ReadFile(
+        [DllImport(Libraries.Kernel32, SetLastError = true)]
+        internal static extern unsafe int ReadFile(
             SafeHandle handle,
             byte* bytes,
             int numBytesToRead,
@@ -8,7 +8,7 @@ using System.Runtime.InteropServices;
 
 internal partial class Interop
 {
-    internal partial class mincore
+    internal partial class Kernel32
     {
         [StructLayout(LayoutKind.Sequential)]
         internal struct SECURITY_ATTRIBUTES
@@ -9,7 +9,7 @@ using Microsoft.Win32.SafeHandles;
 
 internal partial class Interop
 {
-    internal partial class mincore
+    internal partial class Kernel32
     {
         internal static readonly IntPtr INVALID_HANDLE_VALUE = new IntPtr(-1);  // WinBase.h
 
@@ -22,7 +22,7 @@ internal partial class Interop
             String lpFileName,
             int dwDesiredAccess,
             System.IO.FileShare dwShareMode,
-            ref Interop.mincore.SECURITY_ATTRIBUTES securityAttrs,
+            ref Interop.Kernel32.SECURITY_ATTRIBUTES securityAttrs,
             FileMode dwCreationDisposition,
             int dwFlagsAndAttributes,
             IntPtr hTemplateFile)
@@ -31,8 +31,8 @@ internal partial class Interop
 
             if (!handle.IsInvalid)
             {
-                int fileType = Interop.mincore.GetFileType(handle);
-                if (fileType != Interop.mincore.FileTypes.FILE_TYPE_DISK)
+                int fileType = Interop.Kernel32.GetFileType(handle);
+                if (fileType != Interop.Kernel32.FileTypes.FILE_TYPE_DISK)
                 {
                     handle.Dispose();
                     throw new NotSupportedException(SR.NotSupported_FileStreamOnNonFiles);
@@ -4,7 +4,7 @@
 
 internal partial class Interop
 {
-    internal partial class mincore
+    internal partial class Kernel32
     {
         internal partial class SecurityOptions
         {
@@ -7,9 +7,9 @@ using System.Runtime.InteropServices;
 
 internal partial class Interop
 {
-    internal partial class mincore
+    internal partial class Kernel32
     {
-        [DllImport(Libraries.CoreFile_L1, SetLastError = true)]
+        [DllImport(Libraries.Kernel32, SetLastError = true)]
         internal static extern bool SetEndOfFile(SafeFileHandle hFile);
     }
 }
@@ -6,9 +6,9 @@ using System.Runtime.InteropServices;
 
 internal partial class Interop
 {
-    internal partial class mincore
+    internal partial class Kernel32
     {
-        [DllImport(Libraries.ErrorHandling, SetLastError = false, EntryPoint = "SetErrorMode", ExactSpelling = true)]
+        [DllImport(Libraries.Kernel32, SetLastError = false, EntryPoint = "SetErrorMode", ExactSpelling = true)]
         internal static extern uint SetErrorMode(uint newMode);
     }
 }
@@ -8,13 +8,13 @@ using System.Runtime.InteropServices;
 
 internal partial class Interop
 {
-    internal partial class mincore
+    internal partial class Kernel32
     {
-        [DllImport(Libraries.CoreFile_L1, SetLastError = true)]
+        [DllImport(Libraries.Kernel32, SetLastError = true)]
         internal static extern bool SetFileInformationByHandle(SafeFileHandle hFile, FILE_INFO_BY_HANDLE_CLASS FileInformationClass, ref FILE_BASIC_INFO lpFileInformation, uint dwBufferSize);
 
         // Default values indicate "no change".  Use defaults so that we don't force callsites to be aware of the default values
-        internal unsafe static bool SetFileTime(
+        internal static unsafe bool SetFileTime(
             SafeFileHandle hFile,
             long creationTime = -1,
             long lastAccessTime = -1,
@@ -7,9 +7,9 @@ using System.Runtime.InteropServices;
 
 internal partial class Interop
 {
-    internal partial class mincore
+    internal partial class Kernel32
     {
-        [DllImport(Libraries.CoreFile_L1, SetLastError = true)]
+        [DllImport(Libraries.Kernel32, SetLastError = true)]
         internal static extern bool SetFilePointerEx(SafeFileHandle hFile, long liDistanceToMove, out long lpNewFilePointer, uint dwMoveMethod);
     }
 }
@@ -8,13 +8,13 @@ using Microsoft.Win32.SafeHandles;
 
 internal partial class Interop
 {
-    internal partial class mincore
+    internal partial class Kernel32
     {
         internal static SafeFileHandle UnsafeCreateFile(
             string lpFileName,
             int dwDesiredAccess,
             FileShare dwShareMode,
-            ref Interop.mincore.SECURITY_ATTRIBUTES securityAttrs,
+            ref Interop.Kernel32.SECURITY_ATTRIBUTES securityAttrs,
             FileMode dwCreationDisposition,
             int dwFlagsAndAttributes,
             IntPtr hTemplateFile)
@@ -7,9 +7,9 @@ using System.Runtime.InteropServices;
 
 internal partial class Interop
 {
-    internal partial class mincore
+    internal partial class Kernel32
     {
-        [DllImport(Libraries.String_L1)]
+        [DllImport(Libraries.Kernel32)]
         internal static extern unsafe int WideCharToMultiByte(
             uint CodePage, uint dwFlags, 
             char* lpWideCharStr, int cchWideChar, 
@@ -8,7 +8,7 @@ using System.Runtime.InteropServices;
 
 internal partial class Interop
 {
-    internal partial class mincore
+    internal partial class Kernel32
     {
         // Note there are two different WriteFile prototypes - this is to use 
         // the type system to force you to not trip across a "feature" in 
@@ -17,8 +17,8 @@ internal partial class Interop
         // struct in a callback (or an EndWrite method called by that callback),
         // and pass in an address for the numBytesRead parameter.
 
-        [DllImport(Libraries.CoreFile_L1, SetLastError = true)]
-        internal static unsafe extern int WriteFile(SafeHandle handle, byte* bytes, int numBytesToWrite, out int numBytesWritten, IntPtr mustBeZero);
+        [DllImport(Libraries.Kernel32, SetLastError = true)]
+        internal static extern unsafe int WriteFile(SafeHandle handle, byte* bytes, int numBytesToWrite, out int numBytesWritten, IntPtr mustBeZero);
 
     }
 }
@@ -8,7 +8,7 @@ using System.Runtime.InteropServices;
 using System.Threading;
 internal partial class Interop
 {
-    internal partial class mincore
+    internal partial class Kernel32
     {
         // Note there are two different WriteFile prototypes - this is to use 
         // the type system to force you to not trip across a "feature" in 
@@ -16,7 +16,7 @@ internal partial class Interop
         // simultaneously: overlapped IO, free the memory for the overlapped 
         // struct in a callback (or an EndWrite method called by that callback),
         // and pass in an address for the numBytesRead parameter.
-        [DllImport(Libraries.CoreFile_L1, SetLastError = true)]
-        internal static unsafe extern int WriteFile(SafeHandle handle, byte* bytes, int numBytesToWrite, IntPtr numBytesWritten_mustBeZero, NativeOverlapped* lpOverlapped);
+        [DllImport(Libraries.Kernel32, SetLastError = true)]
+        internal static extern unsafe int WriteFile(SafeHandle handle, byte* bytes, int numBytesToWrite, IntPtr numBytesWritten_mustBeZero, NativeOverlapped* lpOverlapped);
     }
 }
diff --git a/src/mscorlib/corefx/Interop/Windows/mincore/Interop.Errors.cs b/src/mscorlib/corefx/Interop/Windows/mincore/Interop.Errors.cs
deleted file mode 100644 (file)
index 05b2250..0000000
+++ /dev/null
@@ -1,74 +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.
-
-internal partial class Interop
-{
-    internal partial class mincore
-    {
-        internal partial class Errors
-        {
-            internal const int ERROR_SUCCESS = 0x0;
-            internal const int ERROR_INVALID_FUNCTION = 0x1;
-            internal const int ERROR_FILE_NOT_FOUND = 0x2;
-            internal const int ERROR_PATH_NOT_FOUND = 0x3;
-            internal const int ERROR_ACCESS_DENIED = 0x5;
-            internal const int ERROR_INVALID_HANDLE = 0x6;
-            internal const int ERROR_NOT_ENOUGH_MEMORY = 0x8;
-            internal const int ERROR_INVALID_DATA = 0xD;
-            internal const int ERROR_INVALID_DRIVE = 0xF;
-            internal const int ERROR_NO_MORE_FILES = 0x12;
-            internal const int ERROR_NOT_READY = 0x15;
-            internal const int ERROR_BAD_LENGTH = 0x18;
-            internal const int ERROR_SHARING_VIOLATION = 0x20;
-            internal const int ERROR_LOCK_VIOLATION = 0x21;
-            internal const int ERROR_HANDLE_EOF = 0x26;
-            internal const int ERROR_FILE_EXISTS = 0x50;
-            internal const int ERROR_INVALID_PARAMETER = 0x57;
-            internal const int ERROR_BROKEN_PIPE = 0x6D;
-            internal const int ERROR_INSUFFICIENT_BUFFER = 0x7A;
-            internal const int ERROR_INVALID_NAME = 0x7B;
-            internal const int ERROR_NEGATIVE_SEEK = 0x83;
-            internal const int ERROR_DIR_NOT_EMPTY = 0x91;
-            internal const int ERROR_BAD_PATHNAME = 0xA1;
-            internal const int ERROR_LOCK_FAILED = 0xA7;
-            internal const int ERROR_BUSY = 0xAA;
-            internal const int ERROR_ALREADY_EXISTS = 0xB7;
-            internal const int ERROR_BAD_EXE_FORMAT = 0xC1;
-            internal const int ERROR_ENVVAR_NOT_FOUND = 0xCB;
-            internal const int ERROR_FILENAME_EXCED_RANGE = 0xCE;
-            internal const int ERROR_EXE_MACHINE_TYPE_MISMATCH = 0xD8;
-            internal const int ERROR_PIPE_BUSY = 0xE7;
-            internal const int ERROR_NO_DATA = 0xE8;
-            internal const int ERROR_PIPE_NOT_CONNECTED = 0xE9;
-            internal const int ERROR_MORE_DATA = 0xEA;
-            internal const int ERROR_NO_MORE_ITEMS = 0x103;
-            internal const int ERROR_PARTIAL_COPY = 0x12B;
-            internal const int ERROR_ARITHMETIC_OVERFLOW = 0x216;
-            internal const int ERROR_PIPE_CONNECTED = 0x217;
-            internal const int ERROR_PIPE_LISTENING = 0x218;
-            internal const int ERROR_OPERATION_ABORTED = 0x3E3;
-            internal const int ERROR_IO_PENDING = 0x3E5;
-            internal const int ERROR_NO_TOKEN = 0x3f0;
-            internal const int ERROR_DLL_INIT_FAILED = 0x45A;
-            internal const int ERROR_NOT_FOUND = 0x490;
-            internal const int ERROR_NON_ACCOUNT_SID = 0x4E9;
-            internal const int ERROR_NOT_ALL_ASSIGNED = 0x514;
-            internal const int ERROR_UNKNOWN_REVISION = 0x519;
-            internal const int ERROR_INVALID_OWNER = 0x51B;
-            internal const int ERROR_INVALID_PRIMARY_GROUP = 0x51C;
-            internal const int ERROR_NO_SUCH_PRIVILEGE = 0x521;
-            internal const int ERROR_PRIVILEGE_NOT_HELD = 0x522;
-            internal const int ERROR_INVALID_ACL = 0x538;
-            internal const int ERROR_INVALID_SECURITY_DESCR = 0x53A;
-            internal const int ERROR_INVALID_SID = 0x539;
-            internal const int ERROR_BAD_IMPERSONATION_LEVEL = 0x542;
-            internal const int ERROR_CANT_OPEN_ANONYMOUS = 0x543;
-            internal const int ERROR_NO_SECURITY_ON_OBJECT = 0x546;
-            internal const int ERROR_TRUSTED_RELATIONSHIP_FAILURE = 0x6FD;
-            internal const int ERROR_RESOURCE_LANG_NOT_FOUND = 0x717;
-            internal const int EFail = unchecked((int)0x80004005);
-            internal const int E_FILENOTFOUND = unchecked((int)0x80070002);
-        }
-    }
-}
diff --git a/src/mscorlib/corefx/Interop/Windows/mincore/Interop.Idna.cs b/src/mscorlib/corefx/Interop/Windows/mincore/Interop.Idna.cs
deleted file mode 100644 (file)
index e14f16b..0000000
+++ /dev/null
@@ -1,37 +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.Runtime.InteropServices;
-
-internal partial class Interop
-{
-    internal partial class mincore
-    {
-        //
-        //  Idn APIs
-        //
-
-        [DllImport("api-ms-win-core-localization-l1-2-0.dll", CharSet = CharSet.Unicode, SetLastError = true)]
-        internal static extern int IdnToAscii(
-                                        uint dwFlags,
-                                        IntPtr lpUnicodeCharStr,
-                                        int cchUnicodeChar,
-                                        [System.Runtime.InteropServices.OutAttribute()]
-                                        IntPtr lpASCIICharStr,
-                                        int cchASCIIChar);
-
-        [DllImport("api-ms-win-core-localization-l1-2-0.dll", CharSet = CharSet.Unicode, SetLastError = true)]
-        internal static extern int IdnToUnicode(
-                                        uint dwFlags,
-                                        IntPtr lpASCIICharStr,
-                                        int cchASCIIChar,
-                                        [System.Runtime.InteropServices.OutAttribute()]
-                                        IntPtr lpUnicodeCharStr,
-                                        int cchUnicodeChar);
-
-        internal const int IDN_ALLOW_UNASSIGNED = 0x1;
-        internal const int IDN_USE_STD3_ASCII_RULES = 0x2;
-    }
-}
diff --git a/src/mscorlib/corefx/Interop/Windows/mincore/Interop.ThreadPoolIO.cs b/src/mscorlib/corefx/Interop/Windows/mincore/Interop.ThreadPoolIO.cs
deleted file mode 100644 (file)
index a0afed5..0000000
+++ /dev/null
@@ -1,27 +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.Runtime.InteropServices;
-using Microsoft.Win32.SafeHandles;
-
-internal static partial class Interop
-{
-    internal static partial class mincore
-    {
-        [DllImport(Libraries.ThreadPool, SetLastError = true)]
-        internal static unsafe extern SafeThreadPoolIOHandle CreateThreadpoolIo(SafeHandle fl, [MarshalAs(UnmanagedType.FunctionPtr)] NativeIoCompletionCallback pfnio, IntPtr context, IntPtr pcbe);
-
-        [DllImport(Libraries.ThreadPool)]
-        internal static unsafe extern void CloseThreadpoolIo(IntPtr pio);
-
-        [DllImport(Libraries.ThreadPool)]
-        internal static unsafe extern void StartThreadpoolIo(SafeThreadPoolIOHandle pio);
-
-        [DllImport(Libraries.ThreadPool)]
-        internal static unsafe extern void CancelThreadpoolIo(SafeThreadPoolIOHandle pio);
-    }
-
-    internal delegate void NativeIoCompletionCallback(IntPtr instance, IntPtr context, IntPtr overlapped, uint ioResult, UIntPtr numberOfBytesTransferred, IntPtr io);
-}
index 7d4dd44..4eabe8f 100644 (file)
@@ -43,7 +43,7 @@ namespace Microsoft.Win32.SafeHandles
 
         override protected bool ReleaseHandle()
         {
-            return Interop.mincore.CloseHandle(handle);
+            return Interop.Kernel32.CloseHandle(handle);
         }
     }
 }
index 350d948..f6896be 100644 (file)
@@ -55,7 +55,7 @@ namespace System.IO
 
         private SafeFileHandle OpenHandle(FileMode mode, FileShare share, FileOptions options)
         {
-            Interop.mincore.SECURITY_ATTRIBUTES secAttrs = GetSecAttrs(share);
+            Interop.Kernel32.SECURITY_ATTRIBUTES secAttrs = GetSecAttrs(share);
 
             int fAccess =
                 ((_access & FileAccess.Read) == FileAccess.Read ? GENERIC_READ : 0) |
@@ -74,13 +74,13 @@ namespace System.IO
             // For mitigating local elevation of privilege attack through named pipes
             // make sure we always call CreateFile with SECURITY_ANONYMOUS so that the
             // named pipe server can't impersonate a high privileged client security context
-            flagsAndAttributes |= (Interop.mincore.SecurityOptions.SECURITY_SQOS_PRESENT | Interop.mincore.SecurityOptions.SECURITY_ANONYMOUS);
+            flagsAndAttributes |= (Interop.Kernel32.SecurityOptions.SECURITY_SQOS_PRESENT | Interop.Kernel32.SecurityOptions.SECURITY_ANONYMOUS);
 
             // Don't pop up a dialog for reading from an empty floppy drive
-            uint oldMode = Interop.mincore.SetErrorMode(Interop.mincore.SEM_FAILCRITICALERRORS);
+            uint oldMode = Interop.Kernel32.SetErrorMode(Interop.Kernel32.SEM_FAILCRITICALERRORS);
             try
             {
-                SafeFileHandle fileHandle = Interop.mincore.SafeCreateFile(_path, fAccess, share, ref secAttrs, mode, flagsAndAttributes, IntPtr.Zero);
+                SafeFileHandle fileHandle = Interop.Kernel32.SafeCreateFile(_path, fAccess, share, ref secAttrs, mode, flagsAndAttributes, IntPtr.Zero);
                 fileHandle.IsAsync = _useAsyncIO;
 
                 if (fileHandle.IsInvalid)
@@ -92,8 +92,8 @@ namespace System.IO
                     // probably be consistent w/ every other directory.
                     int errorCode = Marshal.GetLastWin32Error();
 
-                    if (errorCode == Interop.mincore.Errors.ERROR_PATH_NOT_FOUND && _path.Equals(Directory.InternalGetDirectoryRoot(_path)))
-                        errorCode = Interop.mincore.Errors.ERROR_ACCESS_DENIED;
+                    if (errorCode == Interop.Errors.ERROR_PATH_NOT_FOUND && _path.Equals(Directory.InternalGetDirectoryRoot(_path)))
+                        errorCode = Interop.Errors.ERROR_ACCESS_DENIED;
 
                     throw Win32Marshal.GetExceptionForWin32Error(errorCode, _path);
                 }
@@ -102,7 +102,7 @@ namespace System.IO
             }
             finally
             {
-                Interop.mincore.SetErrorMode(oldMode);
+                Interop.Kernel32.SetErrorMode(oldMode);
             }
         }
 
@@ -112,8 +112,8 @@ namespace System.IO
             // constructors that take a String.  Everyone else can call 
             // CreateFile themselves then use the constructor that takes an 
             // IntPtr.  Disallows "con:", "com1:", "lpt1:", etc.
-            int fileType = Interop.mincore.GetFileType(_fileHandle);
-            if (fileType != Interop.mincore.FileTypes.FILE_TYPE_DISK)
+            int fileType = Interop.Kernel32.GetFileType(_fileHandle);
+            if (fileType != Interop.Kernel32.FileTypes.FILE_TYPE_DISK)
             {
                 _fileHandle.Dispose();
                 throw new NotSupportedException(SR.NotSupported_FileStreamOnNonFiles);
@@ -163,11 +163,11 @@ namespace System.IO
 
         private void InitFromHandle(SafeFileHandle handle)
         {
-            int handleType = Interop.mincore.GetFileType(_fileHandle);
-            Debug.Assert(handleType == Interop.mincore.FileTypes.FILE_TYPE_DISK || handleType == Interop.mincore.FileTypes.FILE_TYPE_PIPE || handleType == Interop.mincore.FileTypes.FILE_TYPE_CHAR, "FileStream was passed an unknown file type!");
+            int handleType = Interop.Kernel32.GetFileType(_fileHandle);
+            Debug.Assert(handleType == Interop.Kernel32.FileTypes.FILE_TYPE_DISK || handleType == Interop.Kernel32.FileTypes.FILE_TYPE_PIPE || handleType == Interop.Kernel32.FileTypes.FILE_TYPE_CHAR, "FileStream was passed an unknown file type!");
 
-            _canSeek = handleType == Interop.mincore.FileTypes.FILE_TYPE_DISK;
-            _isPipe = handleType == Interop.mincore.FileTypes.FILE_TYPE_PIPE;
+            _canSeek = handleType == Interop.Kernel32.FileTypes.FILE_TYPE_DISK;
+            _isPipe = handleType == Interop.Kernel32.FileTypes.FILE_TYPE_PIPE;
 
             // This is necessary for async IO using IO Completion ports via our 
             // managed Threadpool API's.  This calls the OS's 
@@ -196,7 +196,7 @@ namespace System.IO
             }
             else if (!_useAsyncIO)
             {
-                if (handleType != Interop.mincore.FileTypes.FILE_TYPE_PIPE)
+                if (handleType != Interop.Kernel32.FileTypes.FILE_TYPE_PIPE)
                     VerifyHandleIsSync();
             }
 
@@ -211,13 +211,13 @@ namespace System.IO
             return handle.IsAsync.HasValue ? handle.IsAsync.Value : false;
         }
 
-        private unsafe static Interop.mincore.SECURITY_ATTRIBUTES GetSecAttrs(FileShare share)
+        private unsafe static Interop.Kernel32.SECURITY_ATTRIBUTES GetSecAttrs(FileShare share)
         {
-            Interop.mincore.SECURITY_ATTRIBUTES secAttrs = default(Interop.mincore.SECURITY_ATTRIBUTES);
+            Interop.Kernel32.SECURITY_ATTRIBUTES secAttrs = default(Interop.Kernel32.SECURITY_ATTRIBUTES);
             if ((share & FileShare.Inheritable) != 0)
             {
-                secAttrs = new Interop.mincore.SECURITY_ATTRIBUTES();
-                secAttrs.nLength = (uint)sizeof(Interop.mincore.SECURITY_ATTRIBUTES);
+                secAttrs = new Interop.Kernel32.SECURITY_ATTRIBUTES();
+                secAttrs.nLength = (uint)sizeof(Interop.Kernel32.SECURITY_ATTRIBUTES);
 
                 secAttrs.bInheritHandle = Interop.BOOL.TRUE;
             }
@@ -234,7 +234,7 @@ namespace System.IO
             // cause an app to block incorrectly, introducing a deadlock (depending
             // on whether a write will wake up an already-blocked thread or this
             // Win32FileStream's thread).
-            Debug.Assert(Interop.mincore.GetFileType(_fileHandle) != Interop.mincore.FileTypes.FILE_TYPE_PIPE);
+            Debug.Assert(Interop.Kernel32.GetFileType(_fileHandle) != Interop.Kernel32.FileTypes.FILE_TYPE_PIPE);
 
             byte* bytes = stackalloc byte[1];
             int numBytesReadWritten;
@@ -246,11 +246,11 @@ namespace System.IO
             // accidentally read synchronously from an async pipe.
             if ((_access & FileAccess.Read) != 0) // don't use the virtual CanRead or CanWrite, as this may be used in the ctor
             {
-                r = Interop.mincore.ReadFile(_fileHandle, bytes, 0, out numBytesReadWritten, IntPtr.Zero);
+                r = Interop.Kernel32.ReadFile(_fileHandle, bytes, 0, out numBytesReadWritten, IntPtr.Zero);
             }
             else if ((_access & FileAccess.Write) != 0) // don't use the virtual CanRead or CanWrite, as this may be used in the ctor
             {
-                r = Interop.mincore.WriteFile(_fileHandle, bytes, 0, out numBytesReadWritten, IntPtr.Zero);
+                r = Interop.Kernel32.WriteFile(_fileHandle, bytes, 0, out numBytesReadWritten, IntPtr.Zero);
             }
 
             if (r == 0)
@@ -273,9 +273,9 @@ namespace System.IO
 
         private long GetLengthInternal()
         {
-            Interop.mincore.FILE_STANDARD_INFO info = new Interop.mincore.FILE_STANDARD_INFO();
+            Interop.Kernel32.FILE_STANDARD_INFO info = new Interop.Kernel32.FILE_STANDARD_INFO();
 
-            if (!Interop.mincore.GetFileInformationByHandleEx(_fileHandle, Interop.mincore.FILE_INFO_BY_HANDLE_CLASS.FileStandardInfo, out info, (uint)Marshal.SizeOf<Interop.mincore.FILE_STANDARD_INFO>()))
+            if (!Interop.Kernel32.GetFileInformationByHandleEx(_fileHandle, Interop.Kernel32.FILE_INFO_BY_HANDLE_CLASS.FileStandardInfo, out info, (uint)Marshal.SizeOf<Interop.Kernel32.FILE_STANDARD_INFO>()))
                 throw Win32Marshal.GetExceptionForLastWin32Error();
             long len = info.EndOfFile;
             // If we're writing near the end of the file, we must include our
@@ -334,7 +334,7 @@ namespace System.IO
 
         private void FlushOSBuffer()
         {
-            if (!Interop.mincore.FlushFileBuffers(_fileHandle))
+            if (!Interop.Kernel32.FlushFileBuffers(_fileHandle))
             {
                 throw Win32Marshal.GetExceptionForLastWin32Error();
             }
@@ -426,10 +426,10 @@ namespace System.IO
             VerifyOSHandlePosition();
             if (_filePosition != value)
                 SeekCore(value, SeekOrigin.Begin);
-            if (!Interop.mincore.SetEndOfFile(_fileHandle))
+            if (!Interop.Kernel32.SetEndOfFile(_fileHandle))
             {
                 int errorCode = Marshal.GetLastWin32Error();
-                if (errorCode == Interop.mincore.Errors.ERROR_INVALID_PARAMETER)
+                if (errorCode == Interop.Errors.ERROR_INVALID_PARAMETER)
                     throw new ArgumentOutOfRangeException(nameof(value), SR.ArgumentOutOfRange_FileLengthTooBig);
                 throw Win32Marshal.GetExceptionForWin32Error(errorCode);
             }
@@ -658,7 +658,7 @@ namespace System.IO
             Debug.Assert(origin >= SeekOrigin.Begin && origin <= SeekOrigin.End, "origin>=SeekOrigin.Begin && origin<=SeekOrigin.End");
             long ret = 0;
 
-            if (!Interop.mincore.SetFilePointerEx(_fileHandle, offset, out ret, (uint)origin))
+            if (!Interop.Kernel32.SetFilePointerEx(_fileHandle, offset, out ret, (uint)origin))
             {
                 int errorCode = GetLastWin32ErrorAndDisposeHandleIfInvalid();
                 throw Win32Marshal.GetExceptionForWin32Error(errorCode);
@@ -1280,9 +1280,9 @@ namespace System.IO
             fixed (byte* p = bytes)
             {
                 if (_useAsyncIO)
-                    r = Interop.mincore.ReadFile(handle, p + offset, count, IntPtr.Zero, overlapped);
+                    r = Interop.Kernel32.ReadFile(handle, p + offset, count, IntPtr.Zero, overlapped);
                 else
-                    r = Interop.mincore.ReadFile(handle, p + offset, count, out numBytesRead, IntPtr.Zero);
+                    r = Interop.Kernel32.ReadFile(handle, p + offset, count, out numBytesRead, IntPtr.Zero);
             }
 
             if (r == 0)
@@ -1325,9 +1325,9 @@ namespace System.IO
             fixed (byte* p = bytes)
             {
                 if (_useAsyncIO)
-                    r = Interop.mincore.WriteFile(handle, p + offset, count, IntPtr.Zero, overlapped);
+                    r = Interop.Kernel32.WriteFile(handle, p + offset, count, IntPtr.Zero, overlapped);
                 else
-                    r = Interop.mincore.WriteFile(handle, p + offset, count, out numBytesWritten, IntPtr.Zero);
+                    r = Interop.Kernel32.WriteFile(handle, p + offset, count, out numBytesWritten, IntPtr.Zero);
             }
 
             if (r == 0)
@@ -1363,7 +1363,7 @@ namespace System.IO
             // Note that _parent.Dispose doesn't throw so we don't need to special case.
             // SetHandleAsInvalid only sets _closed field to true (without
             // actually closing handle) so we don't need to call that as well.
-            if (errorCode == Interop.mincore.Errors.ERROR_INVALID_HANDLE)
+            if (errorCode == Interop.Errors.ERROR_INVALID_HANDLE)
             {
                 _fileHandle.Dispose();
 
@@ -1473,7 +1473,7 @@ namespace System.IO
                                 {
                                     // Try to cancel the I/O.  We ignore the return value, as cancellation is opportunistic and we
                                     // don't want to fail the operation because we couldn't cancel it.
-                                    Interop.mincore.CancelIoEx(innerAwaitable._fileStream._fileHandle, innerAwaitable._nativeOverlapped);
+                                    Interop.Kernel32.CancelIoEx(innerAwaitable._fileStream._fileHandle, innerAwaitable._nativeOverlapped);
                                 }
                             }
                         }
@@ -1538,7 +1538,7 @@ namespace System.IO
                             case ERROR_HANDLE_EOF:  // logically success with 0 bytes read (read at end of file)
                                 Debug.Assert(readAwaitable._numBytes == 0, $"Expected 0 bytes read, got {readAwaitable._numBytes}");
                                 break;
-                            case Interop.mincore.Errors.ERROR_OPERATION_ABORTED: // canceled
+                            case Interop.Errors.ERROR_OPERATION_ABORTED: // canceled
                                 throw new OperationCanceledException(cancellationToken.IsCancellationRequested ? cancellationToken : new CancellationToken(true));
                             default: // error
                                 throw Win32Marshal.GetExceptionForWin32Error((int)readAwaitable._errorCode);
@@ -1748,7 +1748,7 @@ namespace System.IO
             int lengthLow = unchecked((int)(length));
             int lengthHigh = unchecked((int)(length >> 32));
 
-            if (!Interop.mincore.LockFile(_fileHandle, positionLow, positionHigh, lengthLow, lengthHigh))
+            if (!Interop.Kernel32.LockFile(_fileHandle, positionLow, positionHigh, lengthLow, lengthHigh))
             {
                 throw Win32Marshal.GetExceptionForLastWin32Error();
             }
@@ -1761,7 +1761,7 @@ namespace System.IO
             int lengthLow = unchecked((int)(length));
             int lengthHigh = unchecked((int)(length >> 32));
 
-            if (!Interop.mincore.UnlockFile(_fileHandle, positionLow, positionHigh, lengthLow, lengthHigh))
+            if (!Interop.Kernel32.UnlockFile(_fileHandle, positionLow, positionHigh, lengthLow, lengthHigh))
             {
                 throw Win32Marshal.GetExceptionForLastWin32Error();
             }
index 532dbb0..159e416 100644 (file)
@@ -178,7 +178,7 @@ namespace System.IO
                 if (result == ResultError)
                 {
                     int errorCode = unchecked((int)(packedResult & uint.MaxValue));
-                    if (errorCode == Interop.mincore.Errors.ERROR_OPERATION_ABORTED)
+                    if (errorCode == Interop.Errors.ERROR_OPERATION_ABORTED)
                     {
                         TrySetCanceled(_cancellationToken.IsCancellationRequested ? _cancellationToken : new CancellationToken(true));
                     }
@@ -204,13 +204,13 @@ namespace System.IO
 
                 // If the handle is still valid, attempt to cancel the IO
                 if (!completionSource._stream._fileHandle.IsInvalid && 
-                    !Interop.mincore.CancelIoEx(completionSource._stream._fileHandle, completionSource._overlapped))
+                    !Interop.Kernel32.CancelIoEx(completionSource._stream._fileHandle, completionSource._overlapped))
                 {
                     int errorCode = Marshal.GetLastWin32Error();
 
                     // ERROR_NOT_FOUND is returned if CancelIoEx cannot find the request to cancel.
                     // This probably means that the IO operation has completed.
-                    if (errorCode != Interop.mincore.Errors.ERROR_NOT_FOUND)
+                    if (errorCode != Interop.Errors.ERROR_NOT_FOUND)
                     {
                         throw Win32Marshal.GetExceptionForWin32Error(errorCode);
                     }
index 0c96769..ce867ef 100644 (file)
@@ -94,7 +94,7 @@ namespace System.IO
         public static string GetTempPath()
         {
             StringBuilder sb = StringBuilderCache.Acquire(MaxPath);
-            uint r = Interop.mincore.GetTempPathW(MaxPath, sb);
+            uint r = Interop.Kernel32.GetTempPathW(MaxPath, sb);
             if (r == 0)
                 throw Win32Marshal.GetExceptionForLastWin32Error();
             return GetFullPath(StringBuilderCache.GetStringAndRelease(sb));
@@ -107,7 +107,7 @@ namespace System.IO
             string path = GetTempPath();
 
             StringBuilder sb = StringBuilderCache.Acquire(MaxPath);
-            uint r = Interop.mincore.GetTempFileNameW(path, "tmp", 0, sb);
+            uint r = Interop.Kernel32.GetTempFileNameW(path, "tmp", 0, sb);
             if (r == 0)
                 throw Win32Marshal.GetExceptionForLastWin32Error();
             return StringBuilderCache.GetStringAndRelease(sb);
index 7df435f..e2ead93 100644 (file)
@@ -198,7 +198,7 @@ namespace System.IO
             fixed (char* pathStart = path)
             {
                 uint result = 0;
-                while ((result = Interop.mincore.GetFullPathNameW(pathStart + startIndex, (uint)fullPath.Capacity, fullPath.UnderlyingArray, IntPtr.Zero)) > fullPath.Capacity)
+                while ((result = Interop.Kernel32.GetFullPathNameW(pathStart + startIndex, (uint)fullPath.Capacity, fullPath.UnderlyingArray, IntPtr.Zero)) > fullPath.Capacity)
                 {
                     // Reported size is greater than the buffer size. Increase the capacity.
                     fullPath.EnsureCapacity(checked((int)result));
@@ -209,7 +209,7 @@ namespace System.IO
                     // Failure, get the error and throw
                     int errorCode = Marshal.GetLastWin32Error();
                     if (errorCode == 0)
-                        errorCode = Interop.mincore.Errors.ERROR_BAD_PATHNAME;
+                        errorCode = Interop.Errors.ERROR_BAD_PATHNAME;
                     throw Win32Marshal.GetExceptionForWin32Error(errorCode, path);
                 }
 
@@ -304,7 +304,7 @@ namespace System.IO
 
                 while (!success)
                 {
-                    uint result = Interop.mincore.GetLongPathNameW(inputBuffer.UnderlyingArray, outputBuffer.UnderlyingArray, (uint)outputBuffer.Capacity);
+                    uint result = Interop.Kernel32.GetLongPathNameW(inputBuffer.UnderlyingArray, outputBuffer.UnderlyingArray, (uint)outputBuffer.Capacity);
 
                     // Replace any temporary null we added
                     if (inputBuffer[foundIndex] == '\0') inputBuffer[foundIndex] = '\\';
@@ -313,7 +313,7 @@ namespace System.IO
                     {
                         // Look to see if we couldn't find the file
                         int error = Marshal.GetLastWin32Error();
-                        if (error != Interop.mincore.Errors.ERROR_FILE_NOT_FOUND && error != Interop.mincore.Errors.ERROR_PATH_NOT_FOUND)
+                        if (error != Interop.Errors.ERROR_FILE_NOT_FOUND && error != Interop.Errors.ERROR_PATH_NOT_FOUND)
                         {
                             // Some other failure, give up
                             break;
@@ -338,7 +338,7 @@ namespace System.IO
                     {
                         // Not enough space. The result count for this API does not include the null terminator.
                         outputBuffer.EnsureCapacity(checked((int)result));
-                        result = Interop.mincore.GetLongPathNameW(inputBuffer.UnderlyingArray, outputBuffer.UnderlyingArray, (uint)outputBuffer.Capacity);
+                        result = Interop.Kernel32.GetLongPathNameW(inputBuffer.UnderlyingArray, outputBuffer.UnderlyingArray, (uint)outputBuffer.Capacity);
                     }
                     else
                     {
index b4dfa04..8bdab0b 100644 (file)
@@ -48,49 +48,49 @@ namespace System.IO
         {
             switch (errorCode)
             {
-                case Interop.mincore.Errors.ERROR_FILE_NOT_FOUND:
+                case Interop.Errors.ERROR_FILE_NOT_FOUND:
                     if (path.Length == 0)
                         return new FileNotFoundException(SR.IO_FileNotFound);
                     else
                         return new FileNotFoundException(SR.Format(SR.IO_FileNotFound_FileName, path), path);
 
-                case Interop.mincore.Errors.ERROR_PATH_NOT_FOUND:
+                case Interop.Errors.ERROR_PATH_NOT_FOUND:
                     if (path.Length == 0)
                         return new DirectoryNotFoundException(SR.IO_PathNotFound_NoPathName);
                     else
                         return new DirectoryNotFoundException(SR.Format(SR.IO_PathNotFound_Path, path));
 
-                case Interop.mincore.Errors.ERROR_ACCESS_DENIED:
+                case Interop.Errors.ERROR_ACCESS_DENIED:
                     if (path.Length == 0)
                         return new UnauthorizedAccessException(SR.UnauthorizedAccess_IODenied_NoPathName);
                     else
                         return new UnauthorizedAccessException(SR.Format(SR.UnauthorizedAccess_IODenied_Path, path));
 
-                case Interop.mincore.Errors.ERROR_ALREADY_EXISTS:
+                case Interop.Errors.ERROR_ALREADY_EXISTS:
                     if (path.Length == 0)
                         goto default;
 
                     return new IOException(SR.Format(SR.IO_AlreadyExists_Name, path), MakeHRFromErrorCode(errorCode));
 
-                case Interop.mincore.Errors.ERROR_FILENAME_EXCED_RANGE:
+                case Interop.Errors.ERROR_FILENAME_EXCED_RANGE:
                     return new PathTooLongException(SR.IO_PathTooLong);
 
-                case Interop.mincore.Errors.ERROR_INVALID_PARAMETER:
+                case Interop.Errors.ERROR_INVALID_PARAMETER:
                     return new IOException(GetMessage(errorCode), MakeHRFromErrorCode(errorCode));
 
-                case Interop.mincore.Errors.ERROR_SHARING_VIOLATION:
+                case Interop.Errors.ERROR_SHARING_VIOLATION:
                     if (path.Length == 0)
                         return new IOException(SR.IO_SharingViolation_NoFileName, MakeHRFromErrorCode(errorCode));
                     else
                         return new IOException(SR.Format(SR.IO_SharingViolation_File, path), MakeHRFromErrorCode(errorCode));
 
-                case Interop.mincore.Errors.ERROR_FILE_EXISTS:
+                case Interop.Errors.ERROR_FILE_EXISTS:
                     if (path.Length == 0)
                         goto default;
 
                     return new IOException(SR.Format(SR.IO_FileExists_Name, path), MakeHRFromErrorCode(errorCode));
 
-                case Interop.mincore.Errors.ERROR_OPERATION_ABORTED:
+                case Interop.Errors.ERROR_OPERATION_ABORTED:
                     return new OperationCanceledException();
 
                 default:
@@ -128,7 +128,7 @@ namespace System.IO
         /// </summary>
         internal static string GetMessage(int errorCode)
         {
-            return Interop.mincore.GetMessage(errorCode);
+            return Interop.Kernel32.GetMessage(errorCode);
         }
     }
 }
index 5f56353..7ed0c6a 100644 (file)
@@ -206,11 +206,11 @@ namespace System.Security
                 else
                 {
                     uint defaultChar = '?';
-                    int resultByteLength = 1 + Interop.mincore.WideCharToMultiByte(
-                        Interop.mincore.CP_ACP, Interop.mincore.WC_NO_BEST_FIT_CHARS, (char*)bufferPtr, length, null, 0, (IntPtr)(&defaultChar), IntPtr.Zero);
+                    int resultByteLength = 1 + Interop.Kernel32.WideCharToMultiByte(
+                        Interop.Kernel32.CP_ACP, Interop.Kernel32.WC_NO_BEST_FIT_CHARS, (char*)bufferPtr, length, null, 0, (IntPtr)(&defaultChar), IntPtr.Zero);
                     ptr = globalAlloc ? Marshal.AllocHGlobal(resultByteLength) : Marshal.AllocCoTaskMem(resultByteLength);
-                    Interop.mincore.WideCharToMultiByte(
-                        Interop.mincore.CP_ACP, Interop.mincore.WC_NO_BEST_FIT_CHARS, (char*)bufferPtr, length, (byte*)ptr, resultByteLength - 1, (IntPtr)(&defaultChar), IntPtr.Zero);
+                    Interop.Kernel32.WideCharToMultiByte(
+                        Interop.Kernel32.CP_ACP, Interop.Kernel32.WC_NO_BEST_FIT_CHARS, (char*)bufferPtr, length, (byte*)ptr, resultByteLength - 1, (IntPtr)(&defaultChar), IntPtr.Zero);
                     *(resultByteLength - 1 + (byte*)ptr) = 0;
                 }
                 result = ptr;
index bf00760..038a698 100644 (file)
@@ -10,6 +10,7 @@
     <IsPartialFacadeAssembly>true</IsPartialFacadeAssembly>
     <OutputType>Library</OutputType>
     <ExcludeMscorlibFacade>true</ExcludeMscorlibFacade>
+    <HighEntropyVA>true</HighEntropyVA>
 
     <!-- This prevents the default MsBuild targets from referencing System.Core.dll -->
     <AddAdditionalExplicitAssemblyReferences>false</AddAdditionalExplicitAssemblyReferences>
index 437d5d6..0f34b34 100644 (file)
       <Member Name="GetHashCode(T)" />
       <Member MemberType="Property" Name="Default" />
     </Type>
+    <Type Name="System.Collections.Generic.EnumEqualityComparer&lt;T&gt;">
+      <Member Name="#ctor(System.Runtime.Serialization.SerializationInfo,System.Runtime.Serialization.StreamingContext)" />
+    </Type>
     <Type Name="System.Collections.Generic.ICollection&lt;T&gt;">
       <Member Name="Add(T)" />
       <Member Name="Clear" />
       <Member Name="Trim" />
       <Member Name="Trim(System.Char[])" />
       <Member Name="TrimEnd(System.Char[])" />
+      <Member Name="TrimEnd" />
       <Member Name="TrimStart(System.Char[])" />
+      <Member Name="TrimStart" />
       <Member MemberType="Property" Name="Chars(System.Int32)" />
       <Member MemberType="Property" Name="Length" />
       <Member Status="ImplRoot" Name="System.Collections.IEnumerable.GetEnumerator" />
       <Member MemberType="Field" Name="Never" />
       <Member MemberType="Field" Name="Advanced" />
     </Type>
+    <Type Status="ImplRoot" Name="System.Runtime.CompilerServices.Unsafe">
+      <Member Status="ImplRoot" Name="AsPointer&lt;T&gt;(T@)" />
+    </Type>
   </Assembly>
 </ThinModel>
index c81b4fa..9877112 100644 (file)
   <ItemGroup Condition="'$(TargetsUnix)' != 'true'">
     <WindowsInteropSources Include="$(CoreFxSourcesRoot)\System\HResults.cs" />
     <WindowsInteropSources Include="$(CoreFxSourcesRoot)\Interop\Windows\Interop.BOOL.cs" />
+    <WindowsInteropSources Include="$(CoreFxSourcesRoot)\Interop\Windows\Interop.Errors.cs" />
     <WindowsInteropSources Include="$(CoreFxSourcesRoot)\Interop\Windows\Interop.Libraries.cs" />
     <WindowsInteropSources Include="$(CoreFxSourcesRoot)\Interop\Windows\BCrypt\Interop.BCryptGenRandom.cs" />
     <WindowsInteropSources Include="$(CoreFxSourcesRoot)\Interop\Windows\BCrypt\Interop.NTSTATUS.cs" />
-    <WindowsInteropSources Include="$(CoreFxSourcesRoot)\Interop\Windows\mincore\Interop.CancelIoEx.cs" />
-    <WindowsInteropSources Include="$(CoreFxSourcesRoot)\Interop\Windows\mincore\Interop.CloseHandle.cs" />
-    <WindowsInteropSources Include="$(CoreFxSourcesRoot)\Interop\Windows\mincore\Interop.CreateFile.cs" />
-    <WindowsInteropSources Include="$(CoreFxSourcesRoot)\Interop\Windows\mincore\Interop.Errors.cs" />
-    <WindowsInteropSources Include="$(CoreFxSourcesRoot)\Interop\Windows\mincore\Interop.FileTypes.cs" />
-    <WindowsInteropSources Include="$(CoreFxSourcesRoot)\Interop\Windows\mincore\Interop.FileOperations.cs" />
-    <WindowsInteropSources Include="$(CoreFxSourcesRoot)\Interop\Windows\mincore\Interop.FlushFileBuffers.cs" />
-    <WindowsInteropSources Include="$(CoreFxSourcesRoot)\Interop\Windows\mincore\Interop.FormatMessage.cs" />
-    <WindowsInteropSources Include="$(CoreFxSourcesRoot)\Interop\Windows\mincore\Interop.GetFileInformationByHandleEx.cs" />
-    <WindowsInteropSources Include="$(CoreFxSourcesRoot)\Interop\Windows\mincore\Interop.GetFileType_SafeHandle.cs" />
-    <WindowsInteropSources Include="$(CoreFxSourcesRoot)\Interop\Windows\mincore\Interop.GetFullPathNameW.cs" />
-    <WindowsInteropSources Include="$(CoreFxSourcesRoot)\Interop\Windows\mincore\Interop.GetLongPathNameW.cs" />
-    <WindowsInteropSources Include="$(CoreFxSourcesRoot)\Interop\Windows\mincore\Interop.GetTempFileNameW.cs" />
-    <WindowsInteropSources Include="$(CoreFxSourcesRoot)\Interop\Windows\mincore\Interop.GetTempPathW.cs" />
-    <WindowsInteropSources Include="$(CoreFxSourcesRoot)\Interop\Windows\mincore\Interop.LockFile.cs" />
-    <WindowsInteropSources Include="$(CoreFxSourcesRoot)\Interop\Windows\mincore\Interop.ReadFile_SafeHandle_IntPtr.cs" />
-    <WindowsInteropSources Include="$(CoreFxSourcesRoot)\Interop\Windows\mincore\Interop.ReadFile_SafeHandle_NativeOverlapped.cs" />
-    <WindowsInteropSources Include="$(CoreFxSourcesRoot)\Interop\Windows\mincore\Interop.SafeCreateFile.cs" />
-    <WindowsInteropSources Include="$(CoreFxSourcesRoot)\Interop\Windows\mincore\Interop.SECURITY_ATTRIBUTES.cs" />
-    <WindowsInteropSources Include="$(CoreFxSourcesRoot)\Interop\Windows\mincore\Interop.SecurityOptions.cs" />
-    <WindowsInteropSources Include="$(CoreFxSourcesRoot)\Interop\Windows\mincore\Interop.SetEndOfFile.cs" />
-    <WindowsInteropSources Include="$(CoreFxSourcesRoot)\Interop\Windows\mincore\Interop.SetErrorMode.cs" />
-    <WindowsInteropSources Include="$(CoreFxSourcesRoot)\Interop\Windows\mincore\Interop.SetFileInformationByHandle.cs" />
-    <WindowsInteropSources Include="$(CoreFxSourcesRoot)\Interop\Windows\mincore\Interop.SetFilePointerEx.cs" />
-    <WindowsInteropSources Include="$(CoreFxSourcesRoot)\Interop\Windows\mincore\Interop.UnsafeCreateFile.cs" />
-    <WindowsInteropSources Include="$(CoreFxSourcesRoot)\Interop\Windows\mincore\Interop.WriteFile_SafeHandle_IntPtr.cs" />
-    <WindowsInteropSources Include="$(CoreFxSourcesRoot)\Interop\Windows\mincore\Interop.WriteFile_SafeHandle_NativeOverlapped.cs" />
+    <WindowsInteropSources Include="$(CoreFxSourcesRoot)\Interop\Windows\kernel32\Interop.CancelIoEx.cs" />
+    <WindowsInteropSources Include="$(CoreFxSourcesRoot)\Interop\Windows\kernel32\Interop.CloseHandle.cs" />
+    <WindowsInteropSources Include="$(CoreFxSourcesRoot)\Interop\Windows\kernel32\Interop.CreateFile.cs" />
+    <WindowsInteropSources Include="$(CoreFxSourcesRoot)\Interop\Windows\kernel32\Interop.FileTypes.cs" />
+    <WindowsInteropSources Include="$(CoreFxSourcesRoot)\Interop\Windows\kernel32\Interop.FileOperations.cs" />
+    <WindowsInteropSources Include="$(CoreFxSourcesRoot)\Interop\Windows\kernel32\Interop.FlushFileBuffers.cs" />
+    <WindowsInteropSources Include="$(CoreFxSourcesRoot)\Interop\Windows\kernel32\Interop.FormatMessage.cs" />
+    <WindowsInteropSources Include="$(CoreFxSourcesRoot)\Interop\Windows\kernel32\Interop.GetFileInformationByHandleEx.cs" />
+    <WindowsInteropSources Include="$(CoreFxSourcesRoot)\Interop\Windows\kernel32\Interop.GetFileType_SafeHandle.cs" />
+    <WindowsInteropSources Include="$(CoreFxSourcesRoot)\Interop\Windows\kernel32\Interop.GetFullPathNameW.cs" />
+    <WindowsInteropSources Include="$(CoreFxSourcesRoot)\Interop\Windows\kernel32\Interop.GetLongPathNameW.cs" />
+    <WindowsInteropSources Include="$(CoreFxSourcesRoot)\Interop\Windows\kernel32\Interop.GetTempFileNameW.cs" />
+    <WindowsInteropSources Include="$(CoreFxSourcesRoot)\Interop\Windows\kernel32\Interop.GetTempPathW.cs" />
+    <WindowsInteropSources Include="$(CoreFxSourcesRoot)\Interop\Windows\kernel32\Interop.LockFile.cs" />
+    <WindowsInteropSources Include="$(CoreFxSourcesRoot)\Interop\Windows\kernel32\Interop.ReadFile_SafeHandle_IntPtr.cs" />
+    <WindowsInteropSources Include="$(CoreFxSourcesRoot)\Interop\Windows\kernel32\Interop.ReadFile_SafeHandle_NativeOverlapped.cs" />
+    <WindowsInteropSources Include="$(CoreFxSourcesRoot)\Interop\Windows\kernel32\Interop.SafeCreateFile.cs" />
+    <WindowsInteropSources Include="$(CoreFxSourcesRoot)\Interop\Windows\kernel32\Interop.SECURITY_ATTRIBUTES.cs" />
+    <WindowsInteropSources Include="$(CoreFxSourcesRoot)\Interop\Windows\kernel32\Interop.SecurityOptions.cs" />
+    <WindowsInteropSources Include="$(CoreFxSourcesRoot)\Interop\Windows\kernel32\Interop.SetEndOfFile.cs" />
+    <WindowsInteropSources Include="$(CoreFxSourcesRoot)\Interop\Windows\kernel32\Interop.SetErrorMode.cs" />
+    <WindowsInteropSources Include="$(CoreFxSourcesRoot)\Interop\Windows\kernel32\Interop.SetFileInformationByHandle.cs" />
+    <WindowsInteropSources Include="$(CoreFxSourcesRoot)\Interop\Windows\kernel32\Interop.SetFilePointerEx.cs" />
+    <WindowsInteropSources Include="$(CoreFxSourcesRoot)\Interop\Windows\kernel32\Interop.UnsafeCreateFile.cs" />
+    <WindowsInteropSources Include="$(CoreFxSourcesRoot)\Interop\Windows\kernel32\Interop.WriteFile_SafeHandle_IntPtr.cs" />
+    <WindowsInteropSources Include="$(CoreFxSourcesRoot)\Interop\Windows\kernel32\Interop.WriteFile_SafeHandle_NativeOverlapped.cs" />
   </ItemGroup>
 
   <ItemGroup>
     <!-- Interop sources -->
     <SecuritySources Include="$(CoreFxSourcesRoot)\Interop\Windows\Crypt32\Interop.CryptProtectMemory.cs" />
     <SecuritySources Include="$(CoreFxSourcesRoot)\Interop\Windows\NtDll\Interop.ZeroMemory.cs" />
-    <SecuritySources Include="$(CoreFxSourcesRoot)\Interop\Windows\mincore\Interop.WideCharToMultiByte.cs" />
+    <SecuritySources Include="$(CoreFxSourcesRoot)\Interop\Windows\kernel32\Interop.WideCharToMultiByte.cs" />
     <SecuritySources Include="$(CoreFxSourcesRoot)\Interop\Windows\oleaut32\Interop.SysAllocStringLen.cs" />
     <SecuritySources Include="$(CoreFxSourcesRoot)\Interop\Windows\oleaut32\Interop.SysStringLen.cs" />
   </ItemGroup>
index d5a5e96..3a8ca2d 100644 (file)
@@ -3309,7 +3309,9 @@ namespace System
         public System.String Trim() { throw null; }
         public System.String Trim(params char[] trimChars) { throw null; }
         public System.String TrimEnd(params char[] trimChars) { throw null; }
+        public System.String TrimEnd() { throw null; }
         public System.String TrimStart(params char[] trimChars) { throw null; }
+        public System.String TrimStart() { throw null; }
     }
     [System.Runtime.InteropServices.ComVisibleAttribute(true)]
     public abstract partial class StringComparer : System.Collections.Generic.IComparer<string>, System.Collections.Generic.IEqualityComparer<string>, System.Collections.IComparer, System.Collections.IEqualityComparer
index 6f8bb22..833dab0 100644 (file)
@@ -15,16 +15,20 @@ namespace System
 
         public ByReference(ref T value)
         {
-            // TODO-SPAN: This has GC hole. It needs to be JIT intrinsic instead
-            unsafe { _value = (IntPtr)Unsafe.AsPointer(ref value); }
+            // Implemented as a JIT intrinsic - This default implementation is for 
+            // completeness and to provide a concrete error if called via reflection
+            // or if intrinsic is missed.
+            throw new System.PlatformNotSupportedException();
         }
 
         public ref T Value
         {
             get
             {
-                // TODO-SPAN: This has GC hole. It needs to be JIT intrinsic instead
-                unsafe { return ref Unsafe.As<IntPtr, T>(ref *(IntPtr*)_value); }
+                // Implemented as a JIT intrinsic - This default implementation is for 
+                // completeness and to provide a concrete error if called via reflection
+                // or if the intrinsic is missed.
+                throw new System.PlatformNotSupportedException();
             }
         }
     }
index 4380369..627de8d 100644 (file)
@@ -21,7 +21,7 @@ namespace System.Runtime.InteropServices.WindowsRuntime
 
     internal static class UnsafeNativeMethods
     {
-        [DllImport("api-ms-win-core-winrt-error-l1-1-1.dll", PreserveSig = false)]
+        [DllImport("api-ms-win-core-winrt-error-l1-1-0.dll", PreserveSig = false)]
         [SuppressUnmanagedCodeSecurity]
         internal static extern IRestrictedErrorInfo GetRestrictedErrorInfo();
 
index 194b4f8..51007ba 100644 (file)
@@ -1553,8 +1553,11 @@ namespace System
             }
             return TrimHelper(trimChars,TrimHead);
         }
-    
-    
+
+        // Removes a set of characters from the beginning of this string.
+        public String TrimStart() => TrimHelper(TrimHead);
+        
+
         // Removes a set of characters from the end of this string.
         public String TrimEnd(params char[] trimChars) {
             if (null==trimChars || trimChars.Length == 0) {
@@ -1562,6 +1565,10 @@ namespace System
             }
             return TrimHelper(trimChars,TrimTail);
         }
+        
+        // Removes a set of characters from the end of this string.
+        public String TrimEnd()=> TrimHelper(TrimTail);
+        
 
         // Trims the whitespace from both ends of the string.  Whitespace is defined by
         // Char.IsWhiteSpace.
index fe9e0de..2caa4f2 100644 (file)
@@ -864,12 +864,19 @@ namespace System.Threading
         /// <param name="token2">The second <see cref="T:System.Threading.CancellationToken">CancellationToken</see> to observe.</param>
         /// <returns>A <see cref="T:System.Threading.CancellationTokenSource">CancellationTokenSource</see> that is linked 
         /// to the source tokens.</returns>
-        public static CancellationTokenSource CreateLinkedTokenSource(CancellationToken token1, CancellationToken token2)
-        {
-            return token1.CanBeCanceled || token2.CanBeCanceled ?
-                new LinkedCancellationTokenSource(token1, token2) :
-                new CancellationTokenSource();
-        }
+        public static CancellationTokenSource CreateLinkedTokenSource(CancellationToken token1, CancellationToken token2) =>
+            !token1.CanBeCanceled ? CreateLinkedTokenSource(token2) :
+            token2.CanBeCanceled ? new Linked2CancellationTokenSource(token1, token2) :
+            (CancellationTokenSource)new Linked1CancellationTokenSource(token1);
+
+        /// <summary>
+        /// Creates a <see cref="CancellationTokenSource"/> that will be in the canceled state
+        /// when any of the source tokens are in the canceled state.
+        /// </summary>
+        /// <param name="token">The first <see cref="T:System.Threading.CancellationToken">CancellationToken</see> to observe.</param>
+        /// <returns>A <see cref="CancellationTokenSource"/> that is linked to the source tokens.</returns>
+        internal static CancellationTokenSource CreateLinkedTokenSource(CancellationToken token) =>
+            token.CanBeCanceled ? new Linked1CancellationTokenSource(token) : new CancellationTokenSource();
 
         /// <summary>
         /// Creates a <see cref="T:System.Threading.CancellationTokenSource">CancellationTokenSource</see> that will be in the canceled state
@@ -884,14 +891,19 @@ namespace System.Threading
             if (tokens == null)
                 throw new ArgumentNullException(nameof(tokens));
 
-            if (tokens.Length == 0)
-                throw new ArgumentException(Environment.GetResourceString("CancellationToken_CreateLinkedToken_TokensIsEmpty"));
-
-            // a defensive copy is not required as the array has value-items that have only a single IntPtr field,
-            // hence each item cannot be null itself, and reads of the payloads cannot be torn.
-            Contract.EndContractBlock();
-
-            return new LinkedCancellationTokenSource(tokens);
+            switch (tokens.Length)
+            {
+                case 0:
+                    throw new ArgumentException(Environment.GetResourceString("CancellationToken_CreateLinkedToken_TokensIsEmpty"));
+                case 1:
+                    return CreateLinkedTokenSource(tokens[0]);
+                case 2:
+                    return CreateLinkedTokenSource(tokens[0], tokens[1]);
+                default:
+                    // a defensive copy is not required as the array has value-items that have only a single reference field,
+                    // hence each item cannot be null itself, and reads of the payloads cannot be torn.
+                    return new LinkedNCancellationTokenSource(tokens);
+            }
         }
 
 
@@ -907,35 +919,50 @@ namespace System.Threading
             }
         }
 
-        private sealed class LinkedCancellationTokenSource : CancellationTokenSource
+        private sealed class Linked1CancellationTokenSource : CancellationTokenSource
         {
-            private static readonly Action<object> s_linkedTokenCancelDelegate = 
-                s => ((CancellationTokenSource)s).NotifyCancellation(throwOnFirstException: false); // skip ThrowIfDisposed() check in Cancel()
-            private CancellationTokenRegistration[] m_linkingRegistrations;
+            private readonly CancellationTokenRegistration _reg1;
 
-            internal LinkedCancellationTokenSource(CancellationToken token1, CancellationToken token2)
+            internal Linked1CancellationTokenSource(CancellationToken token1)
             {
-                bool token2CanBeCanceled = token2.CanBeCanceled;
+                _reg1 = token1.InternalRegisterWithoutEC(LinkedNCancellationTokenSource.s_linkedTokenCancelDelegate, this);
+            }
 
-                if (token1.CanBeCanceled)
-                {
-                    m_linkingRegistrations = new CancellationTokenRegistration[token2CanBeCanceled ? 2 : 1]; // there will be at least 1 and at most 2 linkings
-                    m_linkingRegistrations[0] = token1.InternalRegisterWithoutEC(s_linkedTokenCancelDelegate, this);
-                }
+            protected override void Dispose(bool disposing)
+            {
+                if (!disposing || m_disposed) return;
+                _reg1.Dispose();
+                base.Dispose(disposing);
+            }
+        }
 
-                if (token2CanBeCanceled)
-                {
-                    int index = 1;
-                    if (m_linkingRegistrations == null)
-                    {
-                        m_linkingRegistrations = new CancellationTokenRegistration[1]; // this will be the only linking
-                        index = 0;
-                    }
-                    m_linkingRegistrations[index] = token2.InternalRegisterWithoutEC(s_linkedTokenCancelDelegate, this);
-                }
+        private sealed class Linked2CancellationTokenSource : CancellationTokenSource
+        {
+            private readonly CancellationTokenRegistration _reg1;
+            private readonly CancellationTokenRegistration _reg2;
+
+            internal Linked2CancellationTokenSource(CancellationToken token1, CancellationToken token2)
+            {
+                _reg1 = token1.InternalRegisterWithoutEC(LinkedNCancellationTokenSource.s_linkedTokenCancelDelegate, this);
+                _reg2 = token2.InternalRegisterWithoutEC(LinkedNCancellationTokenSource.s_linkedTokenCancelDelegate, this);
             }
 
-            internal LinkedCancellationTokenSource(params CancellationToken[] tokens)
+            protected override void Dispose(bool disposing)
+            {
+                if (!disposing || m_disposed) return;
+                _reg1.Dispose();
+                _reg2.Dispose();
+                base.Dispose(disposing);
+            }
+        }
+
+        private sealed class LinkedNCancellationTokenSource : CancellationTokenSource
+        {
+            internal static readonly Action<object> s_linkedTokenCancelDelegate =
+                s => ((CancellationTokenSource)s).NotifyCancellation(throwOnFirstException: false); // skip ThrowIfDisposed() check in Cancel()
+            private CancellationTokenRegistration[] m_linkingRegistrations;
+
+            internal LinkedNCancellationTokenSource(params CancellationToken[] tokens)
             {
                 m_linkingRegistrations = new CancellationTokenRegistration[tokens.Length];
 
@@ -968,7 +995,6 @@ namespace System.Threading
 
                 base.Dispose(disposing);
             }
-
         }
     }
 
index 24a57fa..b385f06 100644 (file)
@@ -147,7 +147,6 @@ namespace System.Threading.Tasks
         private static StackGuard t_stackGuard;  // The stack guard object for this thread
 
         internal static int s_taskIdCounter; //static counter used to generate unique task IDs
-        private readonly static TaskFactory s_factory = new TaskFactory();
 
         private volatile int m_taskId; // this task's unique ID. initialized only if it is ever requested
 
@@ -1615,23 +1614,10 @@ namespace System.Threading.Tasks
         /// of <see cref="System.Threading.Tasks.TaskFactory"/>, as would result from using
         /// the default constructor on TaskFactory.
         /// </remarks>
-        public static TaskFactory Factory { get { return s_factory; } }
-
-        /// <summary>A task that's already been completed successfully.</summary>
-        private static Task s_completedTask;
+        public static TaskFactory Factory { get; } = new TaskFactory();
 
         /// <summary>Gets a task that's already been completed successfully.</summary>
-        /// <remarks>May not always return the same instance.</remarks>        
-        public static Task CompletedTask
-        {
-            get
-            {
-                var completedTask = s_completedTask;
-                if (completedTask == null)
-                    s_completedTask = completedTask = new Task(false, (TaskCreationOptions)InternalTaskOptions.DoNotDispose, default(CancellationToken)); // benign initialization race condition
-                return completedTask;
-            }
-        }
+        public static Task CompletedTask { get; } = new Task(false, (TaskCreationOptions)InternalTaskOptions.DoNotDispose, default(CancellationToken));
 
         /// <summary>
         /// Provides an event that can be used to wait for completion.
index 51ac5b9..a449ba7 100644 (file)
@@ -6496,8 +6496,8 @@ public:
 
 typedef BOOL (PALAPI *PHARDWARE_EXCEPTION_HANDLER)(PAL_SEHException* ex);
 typedef BOOL (PALAPI *PHARDWARE_EXCEPTION_SAFETY_CHECK_FUNCTION)(PCONTEXT contextRecord, PEXCEPTION_RECORD exceptionRecord);
-typedef VOID (PALAPI *PTERMINATION_REQUEST_HANDLER)();
-typedef DWORD (PALAPI *PGET_GCMARKER_EXCEPTION_CODE)(LPVOID ip);
+typedef VOID (*PTERMINATION_REQUEST_HANDLER)();
+typedef DWORD (*PGET_GCMARKER_EXCEPTION_CODE)(LPVOID ip);
 
 PALIMPORT
 VOID
index 9fdddd6..4a64fcf 100644 (file)
@@ -432,6 +432,8 @@ elseif(CLR_CMAKE_TARGET_ARCH_I386)
     set(VM_SOURCES_WKS_ARCH
         ${ARCH_SOURCES_DIR}/jitinterfacex86.cpp
         ${ARCH_SOURCES_DIR}/profiler.cpp
+        exceptionhandling.cpp
+        gcinfodecoder.cpp
     )
 elseif(CLR_CMAKE_TARGET_ARCH_ARM)
     set(VM_SOURCES_DAC_AND_WKS_ARCH
index d8f6c85..e90217f 100644 (file)
@@ -176,8 +176,10 @@ public:
     {
         LIMITED_METHOD_CONTRACT;
 
+        // SPAN-TODO: GC reporting - https://github.com/dotnet/coreclr/issues/8517
+
        _ASSERTE(IsStructPassedInRegs());
-     
+
         TADDR genRegDest = dac_cast<TADDR>(GetStructGenRegDestinationAddress());
         INDEBUG(int remainingBytes = fieldBytes;)
 
index 65dc513..04d7527 100644 (file)
@@ -1392,8 +1392,6 @@ DelayLoad_MethodCall:
 
     .macro DynamicHelper frameFlags, suffix
 
-__FakePrologName="DelayLoad_Helper\suffix\()_FakeProlog"
-
         NESTED_ENTRY DelayLoad_Helper\suffix\()_FakeProlog, _TEXT, NoHandler
 
         // Match what the lazy thunk has pushed. The actual method arguments will be spilled later.
index cdb7cc8..c615d66 100644 (file)
@@ -3020,7 +3020,7 @@ void * EEJitManager::allocCodeFragmentBlock(size_t blockSize, unsigned alignment
     {
         CrstHolder ch(&m_CodeHeapCritSec);
 
-        mem = (TADDR) allocCodeRaw(&requestInfo, sizeof(TADDR), blockSize, alignment, &pCodeHeap);
+        mem = (TADDR) allocCodeRaw(&requestInfo, sizeof(CodeHeader), blockSize, alignment, &pCodeHeap);
 
         // CodeHeader comes immediately before the block
         CodeHeader * pCodeHdr = (CodeHeader *) (mem - sizeof(CodeHeader));
index 0fe261a..5fb8da1 100644 (file)
@@ -69,6 +69,10 @@ Abstract:
 #include "pedecoder.h"
 #include "gcinfo.h"
 
+#if defined(WIN64EXCEPTIONS) && !defined(USE_INDIRECT_CODEHEADER)
+#error "WIN64EXCEPTIONS requires USE_INDIRECT_CODEHEADER"
+#endif // WIN64EXCEPTIONS && !USE_INDIRECT_CODEHEADER
+
 class MethodDesc;
 class ICorJitCompiler;
 class IJitManager;
index 2ce7b59..16b9de4 100644 (file)
@@ -3048,7 +3048,7 @@ unsigned SKIP_ALLOC_FRAME(int size, PTR_CBYTE base, unsigned offset)
 #endif // !USE_GC_INFO_DECODER
 
 
-#if !defined(_TARGET_X86_) && !defined(CROSSGEN_COMPILE)
+#if defined(WIN64EXCEPTIONS) && !defined(CROSSGEN_COMPILE)
 
 void EECodeManager::EnsureCallerContextIsValid( PREGDISPLAY  pRD, StackwalkCacheEntry* pCacheEntry, EECodeInfo * pCodeInfo /*= NULL*/ )
 {
@@ -3105,7 +3105,7 @@ size_t EECodeManager::GetCallerSp( PREGDISPLAY  pRD )
     return (size_t) (GetSP(pRD->pCallerContext));
 }
 
-#endif // !defined(_TARGET_X86_) && !defined(CROSSGEN_COMPILE)
+#endif // WIN64EXCEPTIONS && !CROSSGEN_COMPILE
 
 /*
   *  Light unwind the current stack frame, using provided cache entry.
@@ -5360,6 +5360,7 @@ PTR_VOID EECodeManager::GetExactGenericsToken(SIZE_T          baseStackSlot,
 {
     LIMITED_METHOD_DAC_CONTRACT;
 
+#ifdef USE_GC_INFO_DECODER
     GCInfoToken gcInfoToken = pCodeInfo->GetGCInfoToken();
 
     GcInfoDecoder gcInfoDecoder(
@@ -5409,6 +5410,10 @@ PTR_VOID EECodeManager::GetExactGenericsToken(SIZE_T          baseStackSlot,
         return PTR_VOID(taExactGenericsToken);
     }
     return NULL;
+#else // USE_GC_INFO_DECODER
+    PORTABILITY_ASSERT("EECodeManager::GetExactGenericsToken");
+    return NULL;
+#endif // USE_GC_INFO_DECODER
 }
 
 
index 5a6f7c6..0346c85 100644 (file)
@@ -7264,11 +7264,13 @@ IsDebuggerFault(EXCEPTION_RECORD *pExceptionRecord,
 
 #ifdef WIN64EXCEPTIONS
 
+#ifndef _TARGET_X86_
 EXTERN_C void JIT_MemSet_End();
 EXTERN_C void JIT_MemCpy_End();
 
 EXTERN_C void JIT_WriteBarrier_End();
 EXTERN_C void JIT_CheckedWriteBarrier_End();
+#endif // _TARGET_X86_
 
 #if defined(_TARGET_AMD64_) && defined(_DEBUG)
 EXTERN_C void JIT_WriteBarrier_Debug();
@@ -7288,11 +7290,13 @@ bool IsIPInMarkedJitHelper(UINT_PTR uControlPc)
 #define CHECK_RANGE(name) \
     if (GetEEFuncEntryPoint(name) <= uControlPc && uControlPc < GetEEFuncEntryPoint(name##_End)) return true;
 
+#ifndef _TARGET_X86_
     CHECK_RANGE(JIT_MemSet)
     CHECK_RANGE(JIT_MemCpy)
 
     CHECK_RANGE(JIT_WriteBarrier)
     CHECK_RANGE(JIT_CheckedWriteBarrier)
+#endif // _TARGET_X86_
 
 #if defined(_TARGET_AMD64_) && defined(_DEBUG)
     CHECK_RANGE(JIT_WriteBarrier_Debug)
@@ -7314,8 +7318,7 @@ AdjustContextForWriteBarrier(
 {
     WRAPPER_NO_CONTRACT;
 
-#ifdef _TARGET_X86_
-
+#if defined(_TARGET_X86_) && !defined(PLATFORM_UNIX)
     void* f_IP = (void *)GetIP(pContext);
 
     if (((f_IP >= (void *) JIT_WriteBarrierStart) && (f_IP <= (void *) JIT_WriteBarrierLast)) ||
@@ -7329,11 +7332,8 @@ AdjustContextForWriteBarrier(
         // put ESP back to what it was before the call.
         SetSP(pContext, PCODE((BYTE*)GetSP(pContext) + sizeof(void*)));
     }
-
     return FALSE;
-
-#elif defined(WIN64EXCEPTIONS)
-
+#elif defined(WIN64EXCEPTIONS) // _TARGET_X86_ && !PLATFORM_UNIX
     void* f_IP = dac_cast<PTR_VOID>(GetIP(pContext));
 
     CONTEXT             tempContext;
@@ -7377,7 +7377,7 @@ AdjustContextForWriteBarrier(
        // Now we save the address back into the context so that it gets used
        // as the faulting address.
        SetIP(pContext, ControlPCPostAdjustment);
-#endif // _TARGET_ARM_
+#endif // _TARGET_ARM_ || _TARGET_ARM64_
 
         // Unwind the frame chain - On Win64, this is required since we may handle the managed fault and to do so,
         // we will replace the exception context with the managed context and "continue execution" there. Thus, we do not
@@ -7399,13 +7399,10 @@ AdjustContextForWriteBarrier(
     }
 
     return FALSE;
-
-#else // ! _X86_ && !WIN64EXCEPTIONS
-
-    PORTABILITY_WARNING("AdjustContextForWriteBarrier() not implemented on this platform");
+#else // WIN64EXCEPTIONS
+    PORTABILITY_ASSERT("AdjustContextForWriteBarrier");
     return FALSE;
-
-#endif
+#endif // ELSE
 }
 
 struct SavedExceptionInfo
@@ -7556,20 +7553,21 @@ void InitSavedExceptionInfo()
 void FaultingExceptionFrame::Init(CONTEXT *pContext)
 {
     WRAPPER_NO_CONTRACT;
-#if defined(_TARGET_X86_)
+#ifndef WIN64EXCEPTIONS
+#ifdef _TARGET_X86_
     CalleeSavedRegisters *pRegs = GetCalleeSavedRegisters();
-    pRegs->ebp = pContext->Ebp;
-    pRegs->ebx = pContext->Ebx;
-    pRegs->esi = pContext->Esi;
-    pRegs->edi = pContext->Edi;
+#define CALLEE_SAVED_REGISTER(regname) pRegs->regname = pContext->regname;
+    ENUM_CALLEE_SAVED_REGISTERS();
+#undef CALLEE_SAVED_REGISTER
     m_ReturnAddress = ::GetIP(pContext);
     m_Esp = (DWORD)GetSP(pContext);
-#elif defined(WIN64EXCEPTIONS)
+#else // _TARGET_X86_
+    PORTABILITY_ASSERT("FaultingExceptionFrame::Init");
+#endif // _TARGET_???_ (ELSE)
+#else // !WIN64EXCEPTIONS
     m_ReturnAddress = ::GetIP(pContext);
     CopyOSContext(&m_ctx, pContext);
-#else
-    PORTABILITY_ASSERT("FaultingExceptionFrame::InitAndLink");
-#endif
+#endif // !WIN64EXCEPTIONS
 }
 
 //
@@ -8986,11 +8984,13 @@ LONG ReflectionInvocationExceptionFilter(
 #else // !(_WIN64 || _TARGET_X86_)
 #error Unsupported platform
 #endif // _WIN64
-        
+
+#ifdef FEATURE_CORRUPTING_EXCEPTIONS
         if (pEHTracker->GetCorruptionSeverity() == ProcessCorrupting)
         {
             EEPolicy::HandleFatalError(COR_E_FAILFAST, reinterpret_cast<UINT_PTR>(pExceptionInfo->ExceptionRecord->ExceptionAddress), NULL, pExceptionInfo);
         }
+#endif // FEATURE_CORRUPTING_EXCEPTIONS
     }
 
     return ret;
@@ -13111,9 +13111,9 @@ StackWalkAction TAResetStateCallback(CrawlFrame* pCf, void* data)
 // there is no more managed code on the stack.
 //
 // Note: This function should be invoked ONLY during unwind.
-#if defined(_TARGET_X86_)
+#ifndef WIN64EXCEPTIONS
 void ResetThreadAbortState(PTR_Thread pThread, void *pEstablisherFrame)
-#elif defined(WIN64EXCEPTIONS)
+#else
 void ResetThreadAbortState(PTR_Thread pThread, CrawlFrame *pCf, StackFrame sfCurrentStackFrame)
 #endif
 {
@@ -13123,9 +13123,9 @@ void ResetThreadAbortState(PTR_Thread pThread, CrawlFrame *pCf, StackFrame sfCur
         GC_NOTRIGGER;
         MODE_ANY;
         PRECONDITION(pThread != NULL);
-#if defined(_TARGET_X86_)
+#ifndef WIN64EXCEPTIONS
         PRECONDITION(pEstablisherFrame != NULL);
-#elif defined(WIN64EXCEPTIONS)
+#else
         PRECONDITION(pCf != NULL);
         PRECONDITION(!sfCurrentStackFrame.IsNull());
 #endif
@@ -13136,14 +13136,14 @@ void ResetThreadAbortState(PTR_Thread pThread, CrawlFrame *pCf, StackFrame sfCur
 
     if (pThread->IsAbortRequested())
     {
-#if defined(_TARGET_X86_)
+#ifndef WIN64EXCEPTIONS
         if (GetNextCOMPlusSEHRecord(static_cast<EXCEPTION_REGISTRATION_RECORD *>(pEstablisherFrame)) == EXCEPTION_CHAIN_END)
         {
             // Topmost handler and abort requested.
             fResetThreadAbortState = TRUE;
             LOG((LF_EH, LL_INFO100, "ResetThreadAbortState: Topmost handler resets abort as no more managed code beyond %p.\n", pEstablisherFrame));
         }
-#elif defined(WIN64EXCEPTIONS)
+#else // !WIN64EXCEPTIONS
         // Get the active exception tracker
         PTR_ExceptionTracker pCurEHTracker = pThread->GetExceptionState()->GetCurrentExceptionTracker();
         _ASSERTE(pCurEHTracker != NULL);
@@ -13198,9 +13198,7 @@ void ResetThreadAbortState(PTR_Thread pThread, CrawlFrame *pCf, StackFrame sfCur
             LOG((LF_EH, LL_INFO100, "ResetThreadAbortState: Resetting thread abort state since there is no more managed code beyond stack frames:\n"));
             LOG((LF_EH, LL_INFO100, "sf.SP = %p   ", dataCallback.sfSeedCrawlFrame.SP));
         }
-#else // WIN64EXCEPTIONS
-#error Unsupported platform
-#endif // WIN64EXCEPTIONS
+#endif // !WIN64EXCEPTIONS
     }
 
     if (fResetThreadAbortState)
index e50a770..53fa201 100644 (file)
@@ -415,7 +415,7 @@ VOID DECLSPEC_NORETURN RealCOMPlusThrowInvalidCastException(TypeHandle thCastFro
 VOID DECLSPEC_NORETURN RealCOMPlusThrowInvalidCastException(OBJECTREF *pObj, TypeHandle thCastTo);
 
 
-#ifdef _TARGET_X86_
+#ifndef WIN64EXCEPTIONS
 
 #include "eexcp.h"
 #include "exinfo.h"
@@ -454,7 +454,7 @@ struct NestedHandlerExRecord : public FrameHandlerExRecord
     }
 };
 
-#endif // _TARGET_X86_
+#endif // !WIN64EXCEPTIONS
 
 #if defined(ENABLE_CONTRACTS_IMPL)
 
@@ -520,10 +520,6 @@ extern "C" BOOL ExceptionIsOfRightType(TypeHandle clauseType, TypeHandle thrownT
 // The stuff below is what works "behind the scenes" of the public macros.
 //==========================================================================
 
-#ifdef _TARGET_X86_
-LPVOID COMPlusEndCatchWorker(Thread *pCurThread);
-EXTERN_C LPVOID STDCALL COMPlusEndCatch(LPVOID ebp, DWORD ebx, DWORD edi, DWORD esi, LPVOID* pRetAddress);
-#endif
 
 // Specify NULL for uTryCatchResumeAddress when not checking for a InducedThreadRedirectAtEndOfCatch
 EXTERN_C LPVOID COMPlusCheckForAbort(UINT_PTR uTryCatchResumeAddress = NULL);
@@ -946,9 +942,9 @@ public:
 
 #ifndef DACCESS_COMPILE
 
-#if defined(_TARGET_X86_)
+#ifndef WIN64EXCEPTIONS
 void ResetThreadAbortState(PTR_Thread pThread, void *pEstablisherFrame);
-#elif defined(WIN64EXCEPTIONS)
+#else
 void ResetThreadAbortState(PTR_Thread pThread, CrawlFrame *pCf, StackFrame sfCurrentStackFrame);
 #endif
 
index 1a839be..475bf3b 100644 (file)
@@ -1293,7 +1293,11 @@ void ExceptionTracker::InitializeCurrentContextForCrawlFrame(CrawlFrame* pcfThis
         *(pRD->pCallerContext)      = *(pDispatcherContext->ContextRecord);
         pRD->IsCallerContextValid   = TRUE;
 
+#ifndef _TARGET_X86_
         pRD->SP = sfEstablisherFrame.SP;
+#else
+        pRD->Esp = sfEstablisherFrame.SP;
+#endif
         pRD->ControlPC = pDispatcherContext->ControlPc;
 
 #if defined(_TARGET_ARM_) || defined(_TARGET_ARM64_)    
@@ -4662,6 +4666,7 @@ VOID DECLSPEC_NORETURN DispatchManagedException(PAL_SEHException& ex, bool isHar
         ThreadExceptionState * pCurTES = pCurThread->GetExceptionState();
         _ASSERTE(pCurTES != NULL);
 
+#ifdef FEATURE_CORRUPTING_EXCEPTIONS
         ExceptionTracker* pEHTracker = pCurTES->GetCurrentExceptionTracker();
         if (pEHTracker == NULL)
         {
@@ -4673,6 +4678,7 @@ VOID DECLSPEC_NORETURN DispatchManagedException(PAL_SEHException& ex, bool isHar
 
             pCurTES->SetLastActiveExceptionCorruptionSeverity(severity);
         }
+#endif // FEATURE_CORRUPTING_EXCEPTIONS
     }
 
     throw std::move(ex);
index 9e07ceb..1ae011e 100644 (file)
@@ -9,6 +9,7 @@
 #include "exinfo.h"
 #include "dbginterface.h"
 
+#ifndef WIN64EXCEPTIONS
 #ifndef DACCESS_COMPILE
 //
 // Destroy the handle within an ExInfo. This respects the fact that we can have preallocated global handles living
@@ -312,3 +313,4 @@ void ExInfo::SetExceptionCode(const EXCEPTION_RECORD *pCER)
     DacError(E_UNEXPECTED);
 #endif // !DACCESS_COMPILE
 }
+#endif // !WIN64EXCEPTIONS
index bde71db..29c7a06 100644 (file)
@@ -498,7 +498,7 @@ BOOL DebuggerExState::SetDebuggerInterceptInfo(IJitManager *pJitManager,
 
     int nestingLevel = 0;
     
-#if defined(_TARGET_X86_)
+#ifndef WIN64EXCEPTIONS
     //
     // Get the SEH frame that covers this location on the stack. Note: we pass a skip count of 1. We know that when
     // this is called, there is a nested exception handler on pThread's stack that is only there during exception
@@ -517,11 +517,7 @@ BOOL DebuggerExState::SetDebuggerInterceptInfo(IJitManager *pJitManager,
     nestingLevel = ComputeEnclosingHandlerNestingLevel(pJitManager,
                                                            methodToken,
                                                            natOffset);
-#elif !defined(WIN64EXCEPTIONS)  
-    // !_TARGET_X86_ && !WIN64EXCEPTIONS
-    PORTABILITY_ASSERT("SetDebuggerInterceptInfo() (ExState.cpp) - continuable exceptions NYI\n");
-    return FALSE;
-#endif // !_TARGET_X86_
+#endif // !WIN64EXCEPTIONS
 
     //
     // These values will override the normal information used by the EH subsystem to handle the exception.
index 7c505b8..2702936 100644 (file)
@@ -51,10 +51,10 @@ public:
         m_pDebuggerContext = NULL;
         m_pDebuggerInterceptNativeOffset = 0;
 
+  #ifndef WIN64EXCEPTIONS
         // x86-specific fields
-  #if defined(_TARGET_X86_)      
         m_pDebuggerInterceptFrame = EXCEPTION_CHAIN_END;
-  #endif // defined(_TARGET_X86_)      
+  #endif // !WIN64EXCEPTIONS
         m_dDebuggerInterceptHandlerDepth  = 0;
     }
     
@@ -133,9 +133,9 @@ public:
     //
 
     void GetDebuggerInterceptInfo(
- #if defined(_TARGET_X86_)   
+ #ifndef WIN64EXCEPTIONS
                                   PEXCEPTION_REGISTRATION_RECORD *pEstablisherFrame,
- #endif // _TARGET_X86_   
+ #endif // !WIN64EXCEPTIONS
                                   MethodDesc **ppFunc,
                                   int *pdHandler,
                                   BYTE **ppStack,
@@ -144,12 +144,12 @@ public:
     {
         LIMITED_METHOD_CONTRACT;
   
-#if defined(_TARGET_X86_)
+#ifndef WIN64EXCEPTIONS
         if (pEstablisherFrame != NULL)
         {
             *pEstablisherFrame = m_pDebuggerInterceptFrame;
         }
-#endif // _TARGET_X86_
+#endif // !WIN64EXCEPTIONS
 
         if (ppFunc != NULL)
         {
@@ -195,10 +195,10 @@ private:
     ULONG_PTR       m_pDebuggerInterceptNativeOffset;
 
     // The remaining fields are only used on x86.
-#if defined(_TARGET_X86_)
+#ifndef WIN64EXCEPTIONS
     // the exception registration record covering the stack range containing the interception point
     PEXCEPTION_REGISTRATION_RECORD m_pDebuggerInterceptFrame;
-#endif // defined(_TARGET_X86_)
+#endif // !WIN64EXCEPTIONS
 
     // the nesting level at which we want to resume execution
     int             m_dDebuggerInterceptHandlerDepth;
index 91ab3c3..e37f980 100644 (file)
@@ -1114,17 +1114,19 @@ class FaultingExceptionFrame : public Frame
 {
     friend class CheckAsmOffsets;
 
-#if defined(_TARGET_X86_)
+#ifndef WIN64EXCEPTIONS
+#ifdef _TARGET_X86_
     DWORD                   m_Esp;
     CalleeSavedRegisters    m_regs;
     TADDR                   m_ReturnAddress;
-#endif
-
-#ifdef WIN64EXCEPTIONS
+#else  // _TARGET_X86_
+    #error "Unsupported architecture"
+#endif // _TARGET_X86_
+#else // WIN64EXCEPTIONS
     BOOL                    m_fFilterExecuted;  // Flag for FirstCallToHandler
     TADDR                   m_ReturnAddress;
     T_CONTEXT               m_ctx;
-#endif // WIN64EXCEPTIONS
+#endif // !WIN64EXCEPTIONS
 
     VPTR_VTABLE_CLASS(FaultingExceptionFrame, Frame)
 
@@ -1156,13 +1158,17 @@ public:
         return FRAME_ATTR_EXCEPTION | FRAME_ATTR_FAULTED;
     }
 
-#if defined(_TARGET_X86_)
+#ifndef WIN64EXCEPTIONS
     CalleeSavedRegisters *GetCalleeSavedRegisters()
     {
+#ifdef _TARGET_X86_
         LIMITED_METHOD_DAC_CONTRACT;
         return &m_regs;
+#else
+        PORTABILITY_ASSERT("GetCalleeSavedRegisters");
+#endif // _TARGET_X86_
     }
-#endif
+#endif // WIN64EXCEPTIONS
 
 #ifdef WIN64EXCEPTIONS
     T_CONTEXT *GetExceptionContext ()
index 5fb83bf..792e748 100644 (file)
@@ -204,6 +204,7 @@ bool FindFirstInterruptiblePointStateCB(
 // the end is exclusive). Return -1 if no such point exists.
 unsigned FindFirstInterruptiblePoint(CrawlFrame* pCF, unsigned offs, unsigned endOffs)
 {
+#ifdef USE_GC_INFO_DECODER
     GCInfoToken gcInfoToken = pCF->GetGCInfoToken();
     GcInfoDecoder gcInfoDecoder(gcInfoToken, DECODE_FOR_RANGES_CALLBACK);
 
@@ -215,6 +216,10 @@ unsigned FindFirstInterruptiblePoint(CrawlFrame* pCF, unsigned offs, unsigned en
     gcInfoDecoder.EnumerateInterruptibleRanges(&FindFirstInterruptiblePointStateCB, &state);
 
     return state.returnOffs;
+#else
+    PORTABILITY_ASSERT("FindFirstInterruptiblePoint");
+    return -1;
+#endif // USE_GC_INFO_DECODER
 }
 
 #endif // WIN64EXCEPTIONS
@@ -283,7 +288,7 @@ StackWalkAction GcStackCrawlCallBack(CrawlFrame* pCF, VOID* pData)
     #endif // _DEBUG
 
             DWORD relOffsetOverride = NO_OVERRIDE_OFFSET;
-#if defined(WIN64EXCEPTIONS)
+#if defined(WIN64EXCEPTIONS) && defined(USE_GC_INFO_DECODER)
             if (pCF->ShouldParentToFuncletUseUnwindTargetLocationForGCReporting())
             {
                 GCInfoToken gcInfoToken = pCF->GetGCInfoToken();
@@ -313,7 +318,7 @@ StackWalkAction GcStackCrawlCallBack(CrawlFrame* pCF, VOID* pData)
                 }
 
             }
-#endif // WIN64EXCEPTIONS
+#endif // WIN64EXCEPTIONS && USE_GC_INFO_DECODER
 
             pCM->EnumGcRefs(pCF->GetRegisterSet(),
                             pCF->GetCodeInfo(),
index 99f4eb4..2c29d27 100644 (file)
@@ -86,6 +86,10 @@ BOOL Runtime_Test_For_SSE2();
 #define JUMP_ALLOCATE_SIZE                      8   // # bytes to allocate for a jump instruction
 #define BACK_TO_BACK_JUMP_ALLOCATE_SIZE         8   // # bytes to allocate for a back to back jump instruction
 
+#ifdef WIN64EXCEPTIONS
+#define USE_INDIRECT_CODEHEADER
+#endif // WIN64EXCEPTIONS
+
 #define HAS_COMPACT_ENTRYPOINTS                 1
 
 // Needed for PInvoke inlining in ngened images
@@ -150,12 +154,17 @@ typedef INT32 StackElemType;
 // This represents some of the FramedMethodFrame fields that are
 // stored at negative offsets.
 //--------------------------------------------------------------------
+#define ENUM_CALLEE_SAVED_REGISTERS() \
+    CALLEE_SAVED_REGISTER(Edi) \
+    CALLEE_SAVED_REGISTER(Esi) \
+    CALLEE_SAVED_REGISTER(Ebx) \
+    CALLEE_SAVED_REGISTER(Ebp)
+
 typedef DPTR(struct CalleeSavedRegisters) PTR_CalleeSavedRegisters;
 struct CalleeSavedRegisters {
-    INT32       edi;
-    INT32       esi;
-    INT32       ebx;
-    INT32       ebp;
+#define CALLEE_SAVED_REGISTER(regname) INT32 regname;
+    ENUM_CALLEE_SAVED_REGISTERS();
+#undef CALLEE_SAVED_REGISTER
 };
 
 //--------------------------------------------------------------------
index 08ccd01..55f8459 100644 (file)
@@ -296,10 +296,9 @@ void TransitionFrame::UpdateRegDisplayHelper(const PREGDISPLAY pRD, UINT cbStack
 
     pRD->pContext = NULL;
 
-    pRD->pEdi = (DWORD*) &regs->edi;
-    pRD->pEsi = (DWORD*) &regs->esi;
-    pRD->pEbx = (DWORD*) &regs->ebx;
-    pRD->pEbp = (DWORD*) &regs->ebp;
+#define CALLEE_SAVED_REGISTER(regname) pRD->p##regname = (DWORD*) &regs->regname;
+    ENUM_CALLEE_SAVED_REGISTERS();
+#undef CALLEE_SAVED_REGISTER
     pRD->PCTAddr = GetReturnAddressPtr();
     pRD->ControlPC = *PTR_PCODE(pRD->PCTAddr);
     pRD->Esp  = (DWORD)(pRD->PCTAddr + sizeof(TADDR) + cbStackPop);
@@ -509,18 +508,33 @@ void FaultingExceptionFrame::UpdateRegDisplay(const PREGDISPLAY pRD)
     }
     CONTRACT_END;
 
+#ifndef WIN64EXCEPTIONS
     CalleeSavedRegisters* regs = GetCalleeSavedRegisters();
 
     // reset pContext; it's only valid for active (top-most) frame
     pRD->pContext = NULL;
 
-    pRD->pEdi = (DWORD*) &regs->edi;
-    pRD->pEsi = (DWORD*) &regs->esi;
-    pRD->pEbx = (DWORD*) &regs->ebx;
-    pRD->pEbp = (DWORD*) &regs->ebp;
+#define CALLEE_SAVED_REGISTER(regname) pRD->p##regname = (DWORD*) &regs->regname;
+    ENUM_CALLEE_SAVED_REGISTERS();
+#undef CALLEE_SAVED_REGISTER
+    pRD->Esp = m_Esp;
     pRD->PCTAddr = GetReturnAddressPtr();
     pRD->ControlPC = *PTR_PCODE(pRD->PCTAddr);
-    pRD->Esp = m_Esp;
+#else
+    memcpy(pRD->pCurrentContext, &m_ctx, sizeof(CONTEXT));
+
+    pRD->ControlPC = m_ctx.Eip;
+
+    pRD->Esp = m_ctx.Esp;
+
+    pRD->pCurrentContextPointers->Ebx = &m_ctx.Ebx;
+    pRD->pCurrentContextPointers->Edi = &m_ctx.Edi;
+    pRD->pCurrentContextPointers->Esi = &m_ctx.Esi;
+    pRD->pCurrentContextPointers->Ebp = &m_ctx.Ebp;
+
+    pRD->IsCallerContextValid = FALSE;
+    pRD->IsCallerSPValid      = FALSE;        // Don't add usage of this field.  This is only temporary.
+#endif // WIN64EXCEPTIONS
     RETURN;
 }
 
@@ -606,6 +620,7 @@ void ResumableFrame::UpdateRegDisplay(const PREGDISPLAY pRD)
 
     CONTEXT* pUnwoundContext = m_Regs;
 
+#ifndef WIN64EXCEPTIONS
 #if !defined(DACCESS_COMPILE)
     // "pContextForUnwind" field is only used on X86 since not only is it initialized just for it,
     // but its used only under the confines of STACKWALKER_MAY_POP_FRAMES preprocessor define,
@@ -625,6 +640,7 @@ void ResumableFrame::UpdateRegDisplay(const PREGDISPLAY pRD)
         pUnwoundContext->Eip = m_Regs->Eip;
     }
 #endif // !defined(DACCESS_COMPILE)
+#endif // !WIN64EXCEPTIONS
 
     pRD->pEax = &pUnwoundContext->Eax;
     pRD->pEcx = &pUnwoundContext->Ecx;
@@ -705,10 +721,9 @@ void TailCallFrame::UpdateRegDisplay(const PREGDISPLAY pRD)
     // reset pContext; it's only valid for active (top-most) frame
     pRD->pContext = NULL;
 
-    pRD->pEdi = (DWORD*)&m_regs.edi;
-    pRD->pEsi = (DWORD*)&m_regs.esi;
-    pRD->pEbx = (DWORD*)&m_regs.ebx;
-    pRD->pEbp = (DWORD*)&m_regs.ebp;
+#define CALLEE_SAVED_REGISTER(regname) pRD->p##regname = (DWORD*) &m_regs.regname;
+    ENUM_CALLEE_SAVED_REGISTERS();
+#undef CALLEE_SAVED_REGISTER
 
     pRD->PCTAddr = GetReturnAddressPtr();
     pRD->ControlPC = *PTR_PCODE(pRD->PCTAddr);
@@ -1058,7 +1073,7 @@ public:
     {
         LIMITED_METHOD_CONTRACT;
         return offsetof(StubForHostStackFrame, m_calleeSavedRegisters) + 
-               offsetof(CalleeSavedRegisters, ebp); 
+               offsetof(CalleeSavedRegisters, Ebp);
     }
 
     static INT32 GetFPrelOffsOfArgumentRegisters() 
index ff540e7..d70c662 100644 (file)
@@ -21,6 +21,7 @@
 
 #define STATUS_CLR_GCCOVER_CODE         STATUS_PRIVILEGED_INSTRUCTION
 
+#ifndef WIN64EXCEPTIONS
 class Thread;
 
 #if defined(_MSC_VER)
@@ -28,19 +29,6 @@ class Thread;
                               // Actually, the handler getting set is properly registered
 #endif
 
-#ifdef FEATURE_PAL
-
-extern VOID SetSEHRecord(PEXCEPTION_REGISTRATION_RECORD record);
-extern VOID ResetSEHRecord(PEXCEPTION_REGISTRATION_RECORD record);
-
-#define INSTALL_SEH_RECORD(record)                                        \
-    SetSEHRecord(record);                                                 \
-
-#define UNINSTALL_SEH_RECORD(record)                                      \
-    ResetSEHRecord(record);
-
-#else  // FEATURE_PAL
-
 #define INSTALL_SEH_RECORD(record)                                        \
     {                                                                     \
        (record)->Next = (PEXCEPTION_REGISTRATION_RECORD)__readfsdword(0); \
@@ -52,8 +40,6 @@ extern VOID ResetSEHRecord(PEXCEPTION_REGISTRATION_RECORD record);
         __writefsdword(0, (DWORD) ((record)->Next));                      \
     }
 
-#endif // FEATURE_PAL
-
 #define INSTALL_EXCEPTION_HANDLING_RECORD(record)               \
     {                                                           \
         PEXCEPTION_REGISTRATION_RECORD __record = (record);     \
@@ -90,14 +76,32 @@ extern VOID ResetSEHRecord(PEXCEPTION_REGISTRATION_RECORD record);
 
 #endif
 
+
+PEXCEPTION_REGISTRATION_RECORD GetCurrentSEHRecord();
+PEXCEPTION_REGISTRATION_RECORD GetFirstCOMPlusSEHRecord(Thread*);
+
+LPVOID COMPlusEndCatchWorker(Thread *pCurThread);
+EXTERN_C LPVOID STDCALL COMPlusEndCatch(LPVOID ebp, DWORD ebx, DWORD edi, DWORD esi, LPVOID* pRetAddress);
+
+#else // WIN64EXCEPTIONS
+#define INSTALL_EXCEPTION_HANDLING_RECORD(record)
+#define UNINSTALL_EXCEPTION_HANDLING_RECORD(record)
+#define DECLARE_CPFH_EH_RECORD(pCurThread)
+
+#endif // WIN64EXCEPTIONS
+
 //
 // Retrieves the redirected CONTEXT* from the stack frame of one of the
 // RedirectedHandledJITCaseForXXX_Stub's.
 //
 PTR_CONTEXT GetCONTEXTFromRedirectedStubStackFrame(CONTEXT * pContext);
+#ifdef WIN64EXCEPTIONS
+PTR_CONTEXT GetCONTEXTFromRedirectedStubStackFrame(T_DISPATCHER_CONTEXT * pDispatcherContext);
 
-PEXCEPTION_REGISTRATION_RECORD GetCurrentSEHRecord();
-PEXCEPTION_REGISTRATION_RECORD GetFirstCOMPlusSEHRecord(Thread*);
+class FaultingExceptionFrame;
+
+FaultingExceptionFrame *GetFrameFromRedirectedStubStackFrame (DISPATCHER_CONTEXT *pDispatcherContext);
+#endif // WIN64EXCEPTIONS
 
 // Determine the address of the instruction that made the current call.
 inline
index c6a95ef..0f05aa2 100644 (file)
@@ -38,6 +38,7 @@
 #include "asmconstants.h"
 #include "virtualcallstub.h"
 
+#ifndef WIN64EXCEPTIONS
 MethodDesc * GetUserMethodForILStub(Thread * pThread, UINT_PTR uStubSP, MethodDesc * pILStubMD, Frame ** ppFrameOut);
 
 #if !defined(DACCESS_COMPILE)
@@ -2018,20 +2019,6 @@ PEXCEPTION_REGISTRATION_RECORD GetCurrentSEHRecord()
     return (EXCEPTION_REGISTRATION_RECORD*) fs0;
 }
 
-#ifdef FEATURE_PAL
-VOID SetSEHRecord(PEXCEPTION_REGISTRATION_RECORD record)
-{
-    WRAPPER_NO_CONTRACT;
-    record->Next = CurrentSEHRecord;
-    CurrentSEHRecord = record;
-}
-
-VOID ResetSEHRecord(PEXCEPTION_REGISTRATION_RECORD record)
-{
-    CurrentSEHRecord = record->Next;
-}
-#endif // FEATURE_PAL
-
 PEXCEPTION_REGISTRATION_RECORD GetFirstCOMPlusSEHRecord(Thread *pThread) {
     WRAPPER_NO_CONTRACT;
 #ifndef FEATURE_PAL
@@ -3622,33 +3609,11 @@ EXCEPTION_HANDLER_IMPL(UMThunkPrestubHandler)
     return retval;
 }
 
-LONG CLRNoCatchHandler(EXCEPTION_POINTERS* pExceptionInfo, PVOID pv)
-{
-    WRAPPER_NO_CONTRACT;
-    STATIC_CONTRACT_ENTRY_POINT;
-
-    LONG result = EXCEPTION_CONTINUE_SEARCH;
-
-    // This function can be called during the handling of a SO
-    //BEGIN_ENTRYPOINT_VOIDRET;
-
-    result = CLRVectoredExceptionHandler(pExceptionInfo);
-
-    if (EXCEPTION_EXECUTE_HANDLER == result)
-    {
-        result = EXCEPTION_CONTINUE_SEARCH;
-    }
-
-    //END_ENTRYPOINT_VOIDRET;
-
-    return result;
-}
-
 #ifdef FEATURE_COMINTEROP
 // The reverse COM interop path needs to be sure to pop the ComMethodFrame that is pushed, but we do not want
-// to have an additional FS:0 handler between the COM callsite and the call into managed.  So we push this 
-// FS:0 handler, which will defer to the usual COMPlusFrameHandler and then perform the cleanup of the 
-// ComMethodFrame, if needed. 
+// to have an additional FS:0 handler between the COM callsite and the call into managed.  So we push this
+// FS:0 handler, which will defer to the usual COMPlusFrameHandler and then perform the cleanup of the
+// ComMethodFrame, if needed.
 EXCEPTION_HANDLER_IMPL(COMPlusFrameHandlerRevCom)
 {
     STATIC_CONTRACT_THROWS;
@@ -3667,7 +3632,36 @@ EXCEPTION_HANDLER_IMPL(COMPlusFrameHandlerRevCom)
     return result;
 }
 #endif // FEATURE_COMINTEROP
+#endif // !DACCESS_COMPILE
+#endif // !WIN64EXCEPTIONS
+
+#ifndef DACCESS_COMPILE
+LONG CLRNoCatchHandler(EXCEPTION_POINTERS* pExceptionInfo, PVOID pv)
+{
+#ifndef WIN64EXCEPTIONS
+    WRAPPER_NO_CONTRACT;
+    STATIC_CONTRACT_ENTRY_POINT;
+
+    LONG result = EXCEPTION_CONTINUE_SEARCH;
+
+    // This function can be called during the handling of a SO
+    //BEGIN_ENTRYPOINT_VOIDRET;
+
+    result = CLRVectoredExceptionHandler(pExceptionInfo);
+
+    if (EXCEPTION_EXECUTE_HANDLER == result)
+    {
+        result = EXCEPTION_CONTINUE_SEARCH;
+    }
 
+    //END_ENTRYPOINT_VOIDRET;
+
+    return result;
+#else  // !WIN64EXCEPTIONS
+    return EXCEPTION_CONTINUE_SEARCH;
+#endif // !WIN64EXCEPTIONS
+}
+#endif // !DACCESS_COMPILE
 
 // Returns TRUE if caller should resume execution.
 BOOL
@@ -3724,11 +3718,3 @@ AdjustContextForVirtualStub(
 
     return TRUE;
 }
-
-#ifdef FEATURE_PAL
-VOID DECLSPEC_NORETURN DispatchManagedException(PAL_SEHException& ex, bool isHardwareException)
-{
-    UNREACHABLE();
-}
-#endif
-#endif // !DACCESS_COMPILE
index 66ae9fb..35a0261 100644 (file)
@@ -727,6 +727,7 @@ LEAF_END JIT_PatchedCodeEnd, _TEXT
 // debugger may need additional support.
 // void __stdcall JIT_EndCatch();
 NESTED_ENTRY JIT_EndCatch, _TEXT, NoHandler
+#ifndef WIN64EXCEPTIONS
     // make temp storage for return address, and push the address of that
     // as the last arg to COMPlusEndCatch
     mov     ecx, [esp]
@@ -746,4 +747,7 @@ NESTED_ENTRY JIT_EndCatch, _TEXT, NoHandler
     pop     edx         // edx = new eip
     mov     esp, eax    // esp = new esp
     jmp     edx         // eip = new eip
+#else
+    int3
+#endif
 NESTED_END JIT_EndCatch, _TEXT
index 3252922..4025c26 100644 (file)
@@ -6,7 +6,7 @@
 
 extern "C"
 {
-    void ThrowControlForThread()
+    void ThrowControlForThread(FaultingExceptionFrame *pfef)
     {
         PORTABILITY_ASSERT("Implement for PAL");
     }
@@ -45,19 +45,6 @@ extern "C"
     {
     }
 
-    _Unwind_Reason_Code
-    UnhandledExceptionHandlerUnix(
-                IN int version,
-                IN _Unwind_Action action,
-                IN uint64_t exceptionClass,
-                IN struct _Unwind_Exception *exception,
-                IN struct _Unwind_Context *context
-              )
-    {
-        PORTABILITY_ASSERT("UnhandledExceptionHandlerUnix");
-        return _URC_FATAL_PHASE1_ERROR;
-    }
-
     BOOL CallRtlUnwind()
     {
         PORTABILITY_ASSERT("CallRtlUnwind");
@@ -94,3 +81,44 @@ EXTERN_C VOID JIT_TailCallLeave()
 {
   PORTABILITY_ASSERT("JIT_TailCallLeave");
 }
+
+PTR_CONTEXT GetCONTEXTFromRedirectedStubStackFrame(T_DISPATCHER_CONTEXT * pDispatcherContext)
+{
+    PORTABILITY_ASSERT("GetCONTEXTFromRedirectedStubStackFrame");
+    return NULL;
+}
+
+FaultingExceptionFrame *GetFrameFromRedirectedStubStackFrame(DISPATCHER_CONTEXT *pDispatcherContext)
+{
+    PORTABILITY_ASSERT("GetFrameFromRedirectedStubStackFrame");
+    return NULL;
+}
+
+EXTERN_C ULONG
+RtlpGetFunctionEndAddress (
+    __in PT_RUNTIME_FUNCTION FunctionEntry,
+    __in ULONG ImageBase
+    )
+{
+    PORTABILITY_ASSERT("RtlpGetFunctionEndAddress");
+    return 0;
+}
+
+EXTERN_C
+NTSYSAPI
+PEXCEPTION_ROUTINE
+NTAPI
+RtlVirtualUnwind (
+    __in DWORD HandlerType,
+    __in DWORD ImageBase,
+    __in DWORD ControlPc,
+    __in PRUNTIME_FUNCTION FunctionEntry,
+    __inout PT_CONTEXT ContextRecord,
+    __out PVOID *HandlerData,
+    __out PDWORD EstablisherFrame,
+    __inout_opt PT_KNONVOLATILE_CONTEXT_POINTERS ContextPointers
+    )
+{
+    PORTABILITY_ASSERT("RtlVirtualUnwind");
+    return NULL;
+}
index 2f9db3d..ee22e72 100644 (file)
@@ -2286,6 +2286,58 @@ BOOL CEEInfo::checkMethodModifier(CORINFO_METHOD_HANDLE hMethod,
 }
 
 /*********************************************************************/
+static unsigned ComputeGCLayout(MethodTable * pMT, BYTE* gcPtrs)
+{
+    STANDARD_VM_CONTRACT;
+
+    unsigned result = 0;
+
+    _ASSERTE(pMT->IsValueType());
+
+    ApproxFieldDescIterator fieldIterator(pMT, ApproxFieldDescIterator::INSTANCE_FIELDS);
+    for (FieldDesc *pFD = fieldIterator.Next(); pFD != NULL; pFD = fieldIterator.Next())
+    {
+        int fieldStartIndex = pFD->GetOffset() / sizeof(void*);
+
+        if (pFD->GetFieldType() != ELEMENT_TYPE_VALUETYPE)
+        {
+            if (pFD->IsObjRef())
+            {
+                if (gcPtrs[fieldStartIndex] == TYPE_GC_NONE)
+                {
+                    gcPtrs[fieldStartIndex] = TYPE_GC_REF;
+                    result++;
+                }
+                else if (gcPtrs[fieldStartIndex] != TYPE_GC_REF)
+                {
+                    COMPlusThrowHR(COR_E_BADIMAGEFORMAT);
+                }
+            }
+        }
+        else
+        {
+            MethodTable * pFieldMT = pFD->GetApproxFieldTypeHandleThrowing().AsMethodTable();
+            if (pFieldMT->HasSameTypeDefAs(g_pByReferenceClass))
+            {
+                if (gcPtrs[fieldStartIndex] == TYPE_GC_NONE)
+                {
+                    gcPtrs[fieldStartIndex] = TYPE_GC_BYREF;
+                    result++;
+                }
+                else if (gcPtrs[fieldStartIndex] != TYPE_GC_BYREF)
+                {
+                    COMPlusThrowHR(COR_E_BADIMAGEFORMAT);
+                }
+            }
+            else
+            {
+                result += ComputeGCLayout(pFieldMT, gcPtrs + fieldStartIndex);
+            }
+        }
+    }
+    return result;
+}
+
 unsigned CEEInfo::getClassGClayout (CORINFO_CLASS_HANDLE clsHnd, BYTE* gcPtrs)
 {
     CONTRACTL {
@@ -2313,10 +2365,12 @@ unsigned CEEInfo::getClassGClayout (CORINFO_CLASS_HANDLE clsHnd, BYTE* gcPtrs)
         }
         else
         {
-            // TODO-SPAN: Proper GC reporting
             memset(gcPtrs, TYPE_GC_NONE,
-                   (VMClsHnd.GetSize() + sizeof(void*) -1)/ sizeof(void*));
-            result = 0;
+                (VMClsHnd.GetSize() + sizeof(void*) - 1) / sizeof(void*));
+            // Note: This case is more complicated than the TypedReference case
+            // due to ByRefLike structs being included as fields in other value 
+            // types (TypedReference can not be.)
+            result = ComputeGCLayout(VMClsHnd.AsMethodTable(), gcPtrs);
         }
     }
     else if (VMClsHnd.IsNativeValueType())
@@ -8764,6 +8818,29 @@ CorInfoIntrinsics CEEInfo::getIntrinsicID(CORINFO_METHOD_HANDLE methodHnd,
     {
         result = ECall::GetIntrinsicID(method);
     }
+    else
+    {
+        MethodTable * pMT = method->GetMethodTable();
+        if (pMT->IsByRefLike() && pMT->GetModule()->IsSystem())
+        {
+            if (pMT->HasSameTypeDefAs(g_pByReferenceClass))
+            {
+                // ByReference<T> has just two methods: constructor and Value property
+                if (method->IsCtor())
+                {
+                    result = CORINFO_INTRINSIC_ByReference_Ctor;
+                }
+                else
+                {
+                    _ASSERTE(strcmp(method->GetName(), "get_Value") == 0);
+                    result = CORINFO_INTRINSIC_ByReference_Value;
+                }
+                *pMustExpand = true;
+            }
+
+            // TODO-SPAN: Span<T> intrinsics for optimizations
+        }
+    }
 
     EE_TO_JIT_TRANSITION();
 
@@ -11082,7 +11159,7 @@ void CEEJitInfo::allocUnwindInfo (
 
     RUNTIME_FUNCTION__SetBeginAddress(pRuntimeFunction, currentCodeOffset + startOffset);
 
-#if defined(_TARGET_X86_) || defined(_TARGET_AMD64_)
+#if defined(_TARGET_AMD64_)
     pRuntimeFunction->EndAddress        = currentCodeOffset + endOffset;
 #endif
 
index ee13b9c..6cc3a05 100644 (file)
@@ -391,7 +391,10 @@ void ValidateWriteBarrierHelpers();
 
 extern "C"
 {
+#ifdef _TARGET_X86_
+    // UNIXTODO: Disable JIT_EndCatch after revising the jitter not to use this (for x86/Linux)
     void STDCALL JIT_EndCatch();               // JIThelp.asm/JIThelp.s
+#endif // _TARGET_X86_
 
     void STDCALL JIT_ByRefWriteBarrier();      // JIThelp.asm/JIThelp.s
 
index 7afe0e9..07636d6 100644 (file)
@@ -2466,7 +2466,18 @@ MethodDesc* Entry2MethodDesc(PCODE entryPoint, MethodTable *pMT)
 BOOL MethodDesc::IsFCallOrIntrinsic()
 {
     WRAPPER_NO_CONTRACT;
-    return (IsFCall() || IsArray());
+
+    if (IsFCall() || IsArray())
+        return TRUE;
+
+#ifdef FEATURE_SPAN_OF_T
+    // Intrinsic methods on ByReference<T> or Span<T>
+    MethodTable * pMT = GetMethodTable();
+    if (pMT->IsByRefLike() && pMT->GetModule()->IsSystem())
+        return TRUE;
+#endif
+
+    return FALSE;
 }
 
 //*******************************************************************************
index e0d4096..9fd7c52 100644 (file)
@@ -829,15 +829,24 @@ Stub * CreateInstantiatingILStub(MethodDesc* pTargetMD, void* pHiddenArg)
     CreateInstantiatingILStubTargetSig(pTargetMD, typeContext, &stubSigBuilder);
     
     // 2. Emit the method body
+    unsigned int numArgs = msig.NumFixedArgs();
     if (msig.HasThis())
     {
         // 2.1 Push the thisptr
         pCode->EmitLoadThis();
+        numArgs++;
     }
 
-    // 2.2 Push the hidden context param 
-    // InstantiatingStub
-    pCode->EmitLDC((TADDR)pHiddenArg);
+#if defined(_TARGET_X86_)
+    if (numArgs < NUM_ARGUMENT_REGISTERS)
+    {
+#endif // _TARGET_X86_
+        // 2.2 Push the hidden context param
+        // InstantiatingStub
+        pCode->EmitLDC((TADDR)pHiddenArg);
+#if defined(_TARGET_X86_)
+    }
+#endif // _TARGET_X86_
 
     // 2.3 Push the rest of the arguments
     for (unsigned i = 0; i < msig.NumFixedArgs();i++)
@@ -845,10 +854,19 @@ Stub * CreateInstantiatingILStub(MethodDesc* pTargetMD, void* pHiddenArg)
         pCode->EmitLDARG(i);
     }
 
-    // 2.4 Push the target address
+#if defined(_TARGET_X86_)
+    if (numArgs >= NUM_ARGUMENT_REGISTERS)
+    {
+        // 2.4 Push the hidden context param
+        // InstantiatingStub
+        pCode->EmitLDC((TADDR)pHiddenArg);
+    }
+#endif // _TARGET_X86_
+
+    // 2.5 Push the target address
     pCode->EmitLDC((TADDR)pTargetMD->GetMultiCallableAddrOfCode(CORINFO_ACCESS_ANY));
 
-    // 2.5 Do the calli
+    // 2.6 Do the calli
     pCode->EmitCALLI(TOKEN_ILSTUB_TARGET_SIG, msig.NumFixedArgs() + 1, msig.IsReturnTypeVoid() ? 0 : 1);
     pCode->EmitRET();
 
index 9adfb49..12803ec 100644 (file)
@@ -4956,7 +4956,9 @@ void PromoteCarefully(promote_func   fn,
 void ReportPointersFromValueType(promote_func *fn, ScanContext *sc, PTR_MethodTable pMT, PTR_VOID pSrc)
 {
     WRAPPER_NO_CONTRACT;
-    
+
+    // SPAN-TODO: GC reporting - https://github.com/dotnet/coreclr/issues/8517
+
     if (!pMT->ContainsPointers())
         return;
     
index 18a8900..44e5f99 100644 (file)
@@ -555,11 +555,9 @@ UINT_PTR Thread::VirtualUnwindCallFrame(PREGDISPLAY pRD, EECodeInfo* pCodeInfo /
         pRD->pCurrentContext = pRD->pCallerContext;
         pRD->pCallerContext  = temp;
 
-#if defined(_TARGET_AMD64_) || defined(_TARGET_ARM_) || defined(_TARGET_ARM64_)
         PT_KNONVOLATILE_CONTEXT_POINTERS tempPtrs = pRD->pCurrentContextPointers;
         pRD->pCurrentContextPointers            = pRD->pCallerContextPointers;
         pRD->pCallerContextPointers             = tempPtrs;
-#endif // defined(_TARGET_AMD64_) || defined(_TARGET_ARM_) || defined(_TARGET_ARM64_)
     }
     else
     {
@@ -722,15 +720,12 @@ PCODE Thread::VirtualUnwindNonLeafCallFrame(T_CONTEXT* pContext, KNONVOLATILE_CO
     CONTRACTL_END;
 
     PCODE           uControlPc = GetIP(pContext);
-#if defined(_WIN64)
+#ifdef BIT64
     UINT64              EstablisherFrame;
-    PVOID               HandlerData;
-#elif defined(_TARGET_ARM_)
+#else  // BIT64
     DWORD               EstablisherFrame;
+#endif // BIT64
     PVOID               HandlerData;
-#else
-    _ASSERTE(!"nyi platform stackwalking");
-#endif
 
     if (NULL == pFunctionEntry)
     {
@@ -893,7 +888,7 @@ StackWalkAction Thread::MakeStackwalkerCallback(
 }
 
 
-#if !defined(DACCESS_COMPILE) && defined(_TARGET_X86_)
+#if !defined(DACCESS_COMPILE) && defined(_TARGET_X86_) && !defined(WIN64EXCEPTIONS)
 #define STACKWALKER_MAY_POP_FRAMES
 #endif
 
@@ -2677,9 +2672,10 @@ StackWalkAction StackFrameIterator::NextRaw(void)
 
                 // We are transitioning from unmanaged code to managed code... lets do some validation of our
                 // EH mechanism on platforms that we can.
-#if defined(_DEBUG)  && !defined(DACCESS_COMPILE) && (defined(_TARGET_X86_) && !defined(FEATURE_STUBS_AS_IL))
+#if defined(_DEBUG)  && !defined(DACCESS_COMPILE) && (defined(_TARGET_X86_) && !defined(FEATURE_PAL)) && !defined(WIN64EXCEPTIONS)               
+                // TODO: Revise this once we enable WIN64EXCEPTIONS for x86/Linux
                 VerifyValidTransitionFromManagedCode(m_crawl.pThread, &m_crawl);
-#endif // _DEBUG && !DACCESS_COMPILE && _TARGET_X86_
+#endif // _DEBUG && !DACCESS_COMPILE && _TARGET_X86_ && !WIN64EXCEPTIONS
             }
         }
 
index f0098c9..10cba00 100644 (file)
@@ -445,7 +445,7 @@ class PrecodeStubManager : public StubManager
 #ifndef DACCESS_COMPILE
     virtual BOOL TraceManager(Thread *thread,
                               TraceDestination *trace,
-                              CONTEXT *pContext,
+                              T_CONTEXT *pContext,
                               BYTE **pRetAddr);
 #endif
 
@@ -509,7 +509,7 @@ class StubLinkStubManager : public StubManager
 #ifndef DACCESS_COMPILE
     virtual BOOL TraceManager(Thread *thread,
                               TraceDestination *trace,
-                              CONTEXT *pContext,
+                              T_CONTEXT *pContext,
                               BYTE **pRetAddr);
 #endif
 
@@ -646,7 +646,7 @@ class RangeSectionStubManager : public StubManager
 #ifndef DACCESS_COMPILE
     virtual BOOL TraceManager(Thread *thread,
                               TraceDestination *trace,
-                              CONTEXT *pContext,
+                              T_CONTEXT *pContext,
                               BYTE **pRetAddr);
 #endif
 
@@ -708,7 +708,7 @@ class ILStubManager : public StubManager
 
     virtual BOOL TraceManager(Thread *thread,
                               TraceDestination *trace,
-                              CONTEXT *pContext,
+                              T_CONTEXT *pContext,
                               BYTE **pRetAddr);
 #endif
 
@@ -752,7 +752,7 @@ class InteropDispatchStubManager : public StubManager
 #ifndef DACCESS_COMPILE
     virtual BOOL TraceManager(Thread *thread,
                               TraceDestination *trace,
-                              CONTEXT *pContext,
+                              T_CONTEXT *pContext,
                               BYTE **pRetAddr);
 #endif
 
@@ -797,7 +797,7 @@ class DelegateInvokeStubManager : public StubManager
     virtual BOOL CheckIsStub_Internal(PCODE stubStartAddress);
 
 #if !defined(DACCESS_COMPILE)
-    virtual BOOL TraceManager(Thread *thread, TraceDestination *trace, CONTEXT *pContext, BYTE **pRetAddr);
+    virtual BOOL TraceManager(Thread *thread, TraceDestination *trace, T_CONTEXT *pContext, BYTE **pRetAddr);
     static BOOL TraceDelegateObject(BYTE *orDel, TraceDestination *trace);
 #endif // DACCESS_COMPILE
 
@@ -846,7 +846,7 @@ public:
     TailCallStubManager() : StubManager() {WRAPPER_NO_CONTRACT;}
     ~TailCallStubManager() {WRAPPER_NO_CONTRACT;}
 
-    virtual BOOL TraceManager(Thread * pThread, TraceDestination * pTrace, CONTEXT * pContext, BYTE ** ppRetAddr);
+    virtual BOOL TraceManager(Thread * pThread, TraceDestination * pTrace, T_CONTEXT * pContext, BYTE ** ppRetAddr);
 
     static bool IsTailCallStubHelper(PCODE code);
 #endif // DACCESS_COMPILE
index 144e17c..9754478 100644 (file)
@@ -3386,7 +3386,7 @@ public:
         m_singleStepper.Disable();
     }
 
-    void ApplySingleStep(CONTEXT *pCtx)
+    void ApplySingleStep(T_CONTEXT *pCtx)
     {
         m_singleStepper.Apply(pCtx);
     }
@@ -3399,7 +3399,7 @@ public:
     // Fixup code called by our vectored exception handler to complete the emulation of single stepping
     // initiated by EnableSingleStep above. Returns true if the exception was indeed encountered during
     // stepping.
-    bool HandleSingleStep(CONTEXT *pCtx, DWORD dwExceptionCode)
+    bool HandleSingleStep(T_CONTEXT *pCtx, DWORD dwExceptionCode)
     {
         return m_singleStepper.Fixup(pCtx, dwExceptionCode);
     }
index 2e6563d..18d04db 100644 (file)
@@ -2190,7 +2190,7 @@ LRetry:
                               | TS_Detached
                               | TS_Unstarted)));
 
-#ifdef _TARGET_X86_
+#if defined(_TARGET_X86_) && !defined(WIN64EXCEPTIONS)
         // TODO WIN64: consider this if there is a way to detect of managed code on stack.
         if ((m_pFrame == FRAME_TOP)
             && (GetFirstCOMPlusSEHRecord(this) == EXCEPTION_CHAIN_END)
@@ -2213,7 +2213,7 @@ LRetry:
         if (!m_fPreemptiveGCDisabled)
         {
             if ((m_pFrame != FRAME_TOP) && m_pFrame->IsTransitionToNativeFrame()
-#ifdef _TARGET_X86_
+#if defined(_TARGET_X86_) && !defined(WIN64EXCEPTIONS)
                 && ((size_t) GetFirstCOMPlusSEHRecord(this) > ((size_t) m_pFrame) - 20)
 #endif // _TARGET_X86_
                 )
index 95655fd..b3db657 100644 (file)
 #include <float.h>
 #include <limits.h>
 
-#if !defined(_TARGET_X86_)
+#if !defined(_TARGET_X86_) || defined(FEATURE_PAL)
 #ifndef WIN64EXCEPTIONS
 #define WIN64EXCEPTIONS
 #endif
-#endif // !_TARGET_X86_
+#endif // !_TARGET_X86_ || FEATURE_PAL
 
 #include "utilcode.h"
 #include "corjit.h"
index 167c0ed..e54e884 100644 (file)
@@ -1130,7 +1130,7 @@ void ZapUnwindInfo::Save(ZapWriter * pZapWriter)
     pZapWriter->Write(&runtimeFunction, sizeof(runtimeFunction));
 }
 
-#if defined(WIN64EXCEPTIONS) && !defined(_TARGET_X86_)
+#if defined(WIN64EXCEPTIONS)
 // Compare the unwind infos by their offset
 int __cdecl ZapUnwindInfo::CompareUnwindInfo(const void* a_, const void* b_)
 {
index 4eb6327..1a0b5e3 100644 (file)
@@ -25,17 +25,18 @@ WARNING:   When setting properties based on their current state (for example:
     <PropertyGroup>
       <InputAssemblyName Condition="'$(CLRTestKind)' == 'RunOnly'">$([MSBuild]::MakeRelative($(OutputPath), $(_CLRTestToRunFileFullPath)).Replace("\","/"))</InputAssemblyName>
       <InputAssemblyName Condition="'$(CLRTestKind)' == 'BuildAndRun'">$(MSBuildProjectName).exe</InputAssemblyName>
-      <JitDisasmOut>$(BaseOutputPathWithConfig.Replace("\","/"))dasm/$(BuildProjectRelativeDir.Replace("\","/"))</JitDisasmOut>
+      <JitDisasmOut>$([MSBuild]::MakeRelative($(OutputPath), $(BaseOutputPathWithConfig)dasm\$(BuildProjectRelativeDir)).Replace("\","/"))</JitDisasmOut>
       <JitDisasmBashScript>
 <![CDATA[
 # JitDisasm Script
 if [ ! -z $RunningJitDisasm ]
 then
-    echo $CORE_ROOT/corerun "$CORE_ROOT/jit-dasm.dll" --crossgen $CORE_ROOT/crossgen.exe --platform $CORE_ROOT --output $(JitDisasmOut) $(InputAssemblyName)
-    "$CORE_ROOT/corerun" "$CORE_ROOT/jit-dasm" --crossgen $CORE_ROOT/crossgen.exe --platform $CORE_ROOT --output $(JitDisasmOut) $(InputAssemblyName)
-    if [ $ERRORLEVEL -ne 0 ]
+    echo $CORE_ROOT/corerun "$CORE_ROOT/jit-dasm.dll" --crossgen $CORE_ROOT/crossgen --platform $CORE_ROOT --output $(JitDisasmOut) $(InputAssemblyName)
+    "$CORE_ROOT/corerun" "$CORE_ROOT/jit-dasm.dll" --crossgen $CORE_ROOT/crossgen --platform $CORE_ROOT --output $(JitDisasmOut) $(InputAssemblyName)
+    _jdExitCode=$?
+    if [ $_jdExitCode -ne 0 ]
     then
-        echo EXECUTION OF JIT-DASM - FAILED $ERRORLEVEL
+        echo EXECUTION OF JIT-DASM - FAILED $_jdExitCode
         exit 1
     fi
 fi
@@ -49,7 +50,7 @@ fi
     <PropertyGroup>
       <InputAssemblyName Condition="'$(CLRTestKind)' == 'RunOnly'">$([MSBuild]::MakeRelative($(OutputPath), $(_CLRTestToRunFileFullPath)))</InputAssemblyName>
       <InputAssemblyName Condition="'$(CLRTestKind)' == 'BuildAndRun'">$(MSBuildProjectName).exe</InputAssemblyName>
-      <JitDisasmOut>$(BaseOutputPathWithConfig)dasm\$(BuildProjectRelativeDir)</JitDisasmOut>
+      <JitDisasmOut>$([MSBuild]::MakeRelative($(OutputPath), $(BaseOutputPathWithConfig)dasm\$(BuildProjectRelativeDir)))</JitDisasmOut>
       <JitDisasmBatchScript>
 <![CDATA[
 REM JitDisasm Script
index f86cca8..8def5e5 100644 (file)
@@ -1,10 +1,10 @@
 {
   "dependencies": {
-    "Microsoft.NETCore.ILAsm": "1.2.0-beta-24906-01",
-    "Microsoft.NETCore.ILDAsm": "1.2.0-beta-24906-01",
-    "Microsoft.NETCore.Jit": "1.2.0-beta-24906-01",
-    "Microsoft.NETCore.Runtime.CoreCLR": "1.2.0-beta-24906-01",
-    "Microsoft.NETCore.TestHost": "1.2.0-beta-24906-01"
+    "Microsoft.NETCore.ILAsm": "1.2.0-beta-24911-02",
+    "Microsoft.NETCore.ILDAsm": "1.2.0-beta-24911-02",
+    "Microsoft.NETCore.Jit": "1.2.0-beta-24911-02",
+    "Microsoft.NETCore.Runtime.CoreCLR": "1.2.0-beta-24911-02",
+    "Microsoft.NETCore.TestHost": "1.2.0-beta-24911-02"
   },
   "frameworks": {
     "netcoreapp1.1": {
index c87a7fb..dafafa5 100644 (file)
@@ -5,66 +5,66 @@
     "emitEntryPoint": true
   },
   "dependencies": {
-    "Microsoft.NETCore.Platforms": "1.2.0-beta-24906-02",
-    "Microsoft.NETCore.Targets": "1.2.0-beta-24906-02",
-    "System.Threading.Thread": "4.4.0-beta-24906-02",
-    "System.Collections": "4.4.0-beta-24906-02",
-    "System.Xml.XmlSerializer": "4.4.0-beta-24906-02",
-    "System.Collections.Concurrent": "4.4.0-beta-24906-02",
-    "System.ObjectModel": "4.4.0-beta-24906-02",
-    "System.Runtime.Numerics": "4.4.0-beta-24906-02",
-    "System.Collections.NonGeneric": "4.4.0-beta-24906-02",
-    "System.Collections.Specialized": "4.4.0-beta-24906-02",
-    "System.ComponentModel": "4.4.0-beta-24906-02",
-    "System.Reflection.Emit.Lightweight": "4.4.0-beta-24906-02",
-    "System.Reflection.TypeExtensions": "4.4.0-beta-24906-02",
-    "System.Console": "4.4.0-beta-24906-02",
-    "System.Diagnostics.Contracts": "4.4.0-beta-24906-02",
-    "System.Diagnostics.Debug": "4.4.0-beta-24906-02",
-    "System.Diagnostics.Process": "4.4.0-beta-24906-02",
-    "System.Diagnostics.Tools": "4.4.0-beta-24906-02",
-    "System.Diagnostics.Tracing": "4.4.0-beta-24906-02",
-    "System.Dynamic.Runtime": "4.4.0-beta-24906-02",
-    "System.Globalization": "4.4.0-beta-24906-02",
-    "System.Globalization.Calendars": "4.4.0-beta-24906-02",
-    "System.IO": "4.4.0-beta-24906-02",
-    "System.IO.FileSystem": "4.4.0-beta-24906-02",
-    "System.IO.FileSystem.Primitives": "4.4.0-beta-24906-02",
-    "System.Linq": "4.4.0-beta-24906-02",
-    "System.Linq.Queryable": "4.4.0-beta-24906-02",
-    "System.Linq.Expressions": "4.4.0-beta-24906-02",
-    "System.Reflection": "4.4.0-beta-24906-02",
-    "System.Reflection.Extensions": "4.4.0-beta-24906-02",
-    "System.Resources.ResourceManager": "4.4.0-beta-24906-02",
-    "System.Runtime": "4.4.0-beta-24906-02",
-    "System.Runtime.CompilerServices.Unsafe": "4.4.0-beta-24906-02",
-    "System.Runtime.Extensions": "4.4.0-beta-24906-02",
-    "System.Runtime.Handles": "4.4.0-beta-24906-02",
-    "System.Runtime.InteropServices": "4.4.0-beta-24906-02",
-    "System.Runtime.InteropServices.RuntimeInformation": "4.4.0-beta-24906-02",
-    "System.Runtime.Loader": "4.4.0-beta-24906-02",
-    "System.Security.Cryptography.Algorithms": "4.4.0-beta-24906-02",
-    "System.Text.Encoding": "4.4.0-beta-24906-02",
-    "System.Text.Encoding.Extensions": "4.4.0-beta-24906-02",
-    "System.Text.RegularExpressions": "4.4.0-beta-24906-02",
-    "System.Threading": "4.4.0-beta-24906-02",
-    "System.Threading.AccessControl": "4.4.0-beta-24906-02",
-    "System.Threading.Overlapped": "4.4.0-beta-24906-02",
-    "System.Threading.Tasks": "4.4.0-beta-24906-02",
-    "System.Threading.Tasks.Parallel": "4.4.0-beta-24906-02",
-    "System.Threading.ThreadPool": "4.4.0-beta-24906-02",
-    "System.Threading.Timer": "4.4.0-beta-24906-02",
-    "System.Xml.ReaderWriter": "4.4.0-beta-24906-02",
-    "System.Xml.XDocument": "4.4.0-beta-24906-02",
-    "System.Xml.XmlDocument": "4.4.0-beta-24906-02",
-    "System.Xml.XPath": "4.4.0-beta-24906-02",
-    "System.Xml.XPath.XmlDocument": "4.4.0-beta-24906-02",
-    "System.Numerics.Vectors": "4.4.0-beta-24906-02"
+    "Microsoft.NETCore.Platforms": "1.2.0-beta-24911-08",
+    "Microsoft.NETCore.Targets": "1.2.0-beta-24911-08",
+    "System.Threading.Thread": "4.4.0-beta-24911-08",
+    "System.Collections": "4.4.0-beta-24911-08",
+    "System.Xml.XmlSerializer": "4.4.0-beta-24911-08",
+    "System.Collections.Concurrent": "4.4.0-beta-24911-08",
+    "System.ObjectModel": "4.4.0-beta-24911-08",
+    "System.Runtime.Numerics": "4.4.0-beta-24911-08",
+    "System.Collections.NonGeneric": "4.4.0-beta-24911-08",
+    "System.Collections.Specialized": "4.4.0-beta-24911-08",
+    "System.ComponentModel": "4.4.0-beta-24911-08",
+    "System.Reflection.Emit.Lightweight": "4.4.0-beta-24911-08",
+    "System.Reflection.TypeExtensions": "4.4.0-beta-24911-08",
+    "System.Console": "4.4.0-beta-24911-08",
+    "System.Diagnostics.Contracts": "4.4.0-beta-24911-08",
+    "System.Diagnostics.Debug": "4.4.0-beta-24911-08",
+    "System.Diagnostics.Process": "4.4.0-beta-24911-08",
+    "System.Diagnostics.Tools": "4.4.0-beta-24911-08",
+    "System.Diagnostics.Tracing": "4.4.0-beta-24911-08",
+    "System.Dynamic.Runtime": "4.4.0-beta-24911-08",
+    "System.Globalization": "4.4.0-beta-24911-08",
+    "System.Globalization.Calendars": "4.4.0-beta-24911-08",
+    "System.IO": "4.4.0-beta-24911-08",
+    "System.IO.FileSystem": "4.4.0-beta-24911-08",
+    "System.IO.FileSystem.Primitives": "4.4.0-beta-24911-08",
+    "System.Linq": "4.4.0-beta-24911-08",
+    "System.Linq.Queryable": "4.4.0-beta-24911-08",
+    "System.Linq.Expressions": "4.4.0-beta-24911-08",
+    "System.Reflection": "4.4.0-beta-24911-08",
+    "System.Reflection.Extensions": "4.4.0-beta-24911-08",
+    "System.Resources.ResourceManager": "4.4.0-beta-24911-08",
+    "System.Runtime": "4.4.0-beta-24911-08",
+    "System.Runtime.CompilerServices.Unsafe": "4.4.0-beta-24911-08",
+    "System.Runtime.Extensions": "4.4.0-beta-24911-08",
+    "System.Runtime.Handles": "4.4.0-beta-24911-08",
+    "System.Runtime.InteropServices": "4.4.0-beta-24911-08",
+    "System.Runtime.InteropServices.RuntimeInformation": "4.4.0-beta-24911-08",
+    "System.Runtime.Loader": "4.4.0-beta-24911-08",
+    "System.Security.Cryptography.Algorithms": "4.4.0-beta-24911-08",
+    "System.Text.Encoding": "4.4.0-beta-24911-08",
+    "System.Text.Encoding.Extensions": "4.4.0-beta-24911-08",
+    "System.Text.RegularExpressions": "4.4.0-beta-24911-08",
+    "System.Threading": "4.4.0-beta-24911-08",
+    "System.Threading.AccessControl": "4.4.0-beta-24911-08",
+    "System.Threading.Overlapped": "4.4.0-beta-24911-08",
+    "System.Threading.Tasks": "4.4.0-beta-24911-08",
+    "System.Threading.Tasks.Parallel": "4.4.0-beta-24911-08",
+    "System.Threading.ThreadPool": "4.4.0-beta-24911-08",
+    "System.Threading.Timer": "4.4.0-beta-24911-08",
+    "System.Xml.ReaderWriter": "4.4.0-beta-24911-08",
+    "System.Xml.XDocument": "4.4.0-beta-24911-08",
+    "System.Xml.XmlDocument": "4.4.0-beta-24911-08",
+    "System.Xml.XPath": "4.4.0-beta-24911-08",
+    "System.Xml.XPath.XmlDocument": "4.4.0-beta-24911-08",
+    "System.Numerics.Vectors": "4.4.0-beta-24911-08"
   },
   "frameworks": {
     "netcoreapp1.1": {
       "dependencies": {
-        "Microsoft.NETCore.Runtime.CoreCLR": "1.2.0-beta-24906-01"
+        "Microsoft.NETCore.Runtime.CoreCLR": "1.2.0-beta-24911-02"
       }
     }
   },
index f3bbbb4..d02628d 100644 (file)
@@ -1,6 +1,6 @@
 {
   "dependencies": {
-    "Microsoft.TargetingPack.Private.CoreCLR": "1.2.0-beta-24906-01"
+    "Microsoft.TargetingPack.Private.CoreCLR": "1.2.0-beta-24911-02"
   },
   "frameworks": {
     "netcoreapp1.1": {
index 8a973b9..d8eca6f 100644 (file)
@@ -7,67 +7,67 @@
     "Microsoft.DotNet.xunit.performance": "1.0.0-alpha-build0040",
     "Microsoft.DotNet.xunit.performance.analysis": "1.0.0-alpha-build0040",
     "Microsoft.DotNet.xunit.performance.runner.Windows": "1.0.0-alpha-build0040",
-    "Microsoft.Win32.Primitives": "4.4.0-beta-24906-02",
+    "Microsoft.Win32.Primitives": "4.4.0-beta-24911-08",
     "Newtonsoft.Json": "8.0.3",
-    "Microsoft.NETCore.Platforms": "1.2.0-beta-24906-02",
-    "Microsoft.NETCore.Targets": "1.2.0-beta-24906-02",
-    "System.Collections.Immutable": "1.4.0-beta-24906-02",
-    "System.Threading.Thread": "4.4.0-beta-24906-02",
-    "System.Collections": "4.4.0-beta-24906-02",
-    "System.Xml.XmlSerializer": "4.4.0-beta-24906-02",
-    "System.Collections.Concurrent": "4.4.0-beta-24906-02",
-    "System.ObjectModel": "4.4.0-beta-24906-02",
-    "System.Runtime.Numerics": "4.4.0-beta-24906-02",
-    "System.Collections.NonGeneric": "4.4.0-beta-24906-02",
-    "System.Collections.Specialized": "4.4.0-beta-24906-02",
-    "System.ComponentModel": "4.4.0-beta-24906-02",
-    "System.Reflection.Emit.Lightweight": "4.4.0-beta-24906-02",
-    "System.Reflection.TypeExtensions": "4.4.0-beta-24906-02",
-    "System.Console": "4.4.0-beta-24906-02",
-    "System.Diagnostics.Contracts": "4.4.0-beta-24906-02",
-    "System.Diagnostics.Debug": "4.4.0-beta-24906-02",
-    "System.Diagnostics.Process": "4.4.0-beta-24906-02",
-    "System.Diagnostics.Tools": "4.4.0-beta-24906-02",
-    "System.Diagnostics.Tracing": "4.4.0-beta-24906-02",
-    "System.Dynamic.Runtime": "4.4.0-beta-24906-02",
-    "System.Globalization": "4.4.0-beta-24906-02",
-    "System.Globalization.Calendars": "4.4.0-beta-24906-02",
-    "System.IO": "4.4.0-beta-24906-02",
-    "System.IO.FileSystem": "4.4.0-beta-24906-02",
-    "System.IO.FileSystem.Primitives": "4.4.0-beta-24906-02",
-    "System.Linq": "4.4.0-beta-24906-02",
-    "System.Linq.Queryable": "4.4.0-beta-24906-02",
-    "System.Linq.Expressions": "4.4.0-beta-24906-02",
-    "System.Reflection": "4.4.0-beta-24906-02",
-    "System.Reflection.Extensions": "4.4.0-beta-24906-02",
-    "System.Resources.ResourceManager": "4.4.0-beta-24906-02",
-    "System.Runtime": "4.4.0-beta-24906-02",
-    "System.Runtime.CompilerServices.Unsafe": "4.4.0-beta-24906-02",
-    "System.Runtime.Extensions": "4.4.0-beta-24906-02",
-    "System.Runtime.Handles": "4.4.0-beta-24906-02",
-    "System.Runtime.InteropServices": "4.4.0-beta-24906-02",
-    "System.Runtime.InteropServices.RuntimeInformation": "4.4.0-beta-24906-02",
-    "System.Runtime.Loader": "4.4.0-beta-24906-02",
-    "System.Runtime.Serialization.Json": "4.4.0-beta-24906-02",
-    "System.Runtime.Serialization.Primitives": "4.4.0-beta-24906-02",
-    "System.Runtime.Serialization.Xml": "4.4.0-beta-24906-02",
-    "System.Security.Cryptography.Algorithms": "4.4.0-beta-24906-02",
-    "System.Text.Encoding": "4.4.0-beta-24906-02",
-    "System.Text.Encoding.Extensions": "4.4.0-beta-24906-02",
-    "System.Text.RegularExpressions": "4.4.0-beta-24906-02",
-    "System.Threading": "4.4.0-beta-24906-02",
-    "System.Threading.AccessControl": "4.4.0-beta-24906-02",
-    "System.Threading.Overlapped": "4.4.0-beta-24906-02",
-    "System.Threading.Tasks": "4.4.0-beta-24906-02",
-    "System.Threading.Tasks.Parallel": "4.4.0-beta-24906-02",
-    "System.Threading.ThreadPool": "4.4.0-beta-24906-02",
-    "System.Threading.Timer": "4.4.0-beta-24906-02",
-    "System.Xml.ReaderWriter": "4.4.0-beta-24906-02",
-    "System.Xml.XDocument": "4.4.0-beta-24906-02",
-    "System.Xml.XmlDocument": "4.4.0-beta-24906-02",
-    "System.Xml.XPath": "4.4.0-beta-24906-02",
-    "System.Xml.XPath.XmlDocument": "4.4.0-beta-24906-02",
-    "System.Numerics.Vectors": "4.4.0-beta-24906-02"
+    "Microsoft.NETCore.Platforms": "1.2.0-beta-24911-08",
+    "Microsoft.NETCore.Targets": "1.2.0-beta-24911-08",
+    "System.Collections.Immutable": "1.4.0-beta-24911-08",
+    "System.Threading.Thread": "4.4.0-beta-24911-08",
+    "System.Collections": "4.4.0-beta-24911-08",
+    "System.Xml.XmlSerializer": "4.4.0-beta-24911-08",
+    "System.Collections.Concurrent": "4.4.0-beta-24911-08",
+    "System.ObjectModel": "4.4.0-beta-24911-08",
+    "System.Runtime.Numerics": "4.4.0-beta-24911-08",
+    "System.Collections.NonGeneric": "4.4.0-beta-24911-08",
+    "System.Collections.Specialized": "4.4.0-beta-24911-08",
+    "System.ComponentModel": "4.4.0-beta-24911-08",
+    "System.Reflection.Emit.Lightweight": "4.4.0-beta-24911-08",
+    "System.Reflection.TypeExtensions": "4.4.0-beta-24911-08",
+    "System.Console": "4.4.0-beta-24911-08",
+    "System.Diagnostics.Contracts": "4.4.0-beta-24911-08",
+    "System.Diagnostics.Debug": "4.4.0-beta-24911-08",
+    "System.Diagnostics.Process": "4.4.0-beta-24911-08",
+    "System.Diagnostics.Tools": "4.4.0-beta-24911-08",
+    "System.Diagnostics.Tracing": "4.4.0-beta-24911-08",
+    "System.Dynamic.Runtime": "4.4.0-beta-24911-08",
+    "System.Globalization": "4.4.0-beta-24911-08",
+    "System.Globalization.Calendars": "4.4.0-beta-24911-08",
+    "System.IO": "4.4.0-beta-24911-08",
+    "System.IO.FileSystem": "4.4.0-beta-24911-08",
+    "System.IO.FileSystem.Primitives": "4.4.0-beta-24911-08",
+    "System.Linq": "4.4.0-beta-24911-08",
+    "System.Linq.Queryable": "4.4.0-beta-24911-08",
+    "System.Linq.Expressions": "4.4.0-beta-24911-08",
+    "System.Reflection": "4.4.0-beta-24911-08",
+    "System.Reflection.Extensions": "4.4.0-beta-24911-08",
+    "System.Resources.ResourceManager": "4.4.0-beta-24911-08",
+    "System.Runtime": "4.4.0-beta-24911-08",
+    "System.Runtime.CompilerServices.Unsafe": "4.4.0-beta-24911-08",
+    "System.Runtime.Extensions": "4.4.0-beta-24911-08",
+    "System.Runtime.Handles": "4.4.0-beta-24911-08",
+    "System.Runtime.InteropServices": "4.4.0-beta-24911-08",
+    "System.Runtime.InteropServices.RuntimeInformation": "4.4.0-beta-24911-08",
+    "System.Runtime.Loader": "4.4.0-beta-24911-08",
+    "System.Runtime.Serialization.Json": "4.4.0-beta-24911-08",
+    "System.Runtime.Serialization.Primitives": "4.4.0-beta-24911-08",
+    "System.Runtime.Serialization.Xml": "4.4.0-beta-24911-08",
+    "System.Security.Cryptography.Algorithms": "4.4.0-beta-24911-08",
+    "System.Text.Encoding": "4.4.0-beta-24911-08",
+    "System.Text.Encoding.Extensions": "4.4.0-beta-24911-08",
+    "System.Text.RegularExpressions": "4.4.0-beta-24911-08",
+    "System.Threading": "4.4.0-beta-24911-08",
+    "System.Threading.AccessControl": "4.4.0-beta-24911-08",
+    "System.Threading.Overlapped": "4.4.0-beta-24911-08",
+    "System.Threading.Tasks": "4.4.0-beta-24911-08",
+    "System.Threading.Tasks.Parallel": "4.4.0-beta-24911-08",
+    "System.Threading.ThreadPool": "4.4.0-beta-24911-08",
+    "System.Threading.Timer": "4.4.0-beta-24911-08",
+    "System.Xml.ReaderWriter": "4.4.0-beta-24911-08",
+    "System.Xml.XDocument": "4.4.0-beta-24911-08",
+    "System.Xml.XmlDocument": "4.4.0-beta-24911-08",
+    "System.Xml.XPath": "4.4.0-beta-24911-08",
+    "System.Xml.XPath.XmlDocument": "4.4.0-beta-24911-08",
+    "System.Numerics.Vectors": "4.4.0-beta-24911-08"
   },
   "frameworks": {
     "netcoreapp1.1": {
index 2c7c15f..7c65ce1 100644 (file)
@@ -1,9 +1,9 @@
 {
   "dependencies": {
     "Microsoft.DotNet.CoreCLR.TestDependencies": "1.0.0-prerelease",
-    "jit-dasm": "0.0.1.1",
+    "jit-dasm": "0.0.1.4",
     "cijobs": "0.0.1.2",
-    "jit-analyze": "0.0.1.0"
+    "jit-analyze": "0.0.1.1"
   },
   "frameworks": {
     "netcoreapp1.1": {
index ad53846..d6233b1 100644 (file)
@@ -23,6 +23,7 @@ public class Test {
         int[] array2 = new int[40000];
         int memnew = (int) GC.GetTotalMemory(false);
         Console.WriteLine("Total Memory: " + memnew);
+        GC.KeepAlive(array2);
 
         if(memnew >= memold) {
             Console.WriteLine("Test for GC.TotalMemory passed!");
diff --git a/tests/src/JIT/Performance/CodeQuality/BenchmarksGame/binarytrees/binarytrees.csharp3.cs b/tests/src/JIT/Performance/CodeQuality/BenchmarksGame/binarytrees/binarytrees.csharp3.cs
new file mode 100644 (file)
index 0000000..6dcf48a
--- /dev/null
@@ -0,0 +1,142 @@
+// 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 Computer Language Benchmarks Game
+   http://benchmarksgame.alioth.debian.org/
+
+   Based on code originally contributed by Marek Safar
+   and optimized by kasthack
+
+   modified for use with xunit-performance
+*/
+
+using Microsoft.Xunit.Performance;
+using System;
+using System.Runtime.CompilerServices;
+using Xunit;
+
+[assembly: OptimizeForBenchmarks]
+[assembly: MeasureInstructionsRetired]
+[assembly: MeasureGCCounts]
+
+namespace BenchmarksGame
+{
+public class BinaryTrees3
+{
+    private const int minDepth = 4;
+    private const int Iterations = 1;
+
+    [MethodImpl(MethodImplOptions.NoInlining)]
+    private static bool Bench(bool verbose = false)
+    {
+        int n = 16;
+        int maxDepth = Math.Max(minDepth + 2, n);
+        int stretchDepth = maxDepth + 1;
+        int t = 0;
+
+        int check = (TreeNode.bottomUpTree(0, stretchDepth)).itemCheck();
+        if (verbose)
+        {
+            Console.WriteLine("stretch tree of depth {0}\t check: {1}", stretchDepth, check);
+        }
+        t += check;
+
+        TreeNode longLivedTree = TreeNode.bottomUpTree(0, maxDepth);
+
+        for (int depth = minDepth; depth <= maxDepth; depth += 2)
+        {
+            int iterations = 1 << (maxDepth - depth + minDepth);
+
+            check = 0;
+            for (int i = 1; i <= iterations; i++)
+            {
+                check += (TreeNode.bottomUpTree(i, depth)).itemCheck();
+                check += (TreeNode.bottomUpTree(-i, depth)).itemCheck();
+            }
+
+            if (verbose)
+            {
+                Console.WriteLine("{0}\t trees of depth {1}\t check: {2}",
+                    iterations * 2, depth, check);
+            }
+
+            t += check;
+        }
+
+        if (verbose)
+        {
+            Console.WriteLine("long lived tree of depth {0}\t check: {1}",
+                maxDepth, longLivedTree.itemCheck());
+        }
+
+        t += check;
+
+        return (t == -174785);
+    }
+
+    private class TreeNode
+    {
+        private TreeNode left, right;
+        private int item;
+
+        private TreeNode(int item)
+        {
+            this.item = item;
+        }
+
+        internal static TreeNode bottomUpTree(int item, int depth)
+        {
+            TreeNode t;
+            ChildTreeNodes(out t, item, depth - 1);
+            return t;
+        }
+
+        static void ChildTreeNodes(out TreeNode node, int item, int depth)
+        {
+            node = new TreeNode(item);
+            if ( depth > 0 )
+            {
+                ChildTreeNodes(out node.left, 2 * item - 1, depth - 1);
+                ChildTreeNodes(out node.right, 2 * item, depth - 1);
+            }
+        }
+
+        internal int itemCheck()
+        {
+            if (right == null) return item;
+            else return item + left.itemCheck() - right.itemCheck();
+        }
+    }
+
+    [Benchmark]
+    public static void Test()
+    {
+        foreach (var iteration in Benchmark.Iterations)
+        {
+            using (iteration.StartMeasurement())
+            {
+                for (int i = 0; i < Iterations; i++)
+                {
+                    Bench();
+                }
+            }
+        }
+    }
+
+    private static bool TestBase()
+    {
+        bool result = true;
+        for (int i = 0; i < Iterations; i++)
+        {
+            result &= Bench(true);
+        }
+        return result;
+    }
+
+    public static int Main()
+    {
+        bool result = TestBase();
+        return (result ? 100 : -1);
+    }
+}
+}
index d970a78..257a1d8 100644 (file)
@@ -20,6 +20,8 @@
   <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
   </PropertyGroup>
   <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+  </PropertyGroup>
+  <PropertyGroup>
     <DebugType>pdbonly</DebugType>
     <Optimize>true</Optimize>
   </PropertyGroup>
diff --git a/tests/src/JIT/Performance/CodeQuality/BenchmarksGame/binarytrees/binarytrees3.csproj b/tests/src/JIT/Performance/CodeQuality/BenchmarksGame/binarytrees/binarytrees3.csproj
new file mode 100644 (file)
index 0000000..169e33d
--- /dev/null
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <SchemaVersion>2.0</SchemaVersion>
+    <ProjectGuid>{95DFC527-4DC1-495E-97D7-E94EE1F7140D}</ProjectGuid>
+    <OutputType>Exe</OutputType>
+    <AppDesignerFolder>Properties</AppDesignerFolder>
+    <FileAlignment>512</FileAlignment>
+    <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
+    <ReferencePath>$(ProgramFiles)\Common Files\microsoft shared\VSTT\11.0\UITestExtensionPackages</ReferencePath>
+    <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\</SolutionDir>
+    <NuGetPackageImportStamp>7a9bfb7d</NuGetPackageImportStamp>
+    <NuGetTargetMoniker>.NETStandard,Version=v1.4</NuGetTargetMoniker>
+    <GCStressIncompatible>true</GCStressIncompatible>
+  </PropertyGroup>
+  <!-- Default configurations to help VS understand the configurations -->
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+  </PropertyGroup>
+  <PropertyGroup>
+    <DebugType>pdbonly</DebugType>
+    <Optimize>true</Optimize>
+  </PropertyGroup>
+  <ItemGroup>
+    <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies">
+      <Visible>False</Visible>
+    </CodeAnalysisDependentAssemblyPaths>
+  </ItemGroup>
+  <ItemGroup>
+    <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="binarytrees.csharp3.cs" />
+  </ItemGroup>
+  <PropertyGroup>
+    <ProjectJson>$(JitPackagesConfigFileDirectory)benchmark\project.json</ProjectJson>
+    <ProjectLockJson>$(JitPackagesConfigFileDirectory)benchmark\project.lock.json</ProjectLockJson>
+  </PropertyGroup>
+  <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
+  <PropertyGroup Condition=" '$(MsBuildProjectDirOverride)' != '' ">
+  </PropertyGroup>
+</Project>
index 34c0ab8..3253e25 100644 (file)
@@ -62,9 +62,9 @@ public static class SeekUnroll
     // Iteration counts for inner loop set to have each call take 1 or
     // 2 seconds or so in release, finish quickly in debug.
 #if DEBUG
-    const int InnerIterations = 1;
+    static int InnerIterations = 1;
 #else
-    const int InnerIterations = 1000000000;
+    static int InnerIterations = 1000000000;
 #endif
 
     // Function to meaure InnerLoop using the xunit-perf benchmark measurement facilities
@@ -143,6 +143,14 @@ public static class SeekUnroll
     public static int Main()
     {
         int failures = 0;
+
+        // On non-hardware accelerated platforms, the test times out because it runs for too long.
+        // In those cases, we decrease InnerIterations so the test doesn't time out.
+        if (!Vector.IsHardwareAccelerated)
+        {
+            InnerIterations = 100000;
+        }
+
         foreach(int index in IndicesToTest)
         {
             ManualLoopTimes = new long[10];
index 0b1dfce..abeaa01 100644 (file)
@@ -133,7 +133,7 @@ public class AA<TA, TB, TC, TD, TE, TF>
         do
         {
             bool[, , , ,][,] local8 = (new bool[81u, 98u, ((uint)(58.0f)), ((uint)(36.0f)),
-                74u][,]);
+                74u*4u][,]);
             while ((((uint)(local5)) != 4u))
             {
                 if (Convert.ToBoolean((local5 + local5)))
index dd22305..78fb304 100644 (file)
@@ -4,23 +4,23 @@
     "Microsoft.DotNet.xunit.performance": "1.0.0-alpha-build0040",
     "Microsoft.DotNet.xunit.performance.analysis": "1.0.0-alpha-build0040",
     "Microsoft.DotNet.xunit.performance.runner.Windows": "1.0.0-alpha-build0040",
-    "Microsoft.NETCore.Platforms": "1.2.0-beta-24906-02",
-    "System.Console": "4.4.0-beta-24906-02",
-    "System.Dynamic.Runtime": "4.4.0-beta-24906-02",
-    "System.Linq": "4.4.0-beta-24906-02",
-    "System.IO.FileSystem": "4.4.0-beta-24906-02",
-    "System.Numerics.Vectors": "4.4.0-beta-24906-02",
-    "System.Reflection": "4.4.0-beta-24906-02",
-    "System.Reflection.Extensions": "4.4.0-beta-24906-02",
-    "System.Reflection.TypeExtensions": "4.4.0-beta-24906-02",
-    "System.Runtime": "4.4.0-beta-24906-02",
-    "System.Runtime.Extensions": "4.4.0-beta-24906-02",
-    "System.Runtime.Numerics": "4.4.0-beta-24906-02",
-    "System.Text.RegularExpressions": "4.4.0-beta-24906-02",
-    "System.Threading": "4.4.0-beta-24906-02",
-    "System.Threading.Tasks": "4.4.0-beta-24906-02",
-    "System.Threading.Tasks.Parallel": "4.4.0-beta-24906-02",
-    "System.Security.Cryptography.Algorithms": "4.4.0-beta-24906-02",
+    "Microsoft.NETCore.Platforms": "1.2.0-beta-24911-08",
+    "System.Console": "4.4.0-beta-24911-08",
+    "System.Dynamic.Runtime": "4.4.0-beta-24911-08",
+    "System.Linq": "4.4.0-beta-24911-08",
+    "System.IO.FileSystem": "4.4.0-beta-24911-08",
+    "System.Numerics.Vectors": "4.4.0-beta-24911-08",
+    "System.Reflection": "4.4.0-beta-24911-08",
+    "System.Reflection.Extensions": "4.4.0-beta-24911-08",
+    "System.Reflection.TypeExtensions": "4.4.0-beta-24911-08",
+    "System.Runtime": "4.4.0-beta-24911-08",
+    "System.Runtime.Extensions": "4.4.0-beta-24911-08",
+    "System.Runtime.Numerics": "4.4.0-beta-24911-08",
+    "System.Text.RegularExpressions": "4.4.0-beta-24911-08",
+    "System.Threading": "4.4.0-beta-24911-08",
+    "System.Threading.Tasks": "4.4.0-beta-24911-08",
+    "System.Threading.Tasks.Parallel": "4.4.0-beta-24911-08",
+    "System.Security.Cryptography.Algorithms": "4.4.0-beta-24911-08",
     "xunit": "2.2.0-beta2-build3300",
     "xunit.console.netcore": "1.0.2-prerelease-00177",
     "xunit.runner.utility": "2.2.0-beta2-build3300"
index 8564733..d8cd769 100644 (file)
@@ -3,24 +3,24 @@
     "Microsoft.DotNet.xunit.performance": "1.0.0-alpha-build0040",
     "Microsoft.DotNet.xunit.performance.analysis": "1.0.0-alpha-build0040",
     "Microsoft.DotNet.xunit.performance.runner.Windows": "1.0.0-alpha-build0040",
-    "Microsoft.NETCore.Platforms": "1.2.0-beta-24906-02",
+    "Microsoft.NETCore.Platforms": "1.2.0-beta-24911-08",
     "Newtonsoft.Json": "7.0.1",
-    "System.Console": "4.4.0-beta-24906-02",
-    "System.IO": "4.4.0-beta-24906-02",
-    "System.IO.FileSystem": "4.4.0-beta-24906-02",
-    "System.Linq": "4.4.0-beta-24906-02",
-    "System.ObjectModel": "4.4.0-beta-24906-02",
-    "System.Dynamic.Runtime": "4.4.0-beta-24906-02",
-    "System.Reflection": "4.4.0-beta-24906-02",
-    "System.Reflection.Extensions": "4.4.0-beta-24906-02",
-    "System.Reflection.TypeExtensions": "4.4.0-beta-24906-02",
-    "System.Runtime": "4.4.0-beta-24906-02",
-    "System.Runtime.Serialization.Json": "4.4.0-beta-24906-02",
-    "System.Runtime.Serialization.Primitives": "4.4.0-beta-24906-02",
-    "System.Runtime.Serialization.Xml": "4.4.0-beta-24906-02",
-    "System.Text.RegularExpressions": "4.4.0-beta-24906-02",
-    "System.Xml.XmlDocument": "4.4.0-beta-24906-02",
-    "System.Xml.XmlSerializer": "4.4.0-beta-24906-02",
+    "System.Console": "4.4.0-beta-24911-08",
+    "System.IO": "4.4.0-beta-24911-08",
+    "System.IO.FileSystem": "4.4.0-beta-24911-08",
+    "System.Linq": "4.4.0-beta-24911-08",
+    "System.ObjectModel": "4.4.0-beta-24911-08",
+    "System.Dynamic.Runtime": "4.4.0-beta-24911-08",
+    "System.Reflection": "4.4.0-beta-24911-08",
+    "System.Reflection.Extensions": "4.4.0-beta-24911-08",
+    "System.Reflection.TypeExtensions": "4.4.0-beta-24911-08",
+    "System.Runtime": "4.4.0-beta-24911-08",
+    "System.Runtime.Serialization.Json": "4.4.0-beta-24911-08",
+    "System.Runtime.Serialization.Primitives": "4.4.0-beta-24911-08",
+    "System.Runtime.Serialization.Xml": "4.4.0-beta-24911-08",
+    "System.Text.RegularExpressions": "4.4.0-beta-24911-08",
+    "System.Xml.XmlDocument": "4.4.0-beta-24911-08",
+    "System.Xml.XmlSerializer": "4.4.0-beta-24911-08",
     "xunit": "2.2.0-beta2-build3300",
     "xunit.console.netcore": "1.0.2-prerelease-00177",
     "xunit.runner.utility": "2.2.0-beta2-build3300"
index 71e8539..e9baf38 100644 (file)
@@ -3,27 +3,27 @@
     "Microsoft.DotNet.xunit.performance": "1.0.0-alpha-build0040",
     "Microsoft.DotNet.xunit.performance.analysis": "1.0.0-alpha-build0040",
     "Microsoft.DotNet.xunit.performance.runner.Windows": "1.0.0-alpha-build0040",
-    "Microsoft.NETCore.Platforms": "1.2.0-beta-24906-02",
-    "System.Collections.NonGeneric": "4.4.0-beta-24906-02",
-    "System.Console": "4.4.0-beta-24906-02",
-    "System.IO.FileSystem": "4.4.0-beta-24906-02",
-    "System.Linq": "4.4.0-beta-24906-02",
-    "System.Linq.Expressions": "4.4.0-beta-24906-02",
-    "System.Numerics.Vectors": "4.4.0-beta-24906-02",
-    "System.Reflection": "4.4.0-beta-24906-02",
-    "System.Reflection.Extensions": "4.4.0-beta-24906-02",
-    "System.Reflection.TypeExtensions": "4.4.0-beta-24906-02",
-    "System.Runtime": "4.4.0-beta-24906-02",
-    "System.Runtime.Extensions": "4.4.0-beta-24906-02",
-    "System.Runtime.Numerics": "4.4.0-beta-24906-02",
-    "System.Text.RegularExpressions": "4.4.0-beta-24906-02",
-    "System.Threading": "4.4.0-beta-24906-02",
-    "System.Threading.Tasks": "4.4.0-beta-24906-02",
-    "System.Threading.Tasks.Parallel": "4.4.0-beta-24906-02",
-    "System.Diagnostics.Process": "4.4.0-beta-24906-02",
-    "System.Xml.XmlDocument": "4.4.0-beta-24906-02",
-    "System.Xml.XPath": "4.4.0-beta-24906-02",
-    "System.Xml.XPath.XmlDocument": "4.4.0-beta-24906-02",
+    "Microsoft.NETCore.Platforms": "1.2.0-beta-24911-08",
+    "System.Collections.NonGeneric": "4.4.0-beta-24911-08",
+    "System.Console": "4.4.0-beta-24911-08",
+    "System.IO.FileSystem": "4.4.0-beta-24911-08",
+    "System.Linq": "4.4.0-beta-24911-08",
+    "System.Linq.Expressions": "4.4.0-beta-24911-08",
+    "System.Numerics.Vectors": "4.4.0-beta-24911-08",
+    "System.Reflection": "4.4.0-beta-24911-08",
+    "System.Reflection.Extensions": "4.4.0-beta-24911-08",
+    "System.Reflection.TypeExtensions": "4.4.0-beta-24911-08",
+    "System.Runtime": "4.4.0-beta-24911-08",
+    "System.Runtime.Extensions": "4.4.0-beta-24911-08",
+    "System.Runtime.Numerics": "4.4.0-beta-24911-08",
+    "System.Text.RegularExpressions": "4.4.0-beta-24911-08",
+    "System.Threading": "4.4.0-beta-24911-08",
+    "System.Threading.Tasks": "4.4.0-beta-24911-08",
+    "System.Threading.Tasks.Parallel": "4.4.0-beta-24911-08",
+    "System.Diagnostics.Process": "4.4.0-beta-24911-08",
+    "System.Xml.XmlDocument": "4.4.0-beta-24911-08",
+    "System.Xml.XPath": "4.4.0-beta-24911-08",
+    "System.Xml.XPath.XmlDocument": "4.4.0-beta-24911-08",
     "xunit": "2.2.0-beta2-build3300",
     "xunit.console.netcore": "1.0.2-prerelease-00177",
     "xunit.runner.utility": "2.2.0-beta2-build3300"
index b1279c8..68e00db 100644 (file)
@@ -1,21 +1,21 @@
 {
   "dependencies": {
-    "Microsoft.NETCore.Platforms": "1.2.0-beta-24906-02",
-    "System.Collections": "4.4.0-beta-24906-02",
-    "System.Console": "4.4.0-beta-24906-02",
-    "System.Diagnostics.Debug": "4.4.0-beta-24906-02",
-    "System.Runtime.InteropServices.RuntimeInformation": "4.4.0-beta-24906-02",
-    "System.Diagnostics.Process": "4.4.0-beta-24906-02",
-    "System.Globalization": "4.4.0-beta-24906-02",
-    "System.IO": "4.4.0-beta-24906-02",
-    "System.IO.FileSystem": "4.4.0-beta-24906-02",
-    "System.Reflection": "4.4.0-beta-24906-02",
-    "System.Reflection.Extensions": "4.4.0-beta-24906-02",
-    "System.Reflection.TypeExtensions": "4.4.0-beta-24906-02",
-    "System.Runtime": "4.4.0-beta-24906-02",
-    "System.Runtime.Extensions": "4.4.0-beta-24906-02",
-    "System.Runtime.CompilerServices.Unsafe": "4.4.0-beta-24906-02",
-    "System.Runtime.InteropServices": "4.4.0-beta-24906-02"
+    "Microsoft.NETCore.Platforms": "1.2.0-beta-24911-08",
+    "System.Collections": "4.4.0-beta-24911-08",
+    "System.Console": "4.4.0-beta-24911-08",
+    "System.Diagnostics.Debug": "4.4.0-beta-24911-08",
+    "System.Runtime.InteropServices.RuntimeInformation": "4.4.0-beta-24911-08",
+    "System.Diagnostics.Process": "4.4.0-beta-24911-08",
+    "System.Globalization": "4.4.0-beta-24911-08",
+    "System.IO": "4.4.0-beta-24911-08",
+    "System.IO.FileSystem": "4.4.0-beta-24911-08",
+    "System.Reflection": "4.4.0-beta-24911-08",
+    "System.Reflection.Extensions": "4.4.0-beta-24911-08",
+    "System.Reflection.TypeExtensions": "4.4.0-beta-24911-08",
+    "System.Runtime": "4.4.0-beta-24911-08",
+    "System.Runtime.Extensions": "4.4.0-beta-24911-08",
+    "System.Runtime.CompilerServices.Unsafe": "4.4.0-beta-24911-08",
+    "System.Runtime.InteropServices": "4.4.0-beta-24911-08"
   },
   "frameworks": {
     "netcoreapp1.1": {}
index f7120df..1c549c2 100644 (file)
@@ -1,10 +1,10 @@
 {
   "dependencies": {
-    "Microsoft.NETCore.Platforms": "1.2.0-beta-24906-02",
-    "System.Console": "4.4.0-beta-24906-02",
-    "System.Runtime": "4.4.0-beta-24906-02",
-    "System.Runtime.Extensions": "4.4.0-beta-24906-02",
-    "System.Runtime.InteropServices": "4.4.0-beta-24906-02"
+    "Microsoft.NETCore.Platforms": "1.2.0-beta-24911-08",
+    "System.Console": "4.4.0-beta-24911-08",
+    "System.Runtime": "4.4.0-beta-24911-08",
+    "System.Runtime.Extensions": "4.4.0-beta-24911-08",
+    "System.Runtime.InteropServices": "4.4.0-beta-24911-08"
   },
   "frameworks": {
     "netcoreapp1.1": {}
index 4653ee8..6b95e22 100644 (file)
@@ -1,12 +1,12 @@
 {
   "dependencies": {
-    "Microsoft.NETCore.Platforms": "1.2.0-beta-24906-02",
-    "System.Console": "4.4.0-beta-24906-02",
-    "System.Numerics.Vectors": "4.4.0-beta-24906-02",
-    "System.Runtime": "4.4.0-beta-24906-02",
-    "System.Runtime.Extensions": "4.4.0-beta-24906-02",
-    "System.Threading": "4.4.0-beta-24906-02",
-    "System.Threading.Thread": "4.4.0-beta-24906-02"
+    "Microsoft.NETCore.Platforms": "1.2.0-beta-24911-08",
+    "System.Console": "4.4.0-beta-24911-08",
+    "System.Numerics.Vectors": "4.4.0-beta-24911-08",
+    "System.Runtime": "4.4.0-beta-24911-08",
+    "System.Runtime.Extensions": "4.4.0-beta-24911-08",
+    "System.Threading": "4.4.0-beta-24911-08",
+    "System.Threading.Thread": "4.4.0-beta-24911-08"
   },
   "frameworks": {
     "netcoreapp1.1": {}
index 2d9c3c2..6d2e73d 100644 (file)
@@ -1,10 +1,10 @@
 {
   "dependencies": {
-    "Microsoft.NETCore.Platforms": "1.2.0-beta-24906-02",
-    "System.Console": "4.4.0-beta-24906-02",
-    "System.Runtime": "4.4.0-beta-24906-02",
-    "System.Runtime.Extensions": "4.4.0-beta-24906-02",
-    "System.Threading": "4.4.0-beta-24906-02"
+    "Microsoft.NETCore.Platforms": "1.2.0-beta-24911-08",
+    "System.Console": "4.4.0-beta-24911-08",
+    "System.Runtime": "4.4.0-beta-24911-08",
+    "System.Runtime.Extensions": "4.4.0-beta-24911-08",
+    "System.Threading": "4.4.0-beta-24911-08"
   },
   "frameworks": {
     "netcoreapp1.1": {}
index 0886950..3ad363f 100644 (file)
@@ -29,6 +29,8 @@
   <PropertyGroup>
     <DebugType>Full</DebugType>
     <Optimize>True</Optimize>
+    <!-- This test is very resource heavy and doesn't play well with some JitStress modes, especially when memory is limited -->
+    <JitOptimizationSensitive Condition="'$(Platform)' == 'x86'">true</JitOptimizationSensitive>
   </PropertyGroup>
   <ItemGroup>
     <Compile Include="hugeexpr1.cs" />
@@ -43,4 +45,4 @@
   <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
   <PropertyGroup Condition=" '$(MsBuildProjectDirOverride)' != '' ">
   </PropertyGroup>
-</Project>
\ No newline at end of file
+</Project>
index 83a29aa..1a4b952 100644 (file)
@@ -162,7 +162,7 @@ public class AA<TA, TB, TC, TD, TE, TF>
         do
         {
             bool[,,,,][,] local8 = (new bool[81u, 98u, ((uint)(58.0f)), ((uint)(36.0f)),
-                74u][,]);
+                74u*4u][,]);
             while ((((uint)(local5)) != 4u))
             {
                 if (Convert.ToBoolean((local5 + local5)))
index 71e8539..e9baf38 100644 (file)
@@ -3,27 +3,27 @@
     "Microsoft.DotNet.xunit.performance": "1.0.0-alpha-build0040",
     "Microsoft.DotNet.xunit.performance.analysis": "1.0.0-alpha-build0040",
     "Microsoft.DotNet.xunit.performance.runner.Windows": "1.0.0-alpha-build0040",
-    "Microsoft.NETCore.Platforms": "1.2.0-beta-24906-02",
-    "System.Collections.NonGeneric": "4.4.0-beta-24906-02",
-    "System.Console": "4.4.0-beta-24906-02",
-    "System.IO.FileSystem": "4.4.0-beta-24906-02",
-    "System.Linq": "4.4.0-beta-24906-02",
-    "System.Linq.Expressions": "4.4.0-beta-24906-02",
-    "System.Numerics.Vectors": "4.4.0-beta-24906-02",
-    "System.Reflection": "4.4.0-beta-24906-02",
-    "System.Reflection.Extensions": "4.4.0-beta-24906-02",
-    "System.Reflection.TypeExtensions": "4.4.0-beta-24906-02",
-    "System.Runtime": "4.4.0-beta-24906-02",
-    "System.Runtime.Extensions": "4.4.0-beta-24906-02",
-    "System.Runtime.Numerics": "4.4.0-beta-24906-02",
-    "System.Text.RegularExpressions": "4.4.0-beta-24906-02",
-    "System.Threading": "4.4.0-beta-24906-02",
-    "System.Threading.Tasks": "4.4.0-beta-24906-02",
-    "System.Threading.Tasks.Parallel": "4.4.0-beta-24906-02",
-    "System.Diagnostics.Process": "4.4.0-beta-24906-02",
-    "System.Xml.XmlDocument": "4.4.0-beta-24906-02",
-    "System.Xml.XPath": "4.4.0-beta-24906-02",
-    "System.Xml.XPath.XmlDocument": "4.4.0-beta-24906-02",
+    "Microsoft.NETCore.Platforms": "1.2.0-beta-24911-08",
+    "System.Collections.NonGeneric": "4.4.0-beta-24911-08",
+    "System.Console": "4.4.0-beta-24911-08",
+    "System.IO.FileSystem": "4.4.0-beta-24911-08",
+    "System.Linq": "4.4.0-beta-24911-08",
+    "System.Linq.Expressions": "4.4.0-beta-24911-08",
+    "System.Numerics.Vectors": "4.4.0-beta-24911-08",
+    "System.Reflection": "4.4.0-beta-24911-08",
+    "System.Reflection.Extensions": "4.4.0-beta-24911-08",
+    "System.Reflection.TypeExtensions": "4.4.0-beta-24911-08",
+    "System.Runtime": "4.4.0-beta-24911-08",
+    "System.Runtime.Extensions": "4.4.0-beta-24911-08",
+    "System.Runtime.Numerics": "4.4.0-beta-24911-08",
+    "System.Text.RegularExpressions": "4.4.0-beta-24911-08",
+    "System.Threading": "4.4.0-beta-24911-08",
+    "System.Threading.Tasks": "4.4.0-beta-24911-08",
+    "System.Threading.Tasks.Parallel": "4.4.0-beta-24911-08",
+    "System.Diagnostics.Process": "4.4.0-beta-24911-08",
+    "System.Xml.XmlDocument": "4.4.0-beta-24911-08",
+    "System.Xml.XPath": "4.4.0-beta-24911-08",
+    "System.Xml.XPath.XmlDocument": "4.4.0-beta-24911-08",
     "xunit": "2.2.0-beta2-build3300",
     "xunit.console.netcore": "1.0.2-prerelease-00177",
     "xunit.runner.utility": "2.2.0-beta2-build3300"