Optimize runtime representation for callable reference subclasses

Instead of generating overrides for getOwner/getName/getSignature in
each anonymous class representing a callable reference, pass them to the
superclass' constructor and store as fields. This occupies some small
memory but helps to reduce the size of the generated class files, and
will be helpful for adding further runtime information to callable
references, such as information about implicit conversions this
reference has been subject to.

Represent owner as java.lang.Class + boolean instead of
KDeclarationContainer, so that the unnecessary wrapping Class->KClass
wouldn't happen before it's needed, and also to make sure all callable
references remain serializable.

Note that the argument type where the "is declaration container a class"
is passed is int instead of boolean. The plan is to pass the
aforementioned implicit conversion information as bits of this same
integer value.

 #KT-27362 Fixed
This commit is contained in:
Alexander Udalov
2020-02-14 20:28:43 +01:00
parent 8d7c8672ac
commit 98aecbef6b
38 changed files with 502 additions and 262 deletions
@@ -32,6 +32,18 @@ public abstract class CallableReference implements KCallable, Serializable {
@SinceKotlin(version = "1.1")
protected final Object receiver;
@SinceKotlin(version = "1.4")
private final Class owner;
@SinceKotlin(version = "1.4")
private final String name;
@SinceKotlin(version = "1.4")
private final String signature;
@SinceKotlin(version = "1.4")
private final boolean isTopLevel;
@SinceKotlin(version = "1.1")
public static final Object NO_RECEIVER = NoReceiver.INSTANCE;
@@ -50,7 +62,20 @@ public abstract class CallableReference implements KCallable, Serializable {
@SinceKotlin(version = "1.1")
protected CallableReference(Object receiver) {
this(receiver, null, null, null, 0);
}
/**
* @param flags Bitmask where bits represent the following flags:<br/>
* <li><ul>0 - the owner of this reference is a package, not a class.</ul></li>
*/
@SinceKotlin(version = "1.4")
protected CallableReference(Object receiver, Class owner, String name, String signature, int flags) {
this.receiver = receiver;
this.owner = owner;
this.name = name;
this.signature = signature;
this.isTopLevel = (flags & 1) == 1;
}
protected abstract KCallable computeReflected();
@@ -79,14 +104,16 @@ public abstract class CallableReference implements KCallable, Serializable {
return result;
}
// The following methods provide the information identifying this callable, which is used by the reflection implementation.
// They are supposed to be overridden in each subclass (each anonymous class generated for a callable reference).
// The following methods provide the information identifying this callable, which is used by the reflection implementation and
// by equals/hashCode/toString. For callable references compiled prior to 1.4, these methods were overridden in each subclass
// (each anonymous class generated for a callable reference).
/**
* @return the class or package where the callable should be located, usually specified on the LHS of the '::' operator
*/
public KDeclarationContainer getOwner() {
throw new AbstractMethodError();
return owner == null ? null :
isTopLevel ? Reflection.getOrCreateKotlinPackage(owner) : Reflection.getOrCreateKotlinClass(owner);
}
/**
@@ -94,7 +121,7 @@ public abstract class CallableReference implements KCallable, Serializable {
*/
@Override
public String getName() {
throw new AbstractMethodError();
return name;
}
/**
@@ -106,7 +133,7 @@ public abstract class CallableReference implements KCallable, Serializable {
* but only as a unique and unambiguous way to map a function/property descriptor to a string.
*/
public String getSignature() {
throw new AbstractMethodError();
return signature;
}
// The following methods are the delegating implementations of reflection functions. They are called when you're using reflection
@@ -9,7 +9,7 @@ import kotlin.SinceKotlin;
import kotlin.reflect.KCallable;
import kotlin.reflect.KFunction;
@SuppressWarnings("rawtypes")
@SuppressWarnings({"rawtypes", "unused"})
public class FunctionReference extends CallableReference implements FunctionBase, KFunction {
private final int arity;
@@ -19,7 +19,12 @@ public class FunctionReference extends CallableReference implements FunctionBase
@SinceKotlin(version = "1.1")
public FunctionReference(int arity, Object receiver) {
super(receiver);
this(arity, receiver, null, null, null, 0);
}
@SinceKotlin(version = "1.4")
public FunctionReference(int arity, Object receiver, Class owner, String name, String signature, int flags) {
super(receiver, owner, name, signature, flags);
this.arity = arity;
}
@@ -5,33 +5,27 @@
package kotlin.jvm.internal;
import kotlin.SinceKotlin;
import kotlin.reflect.KClass;
import kotlin.reflect.KDeclarationContainer;
@SuppressWarnings({"unused", "NullableProblems"})
@SuppressWarnings({"unused", "rawtypes"})
public class FunctionReferenceImpl extends FunctionReference {
private final KDeclarationContainer owner;
private final String name;
private final String signature;
public FunctionReferenceImpl(int arity, KDeclarationContainer owner, String name, String signature) {
super(arity);
this.owner = owner;
this.name = name;
this.signature = signature;
super(
arity, NO_RECEIVER,
((ClassBasedDeclarationContainer) owner).getJClass(), name, signature,
owner instanceof KClass ? 0 : 1
);
}
@Override
public KDeclarationContainer getOwner() {
return owner;
@SinceKotlin(version = "1.4")
public FunctionReferenceImpl(int arity, Class owner, String name, String signature, int flags) {
super(arity, NO_RECEIVER, owner, name, signature, flags);
}
@Override
public String getName() {
return name;
}
@Override
public String getSignature() {
return signature;
@SinceKotlin(version = "1.4")
public FunctionReferenceImpl(int arity, Object receiver, Class owner, String name, String signature, int flags) {
super(arity, receiver, owner, name, signature, flags);
}
}
@@ -8,7 +8,7 @@ package kotlin.jvm.internal;
import kotlin.SinceKotlin;
import kotlin.reflect.KMutableProperty;
@SuppressWarnings("rawtypes")
@SuppressWarnings({"rawtypes", "unused"})
public abstract class MutablePropertyReference extends PropertyReference implements KMutableProperty {
public MutablePropertyReference() {
}
@@ -17,4 +17,9 @@ public abstract class MutablePropertyReference extends PropertyReference impleme
public MutablePropertyReference(Object receiver) {
super(receiver);
}
@SinceKotlin(version = "1.4")
public MutablePropertyReference(Object receiver, Class owner, String name, String signature, int flags) {
super(receiver, owner, name, signature, flags);
}
}
@@ -20,6 +20,11 @@ public abstract class MutablePropertyReference0 extends MutablePropertyReference
super(receiver);
}
@SinceKotlin(version = "1.4")
public MutablePropertyReference0(Object receiver, Class owner, String name, String signature, int flags) {
super(receiver, owner, name, signature, flags);
}
@Override
protected KCallable computeReflected() {
return Reflection.mutableProperty0(this);
@@ -5,33 +5,28 @@
package kotlin.jvm.internal;
import kotlin.SinceKotlin;
import kotlin.reflect.KClass;
import kotlin.reflect.KDeclarationContainer;
@SuppressWarnings({"unused", "NullableProblems"})
@SuppressWarnings({"unused", "rawtypes"})
public class MutablePropertyReference0Impl extends MutablePropertyReference0 {
private final KDeclarationContainer owner;
private final String name;
private final String signature;
public MutablePropertyReference0Impl(KDeclarationContainer owner, String name, String signature) {
this.owner = owner;
this.name = name;
this.signature = signature;
super(
NO_RECEIVER,
((ClassBasedDeclarationContainer) owner).getJClass(), name, signature,
owner instanceof KClass ? 0 : 1
);
}
@Override
public KDeclarationContainer getOwner() {
return owner;
@SinceKotlin(version = "1.4")
public MutablePropertyReference0Impl(Class owner, String name, String signature, int flags) {
super(NO_RECEIVER, owner, name, signature, flags);
}
@Override
public String getName() {
return name;
}
@Override
public String getSignature() {
return signature;
@SinceKotlin(version = "1.4")
public MutablePropertyReference0Impl(Object receiver, Class owner, String name, String signature, int flags) {
super(receiver, owner, name, signature, flags);
}
@Override
@@ -13,6 +13,7 @@ import kotlin.reflect.KProperty1;
@SuppressWarnings({"unchecked", "rawtypes", "unused", "NullableProblems"})
public abstract class MutablePropertyReference1 extends MutablePropertyReference implements KMutableProperty1 {
public MutablePropertyReference1() {
super();
}
@SinceKotlin(version = "1.1")
@@ -20,6 +21,11 @@ public abstract class MutablePropertyReference1 extends MutablePropertyReference
super(receiver);
}
@SinceKotlin(version = "1.4")
public MutablePropertyReference1(Object receiver, Class owner, String name, String signature, int flags) {
super(receiver, owner, name, signature, flags);
}
@Override
protected KCallable computeReflected() {
return Reflection.mutableProperty1(this);
@@ -5,33 +5,28 @@
package kotlin.jvm.internal;
import kotlin.SinceKotlin;
import kotlin.reflect.KClass;
import kotlin.reflect.KDeclarationContainer;
@SuppressWarnings({"unused", "NullableProblems"})
@SuppressWarnings({"unused", "rawtypes"})
public class MutablePropertyReference1Impl extends MutablePropertyReference1 {
private final KDeclarationContainer owner;
private final String name;
private final String signature;
public MutablePropertyReference1Impl(KDeclarationContainer owner, String name, String signature) {
this.owner = owner;
this.name = name;
this.signature = signature;
super(
NO_RECEIVER,
((ClassBasedDeclarationContainer) owner).getJClass(), name, signature,
owner instanceof KClass ? 0 : 1
);
}
@Override
public KDeclarationContainer getOwner() {
return owner;
@SinceKotlin(version = "1.4")
public MutablePropertyReference1Impl(Class owner, String name, String signature, int flags) {
super(NO_RECEIVER, owner, name, signature, flags);
}
@Override
public String getName() {
return name;
}
@Override
public String getSignature() {
return signature;
@SinceKotlin(version = "1.4")
public MutablePropertyReference1Impl(Object receiver, Class owner, String name, String signature, int flags) {
super(receiver, owner, name, signature, flags);
}
@Override
@@ -10,8 +10,17 @@ import kotlin.reflect.KCallable;
import kotlin.reflect.KMutableProperty2;
import kotlin.reflect.KProperty2;
@SuppressWarnings({"unchecked", "rawtypes", "NullableProblems"})
@SuppressWarnings({"unchecked", "rawtypes", "NullableProblems", "unused"})
public abstract class MutablePropertyReference2 extends MutablePropertyReference implements KMutableProperty2 {
public MutablePropertyReference2() {
super();
}
@SinceKotlin(version = "1.4")
public MutablePropertyReference2(Class owner, String name, String signature, int flags) {
super(NO_RECEIVER, owner, name, signature, flags);
}
@Override
protected KCallable computeReflected() {
return Reflection.mutableProperty2(this);
@@ -5,33 +5,22 @@
package kotlin.jvm.internal;
import kotlin.SinceKotlin;
import kotlin.reflect.KClass;
import kotlin.reflect.KDeclarationContainer;
@SuppressWarnings({"unused", "NullableProblems"})
@SuppressWarnings({"unused", "rawtypes"})
public class MutablePropertyReference2Impl extends MutablePropertyReference2 {
private final KDeclarationContainer owner;
private final String name;
private final String signature;
public MutablePropertyReference2Impl(KDeclarationContainer owner, String name, String signature) {
this.owner = owner;
this.name = name;
this.signature = signature;
super(
((ClassBasedDeclarationContainer) owner).getJClass(), name, signature,
owner instanceof KClass ? 0 : 1
);
}
@Override
public KDeclarationContainer getOwner() {
return owner;
}
@Override
public String getName() {
return name;
}
@Override
public String getSignature() {
return signature;
@SinceKotlin(version = "1.4")
public MutablePropertyReference2Impl(Class owner, String name, String signature, int flags) {
super(owner, name, signature, flags);
}
@Override
@@ -20,6 +20,11 @@ public abstract class PropertyReference extends CallableReference implements KPr
super(receiver);
}
@SinceKotlin(version = "1.4")
public PropertyReference(Object receiver, Class owner, String name, String signature, int flags) {
super(receiver, owner, name, signature, flags);
}
@Override
@SinceKotlin(version = "1.1")
protected KProperty getReflected() {
@@ -20,6 +20,11 @@ public abstract class PropertyReference0 extends PropertyReference implements KP
super(receiver);
}
@SinceKotlin(version = "1.4")
public PropertyReference0(Object receiver, Class owner, String name, String signature, int flags) {
super(receiver, owner, name, signature, flags);
}
@Override
protected KCallable computeReflected() {
return Reflection.property0(this);
@@ -5,33 +5,28 @@
package kotlin.jvm.internal;
import kotlin.SinceKotlin;
import kotlin.reflect.KClass;
import kotlin.reflect.KDeclarationContainer;
@SuppressWarnings({"unused", "NullableProblems"})
@SuppressWarnings({"unused", "rawtypes"})
public class PropertyReference0Impl extends PropertyReference0 {
private final KDeclarationContainer owner;
private final String name;
private final String signature;
public PropertyReference0Impl(KDeclarationContainer owner, String name, String signature) {
this.owner = owner;
this.name = name;
this.signature = signature;
super(
NO_RECEIVER,
((ClassBasedDeclarationContainer) owner).getJClass(), name, signature,
owner instanceof KClass ? 0 : 1
);
}
@Override
public KDeclarationContainer getOwner() {
return owner;
@SinceKotlin(version = "1.4")
public PropertyReference0Impl(Class owner, String name, String signature, int flags) {
super(NO_RECEIVER, owner, name, signature, flags);
}
@Override
public String getName() {
return name;
}
@Override
public String getSignature() {
return signature;
@SinceKotlin(version = "1.4")
public PropertyReference0Impl(Object receiver, Class owner, String name, String signature, int flags) {
super(receiver, owner, name, signature, flags);
}
@Override
@@ -12,6 +12,7 @@ import kotlin.reflect.KProperty1;
@SuppressWarnings({"unchecked", "rawtypes", "unused", "NullableProblems"})
public abstract class PropertyReference1 extends PropertyReference implements KProperty1 {
public PropertyReference1() {
super();
}
@SinceKotlin(version = "1.1")
@@ -19,6 +20,11 @@ public abstract class PropertyReference1 extends PropertyReference implements KP
super(receiver);
}
@SinceKotlin(version = "1.4")
public PropertyReference1(Object receiver, Class owner, String name, String signature, int flags) {
super(receiver, owner, name, signature, flags);
}
@Override
protected KCallable computeReflected() {
return Reflection.property1(this);
@@ -5,33 +5,28 @@
package kotlin.jvm.internal;
import kotlin.SinceKotlin;
import kotlin.reflect.KClass;
import kotlin.reflect.KDeclarationContainer;
@SuppressWarnings("NullableProblems")
@SuppressWarnings({"unused", "rawtypes"})
public class PropertyReference1Impl extends PropertyReference1 {
private final KDeclarationContainer owner;
private final String name;
private final String signature;
public PropertyReference1Impl(KDeclarationContainer owner, String name, String signature) {
this.owner = owner;
this.name = name;
this.signature = signature;
super(
NO_RECEIVER,
((ClassBasedDeclarationContainer) owner).getJClass(), name, signature,
owner instanceof KClass ? 0 : 1
);
}
@Override
public KDeclarationContainer getOwner() {
return owner;
@SinceKotlin(version = "1.4")
public PropertyReference1Impl(Class owner, String name, String signature, int flags) {
super(NO_RECEIVER, owner, name, signature, flags);
}
@Override
public String getName() {
return name;
}
@Override
public String getSignature() {
return signature;
@SinceKotlin(version = "1.4")
public PropertyReference1Impl(Object receiver, Class owner, String name, String signature, int flags) {
super(receiver, owner, name, signature, flags);
}
@Override
@@ -9,8 +9,17 @@ import kotlin.SinceKotlin;
import kotlin.reflect.KCallable;
import kotlin.reflect.KProperty2;
@SuppressWarnings({"unchecked", "rawtypes", "NullableProblems"})
@SuppressWarnings({"unchecked", "rawtypes", "NullableProblems", "unused"})
public abstract class PropertyReference2 extends PropertyReference implements KProperty2 {
public PropertyReference2() {
super();
}
@SinceKotlin(version = "1.4")
public PropertyReference2(Class owner, String name, String signature, int flags) {
super(NO_RECEIVER, owner, name, signature, flags);
}
@Override
protected KCallable computeReflected() {
return Reflection.property2(this);
@@ -5,33 +5,22 @@
package kotlin.jvm.internal;
import kotlin.SinceKotlin;
import kotlin.reflect.KClass;
import kotlin.reflect.KDeclarationContainer;
@SuppressWarnings({"unused", "NullableProblems"})
@SuppressWarnings({"unused", "rawtypes"})
public class PropertyReference2Impl extends PropertyReference2 {
private final KDeclarationContainer owner;
private final String name;
private final String signature;
public PropertyReference2Impl(KDeclarationContainer owner, String name, String signature) {
this.owner = owner;
this.name = name;
this.signature = signature;
super(
((ClassBasedDeclarationContainer) owner).getJClass(), name, signature,
owner instanceof KClass ? 0 : 1
);
}
@Override
public KDeclarationContainer getOwner() {
return owner;
}
@Override
public String getName() {
return name;
}
@Override
public String getSignature() {
return signature;
@SinceKotlin(version = "1.4")
public PropertyReference2Impl(Class owner, String name, String signature, int flags) {
super(owner, name, signature, flags);
}
@Override
@@ -46,6 +46,11 @@ public class Reflection {
return factory.createKotlinClass(javaClass, internalName);
}
@SinceKotlin(version = "1.4")
public static KDeclarationContainer getOrCreateKotlinPackage(Class javaClass) {
return factory.getOrCreateKotlinPackage(javaClass, "");
}
public static KDeclarationContainer getOrCreateKotlinPackage(Class javaClass, String moduleName) {
return factory.getOrCreateKotlinPackage(javaClass, moduleName);
}