From: Ruben Ayrapetyan Date: Tue, 27 Jun 2017 18:31:03 +0000 (+0300) Subject: Implement JIT_NewArr1_R2R as R2R wrapper for JIT_NewArr1 to support both MethodTable... X-Git-Tag: submit/tizen/20210909.063632~11030^2~6925^2~340 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=c4d762aea9a2b9eeeef5e6af87bfd6716c76818c;p=platform%2Fupstream%2Fdotnet%2Fruntime.git Implement JIT_NewArr1_R2R as R2R wrapper for JIT_NewArr1 to support both MethodTable-based and TypeDesc-based helpers. (dotnet/coreclr#12475) Related issue: dotnet/coreclr#12463 Commit migrated from https://github.com/dotnet/coreclr/commit/3951920cbd825c2b2251ba3572ca354f887d6033 --- diff --git a/src/coreclr/src/inc/corinfo.h b/src/coreclr/src/inc/corinfo.h index e27283c..4af22e5 100644 --- a/src/coreclr/src/inc/corinfo.h +++ b/src/coreclr/src/inc/corinfo.h @@ -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 diff --git a/src/coreclr/src/inc/jithelpers.h b/src/coreclr/src/inc/jithelpers.h index 4e56250..b45948a 100644 --- a/src/coreclr/src/inc/jithelpers.h +++ b/src/coreclr/src/inc/jithelpers.h @@ -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) diff --git a/src/coreclr/src/inc/readytorunhelpers.h b/src/coreclr/src/inc/readytorunhelpers.h index 9baf0e4..7a1245c 100644 --- a/src/coreclr/src/inc/readytorunhelpers.h +++ b/src/coreclr/src/inc/readytorunhelpers.h @@ -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, ) diff --git a/src/coreclr/src/jit/earlyprop.cpp b/src/coreclr/src/jit/earlyprop.cpp index 51de631..ec460c6 100644 --- a/src/coreclr/src/jit/earlyprop.cpp +++ b/src/coreclr/src/jit/earlyprop.cpp @@ -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)) diff --git a/src/coreclr/src/jit/importer.cpp b/src/coreclr/src/jit/importer.cpp index 3564808..c0293c8 100644 --- a/src/coreclr/src/jit/importer.cpp +++ b/src/coreclr/src/jit/importer.cpp @@ -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 ) { diff --git a/src/coreclr/src/jit/utils.cpp b/src/coreclr/src/jit/utils.cpp index bdf1554..b3939cb 100644 --- a/src/coreclr/src/jit/utils.cpp +++ b/src/coreclr/src/jit/utils.cpp @@ -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 diff --git a/src/coreclr/src/jit/valuenum.cpp b/src/coreclr/src/jit/valuenum.cpp index 72fa2fd..8c4fb9b 100644 --- a/src/coreclr/src/jit/valuenum.cpp +++ b/src/coreclr/src/jit/valuenum.cpp @@ -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; diff --git a/src/coreclr/src/vm/jithelpers.cpp b/src/coreclr/src/vm/jithelpers.cpp index e5fc596..b74c410 100644 --- a/src/coreclr/src/vm/jithelpers.cpp +++ b/src/coreclr/src/vm/jithelpers.cpp @@ -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 /*************************************************************/ diff --git a/src/coreclr/src/vm/jitinterface.cpp b/src/coreclr/src/vm/jitinterface.cpp index 5e459af..2fc5e09 100644 --- a/src/coreclr/src/vm/jitinterface.cpp +++ b/src/coreclr/src/vm/jitinterface.cpp @@ -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); } diff --git a/src/coreclr/src/vm/jitinterface.h b/src/coreclr/src/vm/jitinterface.h index 10efca1..125a847 100644 --- a/src/coreclr/src/vm/jitinterface.h +++ b/src/coreclr/src/vm/jitinterface.h @@ -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 diff --git a/src/coreclr/src/zap/zapinfo.cpp b/src/coreclr/src/zap/zapinfo.cpp index 3e4a180..5616212 100644 --- a/src/coreclr/src/zap/zapinfo.cpp +++ b/src/coreclr/src/zap/zapinfo.cpp @@ -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 index 0000000..66917ab --- /dev/null +++ b/src/coreclr/tests/src/readytorun/tests/newarray.cs @@ -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(); + + Assert.AreEqual(arr.GetType().ToString(), "System.Int32[]"); + } + + static void RunTest4() + { + string [] arr = new_array_generic(); + + Assert.AreEqual(arr.GetType().ToString(), "System.String[]"); + } + + static void RunTest5() + { + object [] arr = new_array_generic(); + + Assert.AreEqual(arr.GetType().ToString(), "System.Object[]"); + } + + static void RunTest6() + { + GenericClass1 [] arr = new GenericClass1[ARRAY_SIZE]; + + Assert.AreEqual(arr.GetType().ToString(), "GenericClass1`1[System.Int32][]"); + } + + static void RunTest7() + { + GenericClass1 [] arr = new_array_generic>(); + + Assert.AreEqual(arr.GetType().ToString(), "GenericClass1`1[System.Object][]"); + } + + static void RunTest8() + { + genericclass1_object_array_field = new_array_generic>(); + + Assert.AreEqual(genericclass1_object_array_field.GetType().ToString(), "GenericClass2`1[System.Object][]"); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + static T[] new_array_generic() + { + return new T[ARRAY_SIZE]; + } + + static volatile GenericClass1 [] genericclass1_object_array_field; +} + +class GenericClass1 +{ +} + +class GenericClass2 : GenericClass1 +{ +} + +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 index 0000000..21acf81 --- /dev/null +++ b/src/coreclr/tests/src/readytorun/tests/newarray.csproj @@ -0,0 +1,32 @@ + + + + + newarray + Debug + AnyCPU + 2.0 + {8DDE6EB9-7CAE-4DD1-B2CC-8D756855EF78} + {786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} + true + Exe + BuildAndRun + 0 + + + + + False + + + + + + + + + + + + +