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

Avoid calling GetTypeAlignment for known types. #321

Merged
merged 1 commit into from
Nov 20, 2024
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
4 changes: 2 additions & 2 deletions src/Tmds.DBus.Protocol/Message.cs
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ private void ClearHeaders()
return null;
}

headerFieldLength = (uint)ProtocolConstants.Align((int)headerFieldLength, DBusType.Struct);
headerFieldLength = (uint)ProtocolConstants.Align((int)headerFieldLength, ProtocolConstants.StructAlignment);

long totalLength = seqReader.Consumed + headerFieldLength + bodyLength;

Expand Down Expand Up @@ -186,7 +186,7 @@ private void ParseHeader(UnixFdCollection? handles, bool isMonitor)
var reader = new Reader(IsBigEndian, _data.AsReadOnlySequence);
reader.Advance(HeaderFieldsLengthOffset);

ArrayEnd headersEnd = reader.ReadArrayStart(DBusType.Struct);
ArrayEnd headersEnd = reader.ReadArrayStart(ProtocolConstants.StructAlignment);
while (reader.HasNext(headersEnd))
{
MessageHeader hdrType = (MessageHeader)reader.ReadByte();
Expand Down
24 changes: 12 additions & 12 deletions src/Tmds.DBus.Protocol/MessageWriter.Basic.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,21 +6,21 @@ public ref partial struct MessageWriter

public void WriteBool(bool value) => WriteUInt32(value ? 1u : 0u);

public void WriteByte(byte value) => WritePrimitiveCore<byte>(value, DBusType.Byte);
public void WriteByte(byte value) => WritePrimitiveCore<byte>(value);

public void WriteInt16(short value) => WritePrimitiveCore<Int16>(value, DBusType.Int16);
public void WriteInt16(short value) => WritePrimitiveCore<Int16>(value);

public void WriteUInt16(ushort value) => WritePrimitiveCore<UInt16>(value, DBusType.UInt16);
public void WriteUInt16(ushort value) => WritePrimitiveCore<UInt16>(value);

public void WriteInt32(int value) => WritePrimitiveCore<Int32>(value, DBusType.Int32);
public void WriteInt32(int value) => WritePrimitiveCore<Int32>(value);

public void WriteUInt32(uint value) => WritePrimitiveCore<UInt32>(value, DBusType.UInt32);
public void WriteUInt32(uint value) => WritePrimitiveCore<UInt32>(value);

public void WriteInt64(long value) => WritePrimitiveCore<Int64>(value, DBusType.Int64);
public void WriteInt64(long value) => WritePrimitiveCore<Int64>(value);

public void WriteUInt64(ulong value) => WritePrimitiveCore<UInt64>(value, DBusType.UInt64);
public void WriteUInt64(ulong value) => WritePrimitiveCore<UInt64>(value);

public void WriteDouble(double value) => WritePrimitiveCore<double>(value, DBusType.Double);
public void WriteDouble(double value) => WritePrimitiveCore<double>(value);

public void WriteString(scoped ReadOnlySpan<byte> value) => WriteStringCore(value);

Expand Down Expand Up @@ -156,7 +156,7 @@ private void WriteStringCore(scoped ReadOnlySpan<byte> span)

private void WriteStringCore(string s)
{
WritePadding(DBusType.UInt32);
WritePadding(ProtocolConstants.UInt32Alignment);
Span<byte> lengthSpan = GetSpan(4);
Advance(4);
int bytesWritten = WriteRaw(s);
Expand All @@ -165,10 +165,10 @@ private void WriteStringCore(string s)
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
private void WritePrimitiveCore<T>(T value, DBusType type)
private void WritePrimitiveCore<T>(T value)
{
WritePadding(type);
int length = ProtocolConstants.GetFixedTypeLength(type);
int length = Marshal.SizeOf<T>();
WritePadding(length);
var span = GetSpan(length);
Unsafe.WriteUnaligned<T>(ref MemoryMarshal.GetReference(span), value);
Advance(length);
Expand Down
2 changes: 1 addition & 1 deletion src/Tmds.DBus.Protocol/MessageWriter.Dictionary.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ namespace Tmds.DBus.Protocol;
public ref partial struct MessageWriter
{
public ArrayStart WriteDictionaryStart()
=> WriteArrayStart(DBusType.Struct);
=> WriteArrayStart(ProtocolConstants.StructAlignment);

public void WriteDictionaryEnd(ArrayStart start)
=> WriteArrayEnd(start);
Expand Down
4 changes: 2 additions & 2 deletions src/Tmds.DBus.Protocol/MessageWriter.Header.cs
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,7 @@ public void WriteSignalHeader(
private void WriteHeaderEnd(ArrayStart start)
{
WriteArrayEnd(start);
WritePadding(DBusType.Struct);
WritePadding(ProtocolConstants.StructAlignment);
}

private ArrayStart WriteHeaderStart(MessageType type, MessageFlags flags)
Expand All @@ -203,7 +203,7 @@ private ArrayStart WriteHeaderStart(MessageType type, MessageFlags flags)
Debug.Assert(_offset == SerialOffset + 4);

// headers
ArrayStart start = WriteArrayStart(DBusType.Struct);
ArrayStart start = WriteArrayStart(ProtocolConstants.StructAlignment);

// UnixFds
WriteStructureStart();
Expand Down
2 changes: 1 addition & 1 deletion src/Tmds.DBus.Protocol/MessageWriter.IntrospectionXml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ internal void WriteIntrospectionXml(
scoped ReadOnlySpan<string> childNames,
IEnumerable<string>? childNamesEnumerable)
{
WritePadding(DBusType.UInt32);
WritePadding(ProtocolConstants.UInt32Alignment);
Span<byte> lengthSpan = GetSpan(4);
Advance(4);

Expand Down
19 changes: 6 additions & 13 deletions src/Tmds.DBus.Protocol/MessageWriter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -67,13 +67,16 @@ internal MessageWriter(MessageBufferPool messagePool, uint serial)
}

public ArrayStart WriteArrayStart(DBusType elementType)
=> WriteArrayStart(ProtocolConstants.GetTypeAlignment(elementType));

private ArrayStart WriteArrayStart(int alignment)
{
// Array length.
WritePadding(DBusType.UInt32);
WritePadding(ProtocolConstants.UInt32Alignment);
Span<byte> lengthSpan = GetSpan(4);
Advance(4);

WritePadding(elementType);
WritePadding(alignment);

return new ArrayStart(lengthSpan, _offset);
}
Expand All @@ -85,7 +88,7 @@ public void WriteArrayEnd(ArrayStart start)

public void WriteStructureStart()
{
WritePadding(DBusType.Struct);
WritePadding(ProtocolConstants.StructAlignment);
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
Expand All @@ -96,16 +99,6 @@ private void Advance(int count)
_span = _span.Slice(count);
}

private void WritePadding(DBusType type)
{
int pad = ProtocolConstants.GetPadding(_offset, type);
if (pad != 0)
{
GetSpan(pad).Slice(0, pad).Fill(0);
Advance(pad);
}
}

private void WritePadding(int alignment)
{
int pad = ProtocolConstants.GetPadding(_offset, alignment);
Expand Down
37 changes: 7 additions & 30 deletions src/Tmds.DBus.Protocol/ProtocolConstants.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ static class ProtocolConstants
public static ReadOnlySpan<byte> SignatureSignature => new byte[] { (byte)'g' };
public static ReadOnlySpan<byte> VariantSignature => new byte[] { (byte)'v' };

public const int StructAlignment = 8;
public const int UInt32Alignment = 4;

private static ReadOnlySpan<byte> SingleTypes => new byte[] { (byte)'y', (byte)'b', (byte)'n', (byte)'q', (byte)'i', (byte)'u', (byte)'x', (byte)'t', (byte)'d', (byte)'h', (byte)'s', (byte)'o', (byte)'g', (byte)'v' };

public static bool IsSingleCompleteType(byte b)
Expand All @@ -38,15 +41,15 @@ public static int GetTypeAlignment(DBusType type)
case DBusType.Int16: return 2;
case DBusType.UInt16: return 2;
case DBusType.Int32: return 4;
case DBusType.UInt32: return 4;
case DBusType.UInt32: return UInt32Alignment;
case DBusType.Int64: return 8;
case DBusType.UInt64: return 8;
case DBusType.Double: return 8;
case DBusType.String: return 4;
case DBusType.ObjectPath: return 4;
case DBusType.Signature: return 4;
case DBusType.Array: return 4;
case DBusType.Struct: return 8;
case DBusType.Struct: return StructAlignment;
case DBusType.Variant: return 1;
case DBusType.DictEntry: return 8;
case DBusType.UnixFd: return 4;
Expand All @@ -55,35 +58,9 @@ public static int GetTypeAlignment(DBusType type)
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static int GetFixedTypeLength(DBusType type)
{
switch (type)
{
case DBusType.Byte: return 1;
case DBusType.Bool: return 4;
case DBusType.Int16: return 2;
case DBusType.UInt16: return 2;
case DBusType.Int32: return 4;
case DBusType.UInt32: return 4;
case DBusType.Int64: return 8;
case DBusType.UInt64: return 8;
case DBusType.Double: return 8;
case DBusType.UnixFd: return 4;
default: return 0;
}
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static int Align(int offset, DBusType type)
{
return offset + GetPadding(offset, type);
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static int GetPadding(int offset, DBusType type)
public static int Align(int offset, int alignment)
{
int alignment = GetTypeAlignment(type);
return GetPadding(offset ,alignment);
return offset + GetPadding(offset, alignment);
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
Expand Down
6 changes: 3 additions & 3 deletions src/Tmds.DBus.Protocol/Reader.Basic.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ public ushort ReadUInt16()

public short ReadInt16()
{
AlignReader(DBusType.Int16);
AlignReader(alignment: 2);
bool dataRead = _isBigEndian ? _reader.TryReadBigEndian(out short rv) : _reader.TryReadLittleEndian(out rv);
if (!dataRead)
{
Expand All @@ -35,7 +35,7 @@ public uint ReadUInt32()

public int ReadInt32()
{
AlignReader(DBusType.Int32);
AlignReader(alignment: 4);
bool dataRead = _isBigEndian ? _reader.TryReadBigEndian(out int rv) : _reader.TryReadLittleEndian(out rv);
if (!dataRead)
{
Expand All @@ -49,7 +49,7 @@ public ulong ReadUInt64()

public long ReadInt64()
{
AlignReader(DBusType.Int64);
AlignReader(alignment: 8);
bool dataRead = _isBigEndian ? _reader.TryReadBigEndian(out long rv) : _reader.TryReadLittleEndian(out rv);
if (!dataRead)
{
Expand Down
2 changes: 1 addition & 1 deletion src/Tmds.DBus.Protocol/Reader.Dictionary.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ namespace Tmds.DBus.Protocol;
public ref partial struct Reader
{
public ArrayEnd ReadDictionaryStart()
=> ReadArrayStart(DBusType.Struct);
=> ReadArrayStart(ProtocolConstants.StructAlignment);

// Read method for the common 'a{sv}' type.
[UnconditionalSuppressMessage("ReflectionAnalysis", "IL2026")] // It's safe to call ReadDictionary with these types.
Expand Down
27 changes: 11 additions & 16 deletions src/Tmds.DBus.Protocol/Reader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,16 +24,8 @@ internal Reader(bool isBigEndian, ReadOnlySequence<byte> sequence, UnixFdCollect
_handleCount = handleCount;
}

public void AlignStruct() => AlignReader(DBusType.Struct);

private void AlignReader(DBusType type)
{
long pad = ProtocolConstants.GetPadding((int)_reader.Consumed, type);
if (pad != 0)
{
_reader.Advance(pad);
}
}
public void AlignStruct()
=> AlignReader(ProtocolConstants.StructAlignment);

private void AlignReader(int alignment)
{
Expand All @@ -45,17 +37,20 @@ private void AlignReader(int alignment)
}

public ArrayEnd ReadArrayStart(DBusType elementType)
=> ReadArrayStart(ProtocolConstants.GetTypeAlignment(elementType));

internal ArrayEnd ReadArrayStart(int alignment)
{
uint arrayLength = ReadUInt32();
AlignReader(elementType);
AlignReader(alignment);
int endOfArray = (int)(_reader.Consumed + arrayLength);
return new ArrayEnd(elementType, endOfArray);
return new ArrayEnd(alignment, endOfArray);
}

public bool HasNext(ArrayEnd iterator)
{
int consumed = (int)_reader.Consumed;
int nextElement = ProtocolConstants.Align(consumed, iterator.Type);
int nextElement = ProtocolConstants.Align(consumed, iterator.Alignment);
if (nextElement >= iterator.EndOfArray)
{
return false;
Expand All @@ -77,12 +72,12 @@ public void SkipTo(ArrayEnd end)

public ref struct ArrayEnd
{
internal readonly DBusType Type;
internal readonly int Alignment;
internal readonly int EndOfArray;

internal ArrayEnd(DBusType type, int endOfArray)
internal ArrayEnd(int alignment, int endOfArray)
{
Type = type;
Alignment = alignment;
EndOfArray = endOfArray;
}
}
Loading