Skip to content

Commit

Permalink
[netcore] Implement Array.GetElementSize as intrinsic (mono/mono#17437)
Browse files Browse the repository at this point in the history
* [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 mono/mono@32ab6bc
  • Loading branch information
filipnavara authored and vargaz committed Oct 20, 2019
1 parent 158a2ad commit 8d38dd1
Show file tree
Hide file tree
Showing 9 changed files with 26 additions and 22 deletions.
1 change: 0 additions & 1 deletion src/mono/mono/metadata/icall-def-netcore.h
Original file line number Diff line number Diff line change
Expand Up @@ -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))
Expand Down
1 change: 0 additions & 1 deletion src/mono/mono/metadata/icall-def.h
Original file line number Diff line number Diff line change
Expand Up @@ -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))
Expand Down
14 changes: 0 additions & 14 deletions src/mono/mono/metadata/marshal.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
Expand Down
9 changes: 8 additions & 1 deletion src/mono/mono/mini/interp/interp.c
Original file line number Diff line number Diff line change
Expand Up @@ -5361,7 +5361,14 @@ interp_exec_method_full (InterpFrame *frame, ThreadContext *context, FrameClause
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;
}
Expand Down
3 changes: 2 additions & 1 deletion src/mono/mono/mini/interp/mintops.def
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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)
Expand Down
2 changes: 2 additions & 0 deletions src/mono/mono/mini/interp/transform.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
11 changes: 11 additions & 0 deletions src/mono/mono/mini/intrinsics.c
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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
/*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,6 @@ partial class Marshal
[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);

Expand Down
4 changes: 3 additions & 1 deletion src/mono/netcore/System.Private.CoreLib/src/System/Array.cs
Original file line number Diff line number Diff line change
Expand Up @@ -465,9 +465,11 @@ internal ref byte GetRawArrayData ()
return ref Unsafe.As<RawData>(this).Data;
}

[Intrinsic]
internal int GetElementSize ()
{
return Marshal.GetArrayElementSize (GetType ());
ThrowHelper.ThrowNotSupportedException ();
return 0;
}

[MethodImplAttribute (MethodImplOptions.InternalCall)]
Expand Down

0 comments on commit 8d38dd1

Please sign in to comment.