Optimize away unneeded FqName computation in KotlinBuiltIns

Before computing the FqName, check the simple class name first. This
code was responsible for about 20% of FqNameUnsafe instances created
during compilation of "core" modules
This commit is contained in:
Alexander Udalov
2017-06-21 15:33:12 +03:00
parent 0352bdbca5
commit 59b932a815
6 changed files with 42 additions and 42 deletions
@@ -119,9 +119,6 @@ object CollectionLiteralResolver {
val descriptor = expectedType.constructor.declarationDescriptor ?: return ARRAY_OF_FUNCTION val descriptor = expectedType.constructor.declarationDescriptor ?: return ARRAY_OF_FUNCTION
val arrayFqName = DescriptorUtils.getFqName(descriptor) return PRIMITIVE_TYPE_TO_ARRAY[KotlinBuiltIns.getPrimitiveArrayType(descriptor)] ?: ARRAY_OF_FUNCTION
val primitiveType = KotlinBuiltIns.getPrimitiveTypeByArrayClassFqName(arrayFqName)
return PRIMITIVE_TYPE_TO_ARRAY[primitiveType] ?: ARRAY_OF_FUNCTION
} }
} }
@@ -196,25 +196,26 @@ private fun <T : Any> mapBuiltInType(
return typeFactory.createObjectType(CONTINUATION_INTERNAL_NAME) return typeFactory.createObjectType(CONTINUATION_INTERNAL_NAME)
} }
val fqName = descriptor.fqNameUnsafe val primitiveType = KotlinBuiltIns.getPrimitiveType(descriptor)
val primitiveType = KotlinBuiltIns.getPrimitiveTypeByFqName(fqName)
if (primitiveType != null) { if (primitiveType != null) {
val jvmType = typeFactory.createFromString(JvmPrimitiveType.get(primitiveType).desc) val jvmType = typeFactory.createFromString(JvmPrimitiveType.get(primitiveType).desc)
val isNullableInJava = TypeUtils.isNullableType(type) || type.hasEnhancedNullability() val isNullableInJava = TypeUtils.isNullableType(type) || type.hasEnhancedNullability()
return typeFactory.boxTypeIfNeeded(jvmType, isNullableInJava) return typeFactory.boxTypeIfNeeded(jvmType, isNullableInJava)
} }
val arrayElementType = KotlinBuiltIns.getPrimitiveTypeByArrayClassFqName(fqName) val arrayElementType = KotlinBuiltIns.getPrimitiveArrayType(descriptor)
if (arrayElementType != null) { if (arrayElementType != null) {
return typeFactory.createFromString("[" + JvmPrimitiveType.get(arrayElementType).desc) return typeFactory.createFromString("[" + JvmPrimitiveType.get(arrayElementType).desc)
} }
val classId = JavaToKotlinClassMap.mapKotlinToJava(fqName) if (KotlinBuiltIns.isUnderKotlinPackage(descriptor)) {
if (classId != null) { val classId = JavaToKotlinClassMap.mapKotlinToJava(descriptor.fqNameUnsafe)
if (!mode.kotlinCollectionsToJavaCollections && JavaToKotlinClassMap.mutabilityMappings.any { it.javaClass == classId }) return null if (classId != null) {
if (!mode.kotlinCollectionsToJavaCollections &&
JavaToKotlinClassMap.mutabilityMappings.any { it.javaClass == classId }) return null
return typeFactory.createObjectType(JvmClassName.byClassId(classId, typeMappingConfiguration).internalName) return typeFactory.createObjectType(JvmClassName.byClassId(classId, typeMappingConfiguration).internalName)
}
} }
return null return null
@@ -50,6 +50,8 @@ import java.util.*;
import static kotlin.collections.SetsKt.setOf; import static kotlin.collections.SetsKt.setOf;
import static org.jetbrains.kotlin.builtins.PrimitiveType.*; import static org.jetbrains.kotlin.builtins.PrimitiveType.*;
import static org.jetbrains.kotlin.resolve.DescriptorUtils.getFqName; import static org.jetbrains.kotlin.resolve.DescriptorUtils.getFqName;
import static org.jetbrains.kotlin.utils.CollectionsKt.newHashMapWithExpectedSize;
import static org.jetbrains.kotlin.utils.CollectionsKt.newHashSetWithExpectedSize;
public abstract class KotlinBuiltIns { public abstract class KotlinBuiltIns {
public static final Name BUILT_INS_PACKAGE_NAME = Name.identifier("kotlin"); public static final Name BUILT_INS_PACKAGE_NAME = Name.identifier("kotlin");
@@ -320,12 +322,14 @@ public abstract class KotlinBuiltIns {
public final FqNameUnsafe kMutableProperty2 = reflect("KMutableProperty2"); public final FqNameUnsafe kMutableProperty2 = reflect("KMutableProperty2");
public final ClassId kProperty = ClassId.topLevel(reflect("KProperty").toSafe()); public final ClassId kProperty = ClassId.topLevel(reflect("KProperty").toSafe());
public final Map<FqNameUnsafe, PrimitiveType> fqNameToPrimitiveType; public final Set<Name> primitiveTypeShortNames = newHashSetWithExpectedSize(PrimitiveType.values().length);
public final Map<FqNameUnsafe, PrimitiveType> arrayClassFqNameToPrimitiveType; public final Set<Name> primitiveArrayTypeShortNames = newHashSetWithExpectedSize(PrimitiveType.values().length);
public final Map<FqNameUnsafe, PrimitiveType> fqNameToPrimitiveType = newHashMapWithExpectedSize(PrimitiveType.values().length);
public final Map<FqNameUnsafe, PrimitiveType> arrayClassFqNameToPrimitiveType = newHashMapWithExpectedSize(PrimitiveType.values().length);
{ {
fqNameToPrimitiveType = new HashMap<FqNameUnsafe, PrimitiveType>(0);
arrayClassFqNameToPrimitiveType = new HashMap<FqNameUnsafe, PrimitiveType>(0);
for (PrimitiveType primitiveType : PrimitiveType.values()) { for (PrimitiveType primitiveType : PrimitiveType.values()) {
primitiveTypeShortNames.add(primitiveType.getTypeName());
primitiveArrayTypeShortNames.add(primitiveType.getArrayTypeName());
fqNameToPrimitiveType.put(fqNameUnsafe(primitiveType.getTypeName().asString()), primitiveType); fqNameToPrimitiveType.put(fqNameUnsafe(primitiveType.getTypeName().asString()), primitiveType);
arrayClassFqNameToPrimitiveType.put(fqNameUnsafe(primitiveType.getArrayTypeName().asString()), primitiveType); arrayClassFqNameToPrimitiveType.put(fqNameUnsafe(primitiveType.getArrayTypeName().asString()), primitiveType);
} }
@@ -835,17 +839,21 @@ public abstract class KotlinBuiltIns {
} }
public static boolean isPrimitiveArray(@NotNull FqNameUnsafe arrayFqName) { public static boolean isPrimitiveArray(@NotNull FqNameUnsafe arrayFqName) {
return getPrimitiveTypeByArrayClassFqName(arrayFqName) != null; return FQ_NAMES.arrayClassFqNameToPrimitiveType.get(arrayFqName) != null;
} }
@Nullable @Nullable
public static PrimitiveType getPrimitiveTypeByFqName(@NotNull FqNameUnsafe primitiveClassFqName) { public static PrimitiveType getPrimitiveType(@NotNull DeclarationDescriptor descriptor) {
return FQ_NAMES.fqNameToPrimitiveType.get(primitiveClassFqName); return FQ_NAMES.primitiveTypeShortNames.contains(descriptor.getName())
? FQ_NAMES.fqNameToPrimitiveType.get(getFqName(descriptor))
: null;
} }
@Nullable @Nullable
public static PrimitiveType getPrimitiveTypeByArrayClassFqName(@NotNull FqNameUnsafe primitiveArrayClassFqName) { public static PrimitiveType getPrimitiveArrayType(@NotNull DeclarationDescriptor descriptor) {
return FQ_NAMES.arrayClassFqNameToPrimitiveType.get(primitiveArrayClassFqName); return FQ_NAMES.primitiveArrayTypeShortNames.contains(descriptor.getName())
? FQ_NAMES.arrayClassFqNameToPrimitiveType.get(getFqName(descriptor))
: null;
} }
@NotNull @NotNull
@@ -871,26 +879,24 @@ public abstract class KotlinBuiltIns {
} }
public static boolean isArrayOrPrimitiveArray(@NotNull ClassDescriptor descriptor) { public static boolean isArrayOrPrimitiveArray(@NotNull ClassDescriptor descriptor) {
return classFqNameEquals(descriptor, FQ_NAMES.array) || getPrimitiveTypeByArrayClassFqName(getFqName(descriptor)) != null; return classFqNameEquals(descriptor, FQ_NAMES.array) || getPrimitiveArrayType(descriptor) != null;
} }
public static boolean isPrimitiveArray(@NotNull KotlinType type) { public static boolean isPrimitiveArray(@NotNull KotlinType type) {
ClassifierDescriptor descriptor = type.getConstructor().getDeclarationDescriptor(); ClassifierDescriptor descriptor = type.getConstructor().getDeclarationDescriptor();
return descriptor != null && getPrimitiveTypeByArrayClassFqName(getFqName(descriptor)) != null; return descriptor != null && getPrimitiveArrayType(descriptor) != null;
} }
@Nullable @Nullable
public static PrimitiveType getPrimitiveArrayElementType(@NotNull KotlinType type) { public static PrimitiveType getPrimitiveArrayElementType(@NotNull KotlinType type) {
ClassifierDescriptor descriptor = type.getConstructor().getDeclarationDescriptor(); ClassifierDescriptor descriptor = type.getConstructor().getDeclarationDescriptor();
if (descriptor == null) return null; return descriptor == null ? null : getPrimitiveArrayType(descriptor);
return getPrimitiveTypeByArrayClassFqName(getFqName(descriptor));
} }
@Nullable @Nullable
public static PrimitiveType getPrimitiveType(@NotNull KotlinType type) { public static PrimitiveType getPrimitiveType(@NotNull KotlinType type) {
ClassifierDescriptor descriptor = type.getConstructor().getDeclarationDescriptor(); ClassifierDescriptor descriptor = type.getConstructor().getDeclarationDescriptor();
if (type.isMarkedNullable() || !(descriptor instanceof ClassDescriptor)) return null; return descriptor == null ? null : getPrimitiveType(descriptor);
return getPrimitiveTypeByFqName(getFqName(descriptor));
} }
public static boolean isPrimitiveType(@NotNull KotlinType type) { public static boolean isPrimitiveType(@NotNull KotlinType type) {
@@ -902,15 +908,8 @@ public abstract class KotlinBuiltIns {
return descriptor instanceof ClassDescriptor && isPrimitiveClass((ClassDescriptor) descriptor); return descriptor instanceof ClassDescriptor && isPrimitiveClass((ClassDescriptor) descriptor);
} }
@Nullable
public static PrimitiveType getPrimitiveTypeByKotlinType(@NotNull KotlinType type) {
ClassifierDescriptor descriptor = type.getConstructor().getDeclarationDescriptor();
if (descriptor == null) return null;
return getPrimitiveTypeByFqName(getFqName(descriptor));
}
public static boolean isPrimitiveClass(@NotNull ClassDescriptor descriptor) { public static boolean isPrimitiveClass(@NotNull ClassDescriptor descriptor) {
return getPrimitiveTypeByFqName(getFqName(descriptor)) != null; return getPrimitiveType(descriptor) != null;
} }
public static boolean isConstructedFromGivenClass(@NotNull KotlinType type, @NotNull FqNameUnsafe fqName) { public static boolean isConstructedFromGivenClass(@NotNull KotlinType type, @NotNull FqNameUnsafe fqName) {
@@ -44,7 +44,6 @@ import org.jetbrains.kotlin.psi.KtExpression;
import org.jetbrains.kotlin.psi.KtIsExpression; import org.jetbrains.kotlin.psi.KtIsExpression;
import org.jetbrains.kotlin.psi.KtTypeReference; import org.jetbrains.kotlin.psi.KtTypeReference;
import org.jetbrains.kotlin.resolve.DescriptorUtils; import org.jetbrains.kotlin.resolve.DescriptorUtils;
import org.jetbrains.kotlin.resolve.descriptorUtil.DescriptorUtilsKt;
import org.jetbrains.kotlin.types.KotlinType; import org.jetbrains.kotlin.types.KotlinType;
import java.util.Collections; import java.util.Collections;
@@ -304,7 +303,7 @@ public final class PatternTranslator extends AbstractTranslator {
DeclarationDescriptor descriptor = type.getConstructor().getDeclarationDescriptor(); DeclarationDescriptor descriptor = type.getConstructor().getDeclarationDescriptor();
if (!(descriptor instanceof ClassDescriptor)) return EqualityType.GENERAL; if (!(descriptor instanceof ClassDescriptor)) return EqualityType.GENERAL;
PrimitiveType primitive = KotlinBuiltIns.getPrimitiveTypeByFqName(DescriptorUtilsKt.getFqNameUnsafe(descriptor)); PrimitiveType primitive = KotlinBuiltIns.getPrimitiveType(descriptor);
if (primitive == null) return EqualityType.GENERAL; if (primitive == null) return EqualityType.GENERAL;
return primitive == PrimitiveType.LONG ? EqualityType.LONG : EqualityType.PRIMITIVE; return primitive == PrimitiveType.LONG ? EqualityType.LONG : EqualityType.PRIMITIVE;
@@ -19,7 +19,10 @@ package org.jetbrains.kotlin.js.translate.intrinsic.operation
import org.jetbrains.kotlin.builtins.KotlinBuiltIns import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.builtins.PrimitiveType import org.jetbrains.kotlin.builtins.PrimitiveType
import org.jetbrains.kotlin.descriptors.FunctionDescriptor import org.jetbrains.kotlin.descriptors.FunctionDescriptor
import org.jetbrains.kotlin.js.backend.ast.* import org.jetbrains.kotlin.js.backend.ast.JsBinaryOperation
import org.jetbrains.kotlin.js.backend.ast.JsBinaryOperator
import org.jetbrains.kotlin.js.backend.ast.JsExpression
import org.jetbrains.kotlin.js.backend.ast.JsNullLiteral
import org.jetbrains.kotlin.js.translate.context.TranslationContext import org.jetbrains.kotlin.js.translate.context.TranslationContext
import org.jetbrains.kotlin.js.translate.general.Translation import org.jetbrains.kotlin.js.translate.general.Translation
import org.jetbrains.kotlin.js.translate.intrinsic.functions.factories.TopLevelFIF import org.jetbrains.kotlin.js.translate.intrinsic.functions.factories.TopLevelFIF
@@ -54,8 +57,8 @@ object EqualsBOIF : BinaryOperationIntrinsicFactory {
val ktLeft = checkNotNull(expression.left) { "No left-hand side: " + expression.text } val ktLeft = checkNotNull(expression.left) { "No left-hand side: " + expression.text }
val ktRight = checkNotNull(expression.right) { "No right-hand side: " + expression.text } val ktRight = checkNotNull(expression.right) { "No right-hand side: " + expression.text }
val leftType = getRefinedType(ktLeft, context)?.let { KotlinBuiltIns.getPrimitiveTypeByKotlinType(it) } val leftType = getRefinedType(ktLeft, context)?.let { KotlinBuiltIns.getPrimitiveType(it) }
val rightType = getRefinedType(ktRight, context)?.let { KotlinBuiltIns.getPrimitiveTypeByKotlinType(it) } val rightType = getRefinedType(ktRight, context)?.let { KotlinBuiltIns.getPrimitiveType(it) }
if (leftType != null && (leftType in SIMPLE_PRIMITIVES || leftType == rightType && leftType != PrimitiveType.LONG)) { if (leftType != null && (leftType in SIMPLE_PRIMITIVES || leftType == rightType && leftType != PrimitiveType.LONG)) {
return JsBinaryOperation(if (isNegated) JsBinaryOperator.REF_NEQ else JsBinaryOperator.REF_EQ, return JsBinaryOperation(if (isNegated) JsBinaryOperator.REF_NEQ else JsBinaryOperator.REF_EQ,
@@ -100,7 +100,8 @@ class CallArgumentTranslator private constructor(
hasSpreadOperator = arguments.any { it.getSpreadElement() != null } hasSpreadOperator = arguments.any { it.getSpreadElement() != null }
} }
varargPrimitiveType = KotlinBuiltIns.getPrimitiveType(parameterDescriptor.original.varargElementType!!) val varargElementType = parameterDescriptor.original.varargElementType!!
varargPrimitiveType = KotlinBuiltIns.getPrimitiveType(varargElementType).takeUnless { varargElementType.isMarkedNullable }
if (hasSpreadOperator) { if (hasSpreadOperator) {
if (isNativeFunctionCall) { if (isNativeFunctionCall) {