From 8793fc21e09b11d5c92cda40cb1dee1388c4ca65 Mon Sep 17 00:00:00 2001 From: Mikhael Bogdanov Date: Thu, 13 Feb 2014 16:27:39 +0400 Subject: [PATCH] Support non-inlinable lambda cloning between modules --- .../jet/codegen/asm/ConstructorInvocation.java | 7 +++++-- .../org/jetbrains/jet/codegen/asm/InlineCodegen.java | 10 +++++++++- .../org/jetbrains/jet/codegen/asm/InliningInfo.java | 1 + .../jetbrains/jet/codegen/asm/LambdaTransformer.java | 6 ++++-- .../org/jetbrains/jet/codegen/asm/MethodInliner.java | 12 ++++++++---- 5 files changed, 27 insertions(+), 9 deletions(-) diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/asm/ConstructorInvocation.java b/compiler/backend/src/org/jetbrains/jet/codegen/asm/ConstructorInvocation.java index 88b367586e5..77df498f54b 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/asm/ConstructorInvocation.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/asm/ConstructorInvocation.java @@ -27,6 +27,8 @@ public class ConstructorInvocation { private final Map access; + private boolean isSameModule; + private Type newLambdaType; private String newConstructorDescriptor; @@ -35,9 +37,10 @@ public class ConstructorInvocation { private Map recapturedLambdas; - ConstructorInvocation(String ownerInternalName, Map access) { + ConstructorInvocation(String ownerInternalName, Map 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 getAccess() { diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/asm/InlineCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/asm/InlineCodegen.java index 8edf7b4903a..c32646e4828 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/asm/InlineCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/asm/InlineCodegen.java @@ -81,11 +81,14 @@ public class InlineCodegen implements ParentCodegenAware, Inliner { private final JvmMethodSignature jvmSignature; + private final boolean isSameModule; + private LambdaInfo activeLambda; protected final List tempTypes = new ArrayList(); protected final Map expressionMap = new HashMap(); + 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); diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/asm/InliningInfo.java b/compiler/backend/src/org/jetbrains/jet/codegen/asm/InliningInfo.java index 67d3f6eb5ef..9386382df2f 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/asm/InliningInfo.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/asm/InliningInfo.java @@ -38,6 +38,7 @@ public class InliningInfo { public final NameGenerator nameGenerator; public final CodegenContext startContext; + public final Call call; public InliningInfo( diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/asm/LambdaTransformer.java b/compiler/backend/src/org/jetbrains/jet/codegen/asm/LambdaTransformer.java index cdb194c2764..fd0c0470655 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/asm/LambdaTransformer.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/asm/LambdaTransformer.java @@ -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); diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/asm/MethodInliner.java b/compiler/backend/src/org/jetbrains/jet/codegen/asm/MethodInliner.java index 4b01f69cc43..9607eb68730 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/asm/MethodInliner.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/asm/MethodInliner.java @@ -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); } }