Skip to content

Commit 7097216

Browse files
committed
[mono] Convert Array icalls to use ObjectHandleOnStack.
1 parent be63af2 commit 7097216

7 files changed

Lines changed: 178 additions & 117 deletions

File tree

src/mono/System.Private.CoreLib/src/System/Array.Mono.cs

Lines changed: 62 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,9 @@ private static void Copy(Array sourceArray, int sourceIndex, Array destinationAr
128128
if (destinationIndex < 0)
129129
throw new ArgumentOutOfRangeException(nameof(destinationIndex), "Value has to be >= 0.");
130130

131-
if (FastCopy(sourceArray, sourceIndex, destinationArray, destinationIndex, length))
131+
var src = sourceArray;
132+
var dst = destinationArray;
133+
if (FastCopy(ObjectHandleOnStack.Create(ref src), sourceIndex, ObjectHandleOnStack.Create(ref dst), destinationIndex, length))
132134
return;
133135

134136
CopySlow(sourceArray, sourceIndex, destinationArray, destinationIndex, length, reliable);
@@ -168,7 +170,8 @@ private static void CopySlow(Array sourceArray, int sourceIndex, Array destinati
168170
if (reliable)
169171
{
170172
if (!dst_type.Equals(src_type) &&
171-
!(dst_type.IsPrimitive && src_type.IsPrimitive && CanChangePrimitive(ref dst_type, ref src_type, true)))
173+
!(dst_type.IsPrimitive && src_type.IsPrimitive &&
174+
CanChangePrimitive(ObjectHandleOnStack.Create(ref dst_type), ObjectHandleOnStack.Create(ref src_type), true)))
172175
{
173176
throw new ArrayTypeMismatchException(SR.ArrayTypeMismatch_CantAssignType);
174177
}
@@ -181,18 +184,25 @@ private static void CopySlow(Array sourceArray, int sourceIndex, Array destinati
181184
}
182185
}
183186

187+
Array src = sourceArray;
188+
ObjectHandleOnStack src_handle = ObjectHandleOnStack.Create(ref src);
189+
Array dst = destinationArray;
190+
ObjectHandleOnStack dst_handle = ObjectHandleOnStack.Create(ref dst);
191+
object? srcval = null;
192+
ObjectHandleOnStack val_handle = ObjectHandleOnStack.Create(ref srcval);
193+
184194
if (!ReferenceEquals(sourceArray, destinationArray) || source_pos > dest_pos)
185195
{
186196
for (int i = 0; i < length; i++)
187197
{
188-
object srcval = sourceArray.GetValueImpl(source_pos + i);
198+
GetValueImpl(src_handle, val_handle, source_pos + i);
189199

190200
if (dst_type_vt && (srcval == null || (src_type == typeof(object) && !dst_elem_type.IsAssignableFrom (srcval.GetType()))))
191201
throw new InvalidCastException(SR.InvalidCast_DownCastArrayElement);
192202

193203
try
194204
{
195-
destinationArray.SetValueRelaxedImpl(srcval, dest_pos + i);
205+
SetValueRelaxedImpl(dst_handle, val_handle, dest_pos + i);
196206
}
197207
catch (ArgumentException)
198208
{
@@ -204,11 +214,11 @@ private static void CopySlow(Array sourceArray, int sourceIndex, Array destinati
204214
{
205215
for (int i = length - 1; i >= 0; i--)
206216
{
207-
object srcval = sourceArray.GetValueImpl(source_pos + i);
217+
GetValueImpl(src_handle, val_handle, source_pos + i);
208218

209219
try
210220
{
211-
destinationArray.SetValueRelaxedImpl(srcval, dest_pos + i);
221+
SetValueRelaxedImpl(dst_handle, val_handle, dest_pos + i);
212222
}
213223
catch (ArgumentException)
214224
{
@@ -254,9 +264,8 @@ private static bool CanAssignArrayElement(Type source, Type target)
254264
}
255265
else if (source.IsPrimitive && target.IsPrimitive)
256266
{
257-
258267
// Allow primitive type widening
259-
return CanChangePrimitive(ref source, ref target, false);
268+
return CanChangePrimitive(ObjectHandleOnStack.Create(ref source), ObjectHandleOnStack.Create(ref target), false);
260269
}
261270
else if (!source.IsValueType && !source.IsPointer)
262271
{
@@ -319,15 +328,19 @@ private unsafe nint GetFlattenedIndex(ReadOnlySpan<int> indices)
319328
if (GetType().GetElementType()!.IsPointer)
320329
throw new NotSupportedException(SR.NotSupported_Type);
321330

322-
return GetValueImpl((int)index);
331+
Array self = this;
332+
object? res = null;
333+
GetValueImpl(ObjectHandleOnStack.Create(ref self), ObjectHandleOnStack.Create(ref res), (int)index);
334+
return res;
323335
}
324336

325337
internal void InternalSetValue(object? value, nint index)
326338
{
327339
if (GetType().GetElementType()!.IsPointer)
328340
throw new NotSupportedException(SR.NotSupported_Type);
329341

330-
SetValueImpl(value, (int)index);
342+
Array self = this;
343+
SetValueImpl(ObjectHandleOnStack.Create(ref self), ObjectHandleOnStack.Create(ref value), (int)index);
331344
}
332345

333346
public void Initialize()
@@ -351,68 +364,92 @@ public int GetUpperBound(int dimension)
351364
return GetLowerBound(dimension) + GetLength(dimension) - 1;
352365
}
353366

367+
internal CorElementType GetCorElementTypeOfElementType()
368+
{
369+
object arr = this;
370+
return GetCorElementTypeOfElementTypeInternal(ObjectHandleOnStack.Create(ref arr));
371+
}
372+
373+
private bool IsValueOfElementType(object value)
374+
{
375+
object arr = this;
376+
return IsValueOfElementTypeInternal(ObjectHandleOnStack.Create(ref arr), ObjectHandleOnStack.Create(ref value));
377+
}
378+
379+
[Intrinsic] // when dimension is `0` constant
380+
public int GetLength(int dimension)
381+
{
382+
object arr = this;
383+
return GetLengthInternal(ObjectHandleOnStack.Create(ref arr), dimension);
384+
}
385+
386+
[Intrinsic] // when dimension is `0` constant
387+
public int GetLowerBound(int dimension)
388+
{
389+
object arr = this;
390+
return GetLowerBoundInternal(ObjectHandleOnStack.Create(ref arr), dimension);
391+
}
392+
354393
[Intrinsic]
355394
internal int GetElementSize() => GetElementSize();
356395

357396
[Intrinsic]
358397
internal bool IsPrimitive() => IsPrimitive();
359398

360399
[MethodImpl(MethodImplOptions.InternalCall)]
361-
internal extern CorElementType GetCorElementTypeOfElementType();
400+
private static extern CorElementType GetCorElementTypeOfElementTypeInternal(ObjectHandleOnStack arr);
362401

363402
[MethodImpl(MethodImplOptions.InternalCall)]
364-
private extern bool IsValueOfElementType(object value);
403+
private static extern bool IsValueOfElementTypeInternal(ObjectHandleOnStack arr, ObjectHandleOnStack obj);
365404

366405
[MethodImplAttribute(MethodImplOptions.InternalCall)]
367-
private static extern bool CanChangePrimitive(ref Type srcType, ref Type dstType, bool reliable);
406+
private static extern bool CanChangePrimitive(ObjectHandleOnStack srcType, ObjectHandleOnStack dstType, bool reliable);
368407

369408
[MethodImplAttribute(MethodImplOptions.InternalCall)]
370-
internal static extern bool FastCopy(Array source, int source_idx, Array dest, int dest_idx, int length);
409+
internal static extern bool FastCopy(ObjectHandleOnStack source, int source_idx, ObjectHandleOnStack dest, int dest_idx, int length);
371410

372-
[Intrinsic] // when dimension is `0` constant
373411
[MethodImplAttribute(MethodImplOptions.InternalCall)]
374-
public extern int GetLength(int dimension);
412+
private static extern int GetLengthInternal(ObjectHandleOnStack arr, int dimension);
375413

376-
[Intrinsic] // when dimension is `0` constant
377414
[MethodImplAttribute(MethodImplOptions.InternalCall)]
378-
public extern int GetLowerBound(int dimension);
415+
private static extern int GetLowerBoundInternal(ObjectHandleOnStack arr, int dimension);
379416

380417
// CAUTION! No bounds checking!
381418
[MethodImplAttribute(MethodImplOptions.InternalCall)]
382-
private static extern void GetGenericValue_icall<T>(ref Array self, int pos, out T value);
419+
private static extern void GetGenericValue_icall<T>(ObjectHandleOnStack self, int pos, out T value);
383420

384421
// CAUTION! No bounds checking!
385422
[MethodImplAttribute(MethodImplOptions.InternalCall)]
386-
private extern object GetValueImpl(int pos);
423+
private static extern void GetValueImpl(ObjectHandleOnStack arr, ObjectHandleOnStack res, int pos);
387424

388425
// CAUTION! No bounds checking!
389426
[MethodImplAttribute(MethodImplOptions.InternalCall)]
390-
private static extern void SetGenericValue_icall<T>(ref Array self, int pos, ref T value);
427+
private static extern void SetGenericValue_icall<T>(ObjectHandleOnStack arr, int pos, ref T value);
391428

392429
[Intrinsic]
393430
private void GetGenericValueImpl<T>(int pos, out T value)
394431
{
395432
Array self = this;
396-
GetGenericValue_icall(ref self, pos, out value);
433+
GetGenericValue_icall(ObjectHandleOnStack.Create(ref self), pos, out value);
397434
}
398435

399436
[Intrinsic]
400437
private void SetGenericValueImpl<T>(int pos, ref T value)
401438
{
402439
Array self = this;
403-
SetGenericValue_icall(ref self, pos, ref value);
440+
SetGenericValue_icall(ObjectHandleOnStack.Create(ref self), pos, ref value);
404441
}
405442

406443
// CAUTION! No bounds checking!
407444
[MethodImplAttribute(MethodImplOptions.InternalCall)]
408-
private extern void SetValueImpl(object? value, int pos);
445+
private static extern void SetValueImpl(ObjectHandleOnStack arr, ObjectHandleOnStack value, int pos);
409446

410447
[MethodImpl(MethodImplOptions.InternalCall)]
411448
private static extern void InitializeInternal(ObjectHandleOnStack arr);
412449

413450
// CAUTION! No bounds checking!
414451
[MethodImplAttribute(MethodImplOptions.InternalCall)]
415-
private extern void SetValueRelaxedImpl(object? value, int pos);
452+
private static extern void SetValueRelaxedImpl(ObjectHandleOnStack arr, ObjectHandleOnStack value, int pos);
416453

417454
#pragma warning disable CA1822
418455
/*

src/mono/System.Private.CoreLib/src/System/Reflection/RuntimeMethodInfo.Mono.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -340,7 +340,7 @@ public override ParameterInfo[] GetParameters()
340340

341341
// Have to clone because GetParametersInfo icall returns cached value
342342
var dest = new ParameterInfo[src.Length];
343-
Array.FastCopy(src, 0, dest, 0, src.Length);
343+
Array.FastCopy(ObjectHandleOnStack.Create (ref src), 0, ObjectHandleOnStack.Create (ref dest), 0, src.Length);
344344
return dest;
345345
}
346346

src/mono/mono/metadata/icall-decl.h

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -126,8 +126,9 @@ ICALL_EXPORT int ves_icall_System_GC_GetCollectionCount (int);
126126
ICALL_EXPORT int ves_icall_System_GC_GetMaxGeneration (void);
127127
ICALL_EXPORT gint64 ves_icall_System_GC_GetAllocatedBytesForCurrentThread (void);
128128
ICALL_EXPORT int ves_icall_get_method_attributes (MonoMethod* method);
129-
ICALL_EXPORT void ves_icall_System_Array_GetGenericValue_icall (MonoArray**, guint32, gpointer);
130-
ICALL_EXPORT void ves_icall_System_Array_SetGenericValue_icall (MonoArray**, guint32, gpointer);
129+
ICALL_EXPORT void ves_icall_System_Array_GetGenericValue_icall (MonoObjectHandleOnStack arr_handle, guint32 pos, gpointer value);
130+
ICALL_EXPORT void ves_icall_System_Array_SetGenericValue_icall (MonoObjectHandleOnStack *arr_handle, guint32 pos, gpointer value);
131+
131132
ICALL_EXPORT void ves_icall_System_Environment_Exit (int);
132133
ICALL_EXPORT void ves_icall_System_GC_InternalCollect (int generation);
133134
ICALL_EXPORT void ves_icall_System_GC_RecordPressure (gint64);
@@ -139,7 +140,7 @@ ICALL_EXPORT void ves_icall_System_Buffer_BulkMoveWithWriteBarrier (guint8 *, gu
139140
ICALL_EXPORT void ves_icall_System_Runtime_RuntimeImports_ZeroMemory (guint8*, size_t);
140141

141142
ICALL_EXPORT void ves_icall_System_Array_InternalCreate (MonoArray *volatile* result, MonoType* type, gint32 rank, gint32* pLengths, gint32* pLowerBounds);
142-
ICALL_EXPORT MonoBoolean ves_icall_System_Array_CanChangePrimitive (MonoReflectionType *volatile* ref_src_type_handle, MonoReflectionType *volatile* ref_dst_type_handle, MonoBoolean reliable);
143+
ICALL_EXPORT MonoBoolean ves_icall_System_Array_CanChangePrimitive (MonoObjectHandleOnStack ref_src_type_handle, MonoObjectHandleOnStack ref_dst_type_handle, MonoBoolean reliable);
143144

144145
ICALL_EXPORT MonoBoolean ves_icall_System_Diagnostics_Debugger_IsAttached_internal (void);
145146
ICALL_EXPORT MonoBoolean ves_icall_System_Diagnostics_Debugger_IsLogging (void);
@@ -201,4 +202,10 @@ ICALL_EXPORT gint32 ves_icall_RuntimeType_GetGenericParameterPosition (MonoQCall
201202

202203
ICALL_EXPORT int ves_icall_System_Enum_InternalGetCorElementType (MonoQCallTypeHandle type_handle);
203204

205+
ICALL_EXPORT gint32 ves_icall_System_Array_GetCorElementTypeOfElementTypeInternal (MonoObjectHandleOnStack arr_handle);
206+
207+
ICALL_EXPORT MonoBoolean ves_icall_System_Array_IsValueOfElementTypeInternal (MonoObjectHandleOnStack arr_handle, MonoObjectHandleOnStack obj_handle);
208+
209+
ICALL_EXPORT MonoBoolean ves_icall_System_Array_FastCopy (MonoObjectHandleOnStack source_handle, int source_idx, MonoObjectHandleOnStack dest_handle, int dest_idx, int length);
210+
204211
#endif // __MONO_METADATA_ICALL_DECL_H__

src/mono/mono/metadata/icall-def.h

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -128,18 +128,18 @@ NOHANDLES(ICALL(ARGI_4, "Setup", ves_icall_System_ArgIterator_Se
128128

129129
ICALL_TYPE(ARRAY, "System.Array", ARRAY_0)
130130
NOHANDLES(ICALL(ARRAY_0, "CanChangePrimitive", ves_icall_System_Array_CanChangePrimitive))
131-
HANDLES(ARRAY_4, "FastCopy", ves_icall_System_Array_FastCopy, MonoBoolean, 5, (MonoArray, int, MonoArray, int, int))
132-
HANDLES(ARRAY_4a, "GetCorElementTypeOfElementType", ves_icall_System_Array_GetCorElementTypeOfElementType, gint32, 1, (MonoArray))
131+
NOHANDLES(ICALL(ARRAY_4, "FastCopy", ves_icall_System_Array_FastCopy))
132+
NOHANDLES(ICALL(ARRAY_4a, "GetCorElementTypeOfElementTypeInternal", ves_icall_System_Array_GetCorElementTypeOfElementTypeInternal))
133133
NOHANDLES(ICALL(ARRAY_5, "GetGenericValue_icall", ves_icall_System_Array_GetGenericValue_icall))
134-
HANDLES(ARRAY_6, "GetLength", ves_icall_System_Array_GetLength, gint32, 2, (MonoArray, gint32))
135-
HANDLES(ARRAY_7, "GetLowerBound", ves_icall_System_Array_GetLowerBound, gint32, 2, (MonoArray, gint32))
136-
HANDLES(ARRAY_10, "GetValueImpl", ves_icall_System_Array_GetValueImpl, MonoObject, 2, (MonoArray, guint32))
134+
HANDLES(ARRAY_6, "GetLengthInternal", ves_icall_System_Array_GetLengthInternal, gint32, 2, (MonoObjectHandleOnStack, gint32))
135+
HANDLES(ARRAY_7, "GetLowerBoundInternal", ves_icall_System_Array_GetLowerBoundInternal, gint32, 2, (MonoObjectHandleOnStack, gint32))
136+
HANDLES(ARRAY_10, "GetValueImpl", ves_icall_System_Array_GetValueImpl, void, 3, (MonoObjectHandleOnStack, MonoObjectHandleOnStack, guint32))
137137
HANDLES(ARRAY_10_a, "InitializeInternal", ves_icall_System_Array_InitializeInternal, void, 1, (MonoObjectHandleOnStack))
138138
NOHANDLES(ICALL(ARRAY_10a, "InternalCreate", ves_icall_System_Array_InternalCreate))
139-
HANDLES(ARRAY_10b, "IsValueOfElementType", ves_icall_System_Array_IsValueOfElementType, gint32, 2, (MonoArray, MonoObject))
139+
NOHANDLES(ICALL(ARRAY_10b, "IsValueOfElementTypeInternal", ves_icall_System_Array_IsValueOfElementTypeInternal))
140140
NOHANDLES(ICALL(ARRAY_11, "SetGenericValue_icall", ves_icall_System_Array_SetGenericValue_icall))
141-
HANDLES(ARRAY_13, "SetValueImpl", ves_icall_System_Array_SetValueImpl, void, 3, (MonoArray, MonoObject, guint32))
142-
HANDLES(ARRAY_14, "SetValueRelaxedImpl", ves_icall_System_Array_SetValueRelaxedImpl, void, 3, (MonoArray, MonoObject, guint32))
141+
HANDLES(ARRAY_13, "SetValueImpl", ves_icall_System_Array_SetValueImpl, void, 3, (MonoObjectHandleOnStack, MonoObjectHandleOnStack, guint32))
142+
HANDLES(ARRAY_14, "SetValueRelaxedImpl", ves_icall_System_Array_SetValueRelaxedImpl, void, 3, (MonoObjectHandleOnStack, MonoObjectHandleOnStack, guint32))
143143

144144
ICALL_TYPE(BUFFER, "System.Buffer", BUFFER_0)
145145
NOHANDLES(ICALL(BUFFER_0, "BulkMoveWithWriteBarrier", ves_icall_System_Buffer_BulkMoveWithWriteBarrier))

0 commit comments

Comments
 (0)