Skip to content

Commit 0d9f25a

Browse files
authored
Simplified string pool entry by leveraging LazyEncodedString (#254)
Co-authored-by: smaillet <25911635+smaillet@users.noreply.github.com>
1 parent f418a6c commit 0d9f25a

File tree

2 files changed

+9
-24
lines changed

2 files changed

+9
-24
lines changed

src/Interop/Ubiquity.NET.Llvm.Interop/ABI/llvm-c/Orc.cs

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -214,14 +214,9 @@ public static unsafe partial void LLVMOrcExecutionSessionLookup(
214214
[UnmanagedCallConv( CallConvs = [ typeof( CallConvCdecl ) ] )]
215215
public static unsafe partial void LLVMOrcReleaseSymbolStringPoolEntry( LLVMOrcSymbolStringPoolEntryRefAlias S );
216216

217-
// This does NOT marshal the string, it only provides the raw pointer so that a span is constructible
218-
// from the pointer. The memory for the string is OWNED by the entry so the returned pointer is valid
219-
// for the lifetime of the referenced entry.
220-
// TODO: Consider if this can't or shouldn't be a LazyEncodedString to contain potentially both forms
221-
// as needed.
222217
[LibraryImport( LibraryName )]
223218
[UnmanagedCallConv( CallConvs = [ typeof( CallConvCdecl ) ] )]
224-
public static unsafe partial byte* LLVMOrcSymbolStringPoolEntryStr( LLVMOrcSymbolStringPoolEntryRef S );
219+
public static unsafe partial LazyEncodedString LLVMOrcSymbolStringPoolEntryStr( LLVMOrcSymbolStringPoolEntryRef S );
225220

226221
[LibraryImport( LibraryName )]
227222
[UnmanagedCallConv( CallConvs = [ typeof( CallConvCdecl ) ] )]

src/Ubiquity.NET.Llvm/OrcJITv2/SymbolStringPoolEntry.cs

Lines changed: 8 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ namespace Ubiquity.NET.Llvm.OrcJITv2
1313
{
1414
/// <summary>Reference to an entry in a symbol string pool for ORC JIT v2</summary>
1515
/// <remarks>
16-
/// This holds a reference to the symbol string which is ONLY marshalled/converted to
16+
/// This holds a reference to the symbol string which is ONLY marshaled/converted to
1717
/// a managed string in the <see cref="ToString"/> method. This allows comparing strings
1818
/// etc... without the need of conversion.
1919
/// <note type="information">
@@ -48,7 +48,7 @@ public SymbolStringPoolEntry( SymbolStringPoolEntry other )
4848
{
4949
ObjectDisposedException.ThrowIf( IsDisposed, this );
5050

51-
return ManagedString.Value;
51+
return DeferredInitSymbolString.Value.ToString();
5252
}
5353

5454
#region IEquatable<SymbolStringPoolEntry>
@@ -119,7 +119,7 @@ public ReadOnlySpan<byte> ReadOnlySpan
119119

120120
unsafe
121121
{
122-
return new( (void*)NativeStringPtr.Value, LazyStrLen.Value );
122+
return DeferredInitSymbolString.Value.ToReadOnlySpan();
123123
}
124124
}
125125
}
@@ -140,23 +140,13 @@ internal SymbolStringPoolEntry( LLVMOrcSymbolStringPoolEntryRef h )
140140
}
141141

142142
Handle = h.Move();
143-
unsafe
144-
{
145-
NativeStringPtr = new( ( ) => (nint)LLVMOrcSymbolStringPoolEntryStr( Handle ), LazyThreadSafetyMode.ExecutionAndPublication );
146-
ManagedString = new( ( ) => ExecutionEncodingStringMarshaller.ConvertToManaged( (byte*)NativeStringPtr.Value ), LazyThreadSafetyMode.ExecutionAndPublication );
147-
LazyStrLen = new( ( ) => MemoryMarshal.CreateReadOnlySpanFromNullTerminated( (byte*)NativeStringPtr.Value ).Length, LazyThreadSafetyMode.ExecutionAndPublication );
148-
}
143+
DeferredInitSymbolString = new(()=>LLVMOrcSymbolStringPoolEntryStr( Handle ), LazyThreadSafetyMode.PublicationOnly);
149144
}
150145

151146
internal SymbolStringPoolEntry( nint abiHandle, bool alias = false )
152147
{
153148
Handle = new( abiHandle, !alias );
154-
unsafe
155-
{
156-
NativeStringPtr = new( ( ) => (nint)LLVMOrcSymbolStringPoolEntryStr( Handle ), LazyThreadSafetyMode.ExecutionAndPublication );
157-
ManagedString = new( ( ) => ExecutionEncodingStringMarshaller.ConvertToManaged( (byte*)NativeStringPtr.Value ), LazyThreadSafetyMode.ExecutionAndPublication );
158-
LazyStrLen = new( ( ) => MemoryMarshal.CreateReadOnlySpanFromNullTerminated( (byte*)NativeStringPtr.Value ).Length, LazyThreadSafetyMode.ExecutionAndPublication );
159-
}
149+
DeferredInitSymbolString = new(()=>LLVMOrcSymbolStringPoolEntryStr( Handle ), LazyThreadSafetyMode.PublicationOnly);
160150
}
161151

162152
internal LLVMOrcSymbolStringPoolEntryRef Handle { get; }
@@ -195,9 +185,9 @@ private LLVMOrcSymbolStringPoolEntryRef AddRefHandle( )
195185
return new( Handle.DangerousGetHandle(), owner: true );
196186
}
197187

198-
private readonly Lazy<string?> ManagedString;
199-
private readonly Lazy<int> LazyStrLen; // count of bytes in the native string (Not including null terminator)
200-
private readonly Lazy<nint> NativeStringPtr;
188+
// Callers might never need the contents of the string so it is lazily
189+
// initialize when needed. String pool entries are interned and thus are immutable, like a .NET string
190+
private readonly Lazy<LazyEncodedString> DeferredInitSymbolString;
201191
}
202192

203193
[SuppressMessage( "StyleCop.CSharp.MaintainabilityRules", "SA1400:Access modifier should be declared", Justification = "'file' is an accessibility" )]

0 commit comments

Comments
 (0)