Support non-inlinable lambda cloning between modules

This commit is contained in:
Mikhael Bogdanov
2014-02-13 16:27:39 +04:00
parent 04be107a06
commit 8793fc21e0
5 changed files with 27 additions and 9 deletions
@@ -27,6 +27,8 @@ public class ConstructorInvocation {
private final Map<Integer, InlinableAccess> access;
private boolean isSameModule;
private Type newLambdaType;
private String newConstructorDescriptor;
@@ -35,9 +37,10 @@ public class ConstructorInvocation {
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.access = access;
this.isSameModule = isSameModule;
}
public String getOwnerInternalName() {
@@ -45,7 +48,7 @@ public class ConstructorInvocation {
}
public boolean isInlinable() {
return !access.isEmpty();
return !access.isEmpty() || !isSameModule;
}
public Map<Integer, InlinableAccess> getAccess() {
@@ -81,11 +81,14 @@ public class InlineCodegen implements ParentCodegenAware, Inliner {
private final JvmMethodSignature jvmSignature;
private final boolean isSameModule;
private LambdaInfo activeLambda;
protected final List<ParameterInfo> tempTypes = new ArrayList<ParameterInfo>();
protected final Map<Integer, LambdaInfo> expressionMap = new HashMap<Integer, LambdaInfo>();
private SimpleFunctionDescriptor inlineFunctionDescriptor;
public InlineCodegen(
@NotNull ExpressionCodegen codegen,
@@ -94,6 +97,7 @@ public class InlineCodegen implements ParentCodegenAware, Inliner {
@NotNull Call call
) {
assert functionDescriptor.getInlineStrategy().isInline() : "InlineCodegen could inline only inline function but " + functionDescriptor;
inlineFunctionDescriptor = functionDescriptor;
this.state = state;
this.typeMapper = state.getTypeMapper();
@@ -110,6 +114,9 @@ public class InlineCodegen implements ParentCodegenAware, Inliner {
InlineStrategy inlineStrategy =
codegen.getContext().isInlineFunction() ? InlineStrategy.IN_PLACE : functionDescriptor.getInlineStrategy();
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,
codegen.getInlineNameGenerator().subGenerator(functionDescriptor.getName().asString()),
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);
@@ -38,6 +38,7 @@ public class InliningInfo {
public final NameGenerator nameGenerator;
public final CodegenContext startContext;
public final Call call;
public InliningInfo(
@@ -65,8 +65,10 @@ public class LambdaTransformer {
private String signature;
private String superName;
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.typeMapper = state.getTypeMapper();
this.info = info;
@@ -122,7 +124,7 @@ public class LambdaTransformer {
MethodVisitor invokeVisitor = newMethod(classBuilder, invoke);
InlineFieldRemapper remapper = new InlineFieldRemapper(oldLambdaType.getInternalName(), newLambdaType.getInternalName(), parameters, invocation.getRecapturedLambdas());
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);
invokeVisitor.visitMaxs(-1, -1);
@@ -34,6 +34,7 @@ public class MethodInliner {
private final Type lambdaInfo;
private final LambdaFieldRemapper lambdaFieldRemapper;
private boolean isSameModule;
private final JetTypeMapper typeMapper;
@@ -56,13 +57,15 @@ public class MethodInliner {
Parameters parameters,
@NotNull InliningInfo parent,
@Nullable Type lambdaInfo,
LambdaFieldRemapper lambdaFieldRemapper
LambdaFieldRemapper lambdaFieldRemapper,
boolean isSameModule
) {
this.node = node;
this.parameters = parameters;
this.parent = parent;
this.lambdaInfo = lambdaInfo;
this.lambdaFieldRemapper = lambdaFieldRemapper;
this.isSameModule = isSameModule;
this.typeMapper = parent.state.getTypeMapper();
}
@@ -113,7 +116,8 @@ public class MethodInliner {
invocation = iterator.next();
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);
super.anew(transformer.getNewLambdaType());
constructorInvocation.put(invocation.getOwnerInternalName(), invocation);
@@ -154,7 +158,7 @@ public class MethodInliner {
this.setInlining(true);
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);
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);
}
}