From 036a5ce9b23a26c7dbb04cc4159738806d459459 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Sim=C3=B5es?= Date: Thu, 6 Nov 2025 02:14:21 +0000 Subject: [PATCH 1/2] TypeSpec table is now minimized - Add method that crawls TypeSpec items and removes the unnused/unnecessary ones. --- .../Tables/nanoTypeSpecificationsTable.cs | 143 +++++++++++++++++- .../nanoAssemblyBuilder.cs | 2 + 2 files changed, 139 insertions(+), 6 deletions(-) diff --git a/MetadataProcessor.Shared/Tables/nanoTypeSpecificationsTable.cs b/MetadataProcessor.Shared/Tables/nanoTypeSpecificationsTable.cs index 68c5c83..10a0e26 100644 --- a/MetadataProcessor.Shared/Tables/nanoTypeSpecificationsTable.cs +++ b/MetadataProcessor.Shared/Tables/nanoTypeSpecificationsTable.cs @@ -471,16 +471,147 @@ private void AddTypeLevelGenericParameters() ushort gpSig = _context.SignaturesTable.GetOrCreateSignatureId(gp); AddIfNew(gp, gpSig); } + } + } - // seed the *open* GenericInstanceType (e.g. Action`1) - var openGeneric = new GenericInstanceType(td); - foreach (GenericParameter gp in td.GenericParameters) + internal void RemoveEmptyItems() + { + var itemsToRemove = new List(); + + foreach (var kvp in _idByTypeSpecifications.ToList()) + { + TypeReference typeReference = kvp.Key; + ushort sigId = kvp.Value; + + // Get the index of this TypeSpec in the collection + if (!TryGetTypeReferenceId(typeReference, out ushort index)) + { + continue; + } + + bool hasMemberReferences = false; + + // Check if this TypeSpec has any member references + if (typeReference is GenericParameter) + { + // Generic parameters might be referenced without explicit member refs + // Keep them for now + continue; + } + else if (typeReference.IsArray) + { + // Arrays might be referenced without explicit member refs + // Keep them for now + continue; + } + else if (typeReference is ByReferenceType || typeReference is PointerType) + { + // ByRef and Pointer types might be referenced without explicit member refs + // Keep them for now + continue; + } + else if (typeReference is GenericInstanceType genericInstanceType) + { + // Check MethodReferencesTable + foreach (MethodReference mr in _context.MethodReferencesTable.Items) + { + if (TryGetTypeReferenceId(mr.DeclaringType, out ushort referenceId) + && referenceId == index + && _context.MethodReferencesTable.TryGetMethodReferenceId(mr, out ushort _)) + { + hasMemberReferences = true; + break; + } + } + + // Check MethodSpecificationTable if no refs found yet + if (!hasMemberReferences) + { + foreach (MethodSpecification ms in _context.MethodSpecificationTable.Items) + { + if (TryGetTypeReferenceId(ms.DeclaringType, out ushort referenceId) + && referenceId == index + && _context.MethodSpecificationTable.TryGetMethodSpecificationId(ms, out ushort _)) + { + hasMemberReferences = true; + break; + } + } + } + + // Check FieldReferencesTable if no refs found yet + if (!hasMemberReferences) + { + foreach (FieldReference fr in _context.FieldReferencesTable.Items) + { + if (TryGetTypeReferenceId(fr.DeclaringType, out ushort referenceId) + && referenceId == index + && _context.FieldReferencesTable.TryGetFieldReferenceId(fr, out ushort _)) + { + hasMemberReferences = true; + break; + } + } + } + + // Check if the ElementType is a TypeDefinition with methods/fields + if (!hasMemberReferences && genericInstanceType.ElementType is TypeDefinition definition) + { + // Check if any of the definition's methods are in MethodDefinitionTable + foreach (MethodDefinition md in definition.Methods) + { + if (_context.MethodDefinitionTable.TryGetMethodReferenceId(md, out ushort _)) + { + hasMemberReferences = true; + break; + } + } + + // Check if any of the definition's fields are in FieldsTable + if (!hasMemberReferences) + { + foreach (FieldDefinition fd in definition.Fields) + { + if (_context.FieldsTable.TryGetFieldDefinitionId(fd, false, out ushort _)) + { + hasMemberReferences = true; + break; + } + } + } + } + } + else + { + // For other TypeSpecification types (arrays, pointers, etc.) + // check member references tables + foreach (MemberReference mr in _context.MemberReferencesTable.Items) + { + try + { + if (TryGetTypeReferenceId(mr.DeclaringType, out ushort referenceId) && referenceId == index) + { + hasMemberReferences = true; + break; + } + } + catch + { + // ignore errors here, as the TypeSpec might not be available + } + } + } + + if (!hasMemberReferences) { - openGeneric.GenericArguments.Add(gp); + itemsToRemove.Add(typeReference); } + } - ushort openSig = _context.SignaturesTable.GetOrCreateSignatureId(openGeneric); - AddIfNew(openGeneric, openSig); + // Remove items that have no member references + foreach (var item in itemsToRemove) + { + _idByTypeSpecifications.Remove(item); } } } diff --git a/MetadataProcessor.Shared/nanoAssemblyBuilder.cs b/MetadataProcessor.Shared/nanoAssemblyBuilder.cs index 157f7cd..0ae7040 100644 --- a/MetadataProcessor.Shared/nanoAssemblyBuilder.cs +++ b/MetadataProcessor.Shared/nanoAssemblyBuilder.cs @@ -248,6 +248,8 @@ public void Minimize() interfacesToRemove.Select(i => c.Interfaces.Remove(i)).ToList(); } + _tablesContext.TypeSpecificationsTable.RemoveEmptyItems(); + // flag minimize completed _tablesContext.MinimizeComplete = true; } From a1697378741a0491c7ce951208e7a5e8593d05eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Sim=C3=B5es?= Date: Thu, 6 Nov 2025 03:34:41 +0000 Subject: [PATCH 2/2] mscorlib is now branch from PR --- MetadataProcessor.Tests/mscorlib | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MetadataProcessor.Tests/mscorlib b/MetadataProcessor.Tests/mscorlib index 5d24cd3..5889e66 160000 --- a/MetadataProcessor.Tests/mscorlib +++ b/MetadataProcessor.Tests/mscorlib @@ -1 +1 @@ -Subproject commit 5d24cd3f058a777b9175f75dd8a390601b77886c +Subproject commit 5889e66770375c7a60842c99ec744c9adce4798f