summaryrefslogtreecommitdiff
path: root/tests/src/jit
diff options
context:
space:
mode:
authorAndy Ayers <andya@microsoft.com>2016-11-21 15:44:21 -0800
committerAndy Ayers <andya@microsoft.com>2016-12-05 13:18:42 -0800
commit043fe32b7489952a62b2cb0cbe41de86895075a3 (patch)
tree019a471453c1e1079d99c97c3f9439c85bd721be /tests/src/jit
parent75a625faaddcd45b5ab396019dc1623dfe3b35c1 (diff)
downloadcoreclr-043fe32b7489952a62b2cb0cbe41de86895075a3.tar.gz
coreclr-043fe32b7489952a62b2cb0cbe41de86895075a3.tar.bz2
coreclr-043fe32b7489952a62b2cb0cbe41de86895075a3.zip
JIT: enable inline pinvoke in more cases
An inline pinvoke is a pinvoke where the managed/native transition overhead is reduced by inlining parts of the transition bookkeeping around the call site. A normal pinvoke does this bookkeeping in a stub method that interposes between the managed caller and the native callee. Previously the jit would not allow pinvoke calls that came from inlines to be optimized via inline pinvoke. This sometimes caused performance surprises for users who wrap DLL imports with managed methods. See for instance #2373. This change lifts this limitation. Pinvokes from inlined method bodies are now given the same treatment as pinvokes in the root method. The legality check for inline pinvokes has been streamlined slightly to remove a redundant check. Inline pinvokes introduced by inlining are handled by accumulating the unmanaged method count with the value from inlinees, and deferring insertion of the special basic blocks until after inlining, so that if the only inline pinvokes come from inline instances they are still properly processed. Inline pinvokes are still disallowed in try and handler regions (catches, filters, and finallies). X87 liveness tracking was updated to handle the implicit inline frame var references. This was a pre-existing issue that now can show up more frequently. Added a test case that fails with the stock legacy jit (and also with the new enhancements to pinvoke). Now both the original failing case and this case pass. Inline pinvokes are also now suppressed in rarely executed blocks, for instance blocks leading up to throws or similar. The inliner is now also changed to preferentially report inline reasons as forced instead of always when both are applicable. This change adds a new test case that shows the variety of situations that can occur with pinvoke, inlining, and EH.
Diffstat (limited to 'tests/src/jit')
-rw-r--r--tests/src/jit/Directed/pinvoke/pinvoke-bug.cs60
-rw-r--r--tests/src/jit/Directed/pinvoke/pinvoke-bug.csproj44
2 files changed, 104 insertions, 0 deletions
diff --git a/tests/src/jit/Directed/pinvoke/pinvoke-bug.cs b/tests/src/jit/Directed/pinvoke/pinvoke-bug.cs
new file mode 100644
index 0000000000..2d4b5f6aea
--- /dev/null
+++ b/tests/src/jit/Directed/pinvoke/pinvoke-bug.cs
@@ -0,0 +1,60 @@
+// 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;
+
+// Test includes an intentional unreachable return
+#pragma warning disable 162
+
+namespace PInvokeTest
+{
+ internal class Test
+ {
+ [DllImport("msvcrt", EntryPoint = "sin")]
+ private static extern double sin(double x);
+
+ private static double g;
+ private static bool b;
+
+ public static int Main(string[] args)
+ {
+ bool result = false;
+ g = 0.0;
+ double val = 1.0;
+ b = false;
+ try
+ {
+ Func(val);
+ }
+ catch(Exception)
+ {
+ result = (Math.Abs(g - sin(val)) < 0.0001);
+ }
+
+ return (result ? 100 : -1);
+ }
+
+ // An inline pinvoke in a method with float math followed by a
+ // throw may causes trouble for liveness models for the inline
+ // frame var.
+ static double Func(double x)
+ {
+ g = sin(x);
+
+ // A bit of control flow to throw off rareness detection
+ // Also we need float in here
+ if (b)
+ {
+ g = 0.0;
+ }
+
+ throw new Exception();
+
+ // Deliberately unreachable return
+ return g;
+ }
+ }
+}
+
diff --git a/tests/src/jit/Directed/pinvoke/pinvoke-bug.csproj b/tests/src/jit/Directed/pinvoke/pinvoke-bug.csproj
new file mode 100644
index 0000000000..2f8a24638b
--- /dev/null
+++ b/tests/src/jit/Directed/pinvoke/pinvoke-bug.csproj
@@ -0,0 +1,44 @@
+<?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>
+ <AssemblyName>$(MSBuildProjectName)</AssemblyName>
+ <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>
+ </PropertyGroup>
+ <!-- Default configurations to help VS understand the configurations -->
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ </PropertyGroup>
+ <ItemGroup>
+ <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies">
+ <Visible>False</Visible>
+ </CodeAnalysisDependentAssemblyPaths>
+ </ItemGroup>
+ <PropertyGroup>
+ <DebugType>PdbOnly</DebugType>
+ </PropertyGroup>
+ <ItemGroup>
+ <Compile Include="pinvoke-bug.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
+ </ItemGroup>
+ <PropertyGroup>
+ <ProjectJson>$(JitPackagesConfigFileDirectory)minimal\project.json</ProjectJson>
+ <ProjectLockJson>$(JitPackagesConfigFileDirectory)minimal\project.lock.json</ProjectLockJson>
+ </PropertyGroup>
+ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
+ <PropertyGroup Condition=" '$(MsBuildProjectDirOverride)' != '' ">
+ </PropertyGroup>
+</Project> \ No newline at end of file