Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/corert.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichal Strehovský <MichalStrehovsky@users.noreply.github.com>2018-07-31 19:04:02 +0300
committerGitHub <noreply@github.com>2018-07-31 19:04:02 +0300
commitebb3632553a4c8f1303c92fc03ce19b4879bb708 (patch)
treed1cc89bc265f5b18d9b012027332d1c319e1ce1a /src/ILCompiler.Compiler
parent7310d4bcf386371660c4bd99d9807fa296ec960d (diff)
parentb7ea3897c635e746573a6ff50bf2f2a54be16126 (diff)
Merge pull request #6158 from dotnet/master
Merge master to nmirror
Diffstat (limited to 'src/ILCompiler.Compiler')
-rw-r--r--src/ILCompiler.Compiler/src/Compiler/Compilation.cs6
-rw-r--r--src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/EETypeNode.cs9
-rw-r--r--src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/NodeFactory.cs12
-rw-r--r--src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/SealedVTableNode.cs11
-rw-r--r--src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/TypeMetadataNode.cs17
-rw-r--r--src/ILCompiler.Compiler/src/Compiler/UsageBasedMetadataManager.cs23
-rw-r--r--src/ILCompiler.Compiler/src/Compiler/VirtualMethodCallHelper.cs8
7 files changed, 72 insertions, 14 deletions
diff --git a/src/ILCompiler.Compiler/src/Compiler/Compilation.cs b/src/ILCompiler.Compiler/src/Compiler/Compilation.cs
index 6a307aac4..defedd0b7 100644
--- a/src/ILCompiler.Compiler/src/Compiler/Compilation.cs
+++ b/src/ILCompiler.Compiler/src/Compiler/Compilation.cs
@@ -419,7 +419,11 @@ namespace ILCompiler
public void RootModuleMetadata(ModuleDesc module, string reason)
{
- _graph.AddRoot(_factory.ModuleMetadata(module), reason);
+ // RootModuleMetadata is kind of a hack - this is pretty much only used to force include
+ // type forwarders from assemblies metadata generator would normally not look at.
+ // This will go away when the temporary RD.XML parser goes away.
+ if (_factory.MetadataManager is UsageBasedMetadataManager)
+ _graph.AddRoot(_factory.ModuleMetadata(module), reason);
}
public void RootReadOnlyDataBlob(byte[] data, int alignment, string reason, string exportName)
diff --git a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/EETypeNode.cs b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/EETypeNode.cs
index 1d2c7832d..6299c3fff 100644
--- a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/EETypeNode.cs
+++ b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/EETypeNode.cs
@@ -774,7 +774,7 @@ namespace ILCompiler.DependencyAnalysis
// Final NewSlot methods cannot be overridden, and therefore can be placed in the sealed-vtable to reduce the size of the vtable
// of this type and any type that inherits from it.
- if (declMethod.CanMethodBeInSealedVTable() && !declType.IsArrayTypeWithoutGenericInterfaces() && !factory.IsCppCodegenTemporaryWorkaround)
+ if (declMethod.CanMethodBeInSealedVTable() && !declType.IsArrayTypeWithoutGenericInterfaces())
continue;
if (!implMethod.IsAbstract)
@@ -838,7 +838,12 @@ namespace ILCompiler.DependencyAnalysis
SealedVTableNode sealedVTable = factory.SealedVTable(_type.ConvertToCanonForm(CanonicalFormKind.Specific));
if (sealedVTable.BuildSealedVTableSlots(factory, relocsOnly) && sealedVTable.NumSealedVTableEntries > 0)
- objData.EmitReloc(sealedVTable, RelocType.IMAGE_REL_BASED_RELPTR32);
+ {
+ if (factory.Target.SupportsRelativePointers)
+ objData.EmitReloc(sealedVTable, RelocType.IMAGE_REL_BASED_RELPTR32);
+ else
+ objData.EmitPointerReloc(sealedVTable);
+ }
}
}
diff --git a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/NodeFactory.cs b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/NodeFactory.cs
index d6ecd195c..26b0c703d 100644
--- a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/NodeFactory.cs
+++ b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/NodeFactory.cs
@@ -912,6 +912,9 @@ namespace ILCompiler.DependencyAnalysis
internal TypeMetadataNode TypeMetadata(MetadataType type)
{
+ // These are only meaningful for UsageBasedMetadataManager. We should not have them
+ // in the dependency graph otherwise.
+ Debug.Assert(MetadataManager is UsageBasedMetadataManager);
return _typesWithMetadata.GetOrAdd(type);
}
@@ -919,6 +922,9 @@ namespace ILCompiler.DependencyAnalysis
internal MethodMetadataNode MethodMetadata(MethodDesc method)
{
+ // These are only meaningful for UsageBasedMetadataManager. We should not have them
+ // in the dependency graph otherwise.
+ Debug.Assert(MetadataManager is UsageBasedMetadataManager);
return _methodsWithMetadata.GetOrAdd(method);
}
@@ -926,6 +932,9 @@ namespace ILCompiler.DependencyAnalysis
internal FieldMetadataNode FieldMetadata(FieldDesc field)
{
+ // These are only meaningful for UsageBasedMetadataManager. We should not have them
+ // in the dependency graph otherwise.
+ Debug.Assert(MetadataManager is UsageBasedMetadataManager);
return _fieldsWithMetadata.GetOrAdd(field);
}
@@ -933,6 +942,9 @@ namespace ILCompiler.DependencyAnalysis
internal ModuleMetadataNode ModuleMetadata(ModuleDesc module)
{
+ // These are only meaningful for UsageBasedMetadataManager. We should not have them
+ // in the dependency graph otherwise.
+ Debug.Assert(MetadataManager is UsageBasedMetadataManager);
return _modulesWithMetadata.GetOrAdd(module);
}
diff --git a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/SealedVTableNode.cs b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/SealedVTableNode.cs
index 942e14dc4..dac6d8dbc 100644
--- a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/SealedVTableNode.cs
+++ b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/SealedVTableNode.cs
@@ -90,10 +90,6 @@ namespace ILCompiler.DependencyAnalysis
_sealedVTableEntries = new List<MethodDesc>();
- // Cpp codegen does not support sealed vtables
- if (factory.IsCppCodegenTemporaryWorkaround)
- return true;
-
IReadOnlyList<MethodDesc> virtualSlots = factory.VTable(declType).Slots;
for (int i = 0; i < virtualSlots.Count; i++)
@@ -153,7 +149,12 @@ namespace ILCompiler.DependencyAnalysis
for (int i = 0; i < _sealedVTableEntries.Count; i++)
{
MethodDesc canonImplMethod = _sealedVTableEntries[i].GetCanonMethodTarget(CanonicalFormKind.Specific);
- objData.EmitReloc(factory.MethodEntrypoint(canonImplMethod, _sealedVTableEntries[i].OwningType.IsValueType), RelocType.IMAGE_REL_BASED_RELPTR32);
+ IMethodNode relocTarget = factory.MethodEntrypoint(canonImplMethod, _sealedVTableEntries[i].OwningType.IsValueType);
+
+ if (factory.Target.SupportsRelativePointers)
+ objData.EmitReloc(relocTarget, RelocType.IMAGE_REL_BASED_RELPTR32);
+ else
+ objData.EmitPointerReloc(relocTarget);
}
}
diff --git a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/TypeMetadataNode.cs b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/TypeMetadataNode.cs
index a8416afad..39ad01e9f 100644
--- a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/TypeMetadataNode.cs
+++ b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/TypeMetadataNode.cs
@@ -51,6 +51,23 @@ namespace ILCompiler.DependencyAnalysis
dependencies.Add(factory.MethodMetadata(_type.GetMethod("Invoke", null)), "Delegate invoke method metadata");
}
+ // If the user asked for complete metadata to be generated for all types that are getting metadata, ensure that.
+ var mdManager = (UsageBasedMetadataManager)factory.MetadataManager;
+ if ((mdManager._generationOptions & UsageBasedMetadataGenerationOptions.CompleteTypesOnly) != 0)
+ {
+ foreach (MethodDesc method in _type.GetMethods())
+ {
+ if (!mdManager.IsReflectionBlocked(method))
+ dependencies.Add(factory.MethodMetadata(method), "Complete metadata for type");
+ }
+
+ foreach (FieldDesc field in _type.GetFields())
+ {
+ if (!mdManager.IsReflectionBlocked(field))
+ dependencies.Add(factory.FieldMetadata(field), "Complete metadata for type");
+ }
+ }
+
return dependencies;
}
diff --git a/src/ILCompiler.Compiler/src/Compiler/UsageBasedMetadataManager.cs b/src/ILCompiler.Compiler/src/Compiler/UsageBasedMetadataManager.cs
index 3d13aa547..c6a71b2b4 100644
--- a/src/ILCompiler.Compiler/src/Compiler/UsageBasedMetadataManager.cs
+++ b/src/ILCompiler.Compiler/src/Compiler/UsageBasedMetadataManager.cs
@@ -2,6 +2,7 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
+using System;
using System.Collections.Generic;
using Internal.TypeSystem;
@@ -23,6 +24,7 @@ namespace ILCompiler
{
private readonly CompilationModuleGroup _compilationModuleGroup;
+ internal readonly UsageBasedMetadataGenerationOptions _generationOptions;
private readonly bool _hasPreciseFieldUsageInformation;
private readonly List<ModuleDesc> _modulesWithMetadata = new List<ModuleDesc>();
@@ -36,12 +38,14 @@ namespace ILCompiler
MetadataBlockingPolicy blockingPolicy,
ManifestResourceBlockingPolicy resourceBlockingPolicy,
string logFile,
- StackTraceEmissionPolicy stackTracePolicy)
+ StackTraceEmissionPolicy stackTracePolicy,
+ UsageBasedMetadataGenerationOptions generationOptions)
: base(typeSystemContext, blockingPolicy, resourceBlockingPolicy, logFile, stackTracePolicy)
{
// We use this to mark places that would behave differently if we tracked exact fields used.
_hasPreciseFieldUsageInformation = false;
_compilationModuleGroup = group;
+ _generationOptions = generationOptions;
}
protected override void Graph_NewMarkedNode(DependencyNodeCore<NodeFactory> obj)
@@ -439,4 +443,21 @@ namespace ILCompiler
}
}
}
+
+ [Flags]
+ public enum UsageBasedMetadataGenerationOptions
+ {
+ None = 0,
+
+ /// <summary>
+ /// Specifies that complete metadata should be generated for types.
+ /// </summary>
+ /// <remarks>
+ /// If this option is set, generated metadata will no longer be pay for play,
+ /// and a certain class of bugs will disappear (APIs returning "member doesn't
+ /// exist" at runtime, even though the member exists and we just didn't generate the metadata).
+ /// Reflection blocking still applies.
+ /// </remarks>
+ CompleteTypesOnly = 1,
+ }
}
diff --git a/src/ILCompiler.Compiler/src/Compiler/VirtualMethodCallHelper.cs b/src/ILCompiler.Compiler/src/Compiler/VirtualMethodCallHelper.cs
index 8266ed8df..19da1f6ae 100644
--- a/src/ILCompiler.Compiler/src/Compiler/VirtualMethodCallHelper.cs
+++ b/src/ILCompiler.Compiler/src/Compiler/VirtualMethodCallHelper.cs
@@ -18,9 +18,7 @@ namespace ILCompiler
/// </summary>
public static int GetVirtualMethodSlot(NodeFactory factory, MethodDesc method, TypeDesc implType, bool countDictionarySlots = true)
{
- // CppCodegen does not yet support sealed vtables.
-
- if (method.CanMethodBeInSealedVTable() && !factory.IsCppCodegenTemporaryWorkaround)
+ if (method.CanMethodBeInSealedVTable())
{
// If the method is a sealed newslot method, it will be put in the sealed vtable instead of the type's vtable. In this
// case, the slot index return should be the index in the sealed vtable, plus the total number of vtable slots.
@@ -71,7 +69,7 @@ namespace ILCompiler
int numSealedVTableEntries = 0;
for (int slot = 0; slot < virtualSlots.Count; slot++)
{
- if (virtualSlots[slot].CanMethodBeInSealedVTable() && !factory.IsCppCodegenTemporaryWorkaround)
+ if (virtualSlots[slot].CanMethodBeInSealedVTable())
{
numSealedVTableEntries++;
continue;
@@ -133,7 +131,7 @@ namespace ILCompiler
foreach (var vtableMethod in baseVirtualSlots)
{
// Methods in the sealed vtable should be excluded from the count
- if (vtableMethod.CanMethodBeInSealedVTable() && !factory.IsCppCodegenTemporaryWorkaround)
+ if (vtableMethod.CanMethodBeInSealedVTable())
continue;
baseSlots++;
}