From a94fa0652fffd7cc3220e096d3ae9c409f126571 Mon Sep 17 00:00:00 2001 From: Zoltan Varga Date: Wed, 7 Dec 2022 05:10:38 -0500 Subject: [PATCH] [mono] Convert Array icalls to use ObjectHandleOnStack. (#77343) --- .../src/System/Array.Mono.cs | 87 ++++++++--- .../Reflection/RuntimeMethodInfo.Mono.cs | 2 +- src/mono/mono/metadata/icall-decl.h | 13 +- src/mono/mono/metadata/icall-def.h | 16 +- src/mono/mono/metadata/icall.c | 147 ++++++++++-------- src/mono/mono/metadata/object-internals.h | 3 + src/mono/mono/metadata/object.c | 27 ++-- 7 files changed, 178 insertions(+), 117 deletions(-) diff --git a/src/mono/System.Private.CoreLib/src/System/Array.Mono.cs b/src/mono/System.Private.CoreLib/src/System/Array.Mono.cs index efb6229b01422d..7e00ff24a20e82 100644 --- a/src/mono/System.Private.CoreLib/src/System/Array.Mono.cs +++ b/src/mono/System.Private.CoreLib/src/System/Array.Mono.cs @@ -128,7 +128,9 @@ private static void Copy(Array sourceArray, int sourceIndex, Array destinationAr if (destinationIndex < 0) throw new ArgumentOutOfRangeException(nameof(destinationIndex), "Value has to be >= 0."); - if (FastCopy(sourceArray, sourceIndex, destinationArray, destinationIndex, length)) + var src = sourceArray; + var dst = destinationArray; + if (FastCopy(ObjectHandleOnStack.Create(ref src), sourceIndex, ObjectHandleOnStack.Create(ref dst), destinationIndex, length)) return; CopySlow(sourceArray, sourceIndex, destinationArray, destinationIndex, length, reliable); @@ -168,7 +170,8 @@ private static void CopySlow(Array sourceArray, int sourceIndex, Array destinati if (reliable) { if (!dst_type.Equals(src_type) && - !(dst_type.IsPrimitive && src_type.IsPrimitive && CanChangePrimitive(ref dst_type, ref src_type, true))) + !(dst_type.IsPrimitive && src_type.IsPrimitive && + CanChangePrimitive(ObjectHandleOnStack.Create(ref dst_type), ObjectHandleOnStack.Create(ref src_type), true))) { throw new ArrayTypeMismatchException(SR.ArrayTypeMismatch_CantAssignType); } @@ -181,18 +184,25 @@ private static void CopySlow(Array sourceArray, int sourceIndex, Array destinati } } + Array src = sourceArray; + ObjectHandleOnStack src_handle = ObjectHandleOnStack.Create(ref src); + Array dst = destinationArray; + ObjectHandleOnStack dst_handle = ObjectHandleOnStack.Create(ref dst); + object? srcval = null; + ObjectHandleOnStack val_handle = ObjectHandleOnStack.Create(ref srcval); + if (!ReferenceEquals(sourceArray, destinationArray) || source_pos > dest_pos) { for (int i = 0; i < length; i++) { - object srcval = sourceArray.GetValueImpl(source_pos + i); + GetValueImpl(src_handle, val_handle, source_pos + i); if (dst_type_vt && (srcval == null || (src_type == typeof(object) && !dst_elem_type.IsAssignableFrom (srcval.GetType())))) throw new InvalidCastException(SR.InvalidCast_DownCastArrayElement); try { - destinationArray.SetValueRelaxedImpl(srcval, dest_pos + i); + SetValueRelaxedImpl(dst_handle, val_handle, dest_pos + i); } catch (ArgumentException) { @@ -204,11 +214,11 @@ private static void CopySlow(Array sourceArray, int sourceIndex, Array destinati { for (int i = length - 1; i >= 0; i--) { - object srcval = sourceArray.GetValueImpl(source_pos + i); + GetValueImpl(src_handle, val_handle, source_pos + i); try { - destinationArray.SetValueRelaxedImpl(srcval, dest_pos + i); + SetValueRelaxedImpl(dst_handle, val_handle, dest_pos + i); } catch (ArgumentException) { @@ -254,9 +264,8 @@ private static bool CanAssignArrayElement(Type source, Type target) } else if (source.IsPrimitive && target.IsPrimitive) { - // Allow primitive type widening - return CanChangePrimitive(ref source, ref target, false); + return CanChangePrimitive(ObjectHandleOnStack.Create(ref source), ObjectHandleOnStack.Create(ref target), false); } else if (!source.IsValueType && !source.IsPointer) { @@ -319,7 +328,10 @@ private unsafe nint GetFlattenedIndex(ReadOnlySpan indices) if (GetType().GetElementType()!.IsPointer) throw new NotSupportedException(SR.NotSupported_Type); - return GetValueImpl((int)index); + Array self = this; + object? res = null; + GetValueImpl(ObjectHandleOnStack.Create(ref self), ObjectHandleOnStack.Create(ref res), (int)index); + return res; } internal void InternalSetValue(object? value, nint index) @@ -327,7 +339,8 @@ internal void InternalSetValue(object? value, nint index) if (GetType().GetElementType()!.IsPointer) throw new NotSupportedException(SR.NotSupported_Type); - SetValueImpl(value, (int)index); + Array self = this; + SetValueImpl(ObjectHandleOnStack.Create(ref self), ObjectHandleOnStack.Create(ref value), (int)index); } public void Initialize() @@ -351,6 +364,32 @@ public int GetUpperBound(int dimension) return GetLowerBound(dimension) + GetLength(dimension) - 1; } + internal CorElementType GetCorElementTypeOfElementType() + { + object arr = this; + return GetCorElementTypeOfElementTypeInternal(ObjectHandleOnStack.Create(ref arr)); + } + + private bool IsValueOfElementType(object value) + { + object arr = this; + return IsValueOfElementTypeInternal(ObjectHandleOnStack.Create(ref arr), ObjectHandleOnStack.Create(ref value)); + } + + [Intrinsic] // when dimension is `0` constant + public int GetLength(int dimension) + { + object arr = this; + return GetLengthInternal(ObjectHandleOnStack.Create(ref arr), dimension); + } + + [Intrinsic] // when dimension is `0` constant + public int GetLowerBound(int dimension) + { + object arr = this; + return GetLowerBoundInternal(ObjectHandleOnStack.Create(ref arr), dimension); + } + [Intrinsic] internal int GetElementSize() => GetElementSize(); @@ -358,61 +397,59 @@ public int GetUpperBound(int dimension) internal bool IsPrimitive() => IsPrimitive(); [MethodImpl(MethodImplOptions.InternalCall)] - internal extern CorElementType GetCorElementTypeOfElementType(); + private static extern CorElementType GetCorElementTypeOfElementTypeInternal(ObjectHandleOnStack arr); [MethodImpl(MethodImplOptions.InternalCall)] - private extern bool IsValueOfElementType(object value); + private static extern bool IsValueOfElementTypeInternal(ObjectHandleOnStack arr, ObjectHandleOnStack obj); [MethodImplAttribute(MethodImplOptions.InternalCall)] - private static extern bool CanChangePrimitive(ref Type srcType, ref Type dstType, bool reliable); + private static extern bool CanChangePrimitive(ObjectHandleOnStack srcType, ObjectHandleOnStack dstType, bool reliable); [MethodImplAttribute(MethodImplOptions.InternalCall)] - internal static extern bool FastCopy(Array source, int source_idx, Array dest, int dest_idx, int length); + internal static extern bool FastCopy(ObjectHandleOnStack source, int source_idx, ObjectHandleOnStack dest, int dest_idx, int length); - [Intrinsic] // when dimension is `0` constant [MethodImplAttribute(MethodImplOptions.InternalCall)] - public extern int GetLength(int dimension); + private static extern int GetLengthInternal(ObjectHandleOnStack arr, int dimension); - [Intrinsic] // when dimension is `0` constant [MethodImplAttribute(MethodImplOptions.InternalCall)] - public extern int GetLowerBound(int dimension); + private static extern int GetLowerBoundInternal(ObjectHandleOnStack arr, int dimension); // CAUTION! No bounds checking! [MethodImplAttribute(MethodImplOptions.InternalCall)] - private static extern void GetGenericValue_icall(ref Array self, int pos, out T value); + private static extern void GetGenericValue_icall(ObjectHandleOnStack self, int pos, out T value); // CAUTION! No bounds checking! [MethodImplAttribute(MethodImplOptions.InternalCall)] - private extern object GetValueImpl(int pos); + private static extern void GetValueImpl(ObjectHandleOnStack arr, ObjectHandleOnStack res, int pos); // CAUTION! No bounds checking! [MethodImplAttribute(MethodImplOptions.InternalCall)] - private static extern void SetGenericValue_icall(ref Array self, int pos, ref T value); + private static extern void SetGenericValue_icall(ObjectHandleOnStack arr, int pos, ref T value); [Intrinsic] private void GetGenericValueImpl(int pos, out T value) { Array self = this; - GetGenericValue_icall(ref self, pos, out value); + GetGenericValue_icall(ObjectHandleOnStack.Create(ref self), pos, out value); } [Intrinsic] private void SetGenericValueImpl(int pos, ref T value) { Array self = this; - SetGenericValue_icall(ref self, pos, ref value); + SetGenericValue_icall(ObjectHandleOnStack.Create(ref self), pos, ref value); } // CAUTION! No bounds checking! [MethodImplAttribute(MethodImplOptions.InternalCall)] - private extern void SetValueImpl(object? value, int pos); + private static extern void SetValueImpl(ObjectHandleOnStack arr, ObjectHandleOnStack value, int pos); [MethodImpl(MethodImplOptions.InternalCall)] private static extern void InitializeInternal(ObjectHandleOnStack arr); // CAUTION! No bounds checking! [MethodImplAttribute(MethodImplOptions.InternalCall)] - private extern void SetValueRelaxedImpl(object? value, int pos); + private static extern void SetValueRelaxedImpl(ObjectHandleOnStack arr, ObjectHandleOnStack value, int pos); #pragma warning disable CA1822 /* diff --git a/src/mono/System.Private.CoreLib/src/System/Reflection/RuntimeMethodInfo.Mono.cs b/src/mono/System.Private.CoreLib/src/System/Reflection/RuntimeMethodInfo.Mono.cs index 6d43a9270910c0..36fe15d5f8afbc 100644 --- a/src/mono/System.Private.CoreLib/src/System/Reflection/RuntimeMethodInfo.Mono.cs +++ b/src/mono/System.Private.CoreLib/src/System/Reflection/RuntimeMethodInfo.Mono.cs @@ -340,7 +340,7 @@ public override ParameterInfo[] GetParameters() // Have to clone because GetParametersInfo icall returns cached value var dest = new ParameterInfo[src.Length]; - Array.FastCopy(src, 0, dest, 0, src.Length); + Array.FastCopy(ObjectHandleOnStack.Create (ref src), 0, ObjectHandleOnStack.Create (ref dest), 0, src.Length); return dest; } diff --git a/src/mono/mono/metadata/icall-decl.h b/src/mono/mono/metadata/icall-decl.h index 7588bb13fc68c4..b166e74107df14 100644 --- a/src/mono/mono/metadata/icall-decl.h +++ b/src/mono/mono/metadata/icall-decl.h @@ -126,8 +126,9 @@ ICALL_EXPORT int ves_icall_System_GC_GetCollectionCount (int); ICALL_EXPORT int ves_icall_System_GC_GetMaxGeneration (void); ICALL_EXPORT gint64 ves_icall_System_GC_GetAllocatedBytesForCurrentThread (void); ICALL_EXPORT int ves_icall_get_method_attributes (MonoMethod* method); -ICALL_EXPORT void ves_icall_System_Array_GetGenericValue_icall (MonoArray**, guint32, gpointer); -ICALL_EXPORT void ves_icall_System_Array_SetGenericValue_icall (MonoArray**, guint32, gpointer); +ICALL_EXPORT void ves_icall_System_Array_GetGenericValue_icall (MonoObjectHandleOnStack arr_handle, guint32 pos, gpointer value); +ICALL_EXPORT void ves_icall_System_Array_SetGenericValue_icall (MonoObjectHandleOnStack *arr_handle, guint32 pos, gpointer value); + ICALL_EXPORT void ves_icall_System_Environment_Exit (int); ICALL_EXPORT void ves_icall_System_GC_InternalCollect (int generation); ICALL_EXPORT void ves_icall_System_GC_RecordPressure (gint64); @@ -139,7 +140,7 @@ ICALL_EXPORT void ves_icall_System_Buffer_BulkMoveWithWriteBarrier (guint8 *, gu ICALL_EXPORT void ves_icall_System_Runtime_RuntimeImports_ZeroMemory (guint8*, size_t); ICALL_EXPORT void ves_icall_System_Array_InternalCreate (MonoArray *volatile* result, MonoType* type, gint32 rank, gint32* pLengths, gint32* pLowerBounds); -ICALL_EXPORT MonoBoolean ves_icall_System_Array_CanChangePrimitive (MonoReflectionType *volatile* ref_src_type_handle, MonoReflectionType *volatile* ref_dst_type_handle, MonoBoolean reliable); +ICALL_EXPORT MonoBoolean ves_icall_System_Array_CanChangePrimitive (MonoObjectHandleOnStack ref_src_type_handle, MonoObjectHandleOnStack ref_dst_type_handle, MonoBoolean reliable); ICALL_EXPORT MonoBoolean ves_icall_System_Diagnostics_Debugger_IsAttached_internal (void); ICALL_EXPORT MonoBoolean ves_icall_System_Diagnostics_Debugger_IsLogging (void); @@ -201,4 +202,10 @@ ICALL_EXPORT gint32 ves_icall_RuntimeType_GetGenericParameterPosition (MonoQCall ICALL_EXPORT int ves_icall_System_Enum_InternalGetCorElementType (MonoQCallTypeHandle type_handle); +ICALL_EXPORT gint32 ves_icall_System_Array_GetCorElementTypeOfElementTypeInternal (MonoObjectHandleOnStack arr_handle); + +ICALL_EXPORT MonoBoolean ves_icall_System_Array_IsValueOfElementTypeInternal (MonoObjectHandleOnStack arr_handle, MonoObjectHandleOnStack obj_handle); + +ICALL_EXPORT MonoBoolean ves_icall_System_Array_FastCopy (MonoObjectHandleOnStack source_handle, int source_idx, MonoObjectHandleOnStack dest_handle, int dest_idx, int length); + #endif // __MONO_METADATA_ICALL_DECL_H__ diff --git a/src/mono/mono/metadata/icall-def.h b/src/mono/mono/metadata/icall-def.h index 467570a2f74683..681f89f1818581 100644 --- a/src/mono/mono/metadata/icall-def.h +++ b/src/mono/mono/metadata/icall-def.h @@ -128,18 +128,18 @@ NOHANDLES(ICALL(ARGI_4, "Setup", ves_icall_System_ArgIterator_Se ICALL_TYPE(ARRAY, "System.Array", ARRAY_0) NOHANDLES(ICALL(ARRAY_0, "CanChangePrimitive", ves_icall_System_Array_CanChangePrimitive)) -HANDLES(ARRAY_4, "FastCopy", ves_icall_System_Array_FastCopy, MonoBoolean, 5, (MonoArray, int, MonoArray, int, int)) -HANDLES(ARRAY_4a, "GetCorElementTypeOfElementType", ves_icall_System_Array_GetCorElementTypeOfElementType, gint32, 1, (MonoArray)) +NOHANDLES(ICALL(ARRAY_4, "FastCopy", ves_icall_System_Array_FastCopy)) +NOHANDLES(ICALL(ARRAY_4a, "GetCorElementTypeOfElementTypeInternal", ves_icall_System_Array_GetCorElementTypeOfElementTypeInternal)) NOHANDLES(ICALL(ARRAY_5, "GetGenericValue_icall", ves_icall_System_Array_GetGenericValue_icall)) -HANDLES(ARRAY_6, "GetLength", ves_icall_System_Array_GetLength, gint32, 2, (MonoArray, gint32)) -HANDLES(ARRAY_7, "GetLowerBound", ves_icall_System_Array_GetLowerBound, gint32, 2, (MonoArray, gint32)) -HANDLES(ARRAY_10, "GetValueImpl", ves_icall_System_Array_GetValueImpl, MonoObject, 2, (MonoArray, guint32)) +HANDLES(ARRAY_6, "GetLengthInternal", ves_icall_System_Array_GetLengthInternal, gint32, 2, (MonoObjectHandleOnStack, gint32)) +HANDLES(ARRAY_7, "GetLowerBoundInternal", ves_icall_System_Array_GetLowerBoundInternal, gint32, 2, (MonoObjectHandleOnStack, gint32)) +HANDLES(ARRAY_10, "GetValueImpl", ves_icall_System_Array_GetValueImpl, void, 3, (MonoObjectHandleOnStack, MonoObjectHandleOnStack, guint32)) HANDLES(ARRAY_10_a, "InitializeInternal", ves_icall_System_Array_InitializeInternal, void, 1, (MonoObjectHandleOnStack)) NOHANDLES(ICALL(ARRAY_10a, "InternalCreate", ves_icall_System_Array_InternalCreate)) -HANDLES(ARRAY_10b, "IsValueOfElementType", ves_icall_System_Array_IsValueOfElementType, gint32, 2, (MonoArray, MonoObject)) +NOHANDLES(ICALL(ARRAY_10b, "IsValueOfElementTypeInternal", ves_icall_System_Array_IsValueOfElementTypeInternal)) NOHANDLES(ICALL(ARRAY_11, "SetGenericValue_icall", ves_icall_System_Array_SetGenericValue_icall)) -HANDLES(ARRAY_13, "SetValueImpl", ves_icall_System_Array_SetValueImpl, void, 3, (MonoArray, MonoObject, guint32)) -HANDLES(ARRAY_14, "SetValueRelaxedImpl", ves_icall_System_Array_SetValueRelaxedImpl, void, 3, (MonoArray, MonoObject, guint32)) +HANDLES(ARRAY_13, "SetValueImpl", ves_icall_System_Array_SetValueImpl, void, 3, (MonoObjectHandleOnStack, MonoObjectHandleOnStack, guint32)) +HANDLES(ARRAY_14, "SetValueRelaxedImpl", ves_icall_System_Array_SetValueRelaxedImpl, void, 3, (MonoObjectHandleOnStack, MonoObjectHandleOnStack, guint32)) ICALL_TYPE(BUFFER, "System.Buffer", BUFFER_0) NOHANDLES(ICALL(BUFFER_0, "BulkMoveWithWriteBarrier", ves_icall_System_Buffer_BulkMoveWithWriteBarrier)) diff --git a/src/mono/mono/metadata/icall.c b/src/mono/mono/metadata/icall.c index 75904f5ad1db18..34a4f476e7d616 100644 --- a/src/mono/mono/metadata/icall.c +++ b/src/mono/mono/metadata/icall.c @@ -148,7 +148,7 @@ icallarray_print (const char *format, ...) static GENERATE_GET_CLASS_WITH_CACHE (module, "System.Reflection", "Module") static void -array_set_value_impl (MonoArrayHandle arr, MonoObjectHandle value, guint32 pos, gboolean strict_enums, gboolean strict_signs, MonoError *error); +array_set_value_impl (MonoArray *arr, MonoObjectHandle value, guint32 pos, gboolean strict_enums, gboolean strict_signs, MonoError *error); static MonoArrayHandle type_array_from_modifiers (MonoType *type, int optional, MonoError *error); @@ -193,31 +193,36 @@ mono_icall_get_file_path_prefix (const gchar *path) MonoJitICallInfos mono_jit_icall_info; -MonoObjectHandle -ves_icall_System_Array_GetValueImpl (MonoArrayHandle array, guint32 pos, MonoError *error) +void +ves_icall_System_Array_GetValueImpl (MonoObjectHandleOnStack array_handle, MonoObjectHandleOnStack res_handle, guint32 pos, MonoError *error) { - MonoClass * const array_class = mono_handle_class (array); + MonoArray *array = *(MonoArray**)array_handle; + MonoClass * const array_class = mono_object_class (array); MonoClass * const element_class = m_class_get_element_class (array_class); if (m_class_is_native_pointer (element_class)) { mono_error_set_not_supported (error, NULL); - return NULL_HANDLE; + return; } if (m_class_is_valuetype (element_class)) { gsize element_size = mono_array_element_size (array_class); - gpointer element_address = mono_array_addr_with_size_fast (MONO_HANDLE_RAW (array), element_size, (gsize)pos); - return mono_value_box_handle (element_class, element_address, error); + gpointer element_address = mono_array_addr_with_size_fast (array, element_size, (gsize)pos); + MonoObject *res = mono_value_box_checked (element_class, element_address, error); + HANDLE_ON_STACK_SET (res_handle, res); + } else { + MonoObject *res = mono_array_get_fast (array, MonoObject*, pos); + HANDLE_ON_STACK_SET (res_handle, res); } - MonoObjectHandle result = mono_new_null (); - mono_handle_array_getref (result, array, pos); - return result; } void -ves_icall_System_Array_SetValueImpl (MonoArrayHandle arr, MonoObjectHandle value, guint32 pos, MonoError *error) +ves_icall_System_Array_SetValueImpl (MonoObjectHandleOnStack arr, MonoObjectHandleOnStack value_handle, guint32 pos, MonoError *error) { - array_set_value_impl (arr, value, pos, TRUE, TRUE, error); + // FIXME: Get rid of handle usage + MonoObjectHandle h = MONO_HANDLE_NEW (MonoObject, *value_handle); + + array_set_value_impl ((MonoArray*)*arr, h, pos, TRUE, TRUE, error); } static inline void @@ -228,9 +233,12 @@ set_invalid_cast (MonoError *error, MonoClass *src_class, MonoClass *dst_class) } void -ves_icall_System_Array_SetValueRelaxedImpl (MonoArrayHandle arr, MonoObjectHandle value, guint32 pos, MonoError *error) +ves_icall_System_Array_SetValueRelaxedImpl (MonoObjectHandleOnStack arr, MonoObjectHandleOnStack value_handle, guint32 pos, MonoError *error) { - array_set_value_impl (arr, value, pos, FALSE, FALSE, error); + // FIXME: Get rid of handle usage + MonoObjectHandle h = MONO_HANDLE_NEW (MonoObject, *value_handle); + + array_set_value_impl ((MonoArray*)*arr, h, pos, FALSE, FALSE, error); } void @@ -309,10 +317,10 @@ get_normalized_integral_array_element_type (MonoTypeEnum elementType) } MonoBoolean -ves_icall_System_Array_CanChangePrimitive (MonoReflectionType *volatile* ref_src_type_handle, MonoReflectionType *volatile* ref_dst_type_handle, MonoBoolean reliable) +ves_icall_System_Array_CanChangePrimitive (MonoObjectHandleOnStack ref_src_type_handle, MonoObjectHandleOnStack ref_dst_type_handle, MonoBoolean reliable) { - MonoReflectionType* const ref_src_type = *ref_src_type_handle; - MonoReflectionType* const ref_dst_type = *ref_dst_type_handle; + MonoReflectionType* const ref_src_type = *(MonoReflectionType**)ref_src_type_handle; + MonoReflectionType* const ref_dst_type = *(MonoReflectionType**)ref_dst_type_handle; MonoType *src_type = ref_src_type->type; MonoType *dst_type = ref_dst_type->type; @@ -339,7 +347,7 @@ ves_icall_System_Array_CanChangePrimitive (MonoReflectionType *volatile* ref_src } static void -array_set_value_impl (MonoArrayHandle arr_handle, MonoObjectHandle value_handle, guint32 pos, gboolean strict_enums, gboolean strict_signs, MonoError *error) +array_set_value_impl (MonoArray *arr, MonoObjectHandle value_handle, guint32 pos, gboolean strict_enums, gboolean strict_signs, MonoError *error) { MonoClass *ac, *vc, *ec; gint32 esize, vsize; @@ -357,7 +365,7 @@ array_set_value_impl (MonoArrayHandle arr_handle, MonoObjectHandle value_handle, else vc = NULL; - ac = mono_handle_class (arr_handle); + ac = mono_object_class (arr); ec = m_class_get_element_class (ac); esize = mono_array_element_size (ac); @@ -369,7 +377,7 @@ array_set_value_impl (MonoArrayHandle arr_handle, MonoObjectHandle value_handle, } MONO_ENTER_NO_SAFEPOINTS; - ea = (gpointer*) mono_array_addr_with_size_internal (MONO_HANDLE_RAW (arr_handle), esize, pos); + ea = (gpointer*) mono_array_addr_with_size_internal (arr, esize, pos); if (!MONO_HANDLE_IS_NULL (value_handle)) va = (gpointer*) mono_object_unbox_internal (MONO_HANDLE_RAW (value_handle)); mono_nullable_init_unboxed ((guint8*)ea, va, ec); @@ -379,7 +387,7 @@ array_set_value_impl (MonoArrayHandle arr_handle, MonoObjectHandle value_handle, if (MONO_HANDLE_IS_NULL (value_handle)) { MONO_ENTER_NO_SAFEPOINTS; - ea = (gpointer*) mono_array_addr_with_size_internal (MONO_HANDLE_RAW (arr_handle), esize, pos); + ea = (gpointer*) mono_array_addr_with_size_internal (arr, esize, pos); mono_gc_bzero_atomic (ea, esize); MONO_EXIT_NO_SAFEPOINTS; goto leave; @@ -456,13 +464,13 @@ array_set_value_impl (MonoArrayHandle arr_handle, MonoObjectHandle value_handle, if (!castOk) INVALID_CAST; if (is_ok (error)) - MONO_HANDLE_ARRAY_SETREF (arr_handle, pos, value_handle); + mono_array_setref_fast (arr, pos, MONO_HANDLE_RAW (value_handle)); goto leave; } if (castOk) { MONO_ENTER_NO_SAFEPOINTS; - ea = (gpointer*) mono_array_addr_with_size_internal (MONO_HANDLE_RAW (arr_handle), esize, pos); + ea = (gpointer*) mono_array_addr_with_size_internal (arr, esize, pos); va = (gpointer*) mono_object_unbox_internal (MONO_HANDLE_RAW (value_handle)); if (m_class_has_references (ec)) mono_value_copy_internal (ea, va, ec); @@ -597,7 +605,7 @@ array_set_value_impl (MonoArrayHandle arr_handle, MonoObjectHandle value_handle, g_assert (!MONO_HANDLE_IS_NULL (value_handle)); g_assert (m_class_is_valuetype (vc)); va = (gpointer*) mono_object_unbox_internal (MONO_HANDLE_RAW (value_handle)); - ea = (gpointer*) mono_array_addr_with_size_internal (MONO_HANDLE_RAW (arr_handle), esize, pos); + ea = (gpointer*) mono_array_addr_with_size_internal (arr, esize, pos); switch (vt) { case MONO_TYPE_U1: @@ -774,36 +782,32 @@ ves_icall_System_Array_InternalCreate (MonoArray *volatile* result, MonoType* ty } gint32 -ves_icall_System_Array_GetCorElementTypeOfElementType (MonoArrayHandle arr, MonoError *error) +ves_icall_System_Array_GetCorElementTypeOfElementTypeInternal (MonoObjectHandleOnStack arr_handle) { - MonoType *type = mono_type_get_underlying_type (m_class_get_byval_arg (m_class_get_element_class (mono_handle_class (arr)))); + MonoArray *arr = *(MonoArray**)arr_handle; + MonoType *type = mono_type_get_underlying_type (m_class_get_byval_arg (m_class_get_element_class (mono_object_class (arr)))); return type->type; } -gint32 -ves_icall_System_Array_IsValueOfElementType (MonoArrayHandle arr, MonoObjectHandle obj, MonoError *error) +MonoBoolean +ves_icall_System_Array_IsValueOfElementTypeInternal (MonoObjectHandleOnStack arr_handle, MonoObjectHandleOnStack obj_handle) { - return m_class_get_element_class (mono_handle_class (arr)) == mono_handle_class (obj); + return m_class_get_element_class (mono_object_class (*arr_handle)) == mono_object_class (*obj_handle); } -static mono_array_size_t -mono_array_get_length (MonoArrayHandle arr, gint32 dimension, MonoError *error) +gint32 +ves_icall_System_Array_GetLengthInternal (MonoObjectHandleOnStack arr_handle, gint32 dimension, MonoError *error) { - if (dimension < 0 || dimension >= m_class_get_rank (mono_handle_class (arr))) { + MonoArray *arr = *(MonoArray**)arr_handle; + + icallarray_print ("%s arr:%p dimension:%d\n", __func__, arr, (int)dimension); + + if (dimension < 0 || dimension >= m_class_get_rank (mono_object_class (arr))) { mono_error_set_index_out_of_range (error); return 0; } - return MONO_HANDLE_GETVAL (arr, bounds) ? MONO_HANDLE_GETVAL (arr, bounds [dimension].length) - : MONO_HANDLE_GETVAL (arr, max_length); -} - -gint32 -ves_icall_System_Array_GetLength (MonoArrayHandle arr, gint32 dimension, MonoError *error) -{ - icallarray_print ("%s arr:%p dimension:%d\n", __func__, MONO_HANDLE_RAW (arr), (int)dimension); - - mono_array_size_t const length = mono_array_get_length (arr, dimension, error); + mono_array_size_t const length = arr->bounds ? arr->bounds [dimension].length : arr->max_length; if (length > G_MAXINT32) { mono_error_set_overflow (error); return 0; @@ -812,30 +816,33 @@ ves_icall_System_Array_GetLength (MonoArrayHandle arr, gint32 dimension, MonoErr } gint32 -ves_icall_System_Array_GetLowerBound (MonoArrayHandle arr, gint32 dimension, MonoError *error) +ves_icall_System_Array_GetLowerBoundInternal (MonoObjectHandleOnStack arr_handle, gint32 dimension, MonoError *error) { - icallarray_print ("%s arr:%p dimension:%d\n", __func__, MONO_HANDLE_RAW (arr), (int)dimension); + MonoArray *arr = *(MonoArray**)arr_handle; - if (dimension < 0 || dimension >= m_class_get_rank (mono_handle_class (arr))) { + icallarray_print ("%s arr:%p dimension:%d\n", __func__, arr, (int)dimension); + + if (dimension < 0 || dimension >= m_class_get_rank (mono_object_class (arr))) { mono_error_set_index_out_of_range (error); return 0; } - return MONO_HANDLE_GETVAL (arr, bounds) ? MONO_HANDLE_GETVAL (arr, bounds [dimension].lower_bound) - : 0; + return arr->bounds ? arr->bounds [dimension].lower_bound : 0; } MonoBoolean -ves_icall_System_Array_FastCopy (MonoArrayHandle source, int source_idx, MonoArrayHandle dest, int dest_idx, int length, MonoError *error) +ves_icall_System_Array_FastCopy (MonoObjectHandleOnStack source_handle, int source_idx, MonoObjectHandleOnStack dest_handle, int dest_idx, int length) { - MonoVTable * const src_vtable = MONO_HANDLE_GETVAL (source, obj.vtable); - MonoVTable * const dest_vtable = MONO_HANDLE_GETVAL (dest, obj.vtable); + MonoArray *source = (MonoArray*)*source_handle; + MonoArray *dest = (MonoArray*)*dest_handle; + MonoVTable *src_vtable = source->obj.vtable; + MonoVTable *dest_vtable = dest->obj.vtable; if (src_vtable->rank != dest_vtable->rank) return FALSE; - MonoArrayBounds *source_bounds = MONO_HANDLE_GETVAL (source, bounds); - MonoArrayBounds *dest_bounds = MONO_HANDLE_GETVAL (dest, bounds); + MonoArrayBounds *source_bounds = source->bounds; + MonoArrayBounds *dest_bounds = dest->bounds; for (int i = 0; i < src_vtable->rank; i++) { if ((source_bounds && source_bounds [i].lower_bound > 0) || @@ -844,8 +851,8 @@ ves_icall_System_Array_FastCopy (MonoArrayHandle source, int source_idx, MonoArr } /* there's no integer overflow since mono_array_length_internal returns an unsigned integer */ - if ((GINT_TO_UINTPTR(dest_idx + length) > mono_array_handle_length (dest)) || - (GINT_TO_UINTPTR(source_idx + length) > mono_array_handle_length (source))) + if ((GINT_TO_UINTPTR(dest_idx + length) > mono_array_length_internal (dest)) || + (GINT_TO_UINTPTR(source_idx + length) > mono_array_length_internal (source))) return FALSE; MonoClass * const src_class = m_class_get_element_class (src_vtable->klass); @@ -876,54 +883,58 @@ ves_icall_System_Array_FastCopy (MonoArrayHandle source, int source_idx, MonoArr } if (m_class_is_valuetype (dest_class)) { - gsize const element_size = mono_array_element_size (MONO_HANDLE_GETVAL (source, obj.vtable->klass)); + gsize const element_size = mono_array_element_size (src_vtable->klass); MONO_ENTER_NO_SAFEPOINTS; // gchandle would also work here, is slow, breaks profiler tests. gconstpointer const source_addr = - mono_array_addr_with_size_fast (MONO_HANDLE_RAW (source), element_size, source_idx); + mono_array_addr_with_size_fast (source, element_size, source_idx); if (m_class_has_references (dest_class)) { - mono_value_copy_array_handle (dest, dest_idx, source_addr, length); + mono_value_copy_array_internal (dest, dest_idx, source_addr, length); } else { gpointer const dest_addr = - mono_array_addr_with_size_fast (MONO_HANDLE_RAW (dest), element_size, dest_idx); + mono_array_addr_with_size_fast (dest, element_size, dest_idx); mono_gc_memmove_atomic (dest_addr, source_addr, element_size * length); } MONO_EXIT_NO_SAFEPOINTS; } else { - mono_array_handle_memcpy_refs (dest, dest_idx, source, source_idx, length); + mono_array_memcpy_refs_fast (dest, dest_idx, source, source_idx, length); } return TRUE; } void -ves_icall_System_Array_GetGenericValue_icall (MonoArray **arr, guint32 pos, gpointer value) +ves_icall_System_Array_GetGenericValue_icall (MonoObjectHandleOnStack arr_handle, guint32 pos, gpointer value) { - icallarray_print ("%s arr:%p pos:%u value:%p\n", __func__, *arr, pos, value); + MonoArray *arr = *(MonoArray**)arr_handle; + + icallarray_print ("%s arr:%p pos:%u value:%p\n", __func__, arr, pos, value); MONO_REQ_GC_UNSAFE_MODE; // because of gpointer value - MonoClass * const ac = mono_object_class (*arr); - gsize const esize = mono_array_element_size (ac); - gconstpointer * const ea = (gconstpointer*)((char*)(*arr)->vector + (pos * esize)); + MonoClass *ac = mono_object_class (arr); + gsize esize = mono_array_element_size (ac); + gconstpointer *ea = (gconstpointer*)mono_array_addr_with_size_fast (arr, esize, pos); mono_gc_memmove_atomic (value, ea, esize); } void -ves_icall_System_Array_SetGenericValue_icall (MonoArray **arr, guint32 pos, gpointer value) +ves_icall_System_Array_SetGenericValue_icall (MonoObjectHandleOnStack *arr_handle, guint32 pos, gpointer value) { - icallarray_print ("%s arr:%p pos:%u value:%p\n", __func__, *arr, pos, value); + MonoArray *arr = *(MonoArray**)arr_handle; + + icallarray_print ("%s arr:%p pos:%u value:%p\n", __func__, arr, pos, value); MONO_REQ_GC_UNSAFE_MODE; // because of gpointer value - MonoClass * const ac = mono_object_class (*arr); + MonoClass * const ac = mono_object_class (arr); MonoClass * const ec = m_class_get_element_class (ac); gsize const esize = mono_array_element_size (ac); - gpointer * const ea = (gpointer*)((char*)(*arr)->vector + (pos * esize)); + gconstpointer *ea = (gconstpointer*)mono_array_addr_with_size_fast (arr, esize, pos); if (MONO_TYPE_IS_REFERENCE (m_class_get_byval_arg (ec))) { g_assert (esize == sizeof (gpointer)); diff --git a/src/mono/mono/metadata/object-internals.h b/src/mono/mono/metadata/object-internals.h index 3967256d5bcbb4..bb6b01a7702ca9 100644 --- a/src/mono/mono/metadata/object-internals.h +++ b/src/mono/mono/metadata/object-internals.h @@ -1810,6 +1810,9 @@ mono_object_handle_isinst_mbyref (MonoObjectHandle obj, MonoClass *klass, MonoEr gboolean mono_object_handle_isinst_mbyref_raw (MonoObjectHandle obj, MonoClass *klass, MonoError *error); +gboolean +mono_object_isinst_vtable_mbyref (MonoVTable *vt, MonoClass *klass, MonoError *error); + MonoStringHandle mono_string_new_size_handle (gint32 len, MonoError *error); diff --git a/src/mono/mono/metadata/object.c b/src/mono/mono/metadata/object.c index fa0b9bf99710d2..752b913b1ada3d 100644 --- a/src/mono/mono/metadata/object.c +++ b/src/mono/mono/metadata/object.c @@ -6720,17 +6720,10 @@ mono_object_handle_isinst_mbyref (MonoObjectHandle obj, MonoClass *klass, MonoEr } gboolean -mono_object_handle_isinst_mbyref_raw (MonoObjectHandle obj, MonoClass *klass, MonoError *error) +mono_object_isinst_vtable_mbyref (MonoVTable *vt, MonoClass *klass, MonoError *error) { - error_init (error); - gboolean result = FALSE; - - if (MONO_HANDLE_IS_NULL (obj)) - goto leave; - - MonoVTable *vt; - vt = MONO_HANDLE_GETVAL (obj, vtable); + MonoClass *oklass = vt->klass; if (mono_class_is_interface (klass)) { if (MONO_VTABLE_IMPLEMENTS_INTERFACE (vt, m_class_get_interface_id (klass))) { @@ -6740,19 +6733,18 @@ mono_object_handle_isinst_mbyref_raw (MonoObjectHandle obj, MonoClass *klass, Mo /* casting an array one of the invariant interfaces that must act as such */ if (m_class_is_array_special_interface (klass)) { - if (mono_class_is_assignable_from_internal (klass, vt->klass)) { + if (mono_class_is_assignable_from_internal (klass, oklass)) { result = TRUE; goto leave; } } /*If the above check fails we are in the slow path of possibly raising an exception. So it's ok to it this way.*/ - else if (mono_class_has_variant_generic_params (klass) && mono_class_is_assignable_from_internal (klass, mono_handle_class (obj))) { + else if (mono_class_has_variant_generic_params (klass) && mono_class_is_assignable_from_internal (klass, oklass)) { result = TRUE; goto leave; } } else { - MonoClass *oklass = vt->klass; mono_class_setup_supertypes (klass); if (mono_class_has_parent_fast (oklass, klass)) { result = TRUE; @@ -6763,6 +6755,17 @@ mono_object_handle_isinst_mbyref_raw (MonoObjectHandle obj, MonoClass *klass, Mo return result; } +gboolean +mono_object_handle_isinst_mbyref_raw (MonoObjectHandle obj, MonoClass *klass, MonoError *error) +{ + error_init (error); + + if (MONO_HANDLE_IS_NULL (obj)) + return FALSE; + else + return mono_object_isinst_vtable_mbyref (MONO_HANDLE_GETVAL (obj, vtable), klass, error); +} + /** * mono_object_castclass_mbyref: * \param obj an object