summaryrefslogtreecommitdiff
path: root/packaging/0013-Implement-JIT_NewArr1_R2R-as-R2R-wrapper-for-JIT_New.patch
blob: 957e1d8759f421cc7c59d49c76d8179031ad327c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
From 6cda73133fcb8785d0c2ab6cb296f956286f4034 Mon Sep 17 00:00:00 2001
From: Ruben Ayrapetyan <ruben-ayrapetyan@users.noreply.github.com>
Date: Tue, 27 Jun 2017 21:31:03 +0300
Subject: [PATCH 13/32] Implement JIT_NewArr1_R2R as R2R wrapper for
 JIT_NewArr1 to support both MethodTable-based and TypeDesc-based helpers.
 (#12475)

Related issue: #12463

FIX: fix No.3, rebased
---
 src/inc/corinfo.h                          |  11 +--
 src/inc/jithelpers.h                       |   1 +
 src/inc/readytorunhelpers.h                |   2 +-
 src/jit/earlyprop.cpp                      |   2 +
 src/jit/importer.cpp                       |   5 +-
 src/jit/utils.cpp                          |   1 +
 src/jit/valuenum.cpp                       |   1 +
 src/vm/jithelpers.cpp                      |  15 ++++
 src/vm/jitinterface.cpp                    |   6 +-
 src/vm/jitinterface.h                      |   1 +
 src/zap/zapinfo.cpp                        |   2 +-
 tests/src/readytorun/tests/newarray.cs     | 126 +++++++++++++++++++++++++++++
 tests/src/readytorun/tests/newarray.csproj |  32 ++++++++
 13 files changed, 195 insertions(+), 10 deletions(-)
 create mode 100644 tests/src/readytorun/tests/newarray.cs
 create mode 100644 tests/src/readytorun/tests/newarray.csproj

diff --git a/src/inc/corinfo.h b/src/inc/corinfo.h
index f6a136c..a6acd71 100644
--- a/src/inc/corinfo.h
+++ b/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 = { /* f00b3f49-ddd2-49be-ba43-6e49ffa66959 */
-    0xf00b3f49,
-    0xddd2,
-    0x49be,
-    { 0xba, 0x43, 0x6e, 0x49, 0xff, 0xa6, 0x69, 0x59 }
+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/inc/jithelpers.h b/src/inc/jithelpers.h
index 4e56250..b45948a 100644
--- a/src/inc/jithelpers.h
+++ b/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/inc/readytorunhelpers.h b/src/inc/readytorunhelpers.h
index 9baf0e4..7a1245c 100644
--- a/src/inc/readytorunhelpers.h
+++ b/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/jit/earlyprop.cpp b/src/jit/earlyprop.cpp
index 51de631..ec460c6 100644
--- a/src/jit/earlyprop.cpp
+++ b/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/jit/importer.cpp b/src/jit/importer.cpp
index 80c0b75..c5f2970 100644
--- a/src/jit/importer.cpp
+++ b/src/jit/importer.cpp
@@ -3004,9 +3004,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/jit/utils.cpp b/src/jit/utils.cpp
index 9fbe394..30ea30a 100644
--- a/src/jit/utils.cpp
+++ b/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/jit/valuenum.cpp b/src/jit/valuenum.cpp
index 5b40122..e4836d6 100644
--- a/src/jit/valuenum.cpp
+++ b/src/jit/valuenum.cpp
@@ -7610,6 +7610,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/vm/jithelpers.cpp b/src/vm/jithelpers.cpp
index 2552b01..0b51339 100644
--- a/src/vm/jithelpers.cpp
+++ b/src/vm/jithelpers.cpp
@@ -3140,6 +3140,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>
 
 /*************************************************************/
diff --git a/src/vm/jitinterface.cpp b/src/vm/jitinterface.cpp
index f756c90..52db7c5 100644
--- a/src/vm/jitinterface.cpp
+++ b/src/vm/jitinterface.cpp
@@ -3412,7 +3412,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/vm/jitinterface.h b/src/vm/jitinterface.h
index a3017ef..d67cfc5 100644
--- a/src/vm/jitinterface.h
+++ b/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/zap/zapinfo.cpp b/src/zap/zapinfo.cpp
index 60e03af..e94dea6 100644
--- a/src/zap/zapinfo.cpp
+++ b/src/zap/zapinfo.cpp
@@ -3384,7 +3384,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/tests/src/readytorun/tests/newarray.cs b/tests/src/readytorun/tests/newarray.cs
new file mode 100644
index 0000000..66917ab
--- /dev/null
+++ b/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<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/tests/src/readytorun/tests/newarray.csproj b/tests/src/readytorun/tests/newarray.csproj
new file mode 100644
index 0000000..21acf81
--- /dev/null
+++ b/tests/src/readytorun/tests/newarray.csproj
@@ -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>
-- 
2.7.4