未验证 提交 10438a57 编写于 作者: S Stephen Toub 提交者: GitHub

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

* 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
上级 a7967552
......@@ -1878,12 +1878,9 @@ private static void ZeroToMaxLen(Span<uint> rgulData, 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,
......
......@@ -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
......@@ -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;
}
......
......@@ -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 };
}
......
......@@ -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,
......@@ -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();
}
......@@ -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);
}
......@@ -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--;
}
......@@ -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++;
......@@ -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++;
......@@ -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;
}
......@@ -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();
......@@ -958,7 +958,7 @@ private new void ReadStartElement()
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();
......@@ -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();
......@@ -1136,18 +1136,18 @@ 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;
}
......@@ -1155,10 +1155,10 @@ private static int ReadText(byte[] buffer, int offset, int offsetMax)
// 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)
{
......@@ -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);
......@@ -1345,7 +1345,7 @@ public override bool Read()
else
ReadStartElement();
}
else if ((s_charType[ch] & CharType.SpecialWhitespace) != 0)
else if ((CharTypeMap[ch] & CharType.SpecialWhitespace) != 0)
{
ReadWhitespace();
}
......@@ -1353,7 +1353,7 @@ public override bool Read()
{
XmlExceptionHelper.ThrowInvalidRootData(this);
}
else if ((s_charType[ch] & CharType.Text) != 0)
else if ((CharTypeMap[ch] & CharType.Text) != 0)
{
ReadText(false);
}
......
......@@ -117,12 +117,9 @@ private static uint UIntFromByteArray(byte[] data, int offset)
//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
};
......
......@@ -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));
}
......@@ -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;
......@@ -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)*
*/
......
......@@ -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,
......@@ -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,
......@@ -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
......
......@@ -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; }
......@@ -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;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册