[netcore] Implement Array.GetElementSize as intrinsic (mono/mono#17437)
authorFilip Navara <navara@emclient.com>
Sun, 20 Oct 2019 22:39:39 +0000 (00:39 +0200)
committerZoltan Varga <vargaz@gmail.com>
Sun, 20 Oct 2019 22:39:39 +0000 (18:39 -0400)
* [netcore] Implement Array.GetElementSize as intrinsic

* Remove unnecessary icall

* alloc_preg -> alloc_ireg

* Implement Array.GetElementSize as intrinsic in interpreter

* Address PR feedback

Commit migrated from https://github.com/mono/mono/commit/32ab6bcf004dee2009ab98f9381842ff3fc6e6f2

src/mono/mono/metadata/icall-def-netcore.h
src/mono/mono/metadata/icall-def.h
src/mono/mono/metadata/marshal.c
src/mono/mono/mini/interp/interp.c
src/mono/mono/mini/interp/mintops.def
src/mono/mono/mini/interp/transform.c
src/mono/mono/mini/intrinsics.c
src/mono/netcore/System.Private.CoreLib/src/System.Runtime.InteropServices/Marshal.cs
src/mono/netcore/System.Private.CoreLib/src/System/Array.cs

index 3d9a3e6..d221baf 100644 (file)
@@ -348,7 +348,6 @@ HANDLES(MARSHAL_4, "DestroyStructure", ves_icall_System_Runtime_InteropServices_
 NOHANDLES(ICALL(MARSHAL_5, "FreeBSTR", ves_icall_System_Runtime_InteropServices_Marshal_FreeBSTR))
 NOHANDLES(ICALL(MARSHAL_6, "FreeCoTaskMem", ves_icall_System_Runtime_InteropServices_Marshal_FreeCoTaskMem))
 NOHANDLES(ICALL(MARSHAL_7, "FreeHGlobal", ves_icall_System_Runtime_InteropServices_Marshal_FreeHGlobal))
-HANDLES(MARSHAL_7a, "GetArrayElementSize", ves_icall_System_Runtime_InteropServices_Marshal_GetArrayElementSize, int, 1, (MonoReflectionType))
 HANDLES(MARSHAL_9, "GetDelegateForFunctionPointerInternal", ves_icall_System_Runtime_InteropServices_Marshal_GetDelegateForFunctionPointerInternal, MonoDelegate, 2, (gpointer, MonoReflectionType))
 HANDLES(MARSHAL_10, "GetFunctionPointerForDelegateInternal", ves_icall_System_Runtime_InteropServices_Marshal_GetFunctionPointerForDelegateInternal, gpointer, 1, (MonoDelegate))
 NOHANDLES(ICALL(MARSHAL_11, "GetLastWin32Error", ves_icall_System_Runtime_InteropServices_Marshal_GetLastWin32Error))
index 40a926e..c7d66c1 100644 (file)
@@ -760,7 +760,6 @@ HANDLES(MARSHAL_4, "DestroyStructure", ves_icall_System_Runtime_InteropServices_
 NOHANDLES(ICALL(MARSHAL_5, "FreeBSTR", ves_icall_System_Runtime_InteropServices_Marshal_FreeBSTR))
 NOHANDLES(ICALL(MARSHAL_6, "FreeCoTaskMem", ves_icall_System_Runtime_InteropServices_Marshal_FreeCoTaskMem))
 NOHANDLES(ICALL(MARSHAL_7, "FreeHGlobal", ves_icall_System_Runtime_InteropServices_Marshal_FreeHGlobal))
-HANDLES(MARSHAL_7a, "GetArrayElementSize", ves_icall_System_Runtime_InteropServices_Marshal_GetArrayElementSize, int, 1, (MonoReflectionType))
 #ifndef DISABLE_COM
 HANDLES(MARSHAL_44, "GetCCW", ves_icall_System_Runtime_InteropServices_Marshal_GetCCW, gpointer, 2, (MonoObject, MonoReflectionType))
 HANDLES(MARSHAL_8, "GetComSlotForMethodInfoInternal", ves_icall_System_Runtime_InteropServices_Marshal_GetComSlotForMethodInfoInternal, guint32, 1, (MonoReflectionMethod))
index b8d7803..e93a251 100644 (file)
@@ -5621,20 +5621,6 @@ ves_icall_System_Runtime_InteropServices_Marshal_GetFunctionPointerForDelegateIn
        return mono_delegate_to_ftnptr_impl (delegate, error);
 }
 
-int
-ves_icall_System_Runtime_InteropServices_Marshal_GetArrayElementSize (MonoReflectionTypeHandle type_h, MonoError *error)
-{
-       MonoClass *eklass = mono_type_get_class_internal (MONO_HANDLE_GETVAL (type_h, type));
-
-       mono_class_init_internal (eklass);
-
-       if (m_class_has_references (eklass)) {
-               mono_error_set_argument (error, NULL, NULL);
-               return 0;
-       }
-       return mono_class_array_element_size (eklass);
-}
-
 MonoBoolean
 ves_icall_System_Runtime_InteropServices_Marshal_IsPinnableType (MonoReflectionTypeHandle type_h, MonoError *error)
 {
index 6575d5b..46fba70 100644 (file)
@@ -5361,7 +5361,14 @@ common_vcall:
                MINT_IN_CASE(MINT_ARRAY_RANK) {
                        MonoObject* const o = sp [-1].data.o;
                        NULL_CHECK (o);
-                       sp [-1].data.i = m_class_get_rank (mono_object_class (sp [-1].data.p));
+                       sp [-1].data.i = m_class_get_rank (mono_object_class (o));
+                       ip++;
+                       MINT_IN_BREAK;
+               }
+               MINT_IN_CASE(MINT_ARRAY_ELEMENT_SIZE) {
+                       MonoObject* const o = sp [-1].data.o;
+                       NULL_CHECK (o);
+                       sp [-1].data.i = mono_class_array_element_size (mono_object_class (o));
                        ip++;
                        MINT_IN_BREAK;
                }
index 6ad387a..47788c0 100644 (file)
@@ -56,7 +56,7 @@ OPDEF(MINT_LDARG_R4, "ldarg.r4", 2, Pop0, Push1, MintOpUShortInt)
 OPDEF(MINT_LDARG_R8, "ldarg.r8", 2, Pop0, Push1, MintOpUShortInt)
 OPDEF(MINT_LDARG_O, "ldarg.o", 2, Pop0, Push1, MintOpUShortInt)
 OPDEF(MINT_LDARG_P, "ldarg.p", 2, Pop0, Push1, MintOpUShortInt)
-OPDEF(MINT_LDARG_P0, "ldarg.p0", 1, Pop0, Push1, MintOpNoArgs)\r
+OPDEF(MINT_LDARG_P0, "ldarg.p0", 1, Pop0, Push1, MintOpNoArgs)
 OPDEF(MINT_LDARG_VT, "ldarg.vt", 4, Pop0, Push1, MintOpShortAndInt)
 
 OPDEF(MINT_STARG_I1, "starg.i1", 2, Pop1, Push0, MintOpUShortInt)
@@ -652,6 +652,7 @@ OPDEF(MINT_CKNULL_N, "cknull_n", 2, Pop0, Push0, MintOpUShortInt)
 OPDEF(MINT_GETCHR, "getchr", 1, Pop2, Push1, MintOpNoArgs)
 OPDEF(MINT_STRLEN, "strlen", 1, Pop1, Push1, MintOpNoArgs)
 OPDEF(MINT_ARRAY_RANK, "array_rank", 1, Pop1, Push1, MintOpNoArgs)
+OPDEF(MINT_ARRAY_ELEMENT_SIZE, "array_element_size", 1, Pop1, Push1, MintOpNoArgs)
 
 /* Calls */
 OPDEF(MINT_CALL, "call", 2, VarPop, Push1, MintOpMethodToken)
index 45c2f35..857ccac 100644 (file)
@@ -1481,6 +1481,8 @@ interp_handle_intrinsics (TransformData *td, MonoMethod *target_method, MonoClas
                        *op = MINT_ARRAY_RANK;
                } else if (!strcmp (tm, "get_Length")) {
                        *op = MINT_LDLEN;
+               } else if (!strcmp (tm, "GetElementSize")) {
+                       *op = MINT_ARRAY_ELEMENT_SIZE;
                } else if (!strcmp (tm, "Address")) {
                        MonoClass *check_class = readonly ? NULL : m_class_get_element_class (target_method->klass);
                        interp_emit_ldelema (td, target_method->klass, check_class);
index 5849fda..b42b92f 100644 (file)
@@ -15,6 +15,7 @@
 #include "debugger-agent.h"
 
 #include <mono/metadata/abi-details.h>
+#include <mono/metadata/class-abi-details.h>
 #include <mono/metadata/gc-internals.h>
 #include <mono/metadata/monitor.h>
 #include <mono/utils/mono-memory-model.h>
@@ -725,6 +726,7 @@ mini_emit_inst_for_method (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSign
                if (strcmp (cmethod->name, "GetType") == 0 && fsig->param_count + fsig->hasthis == 1) {
                        int dreg = alloc_ireg_ref (cfg);
                        int vt_reg = alloc_preg (cfg);
+
                        MONO_EMIT_NEW_LOAD_MEMBASE_FAULT (cfg, vt_reg, args [0]->dreg, MONO_STRUCT_OFFSET (MonoObject, vtable));
                        EMIT_NEW_LOAD_MEMBASE (cfg, ins, OP_LOAD_MEMBASE, dreg, vt_reg, MONO_STRUCT_OFFSET (MonoVTable, type));
                        mini_type_from_op (cfg, ins, NULL, NULL);
@@ -755,6 +757,15 @@ mini_emit_inst_for_method (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSign
                        EMIT_NEW_BIALU_IMM (cfg, ins, OP_PADD_IMM, dreg, args [0]->dreg, MONO_STRUCT_OFFSET (MonoArray, vector));
                        return ins;
                }
+               else if (!strcmp (cmethod->name, "GetElementSize")) {
+                       int vt_reg = alloc_preg (cfg);
+                       int class_reg = alloc_preg (cfg);
+                       int sizes_reg = alloc_ireg (cfg);
+                       MONO_EMIT_NEW_LOAD_MEMBASE_FAULT (cfg, vt_reg, args [0]->dreg, MONO_STRUCT_OFFSET (MonoObject, vtable));
+                       EMIT_NEW_LOAD_MEMBASE (cfg, ins, OP_LOAD_MEMBASE, class_reg, vt_reg, MONO_STRUCT_OFFSET (MonoVTable, klass));
+                       EMIT_NEW_LOAD_MEMBASE (cfg, ins, OP_LOADI4_MEMBASE, sizes_reg, class_reg, m_class_offsetof_sizes ());
+                       return ins;
+               }
 
 #ifndef MONO_BIG_ARRAYS
                /*
index 33bf49d..40bf279 100644 (file)
@@ -46,9 +46,6 @@ namespace System.Runtime.InteropServices
                [MethodImplAttribute (MethodImplOptions.InternalCall)]
                public extern static void StructureToPtr (object structure, IntPtr ptr, bool fDeleteOld);
 
-               [MethodImplAttribute (MethodImplOptions.InternalCall)]
-               internal extern static int GetArrayElementSize (Type type);
-
                [MethodImplAttribute(MethodImplOptions.InternalCall)]
                extern unsafe static IntPtr BufferToBSTR (char* ptr, int slen);
 
index 001aba2..5ae3c7b 100644 (file)
@@ -465,9 +465,11 @@ namespace System
                        return ref Unsafe.As<RawData>(this).Data;
                }
 
+               [Intrinsic]
                internal int GetElementSize ()
                {
-                       return Marshal.GetArrayElementSize (GetType ());
+                       ThrowHelper.ThrowNotSupportedException ();
+                       return 0;
                }
 
                [MethodImplAttribute (MethodImplOptions.InternalCall)]