Skip property accessors for constants

- Inline protected constants from Java at use sites
 - Do not create accessors for private constants in Kotlin

 #KT-11734 In Progress
This commit is contained in:
Mikhail Zarechenskiy
2016-12-05 12:02:43 +03:00
parent bd14c24592
commit 8c1e165f18
12 changed files with 151 additions and 14 deletions
@@ -1,5 +1,5 @@
/*
* Copyright 2010-2015 JetBrains s.r.o.
* Copyright 2010-2016 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -50,6 +50,10 @@ import org.jetbrains.kotlin.codegen.state.GenerationState;
import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper;
import org.jetbrains.kotlin.codegen.when.SwitchCodegen;
import org.jetbrains.kotlin.codegen.when.SwitchCodegenUtil;
import org.jetbrains.kotlin.config.CommonConfigurationKeys;
import org.jetbrains.kotlin.config.LanguageFeature;
import org.jetbrains.kotlin.config.LanguageVersionSettings;
import org.jetbrains.kotlin.config.LanguageVersionSettingsImpl;
import org.jetbrains.kotlin.coroutines.CoroutineUtilKt;
import org.jetbrains.kotlin.descriptors.*;
import org.jetbrains.kotlin.descriptors.impl.LocalVariableDescriptor;
@@ -2603,9 +2607,16 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
boolean skipPropertyAccessors;
PropertyDescriptor originalPropertyDescriptor = DescriptorUtils.unwrapFakeOverride(propertyDescriptor);
LanguageVersionSettings languageVersionSettings = state.getConfiguration().get(CommonConfigurationKeys.LANGUAGE_VERSION_SETTINGS);
if (languageVersionSettings == null) {
languageVersionSettings = LanguageVersionSettingsImpl.DEFAULT;
}
if (fieldAccessorKind != FieldAccessorKind.NORMAL) {
int flags = AsmUtil.getVisibilityForBackingField(propertyDescriptor, isDelegatedProperty);
skipPropertyAccessors = (flags & ACC_PRIVATE) == 0 || skipAccessorsForPrivateFieldInOuterClass;
boolean isInlinedConst = propertyDescriptor.isConst() && languageVersionSettings.supportsFeature(LanguageFeature.InlineConstVals);
skipPropertyAccessors = isInlinedConst || (flags & ACC_PRIVATE) == 0 || skipAccessorsForPrivateFieldInOuterClass;
if (!skipPropertyAccessors) {
//noinspection ConstantConditions
propertyDescriptor = (PropertyDescriptor) backingFieldContext.getAccessor(
@@ -2624,7 +2635,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
}
if (!skipPropertyAccessors) {
if (!couldUseDirectAccessToProperty(propertyDescriptor, true, isDelegatedProperty, context)) {
if (!couldUseDirectAccessToProperty(propertyDescriptor, true, isDelegatedProperty, context, languageVersionSettings)) {
propertyDescriptor = context.getAccessorForSuperCallIfNeeded(propertyDescriptor, superCallTarget);
propertyDescriptor = context.accessibleDescriptor(propertyDescriptor, superCallTarget);
@@ -2638,7 +2649,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
if (propertyDescriptor.isVar()) {
PropertySetterDescriptor setter = propertyDescriptor.getSetter();
if (setter != null &&
!couldUseDirectAccessToProperty(propertyDescriptor, false, isDelegatedProperty, context) &&
!couldUseDirectAccessToProperty(propertyDescriptor, false, isDelegatedProperty, context, languageVersionSettings) &&
!isConstOrHasJvmFieldAnnotation(propertyDescriptor)) {
callableSetter = typeMapper.mapToCallableMethod(setter, isSuper);
}
@@ -37,6 +37,9 @@ import org.jetbrains.kotlin.codegen.signature.BothSignatureWriter;
import org.jetbrains.kotlin.codegen.signature.JvmSignatureWriter;
import org.jetbrains.kotlin.codegen.state.GenerationState;
import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper;
import org.jetbrains.kotlin.config.CommonConfigurationKeys;
import org.jetbrains.kotlin.config.LanguageVersionSettings;
import org.jetbrains.kotlin.config.LanguageVersionSettingsImpl;
import org.jetbrains.kotlin.descriptors.*;
import org.jetbrains.kotlin.incremental.components.NoLookupLocation;
import org.jetbrains.kotlin.lexer.KtTokens;
@@ -646,7 +649,12 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
private Type genPropertyOnStack(InstructionAdapter iv, MethodContext context, @NotNull PropertyDescriptor propertyDescriptor, int index) {
iv.load(index, classAsmType);
if (couldUseDirectAccessToProperty(propertyDescriptor, /* forGetter = */ true, /* isDelegated = */ false, context)) {
LanguageVersionSettings settings = state.getConfiguration().get(CommonConfigurationKeys.LANGUAGE_VERSION_SETTINGS);
if (settings == null) {
settings = LanguageVersionSettingsImpl.DEFAULT;
}
if (couldUseDirectAccessToProperty(propertyDescriptor, /* forGetter = */ true,
/* isDelegated = */ false, context, settings)) {
Type type = typeMapper.mapType(propertyDescriptor.getType());
String fieldName = ((FieldOwnerContext) context.getParentContext()).getFieldName(propertyDescriptor, false);
iv.getfield(classAsmType.getInternalName(), fieldName, type.getDescriptor());
@@ -1,5 +1,5 @@
/*
* Copyright 2010-2015 JetBrains s.r.o.
* Copyright 2010-2016 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -30,6 +30,8 @@ import org.jetbrains.kotlin.codegen.context.MethodContext;
import org.jetbrains.kotlin.codegen.context.RootContext;
import org.jetbrains.kotlin.codegen.state.GenerationState;
import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper;
import org.jetbrains.kotlin.config.LanguageFeature;
import org.jetbrains.kotlin.config.LanguageVersionSettings;
import org.jetbrains.kotlin.descriptors.*;
import org.jetbrains.kotlin.descriptors.impl.LocalVariableDescriptor;
import org.jetbrains.kotlin.load.java.descriptors.JavaPropertyDescriptor;
@@ -182,8 +184,11 @@ public class JvmCodegenUtil {
@NotNull PropertyDescriptor property,
boolean forGetter,
boolean isDelegated,
@NotNull MethodContext contextBeforeInline
@NotNull MethodContext contextBeforeInline,
@NotNull LanguageVersionSettings languageVersionSettings
) {
if (languageVersionSettings.supportsFeature(LanguageFeature.InlineConstVals) && property.isConst()) return true;
if (KotlinTypeMapper.isAccessor(property)) return false;
CodegenContext context = contextBeforeInline.getFirstCrossInlineOrNonInlineContext();