From 8d38dd17a889f3d8a1e4256b9dae81c22d7ced25 Mon Sep 17 00:00:00 2001 From: Filip Navara Date: Mon, 21 Oct 2019 00:39:39 +0200 Subject: [PATCH] [netcore] Implement Array.GetElementSize as intrinsic (mono/mono#17437) * [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 | 1 - src/mono/mono/metadata/icall-def.h | 1 - src/mono/mono/metadata/marshal.c | 14 -------------- src/mono/mono/mini/interp/interp.c | 9 ++++++++- src/mono/mono/mini/interp/mintops.def | 3 ++- src/mono/mono/mini/interp/transform.c | 2 ++ src/mono/mono/mini/intrinsics.c | 11 +++++++++++ .../src/System.Runtime.InteropServices/Marshal.cs | 3 --- .../netcore/System.Private.CoreLib/src/System/Array.cs | 4 +++- 9 files changed, 26 insertions(+), 22 deletions(-) diff --git a/src/mono/mono/metadata/icall-def-netcore.h b/src/mono/mono/metadata/icall-def-netcore.h index 3d9a3e6..d221baf 100644 --- a/src/mono/mono/metadata/icall-def-netcore.h +++ b/src/mono/mono/metadata/icall-def-netcore.h @@ -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)) diff --git a/src/mono/mono/metadata/icall-def.h b/src/mono/mono/metadata/icall-def.h index 40a926e..c7d66c1 100644 --- a/src/mono/mono/metadata/icall-def.h +++ b/src/mono/mono/metadata/icall-def.h @@ -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)) diff --git a/src/mono/mono/metadata/marshal.c b/src/mono/mono/metadata/marshal.c index b8d7803..e93a251 100644 --- a/src/mono/mono/metadata/marshal.c +++ b/src/mono/mono/metadata/marshal.c @@ -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) { diff --git a/src/mono/mono/mini/interp/interp.c b/src/mono/mono/mini/interp/interp.c index 6575d5b..46fba70 100644 --- a/src/mono/mono/mini/interp/interp.c +++ b/src/mono/mono/mini/interp/interp.c @@ -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; } diff --git a/src/mono/mono/mini/interp/mintops.def b/src/mono/mono/mini/interp/mintops.def index 6ad387a..47788c0 100644 --- a/src/mono/mono/mini/interp/mintops.def +++ b/src/mono/mono/mini/interp/mintops.def @@ -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) +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) diff --git a/src/mono/mono/mini/interp/transform.c b/src/mono/mono/mini/interp/transform.c index 45c2f35..857ccac 100644 --- a/src/mono/mono/mini/interp/transform.c +++ b/src/mono/mono/mini/interp/transform.c @@ -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); diff --git a/src/mono/mono/mini/intrinsics.c b/src/mono/mono/mini/intrinsics.c index 5849fda..b42b92f 100644 --- a/src/mono/mono/mini/intrinsics.c +++ b/src/mono/mono/mini/intrinsics.c @@ -15,6 +15,7 @@ #include "debugger-agent.h" #include +#include #include #include #include @@ -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 /* diff --git a/src/mono/netcore/System.Private.CoreLib/src/System.Runtime.InteropServices/Marshal.cs b/src/mono/netcore/System.Private.CoreLib/src/System.Runtime.InteropServices/Marshal.cs index 33bf49d..40bf279 100644 --- a/src/mono/netcore/System.Private.CoreLib/src/System.Runtime.InteropServices/Marshal.cs +++ b/src/mono/netcore/System.Private.CoreLib/src/System.Runtime.InteropServices/Marshal.cs @@ -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); diff --git a/src/mono/netcore/System.Private.CoreLib/src/System/Array.cs b/src/mono/netcore/System.Private.CoreLib/src/System/Array.cs index 001aba2..5ae3c7b 100644 --- a/src/mono/netcore/System.Private.CoreLib/src/System/Array.cs +++ b/src/mono/netcore/System.Private.CoreLib/src/System/Array.cs @@ -465,9 +465,11 @@ namespace System return ref Unsafe.As(this).Data; } + [Intrinsic] internal int GetElementSize () { - return Marshal.GetArrayElementSize (GetType ()); + ThrowHelper.ThrowNotSupportedException (); + return 0; } [MethodImplAttribute (MethodImplOptions.InternalCall)] -- 2.7.4