Reduce memory footprint after functions substitution
Do not recreate new instances if descriptors' parts remain effectively the same
This commit is contained in:
+1
@@ -56,6 +56,7 @@ public abstract class AbstractReceiverParameterDescriptor extends DeclarationDes
|
||||
}
|
||||
|
||||
if (substitutedType == null) return null;
|
||||
if (substitutedType == getType()) return this;
|
||||
|
||||
return new ReceiverParameterDescriptorImpl(getContainingDeclaration(), new TransientReceiver(substitutedType));
|
||||
}
|
||||
|
||||
+32
-5
@@ -16,6 +16,7 @@
|
||||
|
||||
package org.jetbrains.kotlin.descriptors.impl;
|
||||
|
||||
import kotlin.collections.CollectionsKt;
|
||||
import kotlin.jvm.functions.Function0;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
@@ -334,7 +335,7 @@ public abstract class FunctionDescriptorImpl extends DeclarationDescriptorNonRoo
|
||||
if (originalSubstitutor.isEmpty()) {
|
||||
return this;
|
||||
}
|
||||
return newCopyBuilder(originalSubstitutor).setOriginal(getOriginal()).build();
|
||||
return newCopyBuilder(originalSubstitutor).setOriginal(getOriginal()).setJustForTypeSubstitution(true).build();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@@ -370,6 +371,7 @@ public abstract class FunctionDescriptorImpl extends DeclarationDescriptorNonRoo
|
||||
private boolean isHiddenForResolutionEverywhereBesideSupercalls = isHiddenForResolutionEverywhereBesideSupercalls();
|
||||
private Map<UserDataKey<?>, Object> userDataMap = new LinkedHashMap<UserDataKey<?>, Object>();
|
||||
private Boolean newHasSynthesizedParameterNames = null;
|
||||
protected boolean justForTypeSubstitution = false;
|
||||
|
||||
public CopyConfiguration(
|
||||
@NotNull TypeSubstitution substitution,
|
||||
@@ -553,6 +555,12 @@ public abstract class FunctionDescriptorImpl extends DeclarationDescriptorNonRoo
|
||||
public TypeSubstitution getSubstitution() {
|
||||
return substitution;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public CopyConfiguration setJustForTypeSubstitution(boolean value) {
|
||||
justForTypeSubstitution = value;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -571,6 +579,7 @@ public abstract class FunctionDescriptorImpl extends DeclarationDescriptorNonRoo
|
||||
|
||||
@Nullable
|
||||
protected FunctionDescriptor doSubstitute(@NotNull CopyConfiguration configuration) {
|
||||
boolean[] wereChanges = new boolean[1];
|
||||
Annotations resultAnnotations =
|
||||
configuration.additionalAnnotations != null
|
||||
? AnnotationsKt.composeAnnotations(getAnnotations(), configuration.additionalAnnotations)
|
||||
@@ -583,10 +592,12 @@ public abstract class FunctionDescriptorImpl extends DeclarationDescriptorNonRoo
|
||||
List<TypeParameterDescriptor> unsubstitutedTypeParameters =
|
||||
configuration.newTypeParameters == null ? getTypeParameters() : configuration.newTypeParameters;
|
||||
|
||||
wereChanges[0] |= !unsubstitutedTypeParameters.isEmpty();
|
||||
|
||||
List<TypeParameterDescriptor> substitutedTypeParameters =
|
||||
new ArrayList<TypeParameterDescriptor>(unsubstitutedTypeParameters.size());
|
||||
final TypeSubstitutor substitutor = DescriptorSubstitutor.substituteTypeParameters(
|
||||
unsubstitutedTypeParameters, configuration.substitution, substitutedDescriptor, substitutedTypeParameters
|
||||
unsubstitutedTypeParameters, configuration.substitution, substitutedDescriptor, substitutedTypeParameters, wereChanges
|
||||
);
|
||||
|
||||
KotlinType substitutedReceiverParameterType = null;
|
||||
@@ -595,6 +606,8 @@ public abstract class FunctionDescriptorImpl extends DeclarationDescriptorNonRoo
|
||||
if (substitutedReceiverParameterType == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
wereChanges[0] |= substitutedReceiverParameterType != configuration.newExtensionReceiverParameterType;
|
||||
}
|
||||
|
||||
ReceiverParameterDescriptor substitutedExpectedThis = null;
|
||||
@@ -613,11 +626,13 @@ public abstract class FunctionDescriptorImpl extends DeclarationDescriptorNonRoo
|
||||
if (substitutedExpectedThis == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
wereChanges[0] |= substitutedExpectedThis != configuration.dispatchReceiverParameter;
|
||||
}
|
||||
|
||||
List<ValueParameterDescriptor> substitutedValueParameters = getSubstitutedValueParameters(
|
||||
substitutedDescriptor, configuration.newValueParameterDescriptors, substitutor, configuration.dropOriginalInContainingParts,
|
||||
configuration.preserveSourceElement
|
||||
configuration.preserveSourceElement, wereChanges
|
||||
);
|
||||
if (substitutedValueParameters == null) {
|
||||
return null;
|
||||
@@ -628,6 +643,12 @@ public abstract class FunctionDescriptorImpl extends DeclarationDescriptorNonRoo
|
||||
return null;
|
||||
}
|
||||
|
||||
wereChanges[0] |= substitutedReturnType != configuration.newReturnType;
|
||||
|
||||
if (!wereChanges[0] && configuration.justForTypeSubstitution) {
|
||||
return this;
|
||||
}
|
||||
|
||||
substitutedDescriptor.initialize(
|
||||
substitutedReceiverParameterType,
|
||||
substitutedExpectedThis,
|
||||
@@ -682,7 +703,7 @@ public abstract class FunctionDescriptorImpl extends DeclarationDescriptorNonRoo
|
||||
|
||||
if (configuration.copyOverrides && !getOriginal().getOverriddenDescriptors().isEmpty()) {
|
||||
if (configuration.substitution.isEmpty()) {
|
||||
Function0<Set<FunctionDescriptor>> overriddenFunctionsTask = lazyOverriddenFunctionsTask;
|
||||
Function0<Collection<FunctionDescriptor>> overriddenFunctionsTask = lazyOverriddenFunctionsTask;
|
||||
if (overriddenFunctionsTask != null) {
|
||||
substitutedDescriptor.lazyOverriddenFunctionsTask = overriddenFunctionsTask;
|
||||
}
|
||||
@@ -753,7 +774,8 @@ public abstract class FunctionDescriptorImpl extends DeclarationDescriptorNonRoo
|
||||
@NotNull List<ValueParameterDescriptor> unsubstitutedValueParameters,
|
||||
@NotNull TypeSubstitutor substitutor,
|
||||
boolean dropOriginal,
|
||||
boolean preserveSourceElement
|
||||
boolean preserveSourceElement,
|
||||
@Nullable boolean[] wereChanges
|
||||
) {
|
||||
List<ValueParameterDescriptor> result = new ArrayList<ValueParameterDescriptor>(unsubstitutedValueParameters.size());
|
||||
for (ValueParameterDescriptor unsubstitutedValueParameter : unsubstitutedValueParameters) {
|
||||
@@ -763,6 +785,11 @@ public abstract class FunctionDescriptorImpl extends DeclarationDescriptorNonRoo
|
||||
KotlinType substituteVarargElementType =
|
||||
varargElementType == null ? null : substitutor.substitute(varargElementType, Variance.IN_VARIANCE);
|
||||
if (substitutedType == null) return null;
|
||||
if (substitutedType != unsubstitutedValueParameter.getType() || varargElementType != substituteVarargElementType) {
|
||||
if (wereChanges != null) {
|
||||
wereChanges[0] = true;
|
||||
}
|
||||
}
|
||||
result.add(
|
||||
new ValueParameterDescriptorImpl(
|
||||
substitutedDescriptor,
|
||||
|
||||
+1
-1
@@ -385,7 +385,7 @@ public class PropertyDescriptorImpl extends VariableDescriptorWithInitializerImp
|
||||
if (newSetter != null) {
|
||||
List<ValueParameterDescriptor> substitutedValueParameters = FunctionDescriptorImpl.getSubstitutedValueParameters(
|
||||
newSetter, setter.getValueParameters(), substitutor, /* dropOriginal = */ false,
|
||||
false
|
||||
false, null
|
||||
);
|
||||
if (substitutedValueParameters == null) {
|
||||
// The setter is projected out, e.g. in this case:
|
||||
|
||||
+2
-1
@@ -179,7 +179,8 @@ class TypeAliasConstructorDescriptorImpl private constructor(
|
||||
|
||||
val valueParameters =
|
||||
FunctionDescriptorImpl.getSubstitutedValueParameters(
|
||||
typeAliasConstructor, constructor.valueParameters, substitutorForUnderlyingClass, false, false
|
||||
typeAliasConstructor, constructor.valueParameters, substitutorForUnderlyingClass, false, false,
|
||||
null
|
||||
) ?: return null
|
||||
|
||||
val returnType = run {
|
||||
|
||||
@@ -18,6 +18,7 @@ package org.jetbrains.kotlin.types;
|
||||
|
||||
import org.jetbrains.annotations.Mutable;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.annotations.ReadOnly;
|
||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor;
|
||||
import org.jetbrains.kotlin.descriptors.SourceElement;
|
||||
@@ -38,6 +39,17 @@ public class DescriptorSubstitutor {
|
||||
@NotNull TypeSubstitution originalSubstitution,
|
||||
@NotNull DeclarationDescriptor newContainingDeclaration,
|
||||
@NotNull @Mutable List<TypeParameterDescriptor> result
|
||||
) {
|
||||
return substituteTypeParameters(typeParameters, originalSubstitution, newContainingDeclaration, result, null);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static TypeSubstitutor substituteTypeParameters(
|
||||
@ReadOnly @NotNull List<TypeParameterDescriptor> typeParameters,
|
||||
@NotNull TypeSubstitution originalSubstitution,
|
||||
@NotNull DeclarationDescriptor newContainingDeclaration,
|
||||
@NotNull @Mutable List<TypeParameterDescriptor> result,
|
||||
@Nullable boolean[] wereChanges
|
||||
) {
|
||||
Map<TypeConstructor, TypeProjection> mutableSubstitution = new HashMap<TypeConstructor, TypeProjection>();
|
||||
|
||||
@@ -69,6 +81,11 @@ public class DescriptorSubstitutor {
|
||||
for (KotlinType upperBound : descriptor.getUpperBounds()) {
|
||||
KotlinType substitutedBound = substitutor.substitute(upperBound, Variance.IN_VARIANCE);
|
||||
assert substitutedBound != null : "Upper bound failed to substitute: " + descriptor;
|
||||
|
||||
if (substitutedBound != upperBound && wereChanges != null) {
|
||||
wereChanges[0] = true;
|
||||
}
|
||||
|
||||
substituted.addUpperBound(substitutedBound);
|
||||
}
|
||||
substituted.setInitialized();
|
||||
|
||||
Reference in New Issue
Block a user