Skip to content
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

Use new byte[] span optimization in a few more places #70665

Merged
merged 2 commits into from
Jun 17, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
Original file line number Diff line number Diff line change
Expand Up @@ -1878,12 +1878,9 @@ private void ZeroToMaxLen(int cUI4sCur) {
//Precision Length
// 0 invalid
// 1-9 1
// 10-19 2
// 20-28 3
// 29-38 4
// The array in Shiloh. Listed here for comparison.
//private static readonly byte[] rgCLenFromPrec = new byte[] {5,5,5,5,5,5,5,5,5,9,9,9,9,9,
// 9,9,9,9,9,13,13,13,13,13,13,13,13,13,17,17,17,17,17,17,17,17,17,17};
// 10-19 2
// 20-28 3
// 29-38 4
private static ReadOnlySpan<byte> RgCLenFromPrec => new byte[] // rely on C# compiler optimization to eliminate allocation
{
1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,6 @@ public struct SqlGuid : INullable, IComparable, IXmlSerializable, IEquatable<Sql
{
private const int SizeOfGuid = 16;

// Comparison orders.
private static readonly int[] s_rgiGuidOrder = new int[16]
{10, 11, 12, 13, 14, 15, 8, 9, 6, 7, 4, 5, 0, 1, 2, 3};

// NOTE: If any instance fields change, update SqlTypeWorkarounds type in System.Data.SqlClient.
private byte[]? m_value; // the SqlGuid is null if m_value is null

Expand Down Expand Up @@ -125,16 +121,22 @@ public static SqlGuid Parse(string s)
// Comparison operators
private static EComparison Compare(SqlGuid x, SqlGuid y)
{
//Swap to the correct order to be compared
// Comparison orders.
ReadOnlySpan<byte> rgiGuidOrder = new byte[16] { 10, 11, 12, 13, 14, 15, 8, 9, 6, 7, 4, 5, 0, 1, 2, 3 };

// Swap to the correct order to be compared
ReadOnlySpan<byte> xBytes = x.m_value;
ReadOnlySpan<byte> yBytes = y.m_value;
for (int i = 0; i < SizeOfGuid; i++)
{
byte b1, b2;

b1 = x.m_value![s_rgiGuidOrder[i]];
b2 = y.m_value![s_rgiGuidOrder[i]];
byte b1 = xBytes[rgiGuidOrder[i]];
byte b2 = yBytes[rgiGuidOrder[i]];
if (b1 != b2)
{
return (b1 < b2) ? EComparison.LT : EComparison.GT;
}
}

return EComparison.EQ;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,6 @@ namespace System.DirectoryServices.AccountManagement

internal static class Constants
{
internal static byte[] GUID_USERS_CONTAINER_BYTE = new byte[] { 0xa9, 0xd1, 0xca, 0x15, 0x76, 0x88, 0x11, 0xd1, 0xad, 0xed, 0x00, 0xc0, 0x4f, 0xd8, 0xd5, 0xcd };
internal static byte[] GUID_COMPUTRS_CONTAINER_BYTE = new byte[] { 0xaa, 0x31, 0x28, 0x25, 0x76, 0x88, 0x11, 0xd1, 0xad, 0xed, 0x00, 0xc0, 0x4f, 0xd8, 0xd5, 0xcd };
internal static byte[] GUID_FOREIGNSECURITYPRINCIPALS_CONTAINER_BYTE = new byte[] { 0x22, 0xb7, 0x0c, 0x67, 0xd5, 0x6e, 0x4e, 0xfb, 0x91, 0xe9, 0x30, 0x0f, 0xca, 0x3d, 0xc1, 0xaa };
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ internal sealed class XmlUTF8TextReader : XmlBaseReader, IXmlLineInfo, IXmlTextR
private OnXmlDictionaryReaderClose? _onClose;
private bool _buffered;
private int _maxBytesPerRead;
private static readonly byte[] s_charType = new byte[256]
private static ReadOnlySpan<byte> CharTypeMap => new byte[256]
{
/* 0 (.) */
CharType.None,
Expand Down Expand Up @@ -609,7 +609,7 @@ public override void Close()

private void SkipWhitespace()
{
while (!BufferReader.EndOfFile && (s_charType[BufferReader.GetByte()] & CharType.Whitespace) != 0)
while (!BufferReader.EndOfFile && (CharTypeMap[BufferReader.GetByte()] & CharType.Whitespace) != 0)
BufferReader.SkipByte();
}

Expand All @@ -623,7 +623,7 @@ private void ReadDeclaration()
buffer[offset + 1] != (byte)'x' ||
buffer[offset + 2] != (byte)'m' ||
buffer[offset + 3] != (byte)'l' ||
(s_charType[buffer[offset + 4]] & CharType.Whitespace) == 0)
(CharTypeMap[buffer[offset + 4]] & CharType.Whitespace) == 0)
{
XmlExceptionHelper.ThrowProcessingInstructionNotSupported(this);
}
Expand All @@ -646,7 +646,7 @@ private void ReadDeclaration()
while (valueLength > 0)
{
byte ch = BufferReader.GetByte(valueOffset + valueLength - 1);
if ((s_charType[ch] & CharType.Whitespace) == 0)
if ((CharTypeMap[ch] & CharType.Whitespace) == 0)
break;
valueLength--;
}
Expand Down Expand Up @@ -689,14 +689,14 @@ private void ReadQualifiedName(PrefixHandle prefix, StringHandle localName)
{
ch = buffer[offset];
prefixChar = ch;
if ((s_charType[ch] & CharType.FirstName) == 0)
if ((CharTypeMap[ch] & CharType.FirstName) == 0)
anyChar |= 0x80;
anyChar |= ch;
offset++;
while (offset < offsetMax)
{
ch = buffer[offset];
if ((s_charType[ch] & CharType.Name) == 0)
if ((CharTypeMap[ch] & CharType.Name) == 0)
break;
anyChar |= ch;
offset++;
Expand All @@ -720,14 +720,14 @@ private void ReadQualifiedName(PrefixHandle prefix, StringHandle localName)
if (offset < offsetMax)
{
ch = buffer[offset];
if ((s_charType[ch] & CharType.FirstName) == 0)
if ((CharTypeMap[ch] & CharType.FirstName) == 0)
anyChar |= 0x80;
anyChar |= ch;
offset++;
while (offset < offsetMax)
{
ch = buffer[offset];
if ((s_charType[ch] & CharType.Name) == 0)
if ((CharTypeMap[ch] & CharType.Name) == 0)
break;
anyChar |= ch;
offset++;
Expand Down Expand Up @@ -758,9 +758,9 @@ private void ReadQualifiedName(PrefixHandle prefix, StringHandle localName)

private static int ReadAttributeText(byte[] buffer, int offset, int offsetMax)
{
byte[] charType = XmlUTF8TextReader.s_charType;
ReadOnlySpan<byte> charTypeMap = XmlUTF8TextReader.CharTypeMap;
int textOffset = offset;
while (offset < offsetMax && (charType[buffer[offset]] & CharType.AttributeText) != 0)
while (offset < offsetMax && (charTypeMap[buffer[offset]] & CharType.AttributeText) != 0)
offset++;
return offset - textOffset;
}
Expand Down Expand Up @@ -864,7 +864,7 @@ private void ReadAttributes()
ch = BufferReader.GetByte();

bool space = false;
while ((s_charType[ch] & CharType.Whitespace) != 0)
while ((CharTypeMap[ch] & CharType.Whitespace) != 0)
{
space = true;
BufferReader.SkipByte();
Expand Down Expand Up @@ -958,7 +958,7 @@ private void BufferElement()
ReadQualifiedName(elementNode.Prefix, elementNode.LocalName);
elementNode.NameLength = BufferReader.Offset - elementNode.NameOffset;
byte ch = BufferReader.GetByte();
while ((s_charType[ch] & CharType.Whitespace) != 0)
while ((CharTypeMap[ch] & CharType.Whitespace) != 0)
{
BufferReader.SkipByte();
ch = BufferReader.GetByte();
Expand Down Expand Up @@ -1024,7 +1024,7 @@ private void ReadComment()
byte b = BufferReader.GetByte();
if (b == '-')
break;
if ((s_charType[b] & CharType.Comment) == 0)
if ((CharTypeMap[b] & CharType.Comment) == 0)
{
if (b == 0xEF)
ReadNonFFFE();
Expand Down Expand Up @@ -1136,29 +1136,29 @@ private void ReadWhitespace()

private static int ReadWhitespace(byte[] buffer, int offset, int offsetMax)
{
byte[] charType = XmlUTF8TextReader.s_charType;
ReadOnlySpan<byte> charTypeMap = XmlUTF8TextReader.CharTypeMap;
int wsOffset = offset;
while (offset < offsetMax && (charType[buffer[offset]] & CharType.SpecialWhitespace) != 0)
while (offset < offsetMax && (charTypeMap[buffer[offset]] & CharType.SpecialWhitespace) != 0)
offset++;
return offset - wsOffset;
}

private static int ReadText(byte[] buffer, int offset, int offsetMax)
{
byte[] charType = XmlUTF8TextReader.s_charType;
ReadOnlySpan<byte> charTypeMap = XmlUTF8TextReader.CharTypeMap;
int textOffset = offset;
while (offset < offsetMax && (charType[buffer[offset]] & CharType.Text) != 0)
while (offset < offsetMax && (charTypeMap[buffer[offset]] & CharType.Text) != 0)
offset++;
return offset - textOffset;
}

// Read Unicode codepoints 0xFvvv
private int ReadTextAndWatchForInvalidCharacters(byte[] buffer, int offset, int offsetMax)
{
byte[] charType = XmlUTF8TextReader.s_charType;
ReadOnlySpan<byte> charTypeMap = XmlUTF8TextReader.CharTypeMap;
stephentoub marked this conversation as resolved.
Show resolved Hide resolved
int textOffset = offset;

while (offset < offsetMax && ((charType[buffer[offset]] & CharType.Text) != 0 || buffer[offset] == 0xEF))
while (offset < offsetMax && ((charTypeMap[buffer[offset]] & CharType.Text) != 0 || buffer[offset] == 0xEF))
{
if (buffer[offset] != 0xEF)
{
Expand Down Expand Up @@ -1286,7 +1286,7 @@ private void ReadText(bool hasLeadingByteOf0xEF)
private void ReadEscapedText()
{
int ch = ReadCharRef();
if (ch < 256 && (s_charType[ch] & CharType.Whitespace) != 0)
if (ch < 256 && (CharTypeMap[ch] & CharType.Whitespace) != 0)
MoveToWhitespaceText().Value.SetCharValue(ch);
else
MoveToComplexText().Value.SetCharValue(ch);
Expand Down Expand Up @@ -1345,15 +1345,15 @@ public override bool Read()
else
ReadStartElement();
}
else if ((s_charType[ch] & CharType.SpecialWhitespace) != 0)
else if ((CharTypeMap[ch] & CharType.SpecialWhitespace) != 0)
{
ReadWhitespace();
}
else if (OutsideRootElement && ch != '\r')
{
XmlExceptionHelper.ThrowInvalidRootData(this);
}
else if ((s_charType[ch] & CharType.Text) != 0)
else if ((CharTypeMap[ch] & CharType.Text) != 0)
{
ReadText(false);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -117,12 +117,9 @@ ref int ciulU // InOut| # of digits
//Precision Length
// 0 invalid
// 1-9 1
// 10-19 2
// 20-28 3
// 29-38 4
// The array in Shiloh. Listed here for comparison.
//private static readonly byte[] rgCLenFromPrec = new byte[] {5,5,5,5,5,5,5,5,5,9,9,9,9,9,
// 9,9,9,9,9,13,13,13,13,13,13,13,13,13,17,17,17,17,17,17,17,17,17,17};
// 10-19 2
// 20-28 3
// 29-38 4
private static ReadOnlySpan<byte> RgCLenFromPrec => new byte[] { // rely on C# compiler optimization to eliminate allocation
1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -356,11 +356,31 @@ private Node ParseSubExpr(int callerPrec)
XPathOperator op;
Node opnd;

ReadOnlySpan<byte> xpathOperatorPrecedence = new byte[]
{
/*Unknown */ 0,
/*Or */ 1,
/*And */ 2,
/*Eq */ 3,
/*Ne */ 3,
/*Lt */ 4,
/*Le */ 4,
/*Gt */ 4,
/*Ge */ 4,
/*Plus */ 5,
/*Minus */ 5,
/*Multiply */ 6,
/*Divide */ 6,
/*Modulo */ 6,
/*UnaryMinus */ 7,
/*Union */ 8, // Not used
};

// Check for unary operators
if (_scanner!.Kind == LexKind.Minus)
{
op = XPathOperator.UnaryMinus;
int opPrec = s_XPathOperatorPrecedence[(int)op];
byte opPrec = xpathOperatorPrecedence[(int)op];
_scanner.NextLex();
opnd = _builder!.Operator(op, ParseSubExpr(opPrec), default(Node));
}
Expand All @@ -373,7 +393,7 @@ private Node ParseSubExpr(int callerPrec)
while (true)
{
op = (_scanner.Kind <= LexKind.LastOperator) ? (XPathOperator)_scanner.Kind : XPathOperator.Unknown;
int opPrec = s_XPathOperatorPrecedence[(int)op];
byte opPrec = xpathOperatorPrecedence[(int)op];
if (opPrec <= callerPrec)
{
break;
Expand All @@ -387,25 +407,6 @@ private Node ParseSubExpr(int callerPrec)
return opnd;
}

private static readonly int[] s_XPathOperatorPrecedence = {
/*Unknown */ 0,
/*Or */ 1,
/*And */ 2,
/*Eq */ 3,
/*Ne */ 3,
/*Lt */ 4,
/*Le */ 4,
/*Gt */ 4,
/*Ge */ 4,
/*Plus */ 5,
/*Minus */ 5,
/*Multiply */ 6,
/*Divide */ 6,
/*Modulo */ 6,
/*UnaryMinus */ 7,
/*Union */ 8, // Not used
};

/*
* UnionExpr ::= PathExpr ('|' PathExpr)*
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -150,16 +150,23 @@ private ImmutableArray<SerializedSection> SerializeSections()
return result.MoveToImmutable();
}

private static void WritePESignature(BlobBuilder builder)
private static unsafe void WritePESignature(BlobBuilder builder)
{
// MS-DOS stub (128 bytes)
builder.WriteBytes(s_dosHeader);
ReadOnlySpan<byte> header = DosHeader;
Debug.Assert(DosHeader.Length == DosHeaderSize);
fixed (byte* ptr = header)
{
builder.WriteBytes(ptr, header.Length);
}

// PE Signature "PE\0\0"
builder.WriteUInt32(PEHeaders.PESignature);
}

private static readonly byte[] s_dosHeader = new byte[]
internal const int DosHeaderSize = 0x80;

private static ReadOnlySpan<byte> DosHeader => new byte[DosHeaderSize]
{
0x4d, 0x5a, 0x90, 0x00, 0x03, 0x00, 0x00, 0x00,
0x04, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00,
Expand All @@ -170,7 +177,7 @@ private static void WritePESignature(BlobBuilder builder)
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,

0x80, 0x00, 0x00, 0x00, // NT Header offset (0x80 == s_dosHeader.Length)
0x80, 0x00, 0x00, 0x00, // NT Header offset (0x80 == DosHeader.Length)

0x0e, 0x1f, 0xba, 0x0e, 0x00, 0xb4, 0x09, 0xcd,
0x21, 0xb8, 0x01, 0x4c, 0xcd, 0x21, 0x54, 0x68,
Expand All @@ -182,8 +189,6 @@ private static void WritePESignature(BlobBuilder builder)
0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};

internal static int DosHeaderSize = s_dosHeader.Length;

private void WriteCoffHeader(BlobBuilder builder, ImmutableArray<SerializedSection> sections, out Blob stampFixup)
{
// Machine
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ namespace System.Security.Cryptography.Cose
{
public sealed class CoseHeaderMap : IEnumerable<(CoseHeaderLabel Label, ReadOnlyMemory<byte> EncodedValue)>
{
private static readonly byte[] s_emptyBstrEncoded = new byte[] { 0x40 };
private static readonly CoseHeaderMap s_emptyMap = new CoseHeaderMap(isReadOnly: true);

public bool IsReadOnly { get; internal set; }
Expand Down Expand Up @@ -199,8 +198,9 @@ internal static int Encode(CoseHeaderMap? map, Span<byte> destination, bool must

if (map._headerParameters.Count == 0 && mustReturnEmptyBstrIfEmpty && !shouldSlipAlgHeader)
{
s_emptyBstrEncoded.CopyTo(destination);
return s_emptyBstrEncoded.Length;
// Empty Bstr encoded
destination[0] = 0x40;
jozkee marked this conversation as resolved.
Show resolved Hide resolved
return 1;
}

int mapLength = map._headerParameters.Count;
Expand Down