Code clean

This commit is contained in:
Mikhael Bogdanov
2014-03-12 16:31:55 +04:00
parent 2dcc0bce46
commit c95001370a
8 changed files with 61 additions and 66 deletions
@@ -27,15 +27,15 @@ import org.jetbrains.jet.codegen.StackValue;
import java.util.Collection;
import java.util.List;
public class LambdaFieldRemapper {
public class FieldRemapper {
private final String lambdaInternalName;
protected LambdaFieldRemapper parent;
protected FieldRemapper parent;
private final Parameters params;
public LambdaFieldRemapper(@Nullable String lambdaInternalName, @Nullable LambdaFieldRemapper parent, @NotNull Parameters methodParams) {
public FieldRemapper(@Nullable String lambdaInternalName, @Nullable FieldRemapper parent, @NotNull Parameters methodParams) {
this.lambdaInternalName = lambdaInternalName;
this.parent = parent;
params = methodParams;
@@ -51,9 +51,9 @@ public class LambdaFieldRemapper {
return fieldOwner.equals(getLambdaInternalName());
}
@Nullable
public AbstractInsnNode transformIfNeeded(
@NotNull List<AbstractInsnNode> capturedFieldAccess,
int currentInstruction,
@NotNull MethodNode node
) {
if (capturedFieldAccess.size() == 1) {
@@ -61,6 +61,15 @@ public class LambdaFieldRemapper {
return null;
}
return transformIfNeeded(capturedFieldAccess, 1, node);
}
@Nullable
private AbstractInsnNode transformIfNeeded(
@NotNull List<AbstractInsnNode> capturedFieldAccess,
int currentInstruction,
@NotNull MethodNode node
) {
AbstractInsnNode transformed = null;
boolean checkParent = !isRoot() && currentInstruction < capturedFieldAccess.size() - 1;
if (checkParent) {
@@ -99,7 +108,7 @@ public class LambdaFieldRemapper {
return null;
}
public LambdaFieldRemapper getParent() {
public FieldRemapper getParent() {
return parent;
}
@@ -213,11 +213,11 @@ public class InlineCodegen implements ParentCodegenAware, CallGenerator {
codegen.getInlineNameGenerator().subGenerator(functionDescriptor.getName().asString()),
codegen.getContext(), call, Collections.<String, String>emptyMap(), false, false);
MethodInliner inliner = new MethodInliner(node, parameters, info, new LambdaFieldRemapper(null, null, parameters), isSameModule, "InlineCodegenRoot " + call.getCallElement()); //with captured
MethodInliner inliner = new MethodInliner(node, parameters, info, new FieldRemapper(null, null, parameters), isSameModule, "InlineCodegenRoot " + call.getCallElement()); //with captured
VarRemapper.ParamRemapper remapper = new VarRemapper.ParamRemapper(parameters, initialFrameSize);
return inliner.doInline(codegen.v, remapper, new LambdaFieldRemapper(null, null, parameters));
return inliner.doInline(codegen.v, remapper, new FieldRemapper(null, null, parameters));
}
private void generateClosuresBodies() {
@@ -22,11 +22,11 @@ import org.jetbrains.asm4.tree.FieldInsnNode;
import java.util.Collection;
public class InlinedLambdaRemapper extends LambdaFieldRemapper {
public class InlinedLambdaRemapper extends FieldRemapper {
public InlinedLambdaRemapper(
@NotNull String lambdaInternalName,
@NotNull LambdaFieldRemapper parent,
@NotNull FieldRemapper parent,
@NotNull Parameters methodParams
) {
super(lambdaInternalName, parent, methodParams);
@@ -51,7 +51,7 @@ public class InlinedLambdaRemapper extends LambdaFieldRemapper {
}
@Override
public LambdaFieldRemapper getParent() {
public FieldRemapper getParent() {
return parent.getParent();
}
@@ -138,7 +138,7 @@ public class LambdaInfo implements CapturedParamOwner {
return Arrays.asList(types);
}
public Parameters addAllParameters(@NotNull LambdaFieldRemapper remapper) {
public Parameters addAllParameters(@NotNull FieldRemapper remapper) {
ParametersBuilder builder = ParametersBuilder.newBuilder();
//add skipped this cause inlined lambda doesn't have it
builder.addThis(AsmTypeConstants.OBJECT_TYPE, true).setLambda(this);
@@ -105,7 +105,7 @@ public class LambdaTransformer {
}
}
public InlineResult doTransform(ConstructorInvocation invocation, LambdaFieldRemapper parentRemapper) {
public InlineResult doTransform(ConstructorInvocation invocation, FieldRemapper parentRemapper) {
ClassBuilder classBuilder = createClassBuilder();
//TODO: public visibility for inline function
@@ -15,7 +15,6 @@ import org.jetbrains.asm4.tree.analysis.*;
import org.jetbrains.jet.codegen.ClosureCodegen;
import org.jetbrains.jet.codegen.StackValue;
import org.jetbrains.jet.codegen.state.JetTypeMapper;
import org.jetbrains.jet.utils.UtilsPackage;
import java.util.*;
@@ -30,7 +29,7 @@ public class MethodInliner {
private final InliningContext inliningContext;
private final LambdaFieldRemapper nodeRemapper;
private final FieldRemapper nodeRemapper;
private final boolean isSameModule;
@@ -58,7 +57,7 @@ public class MethodInliner {
@NotNull MethodNode node,
@NotNull Parameters parameters,
@NotNull InliningContext parent,
@NotNull LambdaFieldRemapper nodeRemapper,
@NotNull FieldRemapper nodeRemapper,
boolean isSameModule,
@NotNull String errorPrefix
) {
@@ -73,14 +72,14 @@ public class MethodInliner {
}
public InlineResult doInline(MethodVisitor adapter, VarRemapper.ParamRemapper remapper, LambdaFieldRemapper fieldRemapper) {
return doInline(adapter, remapper, fieldRemapper, true);
public InlineResult doInline(MethodVisitor adapter, VarRemapper.ParamRemapper remapper, FieldRemapper capturedRemapper) {
return doInline(adapter, remapper, capturedRemapper, true);
}
public InlineResult doInline(
MethodVisitor adapter,
VarRemapper.ParamRemapper remapper,
LambdaFieldRemapper capturedRemapper, boolean remapReturn
FieldRemapper capturedRemapper, boolean remapReturn
) {
//analyze body
MethodNode transformedNode = markPlacesForInlineAndRemoveInlinable(node);
@@ -93,20 +92,17 @@ public class MethodInliner {
RemapVisitor visitor = new RemapVisitor(adapter, end, remapper, remapReturn, nodeRemapper);
try {
transformedNode.accept(visitor);
} catch (Exception e) {
String text = InlineCodegen.getNodeText(transformedNode);
throw new RuntimeException(errorPrefix + ": couldn't inline method call '" +
transformedNode +
"\ncause: " +
text, e);
}
catch (Exception e) {
throw new RuntimeException(errorPrefix + ": couldn't inline method call " + transformedNode + "\ncause: " +
InlineCodegen.getNodeText(transformedNode), e);
}
visitor.visitLabel(end);
return result;
}
private MethodNode doInline(MethodNode node, final LambdaFieldRemapper capturedRemapper) {
private MethodNode doInline(MethodNode node, final FieldRemapper capturedRemapper) {
final Deque<InvokeCall> currentInvokes = new LinkedList<InvokeCall>(invokeCalls);
@@ -168,13 +164,13 @@ public class MethodInliner {
InlinedLambdaRemapper newCapturedRemapper =
new InlinedLambdaRemapper(info.getLambdaClassType().getInternalName(), capturedRemapper, lambdaParameters);
LambdaFieldRemapper lambdaFieldRemapper =
new LambdaFieldRemapper(info.getLambdaClassType().getInternalName(), capturedRemapper, lambdaParameters);
FieldRemapper fieldRemapper =
new FieldRemapper(info.getLambdaClassType().getInternalName(), capturedRemapper, lambdaParameters);
setInlining(true);
MethodInliner inliner = new MethodInliner(info.getNode(), lambdaParameters,
inliningContext.subInlineLambda(info),
lambdaFieldRemapper, true /*cause all calls in same module as lambda*/,
fieldRemapper, true /*cause all calls in same module as lambda*/,
"Lambda inlining " + info.getLambdaClassType().getInternalName());
VarRemapper.ParamRemapper remapper = new VarRemapper.ParamRemapper(lambdaParameters, valueParamShift);
@@ -212,12 +208,9 @@ public class MethodInliner {
return resultNode;
}
public CapturedParamInfo findCapturedField(FieldInsnNode node) {
return findCapturedField(node, nodeRemapper);
}
@NotNull
public static CapturedParamInfo findCapturedField(FieldInsnNode node, LambdaFieldRemapper fieldRemapper) {
public static CapturedParamInfo findCapturedField(FieldInsnNode node, FieldRemapper fieldRemapper) {
assert node.name.startsWith("$$$") : "Captured field template should start with $$$ prefix";
FieldInsnNode fin = new FieldInsnNode(node.getOpcode(), node.owner, node.name.substring(3), node.desc);
CapturedParamInfo field = fieldRemapper.findField(fin);
if (field == null) {
@@ -282,13 +275,10 @@ public class MethodInliner {
Frame<SourceValue>[] sources;
try {
sources = analyzer.analyze("fake", node);
} catch (AnalyzerException e) {
String text = InlineCodegen.getNodeText(node);
throw new RuntimeException("Couldn't inline method call '" +
node +
"\ncause: " +
text, e);
}
catch (AnalyzerException e) {
throw new RuntimeException("Couldn't inline method call " + node + "\ncause: " +
InlineCodegen.getNodeText(node), e);
}
AbstractInsnNode cur = node.instructions.getFirst();
@@ -378,12 +368,11 @@ public class MethodInliner {
if (varIndex < parameters.totalSize()) {
return parameters.get(varIndex).getLambda();
}
} else if (insnNode instanceof FieldInsnNode) {
}
else if (insnNode instanceof FieldInsnNode) {
FieldInsnNode fieldInsnNode = (FieldInsnNode) insnNode;
if (fieldInsnNode.name.startsWith("$$$")) {
CapturedParamInfo field = findCapturedField(fieldInsnNode);
return field.getLambda();
return findCapturedField(fieldInsnNode, nodeRemapper).getLambda();
}
}
@@ -418,13 +407,14 @@ public class MethodInliner {
return;
}
//encode all captured variable chains - ALOAD 0 ALOAD this$0 GETFIELD $captured - to GETFIELD $$$$captured
//Fold all captured variable chain - ALOAD 0 ALOAD this$0 GETFIELD $captured - to GETFIELD $$$$captured
//On future decoding this field could be inline or unfolded in another field access chain (it can differ in some missed this$0)
AbstractInsnNode cur = node.instructions.getFirst();
while (cur != null) {
if (cur instanceof VarInsnNode && cur.getOpcode() == Opcodes.ALOAD) {
if (((VarInsnNode) cur).var == 0) {
List<AbstractInsnNode> accessChain = getCapturedFieldAccessChain((VarInsnNode) cur);
AbstractInsnNode insnNode = nodeRemapper.transformIfNeeded(accessChain, 1, node);
AbstractInsnNode insnNode = nodeRemapper.transformIfNeeded(accessChain, node);
if (insnNode != null) {
cur = insnNode;
}
@@ -435,15 +425,16 @@ public class MethodInliner {
}
@NotNull
public static List<AbstractInsnNode> getCapturedFieldAccessChain(@NotNull VarInsnNode node) {
public static List<AbstractInsnNode> getCapturedFieldAccessChain(@NotNull VarInsnNode aload0) {
List<AbstractInsnNode> fieldAccessChain = new ArrayList<AbstractInsnNode>();
fieldAccessChain.add(node);
AbstractInsnNode next = node.getNext();
fieldAccessChain.add(aload0);
AbstractInsnNode next = aload0.getNext();
while (next != null && next instanceof FieldInsnNode) {
fieldAccessChain.add(next);
if("this$0".equals(((FieldInsnNode) next).name)) {
if ("this$0".equals(((FieldInsnNode) next).name)) {
next = next.getNext();
} else {
}
else {
break;
}
}
@@ -451,14 +442,6 @@ public class MethodInliner {
return fieldAccessChain;
}
public static AbstractInsnNode getPreviousNoLabelNoLine(AbstractInsnNode cur) {
AbstractInsnNode prev = cur.getPrevious();
while (prev.getType() == AbstractInsnNode.LABEL || prev.getType() == AbstractInsnNode.LINE) {
prev = prev.getPrevious();
}
return prev;
}
public static void putStackValuesIntoLocals(List<Type> directOrder, int shift, InstructionAdapter iv, String descriptor) {
Type[] actualParams = Type.getArgumentTypes(descriptor);
assert actualParams.length == directOrder.size() : "Number of expected and actual params should be equals!";
@@ -27,7 +27,7 @@ import java.util.Collection;
import java.util.List;
import java.util.Map;
public class RegeneratedLambdaFieldRemapper extends LambdaFieldRemapper {
public class RegeneratedLambdaFieldRemapper extends FieldRemapper {
private final String oldOwnerType;
@@ -42,7 +42,7 @@ public class RegeneratedLambdaFieldRemapper extends LambdaFieldRemapper {
String newOwnerType,
Parameters parameters,
Map<String, LambdaInfo> recapturedLambdas,
LambdaFieldRemapper remapper
FieldRemapper remapper
) {
super(oldOwnerType, remapper, parameters);
this.oldOwnerType = oldOwnerType;
@@ -70,7 +70,7 @@ public class RegeneratedLambdaFieldRemapper extends LambdaFieldRemapper {
throw new IllegalStateException("Captured parameter should exists in outer context: " + originalField.getFieldName());
}
CapturedParamInfo info = builder.addCapturedParam(foundField, foundField);
builder.addCapturedParam(foundField, foundField);
}
} else {
//in case when inlining lambda into another one inside inline function
@@ -116,6 +116,7 @@ public class RegeneratedLambdaFieldRemapper extends LambdaFieldRemapper {
@Nullable
@Override
public StackValue getFieldForInline(@NotNull FieldInsnNode node, @Nullable StackValue prefix) {
assert node.name.startsWith("$$$") : "Captured field template should start with $$$ prefix";
FieldInsnNode fin = new FieldInsnNode(node.getOpcode(), node.owner, node.name.substring(3), node.desc);
CapturedParamInfo field = findFieldInMyCaptured(fin);
@@ -31,9 +31,9 @@ public class RemapVisitor extends InstructionAdapter {
private final VarRemapper remapper;
private final boolean remapReturn;
private LambdaFieldRemapper nodeRemapper;
private FieldRemapper nodeRemapper;
protected RemapVisitor(MethodVisitor mv, Label end, VarRemapper.ParamRemapper remapper, boolean remapReturn, LambdaFieldRemapper nodeRemapper) {
protected RemapVisitor(MethodVisitor mv, Label end, VarRemapper.ParamRemapper remapper, boolean remapReturn, FieldRemapper nodeRemapper) {
super(InlineCodegenUtil.API, mv);
this.end = end;
this.remapper = remapper;
@@ -67,8 +67,10 @@ public class RemapVisitor extends InstructionAdapter {
if (nodeRemapper instanceof RegeneratedLambdaFieldRemapper || nodeRemapper.isRoot()) {
FieldInsnNode fin = new FieldInsnNode(opcode, owner, name, desc);
StackValue inline = nodeRemapper.getFieldForInline(fin, null);
assert inline != null : "Captured field should have not null stackValue " + fin;
inline.put(inline.type, this);
} else {
}
else {
super.visitFieldInsn(opcode, owner, name, desc);
}
}