Optimize codegen for generic SAM types

Search abstract members in unsubstituted scope to avoid computation
of substituted descriptors for each type (effectively for each SAM call)

 #KT-20055 In progress
This commit is contained in:
Denis Zharkov
2017-09-12 16:46:53 +03:00
parent 97fd72a1e0
commit 28d785854c
5 changed files with 9 additions and 9 deletions
@@ -203,7 +203,7 @@ public class ClosureCodegen extends MemberCodegen<KtElement> {
erasedInterfaceFunction = getErasedInvokeFunction(funDescriptor);
}
else {
erasedInterfaceFunction = samType.getAbstractMethod().getOriginal();
erasedInterfaceFunction = samType.getOriginalAbstractMethod();
}
generateBridge(
@@ -54,8 +54,8 @@ public class SamType {
}
@NotNull
public SimpleFunctionDescriptor getAbstractMethod() {
return (SimpleFunctionDescriptor) SingleAbstractMethodUtils.getAbstractMembers(type).get(0);
public SimpleFunctionDescriptor getOriginalAbstractMethod() {
return (SimpleFunctionDescriptor) SingleAbstractMethodUtils.getAbstractMembers(getJavaClassDescriptor()).get(0);
}
@Override
@@ -88,7 +88,7 @@ public class SamWrapperCodegen {
/* isExternal = */ false
);
// e.g. compare(T, T)
SimpleFunctionDescriptor erasedInterfaceFunction = samType.getAbstractMethod().getOriginal().copy(
SimpleFunctionDescriptor erasedInterfaceFunction = samType.getOriginalAbstractMethod().copy(
classDescriptor,
Modality.FINAL,
Visibilities.PUBLIC,
@@ -167,7 +167,7 @@ public class SamWrapperCodegen {
// generate sam bridges
// TODO: erasedInterfaceFunction is actually not an interface function, but function in generated class
SimpleFunctionDescriptor originalInterfaceErased = samType.getAbstractMethod().getOriginal();
SimpleFunctionDescriptor originalInterfaceErased = samType.getOriginalAbstractMethod();
SimpleFunctionDescriptorImpl descriptorForBridges = SimpleFunctionDescriptorImpl
.create(erasedInterfaceFunction.getContainingDeclaration(), erasedInterfaceFunction.getAnnotations(), originalInterfaceErased.getName(),
CallableMemberDescriptor.Kind.DECLARATION, erasedInterfaceFunction.getSource());
@@ -899,7 +899,7 @@ public class KotlinTypeMapper {
if (expression instanceof KtLambdaExpression) {
SamType samType = bindingContext.get(SAM_VALUE, (KtExpression) expression);
if (samType != null) {
return samType.getAbstractMethod().getName().asString();
return samType.getOriginalAbstractMethod().getName().asString();
}
}
}
@@ -47,9 +47,9 @@ public class SingleAbstractMethodUtils {
}
@NotNull
public static List<CallableMemberDescriptor> getAbstractMembers(@NotNull KotlinType type) {
public static List<CallableMemberDescriptor> getAbstractMembers(@NotNull ClassDescriptor classDescriptor) {
List<CallableMemberDescriptor> abstractMembers = new ArrayList<>();
for (DeclarationDescriptor member : DescriptorUtils.getAllDescriptors(type.getMemberScope())) {
for (DeclarationDescriptor member : DescriptorUtils.getAllDescriptors(classDescriptor.getUnsubstitutedMemberScope())) {
if (member instanceof CallableMemberDescriptor && ((CallableMemberDescriptor) member).getModality() == Modality.ABSTRACT) {
abstractMembers.add((CallableMemberDescriptor) member);
}
@@ -154,7 +154,7 @@ public class SingleAbstractMethodUtils {
if (klass.isDefinitelyNotSamInterface()) return null;
List<CallableMemberDescriptor> abstractMembers = getAbstractMembers(klass.getDefaultType());
List<CallableMemberDescriptor> abstractMembers = getAbstractMembers(klass);
if (abstractMembers.size() == 1) {
CallableMemberDescriptor member = abstractMembers.get(0);
if (member instanceof SimpleFunctionDescriptor) {