-
Notifications
You must be signed in to change notification settings - Fork 5.4k
[SRM] Optimize MetadataBuilder.GetOrAddConstantBlob.
#121223
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
0a4579b
0635302
3842337
89e2166
b054b30
5378ecb
40944d1
259e337
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,6 +1,7 @@ | ||
| // Licensed to the .NET Foundation under one or more agreements. | ||
| // The .NET Foundation licenses this file to you under the MIT license. | ||
|
|
||
| using System.Buffers.Binary; | ||
| using System.Diagnostics; | ||
|
|
||
| namespace System.Reflection.Metadata | ||
|
|
@@ -12,6 +13,7 @@ internal static class BlobWriterImpl | |
| internal const int MaxCompressedIntegerValue = 0x1fffffff; | ||
| internal const int MinSignedCompressedIntegerValue = unchecked((int)0xF0000000); | ||
| internal const int MaxSignedCompressedIntegerValue = 0x0FFFFFFF; | ||
| internal const int MaxScalarConstantSize = sizeof(ulong); | ||
|
|
||
| internal static int GetCompressedIntegerSize(int value) | ||
| { | ||
|
|
@@ -144,6 +146,109 @@ internal static void WriteCompressedSignedInteger(BlobBuilder writer, int value) | |
| } | ||
| } | ||
|
|
||
| /// <summary> | ||
| /// Writes a scalar (non-string) constant to a span. | ||
| /// </summary> | ||
| /// <param name="bytes">The span where the content will be encoded.</param> | ||
| /// <param name="value">The constant value.</param> | ||
| /// <returns>The number of bytes that was written.</returns> | ||
| internal static int WriteScalarConstant(Span<byte> bytes, object? value) | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The existing two copies of this method below are called
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The existing two methods also accept strings besides scalar values. |
||
| { | ||
| if (value == null) | ||
| { | ||
| // The encoding of Type for the nullref value for FieldInit is ELEMENT_TYPE_CLASS with a Value of a 32-bit. | ||
|
|
||
| BinaryPrimitives.WriteUInt32LittleEndian(bytes, 0); | ||
AaronRobinsonMSFT marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| return sizeof(uint); | ||
| } | ||
|
Comment on lines
+155
to
+162
|
||
|
|
||
| var type = value.GetType(); | ||
jkotas marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| if (type.IsEnum) | ||
| { | ||
| type = Enum.GetUnderlyingType(type); | ||
| } | ||
|
|
||
| if (type == typeof(bool)) | ||
|
Comment on lines
+149
to
+170
|
||
| { | ||
| bytes[0] = (byte)((bool)value ? 1 : 0); | ||
| return sizeof(bool); | ||
| } | ||
| else if (type == typeof(int)) | ||
| { | ||
| BinaryPrimitives.WriteInt32LittleEndian(bytes, (int)value); | ||
| return sizeof(int); | ||
| } | ||
| else if (type == typeof(byte)) | ||
| { | ||
| bytes[0] = (byte)value; | ||
| return sizeof(byte); | ||
| } | ||
| else if (type == typeof(char)) | ||
| { | ||
| BinaryPrimitives.WriteUInt16LittleEndian(bytes, (char)value); | ||
| return sizeof(char); | ||
| } | ||
| else if (type == typeof(double)) | ||
| { | ||
| #if NET | ||
| BinaryPrimitives.WriteDoubleLittleEndian(bytes, (double)value); | ||
| #else | ||
| double v = (double)value; | ||
| unsafe | ||
| { | ||
| BinaryPrimitives.WriteUInt64LittleEndian(bytes, *(ulong*)(&v)); | ||
| } | ||
| #endif | ||
| return sizeof(double); | ||
| } | ||
| else if (type == typeof(short)) | ||
| { | ||
| BinaryPrimitives.WriteInt16LittleEndian(bytes, (short)value); | ||
| return sizeof(short); | ||
| } | ||
| else if (type == typeof(long)) | ||
| { | ||
| BinaryPrimitives.WriteInt64LittleEndian(bytes, (long)value); | ||
| return sizeof(long); | ||
| } | ||
| else if (type == typeof(sbyte)) | ||
| { | ||
| bytes[0] = (byte)(sbyte)value; | ||
| return sizeof(sbyte); | ||
| } | ||
| else if (type == typeof(float)) | ||
| { | ||
| #if NET | ||
| BinaryPrimitives.WriteSingleLittleEndian(bytes, (float)value); | ||
| #else | ||
| float v = (float)value; | ||
| unsafe | ||
| { | ||
| BinaryPrimitives.WriteUInt32LittleEndian(bytes, *(uint*)(&v)); | ||
| } | ||
| #endif | ||
| return sizeof(float); | ||
| } | ||
| else if (type == typeof(ushort)) | ||
| { | ||
| BinaryPrimitives.WriteUInt16LittleEndian(bytes, (ushort)value); | ||
| return sizeof(ushort); | ||
| } | ||
| else if (type == typeof(uint)) | ||
| { | ||
| BinaryPrimitives.WriteUInt32LittleEndian(bytes, (uint)value); | ||
| return sizeof(uint); | ||
| } | ||
| else if (type == typeof(ulong)) | ||
| { | ||
| BinaryPrimitives.WriteUInt64LittleEndian(bytes, (ulong)value); | ||
| return sizeof(ulong); | ||
| } | ||
| else | ||
| { | ||
| throw new ArgumentException(SR.Format(SR.InvalidConstantValueOfType, type)); | ||
| } | ||
| } | ||
|
|
||
| internal static void WriteConstant(ref BlobWriter writer, object? value) | ||
| { | ||
| if (value == null) | ||
|
|
@@ -154,7 +259,7 @@ internal static void WriteConstant(ref BlobWriter writer, object? value) | |
| } | ||
|
|
||
| var type = value.GetType(); | ||
| if (type.GetTypeInfo().IsEnum) | ||
| if (type.IsEnum) | ||
| { | ||
| type = Enum.GetUnderlyingType(type); | ||
| } | ||
|
|
@@ -227,7 +332,7 @@ internal static void WriteConstant(BlobBuilder writer, object? value) | |
| } | ||
|
|
||
| var type = value.GetType(); | ||
| if (type.GetTypeInfo().IsEnum) | ||
| if (type.IsEnum) | ||
| { | ||
| type = Enum.GetUnderlyingType(type); | ||
| } | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The documentation should clarify that
bytesmust be at leastsizeof(ulong)bytes in length to accommodate the largest scalar type. Additionally, it should document the expected behavior whenvalueis null (returns 4 bytes for a zero uint).