From 9e3d381eb3cc5c586669874a459cbcb617481d7e Mon Sep 17 00:00:00 2001 From: Denis Zharkov Date: Wed, 3 Feb 2016 12:59:52 +0300 Subject: [PATCH] Perform computation of overridden descriptors lazy It's makes sense in cases when descriptors are being substituted, because in many cases their overridden are not needed. --- .../impl/FunctionDescriptorImpl.java | 42 +++++++++++++++---- 1 file changed, 34 insertions(+), 8 deletions(-) diff --git a/core/descriptors/src/org/jetbrains/kotlin/descriptors/impl/FunctionDescriptorImpl.java b/core/descriptors/src/org/jetbrains/kotlin/descriptors/impl/FunctionDescriptorImpl.java index e1477f73b39..80da600af44 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/descriptors/impl/FunctionDescriptorImpl.java +++ b/core/descriptors/src/org/jetbrains/kotlin/descriptors/impl/FunctionDescriptorImpl.java @@ -16,6 +16,7 @@ package org.jetbrains.kotlin.descriptors.impl; +import kotlin.jvm.functions.Function0; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.kotlin.descriptors.*; @@ -48,6 +49,7 @@ public abstract class FunctionDescriptorImpl extends DeclarationDescriptorNonRoo private boolean hasStableParameterNames = true; private boolean hasSynthesizedParameterNames = false; private Collection overriddenFunctions = null; + private volatile Function0> lazyOverriddenFunctionsTask = null; private final FunctionDescriptor original; private final Kind kind; @Nullable @@ -162,9 +164,22 @@ public abstract class FunctionDescriptorImpl extends DeclarationDescriptorNonRoo @NotNull @Override public Collection getOverriddenDescriptors() { + performOverriddenLazyCalculationIfNeeded(); return overriddenFunctions != null ? overriddenFunctions : Collections.emptyList(); } + private void performOverriddenLazyCalculationIfNeeded() { + Function0> overriddenTask = lazyOverriddenFunctionsTask; + if (overriddenTask != null) { + overriddenFunctions = overriddenTask.invoke(); + // Here it's important that this assignment is strictly after previous one + // `lazyOverriddenFunctionsTask` is volatile, so when someone will see that it's null, + // he can read consistent collection from `overriddenFunctions`, + // because it's assignment happens-before of "lazyOverriddenFunctionsTask = null" + lazyOverriddenFunctionsTask = null; + } + } + @NotNull @Override public Modality getModality() { @@ -443,7 +458,7 @@ public abstract class FunctionDescriptorImpl extends DeclarationDescriptorNonRoo configuration.preserveSourceElement); List substitutedTypeParameters; - TypeSubstitutor substitutor; + final TypeSubstitutor substitutor; if (configuration.newTypeParameters == null) { List originalTypeParameters = getTypeParameters(); @@ -520,16 +535,27 @@ public abstract class FunctionDescriptorImpl extends DeclarationDescriptorNonRoo substitutedDescriptor.setInitialSignatureDescriptor(initialSignatureSubstituted); } - if (configuration.copyOverrides && !getOverriddenDescriptors().isEmpty()) { + if (configuration.copyOverrides && !getOriginal().getOverriddenDescriptors().isEmpty()) { if (configuration.originalSubstitutor.isEmpty()) { - substitutedDescriptor.setOverriddenDescriptors(getOverriddenDescriptors()); + Function0> overriddenFunctionsTask = lazyOverriddenFunctionsTask; + if (overriddenFunctionsTask != null) { + substitutedDescriptor.lazyOverriddenFunctionsTask = overriddenFunctionsTask; + } + else { + substitutedDescriptor.setOverriddenDescriptors(getOverriddenDescriptors()); + } } else { - Collection substitutedOverridden = SmartSet.create(); - for (FunctionDescriptor overriddenFunction : getOverriddenDescriptors()) { - substitutedOverridden.add(overriddenFunction.substitute(substitutor)); - } - substitutedDescriptor.setOverriddenDescriptors(substitutedOverridden); + substitutedDescriptor.lazyOverriddenFunctionsTask = new Function0>() { + @Override + public Set invoke() { + SmartSet result = SmartSet.create(); + for (FunctionDescriptor overriddenFunction : getOverriddenDescriptors()) { + result.add(overriddenFunction.substitute(substitutor)); + } + return result; + } + }; } }