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 arrayFqName = DescriptorUtils.getFqName(descriptor)
val primitiveType = KotlinBuiltIns.getPrimitiveTypeByArrayClassFqName(arrayFqName)
return PRIMITIVE_TYPE_TO_ARRAY[primitiveType] ?: ARRAY_OF_FUNCTION
return PRIMITIVE_TYPE_TO_ARRAY[KotlinBuiltIns.getPrimitiveArrayType(descriptor)] ?: ARRAY_OF_FUNCTION
}
}
}
@@ -196,25 +196,26 @@ private fun <T : Any> mapBuiltInType(
return typeFactory.createObjectType(CONTINUATION_INTERNAL_NAME)
}
val fqName = descriptor.fqNameUnsafe
val primitiveType = KotlinBuiltIns.getPrimitiveTypeByFqName(fqName)
val primitiveType = KotlinBuiltIns.getPrimitiveType(descriptor)
if (primitiveType != null) {
val jvmType = typeFactory.createFromString(JvmPrimitiveType.get(primitiveType).desc)
val isNullableInJava = TypeUtils.isNullableType(type) || type.hasEnhancedNullability()
return typeFactory.boxTypeIfNeeded(jvmType, isNullableInJava)
}
val arrayElementType = KotlinBuiltIns.getPrimitiveTypeByArrayClassFqName(fqName)
val arrayElementType = KotlinBuiltIns.getPrimitiveArrayType(descriptor)
if (arrayElementType != null) {
return typeFactory.createFromString("[" + JvmPrimitiveType.get(arrayElementType).desc)
}
val classId = JavaToKotlinClassMap.mapKotlinToJava(fqName)
if (classId != null) {
if (!mode.kotlinCollectionsToJavaCollections && JavaToKotlinClassMap.mutabilityMappings.any { it.javaClass == classId }) return null
if (KotlinBuiltIns.isUnderKotlinPackage(descriptor)) {
val classId = JavaToKotlinClassMap.mapKotlinToJava(descriptor.fqNameUnsafe)
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
@@ -50,6 +50,8 @@ import java.util.*;
import static kotlin.collections.SetsKt.setOf;
import static org.jetbrains.kotlin.builtins.PrimitiveType.*;
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 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 ClassId kProperty = ClassId.topLevel(reflect("KProperty").toSafe());
public final Map<FqNameUnsafe, PrimitiveType> fqNameToPrimitiveType;
public final Map<FqNameUnsafe, PrimitiveType> arrayClassFqNameToPrimitiveType;
public final Set<Name> primitiveTypeShortNames = newHashSetWithExpectedSize(PrimitiveType.values().length);
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()) {
primitiveTypeShortNames.add(primitiveType.getTypeName());
primitiveArrayTypeShortNames.add(primitiveType.getArrayTypeName());
fqNameToPrimitiveType.put(fqNameUnsafe(primitiveType.getTypeName().asString()), primitiveType);
arrayClassFqNameToPrimitiveType.put(fqNameUnsafe(primitiveType.getArrayTypeName().asString()), primitiveType);
}
@@ -835,17 +839,21 @@ public abstract class KotlinBuiltIns {
}
public static boolean isPrimitiveArray(@NotNull FqNameUnsafe arrayFqName) {
return getPrimitiveTypeByArrayClassFqName(arrayFqName) != null;
return FQ_NAMES.arrayClassFqNameToPrimitiveType.get(arrayFqName) != null;
}
@Nullable
public static PrimitiveType getPrimitiveTypeByFqName(@NotNull FqNameUnsafe primitiveClassFqName) {
return FQ_NAMES.fqNameToPrimitiveType.get(primitiveClassFqName);
public static PrimitiveType getPrimitiveType(@NotNull DeclarationDescriptor descriptor) {
return FQ_NAMES.primitiveTypeShortNames.contains(descriptor.getName())
? FQ_NAMES.fqNameToPrimitiveType.get(getFqName(descriptor))
: null;
}
@Nullable
public static PrimitiveType getPrimitiveTypeByArrayClassFqName(@NotNull FqNameUnsafe primitiveArrayClassFqName) {
return FQ_NAMES.arrayClassFqNameToPrimitiveType.get(primitiveArrayClassFqName);
public static PrimitiveType getPrimitiveArrayType(@NotNull DeclarationDescriptor descriptor) {
return FQ_NAMES.primitiveArrayTypeShortNames.contains(descriptor.getName())
? FQ_NAMES.arrayClassFqNameToPrimitiveType.get(getFqName(descriptor))
: null;
}
@NotNull
@@ -871,26 +879,24 @@ public abstract class KotlinBuiltIns {
}
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) {
ClassifierDescriptor descriptor = type.getConstructor().getDeclarationDescriptor();
return descriptor != null && getPrimitiveTypeByArrayClassFqName(getFqName(descriptor)) != null;
return descriptor != null && getPrimitiveArrayType(descriptor) != null;
}
@Nullable
public static PrimitiveType getPrimitiveArrayElementType(@NotNull KotlinType type) {
ClassifierDescriptor descriptor = type.getConstructor().getDeclarationDescriptor();
if (descriptor == null) return null;
return getPrimitiveTypeByArrayClassFqName(getFqName(descriptor));
return descriptor == null ? null : getPrimitiveArrayType(descriptor);
}
@Nullable
public static PrimitiveType getPrimitiveType(@NotNull KotlinType type) {
ClassifierDescriptor descriptor = type.getConstructor().getDeclarationDescriptor();
if (type.isMarkedNullable() || !(descriptor instanceof ClassDescriptor)) return null;
return getPrimitiveTypeByFqName(getFqName(descriptor));
return descriptor == null ? null : getPrimitiveType(descriptor);
}
public static boolean isPrimitiveType(@NotNull KotlinType type) {
@@ -902,15 +908,8 @@ public abstract class KotlinBuiltIns {
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) {
return getPrimitiveTypeByFqName(getFqName(descriptor)) != null;
return getPrimitiveType(descriptor) != null;
}
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.KtTypeReference;
import org.jetbrains.kotlin.resolve.DescriptorUtils;
import org.jetbrains.kotlin.resolve.descriptorUtil.DescriptorUtilsKt;
import org.jetbrains.kotlin.types.KotlinType;
import java.util.Collections;
@@ -304,7 +303,7 @@ public final class PatternTranslator extends AbstractTranslator {
DeclarationDescriptor descriptor = type.getConstructor().getDeclarationDescriptor();
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;
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.PrimitiveType
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.general.Translation
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 ktRight = checkNotNull(expression.right) { "No right-hand side: " + expression.text }
val leftType = getRefinedType(ktLeft, context)?.let { KotlinBuiltIns.getPrimitiveTypeByKotlinType(it) }
val rightType = getRefinedType(ktRight, context)?.let { KotlinBuiltIns.getPrimitiveTypeByKotlinType(it) }
val leftType = getRefinedType(ktLeft, context)?.let { KotlinBuiltIns.getPrimitiveType(it) }
val rightType = getRefinedType(ktRight, context)?.let { KotlinBuiltIns.getPrimitiveType(it) }
if (leftType != null && (leftType in SIMPLE_PRIMITIVES || leftType == rightType && leftType != PrimitiveType.LONG)) {
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 }
}
varargPrimitiveType = KotlinBuiltIns.getPrimitiveType(parameterDescriptor.original.varargElementType!!)
val varargElementType = parameterDescriptor.original.varargElementType!!
varargPrimitiveType = KotlinBuiltIns.getPrimitiveType(varargElementType).takeUnless { varargElementType.isMarkedNullable }
if (hasSpreadOperator) {
if (isNativeFunctionCall) {