Skip to content

Commit 5474ab5

Browse files
Use BinaryPrimitives for ObjectDataBuilder primitive emit logic (#102394)
* Add ArrayBuilder.Append(ROS<T>) - Only for .NET because of NS2.0 projects use it too: Microsoft.NET.HostModel and ILVerification * Use BinaryPrimitives to emit integer primitives in ObjectDataBuilder * Use BinaryPrimitives to emit reserved integer primitives in ObjectDataBuilder * Add ArrayBuilder.AsSpan overload to make this possible * Mark some ArrayBuilder members as readonly * Ask ArrayBuilder for a buffer instead of stackalloc + append * Follow ValueStringBuilder's AppendSpan implementation * Don't inline ArrayBuilder resize * This follows ValueStringBuilder and other buffer builder types.
1 parent 0d8c6b7 commit 5474ab5

File tree

2 files changed

+36
-48
lines changed

2 files changed

+36
-48
lines changed

src/coreclr/tools/Common/Compiler/DependencyAnalysis/ObjectDataBuilder.cs

Lines changed: 9 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
// The .NET Foundation licenses this file to you under the MIT license.
33

44
using System;
5+
using System.Buffers.Binary;
56
using System.Collections.Generic;
67
using Internal.TypeSystem;
78

@@ -85,42 +86,27 @@ public void EmitByte(byte emit)
8586

8687
public void EmitShort(short emit)
8788
{
88-
EmitByte((byte)(emit & 0xFF));
89-
EmitByte((byte)((emit >> 8) & 0xFF));
89+
BinaryPrimitives.WriteInt16LittleEndian(_data.AppendSpan(sizeof(short)), emit);
9090
}
9191

9292
public void EmitUShort(ushort emit)
9393
{
94-
EmitByte((byte)(emit & 0xFF));
95-
EmitByte((byte)((emit >> 8) & 0xFF));
94+
BinaryPrimitives.WriteUInt16LittleEndian(_data.AppendSpan(sizeof(ushort)), emit);
9695
}
9796

9897
public void EmitInt(int emit)
9998
{
100-
EmitByte((byte)(emit & 0xFF));
101-
EmitByte((byte)((emit >> 8) & 0xFF));
102-
EmitByte((byte)((emit >> 16) & 0xFF));
103-
EmitByte((byte)((emit >> 24) & 0xFF));
99+
BinaryPrimitives.WriteInt32LittleEndian(_data.AppendSpan(sizeof(int)), emit);
104100
}
105101

106102
public void EmitUInt(uint emit)
107103
{
108-
EmitByte((byte)(emit & 0xFF));
109-
EmitByte((byte)((emit >> 8) & 0xFF));
110-
EmitByte((byte)((emit >> 16) & 0xFF));
111-
EmitByte((byte)((emit >> 24) & 0xFF));
104+
BinaryPrimitives.WriteUInt32LittleEndian(_data.AppendSpan(sizeof(uint)), emit);
112105
}
113106

114107
public void EmitLong(long emit)
115108
{
116-
EmitByte((byte)(emit & 0xFF));
117-
EmitByte((byte)((emit >> 8) & 0xFF));
118-
EmitByte((byte)((emit >> 16) & 0xFF));
119-
EmitByte((byte)((emit >> 24) & 0xFF));
120-
EmitByte((byte)((emit >> 32) & 0xFF));
121-
EmitByte((byte)((emit >> 40) & 0xFF));
122-
EmitByte((byte)((emit >> 48) & 0xFF));
123-
EmitByte((byte)((emit >> 56) & 0xFF));
109+
BinaryPrimitives.WriteInt64LittleEndian(_data.AppendSpan(sizeof(long)), emit);
124110
}
125111

126112
public void EmitNaturalInt(int emit)
@@ -245,8 +231,7 @@ public Reservation ReserveShort()
245231
public void EmitShort(Reservation reservation, short emit)
246232
{
247233
int offset = ReturnReservationTicket(reservation);
248-
_data[offset] = (byte)(emit & 0xFF);
249-
_data[offset + 1] = (byte)((emit >> 8) & 0xFF);
234+
BinaryPrimitives.WriteInt16LittleEndian(_data.AsSpan(offset), emit);
250235
}
251236

252237
public Reservation ReserveInt()
@@ -257,19 +242,13 @@ public Reservation ReserveInt()
257242
public void EmitInt(Reservation reservation, int emit)
258243
{
259244
int offset = ReturnReservationTicket(reservation);
260-
_data[offset] = (byte)(emit & 0xFF);
261-
_data[offset + 1] = (byte)((emit >> 8) & 0xFF);
262-
_data[offset + 2] = (byte)((emit >> 16) & 0xFF);
263-
_data[offset + 3] = (byte)((emit >> 24) & 0xFF);
245+
BinaryPrimitives.WriteInt32LittleEndian(_data.AsSpan(offset), emit);
264246
}
265247

266248
public void EmitUInt(Reservation reservation, uint emit)
267249
{
268250
int offset = ReturnReservationTicket(reservation);
269-
_data[offset] = (byte)(emit & 0xFF);
270-
_data[offset + 1] = (byte)((emit >> 8) & 0xFF);
271-
_data[offset + 2] = (byte)((emit >> 16) & 0xFF);
272-
_data[offset + 3] = (byte)((emit >> 24) & 0xFF);
251+
BinaryPrimitives.WriteUInt32LittleEndian(_data.AsSpan(offset), emit);
273252
}
274253

275254
public void EmitReloc(ISymbolNode symbol, RelocType relocType, int delta = 0)

src/coreclr/tools/Common/System/Collections/Generic/ArrayBuilder.cs

Lines changed: 27 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
// Licensed to the .NET Foundation under one or more agreements.
22
// The .NET Foundation licenses this file to you under the MIT license.
33

4+
using System.Runtime.CompilerServices;
5+
46
using Debug = System.Diagnostics.Debug;
57

68
namespace System.Collections.Generic
@@ -29,6 +31,19 @@ public void Add(T item)
2931
_items[_count++] = item;
3032
}
3133

34+
#if NET
35+
public readonly Span<T> AsSpan(int start) => _items.AsSpan(start);
36+
37+
public Span<T> AppendSpan(int length)
38+
{
39+
int origCount = _count;
40+
EnsureCapacity(origCount + length);
41+
42+
_count = origCount + length;
43+
return _items.AsSpan(origCount, length);
44+
}
45+
#endif
46+
3247
public void Append(T[] newItems)
3348
{
3449
Append(newItems, 0, newItems.Length);
@@ -67,32 +82,26 @@ public void EnsureCapacity(int requestedCapacity)
6782
{
6883
if (requestedCapacity > ((_items != null) ? _items.Length : 0))
6984
{
70-
int newCount = Math.Max(2 * _count + 1, requestedCapacity);
71-
Array.Resize(ref _items, newCount);
85+
Grow(requestedCapacity);
7286
}
7387
}
7488

75-
public int Count
89+
[MethodImpl(MethodImplOptions.NoInlining)]
90+
private void Grow(int requestedCapacity)
7691
{
77-
get
78-
{
79-
return _count;
80-
}
92+
int newCount = Math.Max(2 * _count + 1, requestedCapacity);
93+
Array.Resize(ref _items, newCount);
8194
}
8295

83-
public T this[int index]
96+
public readonly int Count => _count;
97+
98+
public readonly T this[int index]
8499
{
85-
get
86-
{
87-
return _items[index];
88-
}
89-
set
90-
{
91-
_items[index] = value;
92-
}
100+
get => _items[index];
101+
set => _items[index] = value;
93102
}
94103

95-
public bool Contains(T t)
104+
public readonly bool Contains(T t)
96105
{
97106
for (int i = 0; i < _count; i++)
98107
{
@@ -105,7 +114,7 @@ public bool Contains(T t)
105114
return false;
106115
}
107116

108-
public bool Any(Func<T, bool> func)
117+
public readonly bool Any(Func<T, bool> func)
109118
{
110119
for (int i = 0; i < _count; i++)
111120
{

0 commit comments

Comments
 (0)