From 36d76885a7b29e799f6920b8fa34e77060f9796a Mon Sep 17 00:00:00 2001 From: konsoletyper Date: Wed, 6 Aug 2014 18:12:50 +0400 Subject: [PATCH] Fixes bugs with variable debug information tracking --- .../main/java/org/teavm/cli/TeaVMRunner.java | 3 +- .../model/util/InstructionStringifier.java | 12 ++- .../org/teavm/model/util/ListingBuilder.java | 8 ++ .../java/org/teavm/parsing/ProgramParser.java | 76 ++++++------------- .../org/teavm/parsing/SSATransformer.java | 62 ++++++++------- .../parsing/VariableDebugInformation.java | 5 +- 6 files changed, 75 insertions(+), 91 deletions(-) diff --git a/teavm-cli/src/main/java/org/teavm/cli/TeaVMRunner.java b/teavm-cli/src/main/java/org/teavm/cli/TeaVMRunner.java index acd1bb2da..094757564 100644 --- a/teavm-cli/src/main/java/org/teavm/cli/TeaVMRunner.java +++ b/teavm-cli/src/main/java/org/teavm/cli/TeaVMRunner.java @@ -56,7 +56,8 @@ public class TeaVMRunner { .create()); options.addOption(OptionBuilder .withDescription("causes TeaVM to log bytecode") - .create("logbytecode")); + .withLongOpt("logbytecode") + .create()); options.addOption(OptionBuilder .withDescription("Generate debug information") .withLongOpt("debug") diff --git a/teavm-core/src/main/java/org/teavm/model/util/InstructionStringifier.java b/teavm-core/src/main/java/org/teavm/model/util/InstructionStringifier.java index f32559396..28cf52b94 100644 --- a/teavm-core/src/main/java/org/teavm/model/util/InstructionStringifier.java +++ b/teavm-core/src/main/java/org/teavm/model/util/InstructionStringifier.java @@ -31,15 +31,13 @@ public class InstructionStringifier implements InstructionReader { this.sb = sb; } + public InstructionLocation getLocation() { + return location; + } + @Override public void location(InstructionLocation location) { - if (this.location != location) { - if (location != null) { - sb.append("at " + (location.getFileName() != null ? location.getFileName() : "") + ":" + - (location.getLine() >= 0 ? String.valueOf(location.getLine()) : "")); - } - this.location = location; - } + this.location = location; } @Override diff --git a/teavm-core/src/main/java/org/teavm/model/util/ListingBuilder.java b/teavm-core/src/main/java/org/teavm/model/util/ListingBuilder.java index 51d2f1010..5e3de2eb7 100644 --- a/teavm-core/src/main/java/org/teavm/model/util/ListingBuilder.java +++ b/teavm-core/src/main/java/org/teavm/model/util/ListingBuilder.java @@ -26,6 +26,14 @@ public class ListingBuilder { public String buildListing(ProgramReader program, String prefix) { StringBuilder sb = new StringBuilder(); InstructionStringifier stringifier = new InstructionStringifier(sb); + for (int i = 0; i < program.variableCount(); ++i) { + sb.append(prefix).append("var @").append(i); + VariableReader var = program.variableAt(i); + if (var.getDebugName() != null) { + sb.append(" as ").append(var.getDebugName()); + } + sb.append('\n'); + } for (int i = 0; i < program.basicBlockCount(); ++i) { BasicBlockReader block = program.basicBlockAt(i); sb.append(prefix).append("$").append(i).append(":\n"); diff --git a/teavm-core/src/main/java/org/teavm/parsing/ProgramParser.java b/teavm-core/src/main/java/org/teavm/parsing/ProgramParser.java index c6cad5fa5..5ef1bd86c 100644 --- a/teavm-core/src/main/java/org/teavm/parsing/ProgramParser.java +++ b/teavm-core/src/main/java/org/teavm/parsing/ProgramParser.java @@ -20,7 +20,6 @@ import org.objectweb.asm.*; import org.objectweb.asm.tree.*; import org.teavm.model.*; import org.teavm.model.instructions.*; -import org.teavm.model.util.DefinitionExtractor; import org.teavm.model.util.InstructionTransitionExtractor; /** @@ -50,8 +49,7 @@ public class ProgramParser implements VariableDebugInformation { private boolean lineNumberChanged; private InstructionLocation lastInsnLocation; private Map> localVariableMap = new HashMap<>(); - private Map variableDebugNames = new HashMap<>(); - private Map parameterNames = new HashMap<>(); + private Map> variableDebugNames = new HashMap<>(); private static class Step { public final int source; @@ -117,32 +115,11 @@ public class ProgramParser implements VariableDebugInformation { } int signatureVars = countSignatureVariables(method.desc); while (program.variableCount() <= signatureVars) { - program.createVariable(getVariableDebugName(program.variableCount(), 0)); - } - for (int i = 0; i <= signatureVars; ++i) { - parameterNames.put(i, getVariableDebugName(i, 0)); + program.createVariable(null); } return program; } - private String getVariableDebugName(int var, int location) { - if (var < 0) { - return null; - } - List nodes = localVariableMap.get(var); - if (nodes == null) { - return null; - } - for (LocalVariableNode node : nodes) { - int start = labelIndexes.get(node.start.getLabel()); - int end = labelIndexes.get(node.end.getLabel()); - if (location >= start && location < end) { - return node.name; - } - } - return null; - } - private int countSignatureVariables(String desc) { int count = 1; for (Type paramType : Type.getArgumentTypes(desc)) { @@ -185,13 +162,9 @@ public class ProgramParser implements VariableDebugInformation { } @Override - public String getDefinitionDebugName(Instruction insn) { - return variableDebugNames.get(insn); - } - - @Override - public String getParameterDebugName(int index) { - return parameterNames.get(index); + public Map getDebugNames(Instruction insn) { + Map map = variableDebugNames.get(insn); + return map != null ? Collections.unmodifiableMap(map) : Collections.emptyMap(); } private void prepare(MethodNode method) { @@ -213,10 +186,11 @@ public class ProgramParser implements VariableDebugInformation { } } for (LocalVariableNode localVar : method.localVariables) { - List vars = localVariableMap.get(localVar.index); + int location = labelIndexes.get(localVar.start.getLabel()); + List vars = localVariableMap.get(location); if (vars == null) { vars = new ArrayList<>(); - localVariableMap.put(localVar.index, vars); + localVariableMap.put(location, vars); } vars.add(localVar); } @@ -293,24 +267,8 @@ public class ProgramParser implements VariableDebugInformation { } private void assemble() { - DefinitionExtractor defExtractor = new DefinitionExtractor(); - for (int i = 0; i < targetInstructions.size(); ++i) { - List instructionList = targetInstructions.get(i); - if (instructionList == null) { - continue; - } - for (Instruction insn : instructionList) { - insn.acceptVisitor(defExtractor); - for (Variable var : defExtractor.getDefinedVariables()) { - String debugName = getVariableDebugName(var.getIndex() - minLocal, i); - if (debugName != null) { - variableDebugNames.put(insn, debugName); - } - } - } - } - BasicBlock basicBlock = null; + Map accumulatedDebugNames = new HashMap<>(); for (int i = 0; i < basicBlocks.size(); ++i) { BasicBlock newBasicBlock = basicBlocks.get(i); if (newBasicBlock != null) { @@ -320,8 +278,24 @@ public class ProgramParser implements VariableDebugInformation { basicBlock.getInstructions().add(insn); } basicBlock = newBasicBlock; + if (!basicBlock.getInstructions().isEmpty()) { + Map debugNames = new HashMap<>(accumulatedDebugNames); + variableDebugNames.put(basicBlock.getInstructions().get(0), debugNames); + } } List builtInstructions = targetInstructions.get(i); + List localVarNodes = localVariableMap.get(i); + if (localVarNodes != null) { + if (builtInstructions == null || builtInstructions.isEmpty()) { + builtInstructions = Arrays.asList(new EmptyInstruction()); + } + Map debugNames = new HashMap<>(); + variableDebugNames.put(builtInstructions.get(0), debugNames); + for (LocalVariableNode localVar : localVarNodes) { + debugNames.put(localVar.index + minLocal, localVar.name); + } + accumulatedDebugNames.putAll(debugNames); + } if (builtInstructions != null) { basicBlock.getInstructions().addAll(builtInstructions); } diff --git a/teavm-core/src/main/java/org/teavm/parsing/SSATransformer.java b/teavm-core/src/main/java/org/teavm/parsing/SSATransformer.java index af0e333c0..453168a39 100644 --- a/teavm-core/src/main/java/org/teavm/parsing/SSATransformer.java +++ b/teavm-core/src/main/java/org/teavm/parsing/SSATransformer.java @@ -39,6 +39,7 @@ public class SSATransformer { private int[][] phiIndexMap; private ValueType[] arguments; private VariableDebugInformation variableDebugInfo; + private Map variableDebugMap = new HashMap<>(); public void transformToSSA(Program program, VariableDebugInformation variableDebugInfo, ValueType[] arguments) { if (program.basicBlockCount() == 0) { @@ -47,6 +48,7 @@ public class SSATransformer { this.program = program; this.variableDebugInfo = variableDebugInfo; this.arguments = arguments; + variableDebugMap.clear(); cfg = ProgramUtils.buildControlFlowGraphWithoutTryCatch(program); domTree = GraphUtils.buildDominatorTree(cfg); domFrontiers = new int[cfg.size()][]; @@ -57,9 +59,6 @@ public class SSATransformer { phiMap[i] = new Phi[program.variableCount()]; phiIndexMap[i] = new int[program.variableCount()]; } - for (int i = 0; i < program.variableCount(); ++i) { - program.variableAt(i).setDebugName(variableDebugInfo.getParameterDebugName(i)); - } applySignature(); domFrontiers = GraphUtils.findDominanceFrontiers(cfg, domTree); estimatePhis(); @@ -160,6 +159,7 @@ public class SSATransformer { specialPhis.get(currentBlock.getIndex()).add(phi); } for (Instruction insn : currentBlock.getInstructions()) { + variableDebugMap.putAll(variableDebugInfo.getDebugNames(insn)); insn.acceptVisitor(consumer); } int[] successors = domGraph.outgoingEdges(currentBlock.getIndex()); @@ -216,8 +216,8 @@ public class SSATransformer { } } - private Variable define(Variable var, String debugName) { - Variable result = program.createVariable(debugName); + private Variable define(Variable var) { + Variable result = program.createVariable(null); variableMap[var.getIndex()] = result; return result; } @@ -227,6 +227,10 @@ public class SSATransformer { if (mappedVar == null) { throw new AssertionError(); } + String debugName = variableDebugMap.get(var.getIndex()); + if (debugName != null) { + mappedVar.setDebugName(debugName); + } return mappedVar; } @@ -237,56 +241,56 @@ public class SSATransformer { @Override public void visit(ClassConstantInstruction insn) { - insn.setReceiver(define(insn.getReceiver(), variableDebugInfo.getDefinitionDebugName(insn))); + insn.setReceiver(define(insn.getReceiver())); } @Override public void visit(NullConstantInstruction insn) { - insn.setReceiver(define(insn.getReceiver(), variableDebugInfo.getDefinitionDebugName(insn))); + insn.setReceiver(define(insn.getReceiver())); } @Override public void visit(IntegerConstantInstruction insn) { - insn.setReceiver(define(insn.getReceiver(), variableDebugInfo.getDefinitionDebugName(insn))); + insn.setReceiver(define(insn.getReceiver())); } @Override public void visit(LongConstantInstruction insn) { - insn.setReceiver(define(insn.getReceiver(), variableDebugInfo.getDefinitionDebugName(insn))); + insn.setReceiver(define(insn.getReceiver())); } @Override public void visit(FloatConstantInstruction insn) { - insn.setReceiver(define(insn.getReceiver(), variableDebugInfo.getDefinitionDebugName(insn))); + insn.setReceiver(define(insn.getReceiver())); } @Override public void visit(DoubleConstantInstruction insn) { - insn.setReceiver(define(insn.getReceiver(), variableDebugInfo.getDefinitionDebugName(insn))); + insn.setReceiver(define(insn.getReceiver())); } @Override public void visit(StringConstantInstruction insn) { - insn.setReceiver(define(insn.getReceiver(), variableDebugInfo.getDefinitionDebugName(insn))); + insn.setReceiver(define(insn.getReceiver())); } @Override public void visit(BinaryInstruction insn) { insn.setFirstOperand(use(insn.getFirstOperand())); insn.setSecondOperand(use(insn.getSecondOperand())); - insn.setReceiver(define(insn.getReceiver(), variableDebugInfo.getDefinitionDebugName(insn))); + insn.setReceiver(define(insn.getReceiver())); } @Override public void visit(NegateInstruction insn) { insn.setOperand(use(insn.getOperand())); - insn.setReceiver(define(insn.getReceiver(), variableDebugInfo.getDefinitionDebugName(insn))); + insn.setReceiver(define(insn.getReceiver())); } @Override public void visit(AssignInstruction insn) { insn.setAssignee(use(insn.getAssignee())); - insn.setReceiver(define(insn.getReceiver(), variableDebugInfo.getDefinitionDebugName(insn))); + insn.setReceiver(define(insn.getReceiver())); } @Override @@ -324,12 +328,12 @@ public class SSATransformer { @Override public void visit(ConstructArrayInstruction insn) { insn.setSize(use(insn.getSize())); - insn.setReceiver(define(insn.getReceiver(), variableDebugInfo.getDefinitionDebugName(insn))); + insn.setReceiver(define(insn.getReceiver())); } @Override public void visit(ConstructInstruction insn) { - insn.setReceiver(define(insn.getReceiver(), variableDebugInfo.getDefinitionDebugName(insn))); + insn.setReceiver(define(insn.getReceiver())); } @Override @@ -338,7 +342,7 @@ public class SSATransformer { for (int i = 0; i < dimensions.size(); ++i) { dimensions.set(i, use(dimensions.get(i))); } - insn.setReceiver(define(insn.getReceiver(), variableDebugInfo.getDefinitionDebugName(insn))); + insn.setReceiver(define(insn.getReceiver())); } @Override @@ -346,7 +350,7 @@ public class SSATransformer { if (insn.getInstance() != null) { insn.setInstance(use(insn.getInstance())); } - insn.setReceiver(define(insn.getReceiver(), variableDebugInfo.getDefinitionDebugName(insn))); + insn.setReceiver(define(insn.getReceiver())); } @Override @@ -361,7 +365,7 @@ public class SSATransformer { public void visit(GetElementInstruction insn) { insn.setArray(use(insn.getArray())); insn.setIndex(use(insn.getIndex())); - insn.setReceiver(define(insn.getReceiver(), variableDebugInfo.getDefinitionDebugName(insn))); + insn.setReceiver(define(insn.getReceiver())); } @Override @@ -381,50 +385,50 @@ public class SSATransformer { insn.setInstance(use(insn.getInstance())); } if (insn.getReceiver() != null) { - insn.setReceiver(define(insn.getReceiver(), variableDebugInfo.getDefinitionDebugName(insn))); + insn.setReceiver(define(insn.getReceiver())); } } @Override public void visit(IsInstanceInstruction insn) { insn.setValue(use(insn.getValue())); - insn.setReceiver(define(insn.getReceiver(), variableDebugInfo.getDefinitionDebugName(insn))); + insn.setReceiver(define(insn.getReceiver())); } @Override public void visit(CastInstruction insn) { insn.setValue(use(insn.getValue())); - insn.setReceiver(define(insn.getReceiver(), variableDebugInfo.getDefinitionDebugName(insn))); + insn.setReceiver(define(insn.getReceiver())); } @Override public void visit(CastNumberInstruction insn) { insn.setValue(use(insn.getValue())); - insn.setReceiver(define(insn.getReceiver(), variableDebugInfo.getDefinitionDebugName(insn))); + insn.setReceiver(define(insn.getReceiver())); } @Override public void visit(CastIntegerInstruction insn) { insn.setValue(use(insn.getValue())); - insn.setReceiver(define(insn.getReceiver(), variableDebugInfo.getDefinitionDebugName(insn))); + insn.setReceiver(define(insn.getReceiver())); } @Override public void visit(ArrayLengthInstruction insn) { insn.setArray(use(insn.getArray())); - insn.setReceiver(define(insn.getReceiver(), variableDebugInfo.getDefinitionDebugName(insn))); + insn.setReceiver(define(insn.getReceiver())); } @Override public void visit(UnwrapArrayInstruction insn) { insn.setArray(use(insn.getArray())); - insn.setReceiver(define(insn.getReceiver(), variableDebugInfo.getDefinitionDebugName(insn))); + insn.setReceiver(define(insn.getReceiver())); } @Override public void visit(CloneArrayInstruction insn) { insn.setArray(use(insn.getArray())); - insn.setReceiver(define(insn.getReceiver(), variableDebugInfo.getDefinitionDebugName(insn))); + insn.setReceiver(define(insn.getReceiver())); } @Override @@ -434,7 +438,7 @@ public class SSATransformer { @Override public void visit(NullCheckInstruction insn) { insn.setValue(use(insn.getValue())); - insn.setReceiver(define(insn.getReceiver(), variableDebugInfo.getDefinitionDebugName(insn))); + insn.setReceiver(define(insn.getReceiver())); } }; } diff --git a/teavm-core/src/main/java/org/teavm/parsing/VariableDebugInformation.java b/teavm-core/src/main/java/org/teavm/parsing/VariableDebugInformation.java index 55fcda47a..995fa172e 100644 --- a/teavm-core/src/main/java/org/teavm/parsing/VariableDebugInformation.java +++ b/teavm-core/src/main/java/org/teavm/parsing/VariableDebugInformation.java @@ -15,6 +15,7 @@ */ package org.teavm.parsing; +import java.util.Map; import org.teavm.model.Instruction; /** @@ -22,7 +23,5 @@ import org.teavm.model.Instruction; * @author Alexey Andreev */ public interface VariableDebugInformation { - String getDefinitionDebugName(Instruction insn); - - String getParameterDebugName(int index); + Map getDebugNames(Instruction insn); }