Skip to content

Commit

Permalink
EventPipePayloadDecoder clean-up (dotnet/coreclr#21716)
Browse files Browse the repository at this point in the history
* Remove ReadUnalignedGuid

* Make EventPipePayloadDecoder unconditionally little-endian


Commit migrated from dotnet/coreclr@606e36b
  • Loading branch information
pentp authored and jkotas committed Jan 4, 2019
1 parent 76a9761 commit 879cf39
Showing 1 changed file with 32 additions and 73 deletions.
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System.Buffers.Binary;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Text;

namespace System.Diagnostics.Tracing
{
Expand All @@ -12,7 +14,7 @@ internal static class EventPipePayloadDecoder
/// <summary>
/// Given the metadata for an event and an event payload, decode and deserialize the event payload.
/// </summary>
internal static object[] DecodePayload(ref EventSource.EventMetadata metadata, ReadOnlySpan<Byte> payload)
internal static object[] DecodePayload(ref EventSource.EventMetadata metadata, ReadOnlySpan<byte> payload)
{
ParameterInfo[] parameters = metadata.Parameters;
object[] decodedFields = new object[parameters.Length];
Expand All @@ -31,38 +33,33 @@ internal static object[] DecodePayload(ref EventSource.EventMetadata metadata, R
{
if (IntPtr.Size == 8)
{
// Payload is automatically updated to point to the next piece of data.
decodedFields[i] = (IntPtr)ReadUnalignedUInt64(ref payload);
}
else if (IntPtr.Size == 4)
{
decodedFields[i] = (IntPtr)MemoryMarshal.Read<Int32>(payload);
payload = payload.Slice(IntPtr.Size);
decodedFields[i] = (IntPtr)BinaryPrimitives.ReadInt64LittleEndian(payload);
}
else
{
Debug.Assert(false, "Unsupported pointer size.");
decodedFields[i] = (IntPtr)BinaryPrimitives.ReadInt32LittleEndian(payload);
}
payload = payload.Slice(IntPtr.Size);
}
else if (parameterType == typeof(int))
{
decodedFields[i] = MemoryMarshal.Read<int>(payload);
decodedFields[i] = BinaryPrimitives.ReadInt32LittleEndian(payload);
payload = payload.Slice(sizeof(int));
}
else if (parameterType == typeof(uint))
{
decodedFields[i] = MemoryMarshal.Read<uint>(payload);
decodedFields[i] = BinaryPrimitives.ReadUInt32LittleEndian(payload);
payload = payload.Slice(sizeof(uint));
}
else if (parameterType == typeof(long))
{
// Payload is automatically updated to point to the next piece of data.
decodedFields[i] = (long)ReadUnalignedUInt64(ref payload);
decodedFields[i] = BinaryPrimitives.ReadInt64LittleEndian(payload);
payload = payload.Slice(sizeof(long));
}
else if (parameterType == typeof(ulong))
{
// Payload is automatically updated to point to the next piece of data.
decodedFields[i] = ReadUnalignedUInt64(ref payload);
decodedFields[i] = BinaryPrimitives.ReadUInt64LittleEndian(payload);
payload = payload.Slice(sizeof(ulong));
}
else if (parameterType == typeof(byte))
{
Expand All @@ -76,48 +73,55 @@ internal static object[] DecodePayload(ref EventSource.EventMetadata metadata, R
}
else if (parameterType == typeof(short))
{
decodedFields[i] = MemoryMarshal.Read<short>(payload);
decodedFields[i] = BinaryPrimitives.ReadInt16LittleEndian(payload);
payload = payload.Slice(sizeof(short));
}
else if (parameterType == typeof(ushort))
{
decodedFields[i] = MemoryMarshal.Read<ushort>(payload);
decodedFields[i] = BinaryPrimitives.ReadUInt16LittleEndian(payload);
payload = payload.Slice(sizeof(ushort));
}
else if (parameterType == typeof(float))
{
decodedFields[i] = MemoryMarshal.Read<float>(payload);
decodedFields[i] = BitConverter.Int32BitsToSingle(BinaryPrimitives.ReadInt32LittleEndian(payload));
payload = payload.Slice(sizeof(float));
}
else if (parameterType == typeof(double))
{
// Payload is automatically updated to point to the next piece of data.
Int64 doubleBytes = (Int64)ReadUnalignedUInt64(ref payload);
decodedFields[i] = BitConverter.Int64BitsToDouble(doubleBytes);
decodedFields[i] = BitConverter.Int64BitsToDouble(BinaryPrimitives.ReadInt64LittleEndian(payload));
payload = payload.Slice(sizeof(double));
}
else if (parameterType == typeof(bool))
{
// The manifest defines a bool as a 32bit type (WIN32 BOOL), not 1 bit as CLR Does.
decodedFields[i] = (MemoryMarshal.Read<int>(payload) == 1);
decodedFields[i] = (BinaryPrimitives.ReadInt32LittleEndian(payload) == 1);
payload = payload.Slice(sizeof(int));
}
else if (parameterType == typeof(Guid))
{
// Payload is automatically updated to point to the next piece of data.
decodedFields[i] = ReadUnalignedGuid(ref payload);
const int sizeOfGuid = 16;
decodedFields[i] = new Guid(payload.Slice(0, sizeOfGuid));
payload = payload.Slice(sizeOfGuid);
}
else if (parameterType == typeof(char))
{
decodedFields[i] = MemoryMarshal.Read<char>(payload);
decodedFields[i] = (char)BinaryPrimitives.ReadUInt16LittleEndian(payload);
payload = payload.Slice(sizeof(char));
}
else if (parameterType == typeof(string))
{
ReadOnlySpan<char> charPayload = MemoryMarshal.Cast<byte, char>(payload);
int charCount = charPayload.IndexOf('\0');
string val = new string(charCount >= 0 ? charPayload.Slice(0, charCount) : charPayload);
payload = payload.Slice((val.Length + 1) * sizeof(char));
decodedFields[i] = val;
if (charCount < 0)
{
payload = default;
}
else
{
charPayload = charPayload.Slice(0, charCount);
payload = payload.Slice((charCount + 1) * sizeof(char));
}
decodedFields[i] = BitConverter.IsLittleEndian ? new string(charPayload) : Encoding.Unicode.GetString(MemoryMarshal.Cast<char, byte>(charPayload));
}
else
{
Expand All @@ -127,51 +131,6 @@ internal static object[] DecodePayload(ref EventSource.EventMetadata metadata, R

return decodedFields;
}

private static UInt64 ReadUnalignedUInt64(ref ReadOnlySpan<byte> payload)
{
UInt64 val = 0;
if (BitConverter.IsLittleEndian)
{
val |= MemoryMarshal.Read<UInt32>(payload);
payload = payload.Slice(sizeof(UInt32));
val |= (MemoryMarshal.Read<UInt32>(payload) << sizeof(UInt32));
payload = payload.Slice(sizeof(UInt32));
}
else
{
val |= (MemoryMarshal.Read<UInt32>(payload) << sizeof(UInt32));
payload = payload.Slice(sizeof(UInt32));
val |= MemoryMarshal.Read<UInt32>(payload);
payload = payload.Slice(sizeof(UInt32));
}

return val;
}

private static Guid ReadUnalignedGuid(ref ReadOnlySpan<byte> payload)
{
const int sizeOfGuid = 16;
byte[] guidBytes = new byte[sizeOfGuid];
if (BitConverter.IsLittleEndian)
{
for (int i = sizeOfGuid - 1; i >= 0; i--)
{
guidBytes[i] = MemoryMarshal.Read<byte>(payload);
payload = payload.Slice(sizeof(byte));
}
}
else
{
for (int i = 0; i < sizeOfGuid; i++)
{
guidBytes[i] = MemoryMarshal.Read<byte>(payload);
payload = payload.Slice(sizeof(byte));
}
}

return new Guid(guidBytes);
}
}
#endif // FEATURE_PERFTRACING
}

0 comments on commit 879cf39

Please sign in to comment.