diff options
author | Michal Strehovský <MichalStrehovsky@users.noreply.github.com> | 2017-05-20 04:29:45 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-05-20 04:29:45 +0300 |
commit | c723f00d3d95f3a3f6e08a30ea371758e0abb1c7 (patch) | |
tree | 7cc9658f5fb48612ea7e2fc019fe19ca624f52cc /src | |
parent | 9ea7fe4d9f137e36622ee9571888c21ef99cb145 (diff) |
Cache HasFinalizer (#3663)
With some changes I have in flight `GetFinalizer` in compiler traces
went from "might be worth looking into making this faster" to "we spend
15% of compilation time here".
The answer to `HasFinalizer` is cheap to cache and reduces the pressure
on `GetFinalizer` significantly.
Diffstat (limited to 'src')
18 files changed, 55 insertions, 23 deletions
diff --git a/src/Common/src/TypeSystem/Canon/CanonTypes.cs b/src/Common/src/TypeSystem/Canon/CanonTypes.cs index 5a0f8a53b..79963e0e0 100644 --- a/src/Common/src/TypeSystem/Canon/CanonTypes.cs +++ b/src/Common/src/TypeSystem/Canon/CanonTypes.cs @@ -123,6 +123,8 @@ namespace Internal.TypeSystem flags |= TypeFlags.HasGenericVarianceComputed; } + flags |= TypeFlags.HasFinalizerComputed; + return flags; } @@ -211,6 +213,8 @@ namespace Internal.TypeSystem flags |= TypeFlags.ValueType; } + flags |= TypeFlags.HasFinalizerComputed; + return flags; } diff --git a/src/Common/src/TypeSystem/Common/ArrayType.cs b/src/Common/src/TypeSystem/Common/ArrayType.cs index 2aeb169e7..ea3e2ea7b 100644 --- a/src/Common/src/TypeSystem/Common/ArrayType.cs +++ b/src/Common/src/TypeSystem/Common/ArrayType.cs @@ -143,6 +143,8 @@ namespace Internal.TypeSystem flags |= TypeFlags.HasGenericVarianceComputed; + flags |= TypeFlags.HasFinalizerComputed; + return flags; } diff --git a/src/Common/src/TypeSystem/Common/ByRefType.cs b/src/Common/src/TypeSystem/Common/ByRefType.cs index f786451e2..5042c2373 100644 --- a/src/Common/src/TypeSystem/Common/ByRefType.cs +++ b/src/Common/src/TypeSystem/Common/ByRefType.cs @@ -35,6 +35,8 @@ namespace Internal.TypeSystem flags |= TypeFlags.HasGenericVarianceComputed; + flags |= TypeFlags.HasFinalizerComputed; + return flags; } diff --git a/src/Common/src/TypeSystem/Common/FunctionPointerType.cs b/src/Common/src/TypeSystem/Common/FunctionPointerType.cs index 37d9520bc..b523bc2bc 100644 --- a/src/Common/src/TypeSystem/Common/FunctionPointerType.cs +++ b/src/Common/src/TypeSystem/Common/FunctionPointerType.cs @@ -65,6 +65,8 @@ namespace Internal.TypeSystem flags |= TypeFlags.HasGenericVarianceComputed; + flags |= TypeFlags.HasFinalizerComputed; + return flags; } diff --git a/src/Common/src/TypeSystem/Common/InstantiatedType.cs b/src/Common/src/TypeSystem/Common/InstantiatedType.cs index 6ada7993e..9df2c6ae1 100644 --- a/src/Common/src/TypeSystem/Common/InstantiatedType.cs +++ b/src/Common/src/TypeSystem/Common/InstantiatedType.cs @@ -96,6 +96,14 @@ namespace Internal.TypeSystem flags |= TypeFlags.HasGenericVariance; } + if ((mask & TypeFlags.HasFinalizerComputed) != 0) + { + flags |= TypeFlags.HasFinalizerComputed; + + if (_typeDef.HasFinalizer) + flags |= TypeFlags.HasFinalizer; + } + return flags; } @@ -177,14 +185,6 @@ namespace Internal.TypeSystem } } - public override bool HasFinalizer - { - get - { - return _typeDef.HasFinalizer; - } - } - public override IEnumerable<FieldDesc> GetFields() { foreach (var fieldDef in _typeDef.GetFields()) diff --git a/src/Common/src/TypeSystem/Common/MetadataType.cs b/src/Common/src/TypeSystem/Common/MetadataType.cs index 23f4218e6..9fe484c9a 100644 --- a/src/Common/src/TypeSystem/Common/MetadataType.cs +++ b/src/Common/src/TypeSystem/Common/MetadataType.cs @@ -12,14 +12,6 @@ namespace Internal.TypeSystem /// </summary> public abstract partial class MetadataType : DefType { - public override bool HasFinalizer - { - get - { - return GetFinalizer() != null; - } - } - public abstract override string Name { get; } public abstract override string Namespace { get; } diff --git a/src/Common/src/TypeSystem/Common/MethodDesc.cs b/src/Common/src/TypeSystem/Common/MethodDesc.cs index 2e7058e2a..89706ff7f 100644 --- a/src/Common/src/TypeSystem/Common/MethodDesc.cs +++ b/src/Common/src/TypeSystem/Common/MethodDesc.cs @@ -465,7 +465,9 @@ namespace Internal.TypeSystem { get { - return OwningType.GetFinalizer() == this || OwningType.IsObject && Name == "Finalize"; + TypeDesc owningType = OwningType; + return owningType.HasFinalizer && + (owningType.GetFinalizer() == this || owningType.IsObject && Name == "Finalize"); } } diff --git a/src/Common/src/TypeSystem/Common/PointerType.cs b/src/Common/src/TypeSystem/Common/PointerType.cs index 9e642df10..c7e5304bb 100644 --- a/src/Common/src/TypeSystem/Common/PointerType.cs +++ b/src/Common/src/TypeSystem/Common/PointerType.cs @@ -34,6 +34,7 @@ namespace Internal.TypeSystem TypeFlags flags = TypeFlags.Pointer; flags |= TypeFlags.HasGenericVarianceComputed; + flags |= TypeFlags.HasFinalizerComputed; return flags; } diff --git a/src/Common/src/TypeSystem/Common/TypeDesc.cs b/src/Common/src/TypeSystem/Common/TypeDesc.cs index 9c652a719..0e25eb56a 100644 --- a/src/Common/src/TypeSystem/Common/TypeDesc.cs +++ b/src/Common/src/TypeSystem/Common/TypeDesc.cs @@ -577,11 +577,11 @@ namespace Internal.TypeSystem /// Gets a value indicating whether this type has a finalizer method. /// Use <see cref="GetFinalizer"/> to retrieve the method. /// </summary> - public virtual bool HasFinalizer + public bool HasFinalizer { get { - return false; + return (GetTypeFlags(TypeFlags.HasFinalizer | TypeFlags.HasFinalizerComputed) & TypeFlags.HasFinalizer) != 0; } } diff --git a/src/Common/src/TypeSystem/Common/TypeFlags.cs b/src/Common/src/TypeSystem/Common/TypeFlags.cs index 3e7928c07..09e57c19a 100644 --- a/src/Common/src/TypeSystem/Common/TypeFlags.cs +++ b/src/Common/src/TypeSystem/Common/TypeFlags.cs @@ -53,5 +53,8 @@ namespace Internal.TypeSystem HasStaticConstructor = 0x400, HasStaticConstructorComputed = 0x800, + + HasFinalizerComputed = 0x1000, + HasFinalizer = 0x2000, } } diff --git a/src/Common/src/TypeSystem/Ecma/EcmaType.cs b/src/Common/src/TypeSystem/Ecma/EcmaType.cs index 0c3f0c414..af8cf1334 100644 --- a/src/Common/src/TypeSystem/Ecma/EcmaType.cs +++ b/src/Common/src/TypeSystem/Ecma/EcmaType.cs @@ -233,6 +233,14 @@ namespace Internal.TypeSystem.Ecma } } + if ((mask & TypeFlags.HasFinalizerComputed) != 0) + { + flags |= TypeFlags.HasFinalizerComputed; + + if (GetFinalizer() != null) + flags |= TypeFlags.HasFinalizer; + } + return flags; } diff --git a/src/Common/src/TypeSystem/Interop/IL/InlineArrayType.cs b/src/Common/src/TypeSystem/Interop/IL/InlineArrayType.cs index 8f4c3d88e..eca69969a 100644 --- a/src/Common/src/TypeSystem/Interop/IL/InlineArrayType.cs +++ b/src/Common/src/TypeSystem/Interop/IL/InlineArrayType.cs @@ -218,6 +218,8 @@ namespace Internal.TypeSystem.Interop flags |= TypeFlags.ValueType; } + flags |= TypeFlags.HasFinalizerComputed; + return flags; } diff --git a/src/Common/src/TypeSystem/Interop/IL/NativeStructType.cs b/src/Common/src/TypeSystem/Interop/IL/NativeStructType.cs index 266eddc3e..c23c43555 100644 --- a/src/Common/src/TypeSystem/Interop/IL/NativeStructType.cs +++ b/src/Common/src/TypeSystem/Interop/IL/NativeStructType.cs @@ -282,6 +282,8 @@ namespace Internal.TypeSystem.Interop flags |= TypeFlags.ValueType; } + flags |= TypeFlags.HasFinalizerComputed; + return flags; } diff --git a/src/Common/src/TypeSystem/Interop/IL/PInvokeDelegateWrapper.cs b/src/Common/src/TypeSystem/Interop/IL/PInvokeDelegateWrapper.cs index 12c39bc7a..3931f3aef 100644 --- a/src/Common/src/TypeSystem/Interop/IL/PInvokeDelegateWrapper.cs +++ b/src/Common/src/TypeSystem/Interop/IL/PInvokeDelegateWrapper.cs @@ -203,6 +203,8 @@ namespace Internal.TypeSystem.Interop flags |= TypeFlags.Class; } + flags |= TypeFlags.HasFinalizerComputed; + return flags; } diff --git a/src/Common/src/TypeSystem/NativeFormat/NativeFormatType.cs b/src/Common/src/TypeSystem/NativeFormat/NativeFormatType.cs index cfcc38964..d1d7e4650 100644 --- a/src/Common/src/TypeSystem/NativeFormat/NativeFormatType.cs +++ b/src/Common/src/TypeSystem/NativeFormat/NativeFormatType.cs @@ -279,6 +279,14 @@ namespace Internal.TypeSystem.NativeFormat } } + if ((mask & TypeFlags.HasFinalizerComputed) != 0) + { + flags |= TypeFlags.HasFinalizerComputed; + + if (GetFinalizer() != null) + flags |= TypeFlags.HasFinalizer; + } + return flags; } diff --git a/src/ILCompiler.Compiler/src/Compiler/CompilerGeneratedType.cs b/src/ILCompiler.Compiler/src/Compiler/CompilerGeneratedType.cs index 9ba499349..d00064826 100644 --- a/src/ILCompiler.Compiler/src/Compiler/CompilerGeneratedType.cs +++ b/src/ILCompiler.Compiler/src/Compiler/CompilerGeneratedType.cs @@ -76,7 +76,8 @@ namespace ILCompiler { return TypeFlags.Class | TypeFlags.HasGenericVarianceComputed | - TypeFlags.HasStaticConstructorComputed; + TypeFlags.HasStaticConstructorComputed | + TypeFlags.HasFinalizerComputed; } public override ClassLayoutMetadata GetClassLayout() diff --git a/src/ILCompiler.Compiler/src/Compiler/CompilerTypeSystemContext.BoxedTypes.cs b/src/ILCompiler.Compiler/src/Compiler/CompilerTypeSystemContext.BoxedTypes.cs index 6a7f8fc40..70f806bde 100644 --- a/src/ILCompiler.Compiler/src/Compiler/CompilerTypeSystemContext.BoxedTypes.cs +++ b/src/ILCompiler.Compiler/src/Compiler/CompilerTypeSystemContext.BoxedTypes.cs @@ -267,6 +267,8 @@ namespace ILCompiler flags |= TypeFlags.Class; } + flags |= TypeFlags.HasFinalizerComputed; + return flags; } diff --git a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/EETypeNode.cs b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/EETypeNode.cs index 40438a24e..f5a762cb5 100644 --- a/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/EETypeNode.cs +++ b/src/ILCompiler.Compiler/src/Compiler/DependencyAnalysis/EETypeNode.cs @@ -484,10 +484,9 @@ namespace ILCompiler.DependencyAnalysis private void OutputFinalizerMethod(NodeFactory factory, ref ObjectDataBuilder objData) { - MethodDesc finalizerMethod = _type.GetFinalizer(); - - if (finalizerMethod != null) + if (_type.HasFinalizer) { + MethodDesc finalizerMethod = _type.GetFinalizer(); MethodDesc canonFinalizerMethod = finalizerMethod.GetCanonMethodTarget(CanonicalFormKind.Specific); objData.EmitPointerReloc(factory.MethodEntrypoint(canonFinalizerMethod)); } |