Support non-inlinable lambda cloning between modules
This commit is contained in:
@@ -27,6 +27,8 @@ public class ConstructorInvocation {
|
|||||||
|
|
||||||
private final Map<Integer, InlinableAccess> access;
|
private final Map<Integer, InlinableAccess> access;
|
||||||
|
|
||||||
|
private boolean isSameModule;
|
||||||
|
|
||||||
private Type newLambdaType;
|
private Type newLambdaType;
|
||||||
|
|
||||||
private String newConstructorDescriptor;
|
private String newConstructorDescriptor;
|
||||||
@@ -35,9 +37,10 @@ public class ConstructorInvocation {
|
|||||||
|
|
||||||
private Map<String, LambdaInfo> recapturedLambdas;
|
private Map<String, LambdaInfo> recapturedLambdas;
|
||||||
|
|
||||||
ConstructorInvocation(String ownerInternalName, Map<Integer, InlinableAccess> access) {
|
ConstructorInvocation(String ownerInternalName, Map<Integer, InlinableAccess> access, boolean isSameModule) {
|
||||||
this.ownerInternalName = ownerInternalName;
|
this.ownerInternalName = ownerInternalName;
|
||||||
this.access = access;
|
this.access = access;
|
||||||
|
this.isSameModule = isSameModule;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getOwnerInternalName() {
|
public String getOwnerInternalName() {
|
||||||
@@ -45,7 +48,7 @@ public class ConstructorInvocation {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public boolean isInlinable() {
|
public boolean isInlinable() {
|
||||||
return !access.isEmpty();
|
return !access.isEmpty() || !isSameModule;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Map<Integer, InlinableAccess> getAccess() {
|
public Map<Integer, InlinableAccess> getAccess() {
|
||||||
|
|||||||
@@ -81,11 +81,14 @@ public class InlineCodegen implements ParentCodegenAware, Inliner {
|
|||||||
|
|
||||||
private final JvmMethodSignature jvmSignature;
|
private final JvmMethodSignature jvmSignature;
|
||||||
|
|
||||||
|
private final boolean isSameModule;
|
||||||
|
|
||||||
private LambdaInfo activeLambda;
|
private LambdaInfo activeLambda;
|
||||||
|
|
||||||
protected final List<ParameterInfo> tempTypes = new ArrayList<ParameterInfo>();
|
protected final List<ParameterInfo> tempTypes = new ArrayList<ParameterInfo>();
|
||||||
|
|
||||||
protected final Map<Integer, LambdaInfo> expressionMap = new HashMap<Integer, LambdaInfo>();
|
protected final Map<Integer, LambdaInfo> expressionMap = new HashMap<Integer, LambdaInfo>();
|
||||||
|
private SimpleFunctionDescriptor inlineFunctionDescriptor;
|
||||||
|
|
||||||
public InlineCodegen(
|
public InlineCodegen(
|
||||||
@NotNull ExpressionCodegen codegen,
|
@NotNull ExpressionCodegen codegen,
|
||||||
@@ -94,6 +97,7 @@ public class InlineCodegen implements ParentCodegenAware, Inliner {
|
|||||||
@NotNull Call call
|
@NotNull Call call
|
||||||
) {
|
) {
|
||||||
assert functionDescriptor.getInlineStrategy().isInline() : "InlineCodegen could inline only inline function but " + functionDescriptor;
|
assert functionDescriptor.getInlineStrategy().isInline() : "InlineCodegen could inline only inline function but " + functionDescriptor;
|
||||||
|
inlineFunctionDescriptor = functionDescriptor;
|
||||||
|
|
||||||
this.state = state;
|
this.state = state;
|
||||||
this.typeMapper = state.getTypeMapper();
|
this.typeMapper = state.getTypeMapper();
|
||||||
@@ -110,6 +114,9 @@ public class InlineCodegen implements ParentCodegenAware, Inliner {
|
|||||||
InlineStrategy inlineStrategy =
|
InlineStrategy inlineStrategy =
|
||||||
codegen.getContext().isInlineFunction() ? InlineStrategy.IN_PLACE : functionDescriptor.getInlineStrategy();
|
codegen.getContext().isInlineFunction() ? InlineStrategy.IN_PLACE : functionDescriptor.getInlineStrategy();
|
||||||
this.asFunctionInline = false;
|
this.asFunctionInline = false;
|
||||||
|
|
||||||
|
isSameModule = !(functionDescriptor instanceof DeserializedSimpleFunctionDescriptor) /*not compiled library*/ &&
|
||||||
|
CodegenUtil.isCallInsideSameModuleAsDeclared(inlineFunctionDescriptor, codegen.getContext());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -193,7 +200,8 @@ public class InlineCodegen implements ParentCodegenAware, Inliner {
|
|||||||
new InliningInfo(expressionMap, null, null, null, state,
|
new InliningInfo(expressionMap, null, null, null, state,
|
||||||
codegen.getInlineNameGenerator().subGenerator(functionDescriptor.getName().asString()),
|
codegen.getInlineNameGenerator().subGenerator(functionDescriptor.getName().asString()),
|
||||||
codegen.getContext(), call);
|
codegen.getContext(), call);
|
||||||
MethodInliner inliner = new MethodInliner(node, parameters, info, null, new LambdaFieldRemapper()); //with captured
|
|
||||||
|
MethodInliner inliner = new MethodInliner(node, parameters, info, null, new LambdaFieldRemapper(), isSameModule); //with captured
|
||||||
|
|
||||||
VarRemapper.ParamRemapper remapper = new VarRemapper.ParamRemapper(parameters, initialFrameSize);
|
VarRemapper.ParamRemapper remapper = new VarRemapper.ParamRemapper(parameters, initialFrameSize);
|
||||||
|
|
||||||
|
|||||||
@@ -38,6 +38,7 @@ public class InliningInfo {
|
|||||||
public final NameGenerator nameGenerator;
|
public final NameGenerator nameGenerator;
|
||||||
|
|
||||||
public final CodegenContext startContext;
|
public final CodegenContext startContext;
|
||||||
|
|
||||||
public final Call call;
|
public final Call call;
|
||||||
|
|
||||||
public InliningInfo(
|
public InliningInfo(
|
||||||
|
|||||||
@@ -65,8 +65,10 @@ public class LambdaTransformer {
|
|||||||
private String signature;
|
private String signature;
|
||||||
private String superName;
|
private String superName;
|
||||||
private String[] interfaces;
|
private String[] interfaces;
|
||||||
|
private boolean isSameModule;
|
||||||
|
|
||||||
public LambdaTransformer(String lambdaInternalName, InliningInfo info) {
|
public LambdaTransformer(String lambdaInternalName, InliningInfo info, boolean isSameModule) {
|
||||||
|
this.isSameModule = isSameModule;
|
||||||
this.state = info.state;
|
this.state = info.state;
|
||||||
this.typeMapper = state.getTypeMapper();
|
this.typeMapper = state.getTypeMapper();
|
||||||
this.info = info;
|
this.info = info;
|
||||||
@@ -122,7 +124,7 @@ public class LambdaTransformer {
|
|||||||
MethodVisitor invokeVisitor = newMethod(classBuilder, invoke);
|
MethodVisitor invokeVisitor = newMethod(classBuilder, invoke);
|
||||||
InlineFieldRemapper remapper = new InlineFieldRemapper(oldLambdaType.getInternalName(), newLambdaType.getInternalName(), parameters, invocation.getRecapturedLambdas());
|
InlineFieldRemapper remapper = new InlineFieldRemapper(oldLambdaType.getInternalName(), newLambdaType.getInternalName(), parameters, invocation.getRecapturedLambdas());
|
||||||
MethodInliner inliner = new MethodInliner(invoke, parameters, info.subInline(info.nameGenerator.subGenerator("lambda")), oldLambdaType,
|
MethodInliner inliner = new MethodInliner(invoke, parameters, info.subInline(info.nameGenerator.subGenerator("lambda")), oldLambdaType,
|
||||||
remapper);
|
remapper, isSameModule);
|
||||||
inliner.doTransformAndMerge(invokeVisitor, new VarRemapper.ParamRemapper(parameters, 0), remapper, false);
|
inliner.doTransformAndMerge(invokeVisitor, new VarRemapper.ParamRemapper(parameters, 0), remapper, false);
|
||||||
invokeVisitor.visitMaxs(-1, -1);
|
invokeVisitor.visitMaxs(-1, -1);
|
||||||
|
|
||||||
|
|||||||
@@ -34,6 +34,7 @@ public class MethodInliner {
|
|||||||
private final Type lambdaInfo;
|
private final Type lambdaInfo;
|
||||||
|
|
||||||
private final LambdaFieldRemapper lambdaFieldRemapper;
|
private final LambdaFieldRemapper lambdaFieldRemapper;
|
||||||
|
private boolean isSameModule;
|
||||||
|
|
||||||
private final JetTypeMapper typeMapper;
|
private final JetTypeMapper typeMapper;
|
||||||
|
|
||||||
@@ -56,13 +57,15 @@ public class MethodInliner {
|
|||||||
Parameters parameters,
|
Parameters parameters,
|
||||||
@NotNull InliningInfo parent,
|
@NotNull InliningInfo parent,
|
||||||
@Nullable Type lambdaInfo,
|
@Nullable Type lambdaInfo,
|
||||||
LambdaFieldRemapper lambdaFieldRemapper
|
LambdaFieldRemapper lambdaFieldRemapper,
|
||||||
|
boolean isSameModule
|
||||||
) {
|
) {
|
||||||
this.node = node;
|
this.node = node;
|
||||||
this.parameters = parameters;
|
this.parameters = parameters;
|
||||||
this.parent = parent;
|
this.parent = parent;
|
||||||
this.lambdaInfo = lambdaInfo;
|
this.lambdaInfo = lambdaInfo;
|
||||||
this.lambdaFieldRemapper = lambdaFieldRemapper;
|
this.lambdaFieldRemapper = lambdaFieldRemapper;
|
||||||
|
this.isSameModule = isSameModule;
|
||||||
this.typeMapper = parent.state.getTypeMapper();
|
this.typeMapper = parent.state.getTypeMapper();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -113,7 +116,8 @@ public class MethodInliner {
|
|||||||
invocation = iterator.next();
|
invocation = iterator.next();
|
||||||
|
|
||||||
if (invocation.isInlinable()) {
|
if (invocation.isInlinable()) {
|
||||||
LambdaTransformer transformer = new LambdaTransformer(invocation.getOwnerInternalName(), parent.subInline(parent.nameGenerator));
|
LambdaTransformer transformer = new LambdaTransformer(invocation.getOwnerInternalName(), parent.subInline(parent.nameGenerator),
|
||||||
|
isSameModule);
|
||||||
transformer.doTransform(invocation);
|
transformer.doTransform(invocation);
|
||||||
super.anew(transformer.getNewLambdaType());
|
super.anew(transformer.getNewLambdaType());
|
||||||
constructorInvocation.put(invocation.getOwnerInternalName(), invocation);
|
constructorInvocation.put(invocation.getOwnerInternalName(), invocation);
|
||||||
@@ -154,7 +158,7 @@ public class MethodInliner {
|
|||||||
|
|
||||||
this.setInlining(true);
|
this.setInlining(true);
|
||||||
MethodInliner inliner = new MethodInliner(info.getNode(), params, parent.subInline(parent.nameGenerator.subGenerator("lambda")), info.getLambdaClassType(),
|
MethodInliner inliner = new MethodInliner(info.getNode(), params, parent.subInline(parent.nameGenerator.subGenerator("lambda")), info.getLambdaClassType(),
|
||||||
capturedRemapper);
|
capturedRemapper, isSameModule);
|
||||||
|
|
||||||
VarRemapper.ParamRemapper remapper = new VarRemapper.ParamRemapper(params, valueParamShift);
|
VarRemapper.ParamRemapper remapper = new VarRemapper.ParamRemapper(params, valueParamShift);
|
||||||
inliner.doTransformAndMerge(this.mv, remapper); //TODO add skipped this and receiver
|
inliner.doTransformAndMerge(this.mv, remapper); //TODO add skipped this and receiver
|
||||||
@@ -318,7 +322,7 @@ public class MethodInliner {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ConstructorInvocation invocation = new ConstructorInvocation(owner, infos);
|
ConstructorInvocation invocation = new ConstructorInvocation(owner, infos, isSameModule);
|
||||||
constructorInvocationList.add(invocation);
|
constructorInvocationList.add(invocation);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user