Background and motivation
MetadataBuilder is a large type holding references to several objects, which might include LOH-allocated arrays. Allowing the object to be reused across metadata emits would help with reducing GC pressure. This requires an API to clear the internal state of a MetadataBuilder, which I am proposing.
API Proposal
namespace System.Reflection.Metadata.Ecma335;
public class MetadataBuilder
{
// Uses the same parameters with the constructor.
// The BlobBuilder factory delegate proposed in #100418 is not very useful to reassign
// when clearing the metadata builder, so it was omitted.
public void Clear(int userStringHeapStartOffset = 0, int stringHeapStartOffset = 0, int blobHeapStartOffset = 0, int guidHeapStartOffset = 0);
}
API Usage
This API can be used by a pool of MetadataBuilder objects. Here's an illustrative example:
internal static class MetadataBuilderPool
{
private static readonly ConcurrentQueue<MetadataBuilder> s_pool = new();
public static MetadataBuilder Rent()
{
if (!s_pool.TryDequeue(out var builder))
{
builder = new MetadataBuilder();
}
return builder;
}
public static void Return(MetadataBuilder builder)
{
if (s_pool.Count >= 16)
{
return;
}
builder.Clear();
s_pool.Enqueue(builder);
}
}
Alternative Designs
- Do not add parameters to
Clear, and stick with the heap offsets specified in the constructor. This would preclude using pooled MetadataBuilders when emitting EnC deltas.
- Automatically reset the
MetadataBuilder's state after serializing its data through MetadataRootBuilder, PortablePdbBuilder, or another API using these. I'm not a big fan of silently changing behavior like this, but it might make sense here, since serializing a MetadataBuilder multiple times already fails.
Risks
No response
Background and motivation
MetadataBuilderis a large type holding references to several objects, which might include LOH-allocated arrays. Allowing the object to be reused across metadata emits would help with reducing GC pressure. This requires an API to clear the internal state of aMetadataBuilder, which I am proposing.API Proposal
API Usage
This API can be used by a pool of
MetadataBuilderobjects. Here's an illustrative example:Alternative Designs
Clear, and stick with the heap offsets specified in the constructor. This would preclude using pooledMetadataBuilders when emitting EnC deltas.MetadataBuilder's state after serializing its data throughMetadataRootBuilder,PortablePdbBuilder, or another API using these. I'm not a big fan of silently changing behavior like this, but it might make sense here, since serializing aMetadataBuildermultiple times already fails.Risks
No response