Skip to content

Commit

Permalink
Use new byte[] span optimization in a few more places (#70665)
Browse files Browse the repository at this point in the history
* Use new byte[] span optimization in a few more places

Separated out of larger change to use CreateSpan (these don't rely on that).

* Address PR feedback
  • Loading branch information
stephentoub authored Jun 17, 2022
1 parent a796755 commit 10438a5
Show file tree
Hide file tree
Showing 8 changed files with 75 additions and 75 deletions.
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;
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;
return 1;
}

int mapLength = map._headerParameters.Count;
Expand Down

0 comments on commit 10438a5

Please sign in to comment.