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

Add and use collection Capacity properties #316

Merged
merged 6 commits into from
May 26, 2022
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
24 changes: 24 additions & 0 deletions src/AsmResolver.DotNet/Builder/DotNetDirectoryBuffer.MemberTree.cs
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,9 @@ public void DefineTypes(IEnumerable<TypeDefinition> types)
var typeDefTable = Metadata.TablesStream.GetTable<TypeDefinitionRow>(TableIndex.TypeDef);
var nestedClassTable = Metadata.TablesStream.GetSortedTable<TypeDefinition, NestedClassRow>(TableIndex.NestedClass);

if (types is ICollection<TypeDefinition> collection)
typeDefTable.EnsureCapacity(typeDefTable.Count + collection.Count);

foreach (var type in types)
{
// At this point, we might not have added all type defs/refs/specs yet, so we cannot determine
Expand Down Expand Up @@ -177,6 +180,8 @@ public void DefineTypes(IEnumerable<TypeDefinition> types)
public void DefineFields(IEnumerable<FieldDefinition> fields)
{
var table = Metadata.TablesStream.GetTable<FieldDefinitionRow>(TableIndex.Field);
if (fields is ICollection<FieldDefinition> collection)
table.EnsureCapacity(table.Count + collection.Count);

foreach (var field in fields)
{
Expand All @@ -197,6 +202,8 @@ public void DefineFields(IEnumerable<FieldDefinition> fields)
public void DefineMethods(IEnumerable<MethodDefinition> methods)
{
var table = Metadata.TablesStream.GetTable<MethodDefinitionRow>(TableIndex.Method);
if (methods is ICollection<MethodDefinition> collection)
table.EnsureCapacity(table.Count + collection.Count);

foreach (var method in methods)
{
Expand Down Expand Up @@ -227,6 +234,8 @@ public void DefineMethods(IEnumerable<MethodDefinition> methods)
public void DefineParameters(IEnumerable<ParameterDefinition> parameters)
{
var table = Metadata.TablesStream.GetTable<ParameterDefinitionRow>(TableIndex.Param);
if (parameters is ICollection<ParameterDefinition> collection)
table.EnsureCapacity(table.Count + collection.Count);

foreach (var parameter in parameters)
{
Expand All @@ -247,6 +256,8 @@ public void DefineParameters(IEnumerable<ParameterDefinition> parameters)
public void DefineProperties(IEnumerable<PropertyDefinition> properties)
{
var table = Metadata.TablesStream.GetTable<PropertyDefinitionRow>(TableIndex.Property);
if (properties is ICollection<PropertyDefinition> collection)
table.EnsureCapacity(table.Count + collection.Count);

foreach (var property in properties)
{
Expand All @@ -267,6 +278,8 @@ public void DefineProperties(IEnumerable<PropertyDefinition> properties)
public void DefineEvents(IEnumerable<EventDefinition> events)
{
var table = Metadata.TablesStream.GetTable<EventDefinitionRow>(TableIndex.Event);
if (events is ICollection<EventDefinition> collection)
table.EnsureCapacity(table.Count + collection.Count);

foreach (var @event in events)
{
Expand Down Expand Up @@ -299,6 +312,17 @@ public void FinalizeTypes()
uint propertyList = 1;
uint eventList = 1;

tablesStream.GetTable<FieldPointerRow>(TableIndex.FieldPtr)
.EnsureCapacity(tablesStream.GetTable<FieldDefinitionRow>(TableIndex.Field).Count);
tablesStream.GetTable<MethodPointerRow>(TableIndex.MethodPtr)
.EnsureCapacity(tablesStream.GetTable<MethodDefinitionRow>(TableIndex.Method).Count);
tablesStream.GetTable<ParameterPointerRow>(TableIndex.ParamPtr)
.EnsureCapacity(tablesStream.GetTable<ParameterDefinitionRow>(TableIndex.Param).Count);
tablesStream.GetTable<PropertyPointerRow>(TableIndex.PropertyPtr)
.EnsureCapacity(tablesStream.GetTable<PropertyDefinitionRow>(TableIndex.Property).Count);
tablesStream.GetTable<EventPointerRow>(TableIndex.EventPtr)
.EnsureCapacity(tablesStream.GetTable<EventDefinitionRow>(TableIndex.Event).Count);

for (uint rid = 1; rid <= typeDefTable.Count; rid++)
{
var typeToken = new MetadataToken(TableIndex.TypeDef, rid);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,16 @@ public TRow this[uint rid]
}
}

/// <inheritdoc />
public void EnsureCapacity(int capacity)
{
_underlyingBuffer.EnsureCapacity(capacity);

#if NETSTANDARD2_1_OR_GREATER
_entries.EnsureCapacity(capacity);
#endif
}

/// <inheritdoc />
public ref TRow GetRowRef(uint rid) => ref _underlyingBuffer.GetRowRef(rid);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,12 @@ TRow this[uint rid]
set;
}

/// <summary>
/// Ensures the capacity of the table buffer is at least the provided amount of elements.
/// </summary>
/// <param name="capacity">The number of elements to store.</param>
void EnsureCapacity(int capacity);

/// <summary>
/// Gets or sets a reference to a row in the metadata table.
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,13 @@ public virtual TRow this[uint rid]
set => _entries[(int) (rid - 1)] = value;
}

/// <inheritdoc />
public void EnsureCapacity(int capacity)
{
if (_entries.Capacity < capacity)
_entries.Capacity = capacity;
}

/// <inheritdoc />
public ref TRow GetRowRef(uint rid) => ref _entries.GetElementRef((int)(rid - 1));

Expand All @@ -49,6 +56,9 @@ public virtual MetadataToken Add(in TRow row)
/// <inheritdoc />
public void FlushToTable()
{
if (_table.Capacity < _entries.Count)
_table.Capacity = _entries.Count;

foreach (var row in _entries)
_table.Add(row);
}
Expand Down
10 changes: 10 additions & 0 deletions src/AsmResolver.DotNet/Collections/MethodSemanticsCollection.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,16 @@ public MethodSemanticsCollection(IHasSemantics owner)
{
}

/// <summary>
/// Creates a new instance of the <see cref="MethodSemanticsCollection"/> class.
/// </summary>
/// <param name="owner">The owner of the collection.</param>
/// <param name="capacity">The initial number of elements the collection can store.</param>
public MethodSemanticsCollection(IHasSemantics owner, int capacity)
: base(owner, capacity)
{
}

internal bool ValidateMembership
{
get;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,10 +58,11 @@ public SerializedGenericParameter(ModuleReaderContext context, MetadataToken tok
/// <inheritdoc />
protected override IList<GenericParameterConstraint> GetConstraints()
{
var result = new OwnedCollection<GenericParameter, GenericParameterConstraint>(this);

var module = _context.ParentModule;
foreach (uint rid in module.GetGenericParameterConstraints(MetadataToken))
var rids = module.GetGenericParameterConstraints(MetadataToken);
var result = new OwnedCollection<GenericParameter, GenericParameterConstraint>(this, rids.Count);

foreach (uint rid in rids)
{
var constraintToken = new MetadataToken(TableIndex.GenericParamConstraint, rid);
result.Add((GenericParameterConstraint) module.LookupMember(constraintToken));
Expand Down
10 changes: 6 additions & 4 deletions src/AsmResolver.DotNet/Serialized/SerializedMethodDefinition.cs
Original file line number Diff line number Diff line change
Expand Up @@ -81,9 +81,10 @@ protected override IList<SecurityDeclaration> GetSecurityDeclarations() =>
/// <inheritdoc />
protected override IList<ParameterDefinition> GetParameterDefinitions()
{
var result = new OwnedCollection<MethodDefinition, ParameterDefinition>(this);
var parameterRange = _context.ParentModule.GetParameterRange(MetadataToken.Rid);
var result = new OwnedCollection<MethodDefinition, ParameterDefinition>(this, parameterRange.Count);

foreach (var token in _context.ParentModule.GetParameterRange(MetadataToken.Rid))
foreach (var token in parameterRange)
{
if (_context.ParentModule.TryLookupMember(token, out var member) && member is ParameterDefinition parameter)
result.Add(parameter);
Expand All @@ -108,9 +109,10 @@ protected override IList<ParameterDefinition> GetParameterDefinitions()
/// <inheritdoc />
protected override IList<GenericParameter> GetGenericParameters()
{
var result = new OwnedCollection<IHasGenericParameters, GenericParameter>(this);
var rids = _context.ParentModule.GetGenericParameters(MetadataToken);
var result = new OwnedCollection<IHasGenericParameters, GenericParameter>(this, rids.Count);

foreach (uint rid in _context.ParentModule.GetGenericParameters(MetadataToken))
foreach (uint rid in rids)
{
if (_context.ParentModule.TryLookupMember(new MetadataToken(TableIndex.GenericParam, rid), out var member)
&& member is GenericParameter genericParameter)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ private OneToManyRelation<uint, uint> InitializeTypeDefinitionTree()
return typeDefTree;
}

internal IEnumerable<uint> GetNestedTypeRids(uint enclosingTypeRid)
internal ICollection<uint> GetNestedTypeRids(uint enclosingTypeRid)
{
EnsureTypeDefinitionTreeInitialized();
return _typeDefTree.GetValues(enclosingTypeRid);
Expand Down Expand Up @@ -107,8 +107,8 @@ private void InitializeMethodSemantics()
var semanticsTable = tablesStream.GetTable<MethodSemanticsRow>(TableIndex.MethodSemantics);
var encoder = tablesStream.GetIndexEncoder(CodedIndex.HasSemantics);

var semantics = new OneToManyRelation<MetadataToken, uint>();
var semanticMethods = new Dictionary<uint, MetadataToken>();
var semantics = new OneToManyRelation<MetadataToken, uint>(semanticsTable.Count);
var semanticMethods = new Dictionary<uint, MetadataToken>(semanticsTable.Count);
for (int i = 0; i < semanticsTable.Count; i++)
{
var methodSemanticsRow = semanticsTable[i];
Expand All @@ -123,7 +123,7 @@ private void InitializeMethodSemantics()
Interlocked.CompareExchange(ref _semanticMethods, semanticMethods, null);
}

internal IEnumerable<uint> GetMethodSemantics(MetadataToken owner)
internal ICollection<uint> GetMethodSemantics(MetadataToken owner)
{
EnsureMethodSemanticsInitialized();
return _semantics.GetValues(owner);
Expand Down Expand Up @@ -155,7 +155,7 @@ private OneToOneRelation<MetadataToken, uint> GetConstants()
var constantTable = tablesStream.GetTable<ConstantRow>(TableIndex.Constant);
var encoder = tablesStream.GetIndexEncoder(CodedIndex.HasConstant);

var constants = new OneToOneRelation<MetadataToken, uint>();
var constants = new OneToOneRelation<MetadataToken, uint>(constantTable.Count);
for (int i = 0; i < constantTable.Count; i++)
{
var ownerToken = encoder.DecodeIndex(constantTable[i].Parent);
Expand Down Expand Up @@ -199,7 +199,7 @@ private OneToManyRelation<MetadataToken, uint> InitializeCustomAttributes()
var attributeTable = tablesStream.GetTable<CustomAttributeRow>(TableIndex.CustomAttribute);
var encoder = tablesStream.GetIndexEncoder(CodedIndex.HasCustomAttribute);

var customAttributes = new OneToManyRelation<MetadataToken, uint>();
var customAttributes = new OneToManyRelation<MetadataToken, uint>(attributeTable.Count);
for (int i = 0; i < attributeTable.Count; i++)
{
var ownerToken = encoder.DecodeIndex(attributeTable[i].Parent);
Expand Down Expand Up @@ -228,9 +228,10 @@ internal MetadataToken GetCustomAttributeOwner(uint attributeRid)
internal IList<CustomAttribute> GetCustomAttributeCollection(IHasCustomAttribute owner)
{
EnsureCustomAttributesInitialized();
var result = new OwnedCollection<IHasCustomAttribute, CustomAttribute>(owner);
var rids = _customAttributes.GetValues(owner.MetadataToken);
var result = new OwnedCollection<IHasCustomAttribute, CustomAttribute>(owner, rids.Count);

foreach (uint rid in _customAttributes.GetValues(owner.MetadataToken))
foreach (uint rid in rids)
{
var attribute = (CustomAttribute) LookupMember(new MetadataToken(TableIndex.CustomAttribute, rid));
result.Add(attribute);
Expand All @@ -252,7 +253,7 @@ private OneToManyRelation<MetadataToken, uint> InitializeSecurityDeclarations()
var declarationTable = tablesStream.GetTable<SecurityDeclarationRow>(TableIndex.DeclSecurity);
var encoder = tablesStream.GetIndexEncoder(CodedIndex.HasDeclSecurity);

var securityDeclarations = new OneToManyRelation<MetadataToken, uint>();
var securityDeclarations = new OneToManyRelation<MetadataToken, uint>(declarationTable.Count);
for (int i = 0; i < declarationTable.Count; i++)
{
var ownerToken = encoder.DecodeIndex(declarationTable[i].Parent);
Expand All @@ -272,9 +273,10 @@ internal MetadataToken GetSecurityDeclarationOwner(uint attributeRid)
internal IList<SecurityDeclaration> GetSecurityDeclarationCollection(IHasSecurityDeclaration owner)
{
EnsureSecurityDeclarationsInitialized();
var result = new OwnedCollection<IHasSecurityDeclaration, SecurityDeclaration>(owner);
var rids = _securityDeclarations.GetValues(owner.MetadataToken);
var result = new OwnedCollection<IHasSecurityDeclaration, SecurityDeclaration>(owner, rids.Count);

foreach (uint rid in _securityDeclarations.GetValues(owner.MetadataToken))
foreach (uint rid in rids)
{
var attribute = (SecurityDeclaration) LookupMember(new MetadataToken(TableIndex.DeclSecurity, rid));
result.Add(attribute);
Expand All @@ -296,7 +298,7 @@ private OneToManyRelation<MetadataToken, uint> InitializeGenericParameters()
var parameterTable = tablesStream.GetTable<GenericParameterRow>(TableIndex.GenericParam);
var encoder = tablesStream.GetIndexEncoder(CodedIndex.TypeOrMethodDef);

var genericParameters = new OneToManyRelation<MetadataToken, uint>();
var genericParameters = new OneToManyRelation<MetadataToken, uint>(parameterTable.Count);
for (int i = 0; i < parameterTable.Count; i++)
{
var ownerToken = encoder.DecodeIndex(parameterTable[i].Owner);
Expand Down Expand Up @@ -331,7 +333,7 @@ private OneToManyRelation<MetadataToken, uint> InitializeGenericParameterConstra
var tablesStream = DotNetDirectory.Metadata!.GetStream<TablesStream>();
var constraintTable = tablesStream.GetTable<GenericParameterConstraintRow>(TableIndex.GenericParamConstraint);

var constraints = new OneToManyRelation<MetadataToken, uint>();
var constraints = new OneToManyRelation<MetadataToken, uint>(constraintTable.Count);
for (int i = 0; i < constraintTable.Count; i++)
{
var ownerToken = new MetadataToken(TableIndex.GenericParam, constraintTable[i].Owner);
Expand Down Expand Up @@ -366,7 +368,7 @@ private OneToManyRelation<MetadataToken, uint> InitializeInterfaces()
var tablesStream = DotNetDirectory.Metadata!.GetStream<TablesStream>();
var interfaceImplTable = tablesStream.GetTable<InterfaceImplementationRow>(TableIndex.InterfaceImpl);

var interfaces = new OneToManyRelation<MetadataToken, uint>();
var interfaces = new OneToManyRelation<MetadataToken, uint>(interfaceImplTable.Count);
for (int i = 0; i < interfaceImplTable.Count; i++)
{
var ownerToken = new MetadataToken(TableIndex.TypeDef, interfaceImplTable[i].Class);
Expand Down Expand Up @@ -401,7 +403,7 @@ private OneToManyRelation<MetadataToken, uint> InitializeMethodImplementations()
var tablesStream = DotNetDirectory.Metadata!.GetStream<TablesStream>();
var methodImplTable = tablesStream.GetTable<MethodImplementationRow>(TableIndex.MethodImpl);

var methodImplementations = new OneToManyRelation<MetadataToken, uint>();
var methodImplementations = new OneToManyRelation<MetadataToken, uint>(methodImplTable.Count);
for (int i = 0; i < methodImplTable.Count; i++)
{
var ownerToken = new MetadataToken(TableIndex.TypeDef, methodImplTable[i].Class);
Expand Down Expand Up @@ -430,7 +432,7 @@ private OneToOneRelation<MetadataToken, uint> InitializeClassLayouts()
var tablesStream = DotNetDirectory.Metadata!.GetStream<TablesStream>();
var layoutTable = tablesStream.GetTable<ClassLayoutRow>(TableIndex.ClassLayout);

var layouts = new OneToOneRelation<MetadataToken, uint>();
var layouts = new OneToOneRelation<MetadataToken, uint>(layoutTable.Count);
for (int i = 0; i < layoutTable.Count; i++)
{
var ownerToken = new MetadataToken(TableIndex.TypeDef, layoutTable[i].Parent);
Expand Down Expand Up @@ -460,7 +462,7 @@ private OneToOneRelation<MetadataToken, uint> InitializeImplementationMaps()
var mapTable = tablesStream.GetTable<ImplementationMapRow>(TableIndex.ImplMap);
var encoder = tablesStream.GetIndexEncoder(CodedIndex.TypeOrMethodDef);

var maps = new OneToOneRelation<MetadataToken, uint>();
var maps = new OneToOneRelation<MetadataToken, uint>(mapTable.Count);
for (int i = 0; i < mapTable.Count; i++)
{
var ownerToken = encoder.DecodeIndex(mapTable[i].MemberForwarded);
Expand Down Expand Up @@ -495,7 +497,7 @@ private OneToOneRelation<MetadataToken, uint> InitializeFieldRvas()
var tablesStream = DotNetDirectory.Metadata!.GetStream<TablesStream>();
var rvaTable = tablesStream.GetTable<FieldRvaRow>(TableIndex.FieldRva);

var rvas = new OneToOneRelation<MetadataToken, uint>();
var rvas = new OneToOneRelation<MetadataToken, uint>(rvaTable.Count);
for (int i = 0; i < rvaTable.Count; i++)
{
var ownerToken = new MetadataToken(TableIndex.Field, rvaTable[i].Field);
Expand Down Expand Up @@ -525,7 +527,7 @@ private OneToOneRelation<MetadataToken, uint> InitializeFieldMarshals()
var marshalTable = tablesStream.GetTable<FieldMarshalRow>(TableIndex.FieldMarshal);
var encoder = tablesStream.GetIndexEncoder(CodedIndex.HasFieldMarshal);

var marshals = new OneToOneRelation<MetadataToken, uint>();
var marshals = new OneToOneRelation<MetadataToken, uint>(marshalTable.Count);
for (int i = 0; i < marshalTable.Count; i++)
{
var ownerToken = encoder.DecodeIndex(marshalTable[i].Parent);
Expand Down Expand Up @@ -571,7 +573,7 @@ private OneToOneRelation<MetadataToken, uint> InitializeFieldLayouts()
var tablesStream = DotNetDirectory.Metadata!.GetStream<TablesStream>();
var layoutTable = tablesStream.GetTable<FieldLayoutRow>(TableIndex.FieldLayout);

var fieldLayouts = new OneToOneRelation<MetadataToken, uint>();
var fieldLayouts = new OneToOneRelation<MetadataToken, uint>(layoutTable.Count);
for (int i = 0; i < layoutTable.Count; i++)
{
var ownerToken = new MetadataToken(TableIndex.Field, layoutTable[i].Field);
Expand Down
Loading