Skip to content

Commit 99d5cbc

Browse files
PaulusParssinendirecthex
authored andcommitted
Use BinaryPrimitives more in the ILCompiler (#105404)
1 parent 113fd97 commit 99d5cbc

File tree

4 files changed

+46
-47
lines changed

4 files changed

+46
-47
lines changed

src/coreclr/tools/Common/Pgo/PgoFormat.cs

Lines changed: 3 additions & 12 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;
67
using System.Collections.Generic;
78
using System.Diagnostics;
@@ -163,22 +164,12 @@ public bool MoveNext()
163164
}
164165
else if ((bytes[offset]) == 0xC1) // 8 byte specifier
165166
{
166-
signedInt = (((long)bytes[offset + 1]) << 56) |
167-
(((long)bytes[offset + 2]) << 48) |
168-
(((long)bytes[offset + 3]) << 40) |
169-
(((long)bytes[offset + 4]) << 32) |
170-
(((long)bytes[offset + 5]) << 24) |
171-
(((long)bytes[offset + 6]) << 16) |
172-
(((long)bytes[offset + 7]) << 8) |
173-
((long)bytes[offset + 8]);
167+
signedInt = BinaryPrimitives.ReadInt64BigEndian(bytes.AsSpan(offset + 1, sizeof(long)));
174168
offset += 9;
175169
}
176170
else
177171
{
178-
signedInt = (((int)bytes[offset + 1]) << 24) |
179-
(((int)bytes[offset + 2]) << 16) |
180-
(((int)bytes[offset + 3]) << 8) |
181-
((int)bytes[offset + 4]);
172+
signedInt = BinaryPrimitives.ReadInt32BigEndian(bytes.AsSpan(offset + 1, sizeof(int)));
182173
offset += 5;
183174
}
184175

src/coreclr/tools/Common/TypeSystem/IL/ILDisassembler.cs

Lines changed: 7 additions & 6 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.Text;
67

78
using Internal.TypeSystem;
@@ -191,15 +192,15 @@ private byte ReadILByte()
191192

192193
private ushort ReadILUInt16()
193194
{
194-
ushort val = (ushort)(_ilBytes[_currentOffset] + (_ilBytes[_currentOffset + 1] << 8));
195-
_currentOffset += 2;
195+
ushort val = BinaryPrimitives.ReadUInt16LittleEndian(_ilBytes.AsSpan(_currentOffset, sizeof(ushort)));
196+
_currentOffset += sizeof(ushort);
196197
return val;
197198
}
198199

199200
private uint ReadILUInt32()
200201
{
201-
uint val = (uint)(_ilBytes[_currentOffset] + (_ilBytes[_currentOffset + 1] << 8) + (_ilBytes[_currentOffset + 2] << 16) + (_ilBytes[_currentOffset + 3] << 24));
202-
_currentOffset += 4;
202+
uint val = BinaryPrimitives.ReadUInt32LittleEndian(_ilBytes.AsSpan(_currentOffset, sizeof(uint)));
203+
_currentOffset += sizeof(uint);
203204
return val;
204205
}
205206

@@ -211,8 +212,8 @@ private int ReadILToken()
211212

212213
private ulong ReadILUInt64()
213214
{
214-
ulong value = ReadILUInt32();
215-
value |= (((ulong)ReadILUInt32()) << 32);
215+
ulong value = BinaryPrimitives.ReadUInt64LittleEndian(_ilBytes.AsSpan(_currentOffset, sizeof(ulong)));
216+
_currentOffset += sizeof(ulong);
216217
return value;
217218
}
218219

src/coreclr/tools/Common/TypeSystem/IL/ILImporter.cs

Lines changed: 13 additions & 11 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;
5+
using System.Buffers.Binary;
46
using Internal.TypeSystem;
57

68
namespace Internal.IL
@@ -20,30 +22,28 @@ internal sealed partial class ILImporter
2022

2123
private byte ReadILByte()
2224
{
23-
if (_currentOffset >= _ilBytes.Length)
25+
if (_currentOffset + 1 > _ilBytes.Length)
2426
ReportMethodEndInsideInstruction();
2527

2628
return _ilBytes[_currentOffset++];
2729
}
2830

2931
private ushort ReadILUInt16()
3032
{
31-
if (_currentOffset + 1 >= _ilBytes.Length)
33+
if (!BinaryPrimitives.TryReadUInt16LittleEndian(_ilBytes.AsSpan(_currentOffset), out ushort value))
3234
ReportMethodEndInsideInstruction();
3335

34-
ushort val = (ushort)(_ilBytes[_currentOffset] + (_ilBytes[_currentOffset + 1] << 8));
35-
_currentOffset += 2;
36-
return val;
36+
_currentOffset += sizeof(ushort);
37+
return value;
3738
}
3839

3940
private uint ReadILUInt32()
4041
{
41-
if (_currentOffset + 3 >= _ilBytes.Length)
42+
if (!BinaryPrimitives.TryReadUInt32LittleEndian(_ilBytes.AsSpan(_currentOffset), out uint value))
4243
ReportMethodEndInsideInstruction();
4344

44-
uint val = (uint)(_ilBytes[_currentOffset] + (_ilBytes[_currentOffset + 1] << 8) + (_ilBytes[_currentOffset + 2] << 16) + (_ilBytes[_currentOffset + 3] << 24));
45-
_currentOffset += 4;
46-
return val;
45+
_currentOffset += sizeof(uint);
46+
return value;
4747
}
4848

4949
private int ReadILToken()
@@ -53,8 +53,10 @@ private int ReadILToken()
5353

5454
private ulong ReadILUInt64()
5555
{
56-
ulong value = ReadILUInt32();
57-
value |= (((ulong)ReadILUInt32()) << 32);
56+
if (!BinaryPrimitives.TryReadUInt64LittleEndian(_ilBytes.AsSpan(_currentOffset), out ulong value))
57+
ReportMethodEndInsideInstruction();
58+
59+
_currentOffset += sizeof(ulong);
5860
return value;
5961
}
6062

src/coreclr/tools/Common/TypeSystem/IL/Stubs/ILEmitter.cs

Lines changed: 23 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,9 @@
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;
6-
7+
using System.Runtime.CompilerServices;
78
using Internal.TypeSystem;
89

910
using Debug = System.Diagnostics.Debug;
@@ -49,23 +50,33 @@ internal int RelativeToAbsoluteOffset(int relativeOffset)
4950

5051
private void EmitByte(byte b)
5152
{
52-
if (_instructions.Length == _length)
53-
Array.Resize<byte>(ref _instructions, 2 * _instructions.Length + 10);
53+
if (_length == _instructions.Length)
54+
Grow();
5455
_instructions[_length++] = b;
5556
}
5657

5758
private void EmitUInt16(ushort value)
5859
{
59-
EmitByte((byte)value);
60-
EmitByte((byte)(value >> 8));
60+
if (_length + sizeof(ushort) > _instructions.Length)
61+
Grow();
62+
63+
BinaryPrimitives.WriteUInt16LittleEndian(_instructions.AsSpan(_length, sizeof(ushort)), value);
64+
_length += sizeof(ushort);
6165
}
6266

6367
private void EmitUInt32(int value)
6468
{
65-
EmitByte((byte)value);
66-
EmitByte((byte)(value >> 8));
67-
EmitByte((byte)(value >> 16));
68-
EmitByte((byte)(value >> 24));
69+
if (_length + sizeof(int) > _instructions.Length)
70+
Grow();
71+
72+
BinaryPrimitives.WriteInt32LittleEndian(_instructions.AsSpan(_length, sizeof(int)), value);
73+
_length += sizeof(int);
74+
}
75+
76+
[MethodImpl(MethodImplOptions.NoInlining)]
77+
private void Grow()
78+
{
79+
Array.Resize(ref _instructions, 2 * _instructions.Length + 10);
6980
}
7081

7182
public void Emit(ILOpcode opcode)
@@ -468,19 +479,13 @@ internal void PatchLabels()
468479
Debug.Assert(patch.Label.IsPlaced);
469480
Debug.Assert(_startOffsetForLinking != StartOffsetNotSet);
470481

471-
int offset = patch.Offset;
482+
Span<byte> offsetSpan = _instructions.AsSpan(patch.Offset, sizeof(int));
472483

473-
int delta = _instructions[offset + 3] << 24 |
474-
_instructions[offset + 2] << 16 |
475-
_instructions[offset + 1] << 8 |
476-
_instructions[offset];
484+
int delta = BinaryPrimitives.ReadInt32LittleEndian(offsetSpan);
477485

478486
int value = patch.Label.AbsoluteOffset - _startOffsetForLinking - patch.Offset - delta;
479487

480-
_instructions[offset] = (byte)value;
481-
_instructions[offset + 1] = (byte)(value >> 8);
482-
_instructions[offset + 2] = (byte)(value >> 16);
483-
_instructions[offset + 3] = (byte)(value >> 24);
488+
BinaryPrimitives.WriteInt32LittleEndian(offsetSpan, value);
484489
}
485490
}
486491

0 commit comments

Comments
 (0)