Implement JIT_NewArr1_R2R as R2R wrapper for JIT_NewArr1 to support both MethodTable...
authorRuben Ayrapetyan <ruben-ayrapetyan@users.noreply.github.com>
Tue, 27 Jun 2017 18:31:03 +0000 (21:31 +0300)
committerJan Kotas <jkotas@microsoft.com>
Tue, 27 Jun 2017 18:31:03 +0000 (11:31 -0700)
Related issue: dotnet/coreclr#12463

Commit migrated from https://github.com/dotnet/coreclr/commit/3951920cbd825c2b2251ba3572ca354f887d6033

13 files changed:
src/coreclr/src/inc/corinfo.h
src/coreclr/src/inc/jithelpers.h
src/coreclr/src/inc/readytorunhelpers.h
src/coreclr/src/jit/earlyprop.cpp
src/coreclr/src/jit/importer.cpp
src/coreclr/src/jit/utils.cpp
src/coreclr/src/jit/valuenum.cpp
src/coreclr/src/vm/jithelpers.cpp
src/coreclr/src/vm/jitinterface.cpp
src/coreclr/src/vm/jitinterface.h
src/coreclr/src/zap/zapinfo.cpp
src/coreclr/tests/src/readytorun/tests/newarray.cs [new file with mode: 0644]
src/coreclr/tests/src/readytorun/tests/newarray.csproj [new file with mode: 0644]

index e27283c..4af22e5 100644 (file)
@@ -213,11 +213,11 @@ TODO: Talk about initializing strutures before use
     #define SELECTANY extern __declspec(selectany)
 #endif
 
-SELECTANY const GUID JITEEVersionIdentifier = { /* e5708e9e-dd18-4287-8745-5d10ff2697cf */
-    0xe5708e9e,
-    0xdd18,
-    0x4287,
-    { 0x87, 0x45, 0x5d, 0x10, 0xff, 0x26, 0x97, 0xcf }
+SELECTANY const GUID JITEEVersionIdentifier = { /* 28eb875f-b6a9-4a04-9ba7-69ba59deed46 */
+    0x28eb875f,
+    0xb6a9,
+    0x4a04,
+    { 0x9b, 0xa7, 0x69, 0xba, 0x59, 0xde, 0xed, 0x46 }
 };
 
 //////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -400,6 +400,7 @@ enum CorInfoHelpFunc
     CORINFO_HELP_NEW_MDARR,         // multi-dim array helper (with or without lower bounds - dimensions passed in as vararg)
     CORINFO_HELP_NEW_MDARR_NONVARARG,// multi-dim array helper (with or without lower bounds - dimensions passed in as unmanaged array)
     CORINFO_HELP_NEWARR_1_DIRECT,   // helper for any one dimensional array creation
+    CORINFO_HELP_NEWARR_1_R2R_DIRECT, // wrapper for R2R direct call, which extracts method table from ArrayTypeDesc
     CORINFO_HELP_NEWARR_1_OBJ,      // optimized 1-D object arrays
     CORINFO_HELP_NEWARR_1_VC,       // optimized 1-D value class arrays
     CORINFO_HELP_NEWARR_1_ALIGN8,   // like VC, but aligns the array start
index 4e56250..b45948a 100644 (file)
@@ -77,6 +77,7 @@
     JITHELPER(CORINFO_HELP_NEW_MDARR,                   JIT_NewMDArr,CORINFO_HELP_SIG_8_VA)
     JITHELPER(CORINFO_HELP_NEW_MDARR_NONVARARG,         JIT_NewMDArrNonVarArg,CORINFO_HELP_SIG_4_STACK)
     JITHELPER(CORINFO_HELP_NEWARR_1_DIRECT,             JIT_NewArr1,CORINFO_HELP_SIG_REG_ONLY)
+    JITHELPER(CORINFO_HELP_NEWARR_1_R2R_DIRECT,         JIT_NewArr1_R2R,CORINFO_HELP_SIG_REG_ONLY)
     DYNAMICJITHELPER(CORINFO_HELP_NEWARR_1_OBJ,         JIT_NewArr1,CORINFO_HELP_SIG_REG_ONLY)
     DYNAMICJITHELPER(CORINFO_HELP_NEWARR_1_VC,          JIT_NewArr1,CORINFO_HELP_SIG_REG_ONLY)
     DYNAMICJITHELPER(CORINFO_HELP_NEWARR_1_ALIGN8,      JIT_NewArr1,CORINFO_HELP_SIG_REG_ONLY)
index 9baf0e4..7a1245c 100644 (file)
@@ -46,7 +46,7 @@ HELPER(READYTORUN_HELPER_NewMultiDimArr,            CORINFO_HELP_NEW_MDARR,
 HELPER(READYTORUN_HELPER_NewMultiDimArr_NonVarArg,  CORINFO_HELP_NEW_MDARR_NONVARARG,               )
 
 HELPER(READYTORUN_HELPER_NewObject,                 CORINFO_HELP_NEWFAST,                           )
-HELPER(READYTORUN_HELPER_NewArray,                  CORINFO_HELP_NEWARR_1_DIRECT,                   )
+HELPER(READYTORUN_HELPER_NewArray,                  CORINFO_HELP_NEWARR_1_R2R_DIRECT,               )
 HELPER(READYTORUN_HELPER_CheckCastAny,              CORINFO_HELP_CHKCASTANY,                        )
 HELPER(READYTORUN_HELPER_CheckInstanceAny,          CORINFO_HELP_ISINSTANCEOFANY,                   )
 
index 51de631..ec460c6 100644 (file)
@@ -79,6 +79,7 @@ GenTreePtr Compiler::getArrayLengthFromAllocation(GenTreePtr tree)
         if (call->gtCallType == CT_HELPER)
         {
             if (call->gtCallMethHnd == eeFindHelper(CORINFO_HELP_NEWARR_1_DIRECT) ||
+                call->gtCallMethHnd == eeFindHelper(CORINFO_HELP_NEWARR_1_R2R_DIRECT) ||
                 call->gtCallMethHnd == eeFindHelper(CORINFO_HELP_NEWARR_1_OBJ) ||
                 call->gtCallMethHnd == eeFindHelper(CORINFO_HELP_NEWARR_1_VC) ||
                 call->gtCallMethHnd == eeFindHelper(CORINFO_HELP_NEWARR_1_ALIGN8))
@@ -116,6 +117,7 @@ GenTreePtr Compiler::getObjectHandleNodeFromAllocation(GenTreePtr tree)
                 call->gtCallMethHnd == eeFindHelper(CORINFO_HELP_NEWSFAST) ||
                 call->gtCallMethHnd == eeFindHelper(CORINFO_HELP_NEWSFAST_ALIGN8) ||
                 call->gtCallMethHnd == eeFindHelper(CORINFO_HELP_NEWARR_1_DIRECT) ||
+                call->gtCallMethHnd == eeFindHelper(CORINFO_HELP_NEWARR_1_R2R_DIRECT) ||
                 call->gtCallMethHnd == eeFindHelper(CORINFO_HELP_NEWARR_1_OBJ) ||
                 call->gtCallMethHnd == eeFindHelper(CORINFO_HELP_NEWARR_1_VC) ||
                 call->gtCallMethHnd == eeFindHelper(CORINFO_HELP_NEWARR_1_ALIGN8))
index 3564808..c0293c8 100644 (file)
@@ -3007,9 +3007,10 @@ GenTreePtr Compiler::impInitializeArrayIntrinsic(CORINFO_SIG_INFO* sig)
     if (newArrayCall->gtCall.gtCallMethHnd != eeFindHelper(CORINFO_HELP_NEWARR_1_DIRECT) &&
         newArrayCall->gtCall.gtCallMethHnd != eeFindHelper(CORINFO_HELP_NEWARR_1_OBJ) &&
         newArrayCall->gtCall.gtCallMethHnd != eeFindHelper(CORINFO_HELP_NEWARR_1_VC) &&
-        newArrayCall->gtCall.gtCallMethHnd != eeFindHelper(CORINFO_HELP_NEWARR_1_ALIGN8)
+        newArrayCall->gtCall.gtCallMethHnd != eeFindHelper(CORINFO_HELP_NEWARR_1_ALIGN8) &&
 #ifdef FEATURE_READYTORUN_COMPILER
-        && newArrayCall->gtCall.gtCallMethHnd != eeFindHelper(CORINFO_HELP_READYTORUN_NEWARR_1)
+        newArrayCall->gtCall.gtCallMethHnd != eeFindHelper(CORINFO_HELP_NEWARR_1_R2R_DIRECT) &&
+        newArrayCall->gtCall.gtCallMethHnd != eeFindHelper(CORINFO_HELP_READYTORUN_NEWARR_1)
 #endif
             )
     {
index bdf1554..b3939cb 100644 (file)
@@ -1315,6 +1315,7 @@ void HelperCallProperties::init()
             case CORINFO_HELP_NEW_MDARR:
             case CORINFO_HELP_NEWARR_1_DIRECT:
             case CORINFO_HELP_NEWARR_1_OBJ:
+            case CORINFO_HELP_NEWARR_1_R2R_DIRECT:
             case CORINFO_HELP_READYTORUN_NEWARR_1:
 
                 mayFinalize   = true; // These may run a finalizer
index 72fa2fd..8c4fb9b 100644 (file)
@@ -7652,6 +7652,7 @@ VNFunc Compiler::fgValueNumberHelperMethVNFunc(CorInfoHelpFunc helpFunc)
             vnf = VNF_JitNewArr;
             break;
 
+        case CORINFO_HELP_NEWARR_1_R2R_DIRECT:
         case CORINFO_HELP_READYTORUN_NEWARR_1:
             vnf = VNF_JitReadyToRunNewArr;
             break;
index e5fc596..b74c410 100644 (file)
@@ -3139,6 +3139,21 @@ HCIMPL2(Object*, JIT_NewArr1OBJ_MP_FastPortable, CORINFO_CLASS_HANDLE arrayMT, I
 }
 HCIMPLEND
 
+//*************************************************************
+// R2R-specific array allocation wrapper that extracts array method table from ArrayTypeDesc
+//
+HCIMPL2(Object*, JIT_NewArr1_R2R, CORINFO_CLASS_HANDLE arrayTypeHnd_, INT_PTR size)
+{
+    FCALL_CONTRACT;
+
+    TypeHandle arrayTypeHandle(arrayTypeHnd_);
+    ArrayTypeDesc *pArrayTypeDesc = arrayTypeHandle.AsArray();
+    MethodTable *pArrayMT = pArrayTypeDesc->GetTemplateMethodTable();
+
+    return HCCALL2(JIT_NewArr1, (CORINFO_CLASS_HANDLE)pArrayMT, size);
+}
+HCIMPLEND
+
 #include <optdefault.h>
 
 /*************************************************************/
index 5e459af..2fc5e09 100644 (file)
@@ -3356,7 +3356,11 @@ NoSpecialCase:
         {
             if (pResolvedToken->tokenType == CORINFO_TOKENKIND_Newarr)
             {
-                sigBuilder.AppendElementType((CorElementType)ELEMENT_TYPE_NATIVE_ARRAY_TEMPLATE_ZAPSIG);
+                if (!IsReadyToRunCompilation())
+                {
+                    sigBuilder.AppendElementType((CorElementType)ELEMENT_TYPE_NATIVE_ARRAY_TEMPLATE_ZAPSIG);
+                }
+
                 sigBuilder.AppendElementType(ELEMENT_TYPE_SZARRAY);
             }
 
index 10efca1..125a847 100644 (file)
@@ -217,6 +217,7 @@ extern FCDECL1(StringObject*, FramedAllocateString, DWORD stringLength);
 
 extern FCDECL2(Object*, JIT_NewArr1VC_MP_FastPortable, CORINFO_CLASS_HANDLE arrayMT, INT_PTR size);
 extern FCDECL2(Object*, JIT_NewArr1OBJ_MP_FastPortable, CORINFO_CLASS_HANDLE arrayMT, INT_PTR size);
+extern FCDECL2(Object*, JIT_NewArr1_R2R, CORINFO_CLASS_HANDLE arrayTypeHnd_, INT_PTR size);
 extern FCDECL2(Object*, JIT_NewArr1, CORINFO_CLASS_HANDLE arrayMT, INT_PTR size);
 
 #ifndef JIT_Stelem_Ref
index 3e4a180..5616212 100644 (file)
@@ -3378,7 +3378,7 @@ CorInfoHelpFunc ZapInfo::getCastingHelper(CORINFO_RESOLVED_TOKEN * pResolvedToke
 CorInfoHelpFunc ZapInfo::getNewArrHelper(CORINFO_CLASS_HANDLE arrayCls)
 {
        if (IsReadyToRunCompilation())
-               return CORINFO_HELP_NEWARR_1_DIRECT;
+               return CORINFO_HELP_NEWARR_1_R2R_DIRECT;
 
        return m_pEEJitInfo->getNewArrHelper(arrayCls);
 }
diff --git a/src/coreclr/tests/src/readytorun/tests/newarray.cs b/src/coreclr/tests/src/readytorun/tests/newarray.cs
new file mode 100644 (file)
index 0000000..66917ab
--- /dev/null
@@ -0,0 +1,126 @@
+// 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.Collections.Generic;
+using System.Globalization;
+using System.Runtime.CompilerServices;
+using System.Text;
+using System.Threading;
+
+class Program
+{
+    const int ARRAY_SIZE = 1024;
+
+    static int Main()
+    {
+        // Run all tests 3x times to exercise both slow and fast paths work
+        for (int i = 0; i < 3; i++)
+            RunAllTests();
+
+        Console.WriteLine(Assert.HasAssertFired ? "FAILED" : "PASSED");
+        return Assert.HasAssertFired ? 1 : 100;
+    }
+
+    static void RunAllTests()
+    {
+        RunTest1();
+        RunTest2();
+        RunTest3();
+        RunTest4();
+        RunTest5();
+        RunTest6();
+        RunTest7();
+        RunTest8();
+    }
+
+    static void RunTest1()
+    {
+        int [] arr = new int[ARRAY_SIZE];
+
+        Assert.AreEqual(arr.GetType().ToString(), "System.Int32[]");
+    }
+
+    static void RunTest2()
+    {
+        object [] arr = new object[ARRAY_SIZE];
+
+        Assert.AreEqual(arr.GetType().ToString(), "System.Object[]");
+    }
+
+    static void RunTest3()
+    {
+        int [] arr = new_array_generic<int>();
+
+        Assert.AreEqual(arr.GetType().ToString(), "System.Int32[]");
+    }
+
+    static void RunTest4()
+    {
+        string [] arr = new_array_generic<string>();
+
+        Assert.AreEqual(arr.GetType().ToString(), "System.String[]");
+    }
+
+    static void RunTest5()
+    {
+        object [] arr = new_array_generic<object>();
+
+        Assert.AreEqual(arr.GetType().ToString(), "System.Object[]");
+    }
+
+    static void RunTest6()
+    {
+        GenericClass1<int> [] arr = new GenericClass1<int>[ARRAY_SIZE];
+
+        Assert.AreEqual(arr.GetType().ToString(), "GenericClass1`1[System.Int32][]");
+    }
+
+    static void RunTest7()
+    {
+        GenericClass1<object> [] arr = new_array_generic<GenericClass1<object>>();
+
+        Assert.AreEqual(arr.GetType().ToString(), "GenericClass1`1[System.Object][]");
+    }
+
+    static void RunTest8()
+    {
+        genericclass1_object_array_field = new_array_generic<GenericClass2<object>>();
+
+        Assert.AreEqual(genericclass1_object_array_field.GetType().ToString(), "GenericClass2`1[System.Object][]");
+    }
+
+    [MethodImpl(MethodImplOptions.NoInlining)]
+    static T[] new_array_generic<T>()
+    {
+        return new T[ARRAY_SIZE];
+    }
+
+    static volatile GenericClass1<object> [] genericclass1_object_array_field;
+}
+
+class GenericClass1<T>
+{
+}
+
+class GenericClass2<T> : GenericClass1<T>
+{
+}
+
+public static class Assert
+{
+    public static bool HasAssertFired;
+
+    public static void AreEqual(Object actual, Object expected)
+    {
+        if (!(actual == null && expected == null) && !actual.Equals(expected))
+        {
+            Console.WriteLine("Not equal!");
+            Console.WriteLine("actual   = " + actual.ToString());
+            Console.WriteLine("expected = " + expected.ToString());
+            HasAssertFired = true;
+        }
+    }
+}
diff --git a/src/coreclr/tests/src/readytorun/tests/newarray.csproj b/src/coreclr/tests/src/readytorun/tests/newarray.csproj
new file mode 100644 (file)
index 0000000..21acf81
--- /dev/null
@@ -0,0 +1,32 @@
+<?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>
+    <AssemblyName>newarray</AssemblyName>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <SchemaVersion>2.0</SchemaVersion>
+    <ProjectGuid>{8DDE6EB9-7CAE-4DD1-B2CC-8D756855EF78}</ProjectGuid>
+    <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
+    <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
+    <OutputType>Exe</OutputType>
+    <CLRTestKind>BuildAndRun</CLRTestKind>
+    <CLRTestPriority>0</CLRTestPriority>
+  </PropertyGroup>
+
+  <ItemGroup>
+    <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies">
+      <Visible>False</Visible>
+    </CodeAnalysisDependentAssemblyPaths>
+  </ItemGroup>
+
+  <ItemGroup>
+    <Compile Include="newarray.cs" />
+  </ItemGroup>
+
+
+  <ItemGroup>
+    <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
+  </ItemGroup>
+  <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
+</Project>