Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
dfc09e0
Adapt CopyImpl and CanAssignArrayType to NativeAot
huoyaoyuan Jun 22, 2025
3c031da
Adapt CopySlow paths
huoyaoyuan Jun 22, 2025
8af6824
Cleanup old CopyImpl
huoyaoyuan Jun 22, 2025
ae4a0d5
Add test for primitive widen with enum
huoyaoyuan Jun 22, 2025
ce29d08
Cleanup unreachable path
huoyaoyuan Jun 22, 2025
97dc439
Fold identical ConstrainedCopy
huoyaoyuan Jun 22, 2025
c9e0ae2
Share Array.Clear
huoyaoyuan Jun 22, 2025
2488fe9
Share GetFlattenedIndex
huoyaoyuan Jun 22, 2025
b65a093
Reduce overhead of GetLength/LowerBound/UpperBound
huoyaoyuan Jun 22, 2025
e975e11
Fix mono build
huoyaoyuan Jun 22, 2025
e7fc110
Fix direction of CanPrimitiveWiden
huoyaoyuan Jun 23, 2025
e366c6a
Share GetLength/GetUpperBound/GetLowerBound
huoyaoyuan Jun 23, 2025
bc584d1
Cleanup IsSzArray
huoyaoyuan Jun 23, 2025
c409556
Encounter for pointer in IsSystemObject
huoyaoyuan Jun 23, 2025
83b6ea8
Fix unit tests
huoyaoyuan Jun 23, 2025
b3c5374
Merge branch 'main' into array-shared
huoyaoyuan Jun 24, 2025
11da64e
Merge branch 'main' into array-shared
huoyaoyuan Jun 30, 2025
072519a
Cleanup exception throwing.
huoyaoyuan Jun 30, 2025
9c6ecaa
Invert condition for pointer check
huoyaoyuan Jun 30, 2025
0766d2c
Remove redundant throwing condition
huoyaoyuan Jun 30, 2025
9344eec
Fix nullability
huoyaoyuan Jun 30, 2025
fb403f4
Reduce overhead of ArrayRank
huoyaoyuan Jun 30, 2025
e7e11b9
Cleanup
huoyaoyuan Jun 30, 2025
3e60780
Add test for copying value types
huoyaoyuan Jun 30, 2025
36cf203
Revert "Remove redundant throwing condition"
huoyaoyuan Jun 30, 2025
3370988
Add back overflow check
huoyaoyuan Jun 30, 2025
1c0901a
Update array type checking
huoyaoyuan Jul 1, 2025
6044d8a
Simplify bound checking
huoyaoyuan Jul 1, 2025
1b9a1d8
Cleanup CER comment
huoyaoyuan Jul 1, 2025
d8ce97e
Add test for nullable case
huoyaoyuan Jul 1, 2025
5fa7174
Handle nullable conversion
huoyaoyuan Jul 1, 2025
67f6774
Move comment
huoyaoyuan Jul 1, 2025
11dcdca
Move copy cases to shared
huoyaoyuan Jul 1, 2025
41d3318
AsMethodTable() already asserts
huoyaoyuan Jul 1, 2025
05f246e
Delete misaligned comment
huoyaoyuan Jul 1, 2025
b40e433
Fix case ordering
huoyaoyuan Jul 1, 2025
b7d184f
Avoid multiplication by non-constant
huoyaoyuan Jul 1, 2025
baf176f
Reorder PrimitiveWiden
huoyaoyuan Jul 1, 2025
88d2cf2
Align asserts
huoyaoyuan Jul 1, 2025
5e65943
Fix element type
huoyaoyuan Jul 1, 2025
34cf416
Apply suggestions from code review
jkotas Jul 2, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
453 changes: 44 additions & 409 deletions src/coreclr/System.Private.CoreLib/src/System/Array.CoreCLR.cs

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -415,15 +415,15 @@ internal static unsafe ushort GetElementSize(this Array array)

// Returns pointer to the multi-dimensional array bounds.
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal static ref int GetMultiDimensionalArrayBounds(Array array)
internal static ref int GetMultiDimensionalArrayBounds(this Array array)
{
Debug.Assert(GetMultiDimensionalArrayRank(array) > 0);
// See comment on RawArrayData for details
return ref Unsafe.As<byte, int>(ref Unsafe.As<RawArrayData>(array).Data);
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal static unsafe int GetMultiDimensionalArrayRank(Array array)
internal static unsafe int GetMultiDimensionalArrayRank(this Array array)
{
int rank = GetMethodTable(array)->MultiDimensionalArrayRank;
GC.KeepAlive(array); // Keep MethodTable alive
Expand Down Expand Up @@ -822,6 +822,16 @@ internal unsafe struct MethodTable

public bool HasDefaultConstructor => (Flags & (enum_flag_HasComponentSize | enum_flag_HasDefaultCtor)) == enum_flag_HasDefaultCtor;

public bool IsSzArray
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get
{
Debug.Assert(IsArray);
return BaseSize == (uint)(3 * sizeof(IntPtr));
}
}

public bool IsMultiDimensionalArray
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -408,17 +408,31 @@ internal int ArrayRank
{
Debug.Assert(this.IsArray);

int boundsSize = (int)this.ParameterizedTypeShape - SZARRAY_BASE_SIZE;
int boundsSize = (int)this.BaseSize - SZARRAY_BASE_SIZE;
if (boundsSize > 0)
{
// Multidim array case: Base size includes space for two Int32s
// (upper and lower bound) per each dimension of the array.
return boundsSize / (2 * sizeof(int));
return (int)((uint)boundsSize / (uint)(2 * sizeof(int)));
}
return 1;
}
}

// Returns rank of multi-dimensional array rank, 0 for sz arrays
internal int MultiDimensionalArrayRank
{
get
{
Debug.Assert(this.IsArray);

int boundsSize = (int)this.BaseSize - SZARRAY_BASE_SIZE;
// Multidim array case: Base size includes space for two Int32s
// (upper and lower bound) per each dimension of the array.
return (int)((uint)boundsSize / (uint)(2 * sizeof(int)));
}
}

internal bool IsSzArray
{
get
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ internal static class WellKnownEETypes
// This is recognized by the fact that System.Object and interfaces are the only ones without a base type
internal static unsafe bool IsSystemObject(MethodTable* pEEType)
{
if (pEEType->IsArray)
if (!pEEType->IsCanonical)
return false;
return (pEEType->NonArrayBaseType == null) && !pEEType->IsInterface;
}
Expand Down

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -144,13 +144,13 @@ private static Exception ConvertOrWidenPrimitivesEnumsAndPointersIfPossible(obje
}

dstObject = RuntimeImports.RhNewObject(dstEEType);
PrimitiveWiden(dstElementType, srcElementType, ref dstObject.GetRawData(), ref srcObject.GetRawData());
PrimitiveWiden(ref srcObject.GetRawData(), ref dstObject.GetRawData(), srcElementType, dstElementType);
}
return null;
}

[MethodImpl(MethodImplOptions.AggressiveInlining)] // Two callers, one of them is potentially perf sensitive
internal static void PrimitiveWiden(EETypeElementType dstType, EETypeElementType srcType, ref byte dstValue, ref byte srcValue)
internal static void PrimitiveWiden(ref byte srcValue, ref byte dstValue, EETypeElementType srcType, EETypeElementType dstType)
{
// Caller must check that the conversion is valid and the source/destination types are different
Debug.Assert(CanPrimitiveWiden(dstType, srcType) && dstType != srcType);
Expand Down
Loading
Loading