Add statement boundary mapping to debug information

This commit is contained in:
konsoletyper 2014-10-03 21:30:55 +04:00
parent f628a996ac
commit 7b4a7fc471
10 changed files with 64 additions and 3 deletions

View File

@ -146,6 +146,7 @@ public class Debugger {
public void visit(DebuggerVirtualCallSite callSite) { public void visit(DebuggerVirtualCallSite callSite) {
for (MethodReference potentialMethod : debugInfo.getOverridingMethods(callSite.getMethod())) { for (MethodReference potentialMethod : debugInfo.getOverridingMethods(callSite.getMethod())) {
for (GeneratedLocation loc : debugInfo.getMethodEntrances(potentialMethod)) { for (GeneratedLocation loc : debugInfo.getMethodEntrances(potentialMethod)) {
loc = debugInfo.getStatementLocation(loc);
locations.add(new JavaScriptLocation(script, loc.getLine(), loc.getColumn())); locations.add(new JavaScriptLocation(script, loc.getLine(), loc.getColumn()));
} }
} }
@ -154,6 +155,7 @@ public class Debugger {
@Override @Override
public void visit(DebuggerStaticCallSite callSite) { public void visit(DebuggerStaticCallSite callSite) {
for (GeneratedLocation loc : debugInfo.getMethodEntrances(callSite.getMethod())) { for (GeneratedLocation loc : debugInfo.getMethodEntrances(callSite.getMethod())) {
loc = debugInfo.getStatementLocation(loc);
locations.add(new JavaScriptLocation(script, loc.getLine(), loc.getColumn())); locations.add(new JavaScriptLocation(script, loc.getLine(), loc.getColumn()));
} }
} }
@ -174,6 +176,7 @@ public class Debugger {
Collection<GeneratedLocation> genLocations = debugInfo.getGeneratedLocations(successor); Collection<GeneratedLocation> genLocations = debugInfo.getGeneratedLocations(successor);
if (!genLocations.isEmpty()) { if (!genLocations.isEmpty()) {
for (GeneratedLocation loc : genLocations) { for (GeneratedLocation loc : genLocations) {
loc = debugInfo.getStatementLocation(loc);
successors.add(new JavaScriptLocation(script, loc.getLine(), loc.getColumn())); successors.add(new JavaScriptLocation(script, loc.getLine(), loc.getColumn()));
} }
} else { } else {

View File

@ -46,6 +46,7 @@ public class DebugInformation {
RecordArray methodMapping; RecordArray methodMapping;
RecordArray lineMapping; RecordArray lineMapping;
RecordArray callSiteMapping; RecordArray callSiteMapping;
RecordArray statementStartMapping;
RecordArray[] variableMappings; RecordArray[] variableMappings;
RecordArray[] lineCallSites; RecordArray[] lineCallSites;
RecordArray[] controlFlowGraphs; RecordArray[] controlFlowGraphs;
@ -356,6 +357,28 @@ public class DebugInformation {
return callSites; return callSites;
} }
public List<GeneratedLocation> getStatementStartLocations() {
return new LocationList(statementStartMapping);
}
public GeneratedLocation getStatementLocation(GeneratedLocation location) {
int index = indexByKey(statementStartMapping, location);
if (index < 0) {
return new GeneratedLocation(0, 0);
}
RecordArray.Record record = statementStartMapping.get(index);
return new GeneratedLocation(record.get(0), record.get(1));
}
public GeneratedLocation getNextStatementLocation(GeneratedLocation location) {
int index = indexByKey(statementStartMapping, location);
if (index >= statementStartMapping.size()) {
return new GeneratedLocation(0, 0);
}
RecordArray.Record record = statementStartMapping.get(index + 1);
return new GeneratedLocation(record.get(0), record.get(1));
}
private <T> T componentByKey(RecordArray mapping, T[] values, GeneratedLocation location) { private <T> T componentByKey(RecordArray mapping, T[] values, GeneratedLocation location) {
int keyIndex = indexByKey(mapping, location); int keyIndex = indexByKey(mapping, location);
int valueIndex = keyIndex >= 0 ? mapping.get(keyIndex).get(2) : -1; int valueIndex = keyIndex >= 0 ? mapping.get(keyIndex).get(2) : -1;

View File

@ -36,6 +36,7 @@ public class DebugInformationBuilder implements DebugInformationEmitter {
private MappedList variableNames = new MappedList(); private MappedList variableNames = new MappedList();
private List<Long> exactMethods = new ArrayList<>(); private List<Long> exactMethods = new ArrayList<>();
private Map<Long, Integer> exactMethodMap = new HashMap<>(); private Map<Long, Integer> exactMethodMap = new HashMap<>();
private RecordArrayBuilder statementStartMapping = new RecordArrayBuilder(2, 0);
private RecordArrayBuilder fileMapping = new RecordArrayBuilder(3, 0); private RecordArrayBuilder fileMapping = new RecordArrayBuilder(3, 0);
private RecordArrayBuilder lineMapping = new RecordArrayBuilder(3, 0); private RecordArrayBuilder lineMapping = new RecordArrayBuilder(3, 0);
private RecordArrayBuilder classMapping = new RecordArrayBuilder(3, 0); private RecordArrayBuilder classMapping = new RecordArrayBuilder(3, 0);
@ -120,6 +121,13 @@ public class DebugInformationBuilder implements DebugInformationEmitter {
} }
} }
@Override
public void emitStatementStart() {
RecordArrayBuilder.Record record = statementStartMapping.add();
record.set(0, locationProvider.getLine());
record.set(1, locationProvider.getColumn());
}
@Override @Override
public void emitVariable(String[] sourceNames, String generatedName) { public void emitVariable(String[] sourceNames, String generatedName) {
int[] sourceIndexes = new int[sourceNames.length]; int[] sourceIndexes = new int[sourceNames.length];
@ -273,6 +281,7 @@ public class DebugInformationBuilder implements DebugInformationEmitter {
} }
debugInformation.exactMethodMap = new HashMap<>(exactMethodMap); debugInformation.exactMethodMap = new HashMap<>(exactMethodMap);
debugInformation.statementStartMapping = statementStartMapping.build();
debugInformation.fileMapping = compress(fileMapping).build(); debugInformation.fileMapping = compress(fileMapping).build();
debugInformation.lineMapping = compress(lineMapping).build(); debugInformation.lineMapping = compress(lineMapping).build();
debugInformation.classMapping = compress(classMapping).build(); debugInformation.classMapping = compress(classMapping).build();

View File

@ -27,6 +27,8 @@ public interface DebugInformationEmitter {
void emitLocation(String fileName, int line); void emitLocation(String fileName, int line);
void emitStatementStart();
void emitMethod(MethodDescriptor method); void emitMethod(MethodDescriptor method);
void emitClass(String className); void emitClass(String className);

View File

@ -47,6 +47,7 @@ class DebugInformationReader {
debugInfo.lineMapping = readMapping(); debugInfo.lineMapping = readMapping();
debugInfo.classMapping = readMapping(); debugInfo.classMapping = readMapping();
debugInfo.methodMapping = readMapping(); debugInfo.methodMapping = readMapping();
debugInfo.statementStartMapping = readBooleanMapping();
debugInfo.callSiteMapping = readCallSiteMapping(); debugInfo.callSiteMapping = readCallSiteMapping();
debugInfo.variableMappings = readVariableMappings(debugInfo.variableNames.length); debugInfo.variableMappings = readVariableMappings(debugInfo.variableNames.length);
debugInfo.classesMetadata = readClassesMetadata(debugInfo.classNames.length); debugInfo.classesMetadata = readClassesMetadata(debugInfo.classNames.length);
@ -157,6 +158,11 @@ class DebugInformationReader {
return builder.build(); return builder.build();
} }
private RecordArray readBooleanMapping() throws IOException {
RecordArrayBuilder builder = readLinesAndColumns(2, 0);
return builder.build();
}
private RecordArray readMapping() throws IOException { private RecordArray readMapping() throws IOException {
RecordArrayBuilder builder = readLinesAndColumns(3, 0); RecordArrayBuilder builder = readLinesAndColumns(3, 0);
readValues(builder); readValues(builder);

View File

@ -49,6 +49,7 @@ class DebugInformationWriter {
writeMapping(debugInfo.lineMapping); writeMapping(debugInfo.lineMapping);
writeMapping(debugInfo.classMapping); writeMapping(debugInfo.classMapping);
writeMapping(debugInfo.methodMapping); writeMapping(debugInfo.methodMapping);
writeLinesAndColumns(debugInfo.statementStartMapping);
writeCallSiteMapping(debugInfo.callSiteMapping); writeCallSiteMapping(debugInfo.callSiteMapping);
writeVariableMappings(debugInfo); writeVariableMappings(debugInfo);
writeClassMetadata(debugInfo.classesMetadata); writeClassMetadata(debugInfo.classesMetadata);

View File

@ -40,6 +40,10 @@ public class DummyDebugInformationEmitter implements DebugInformationEmitter {
public void emitVariable(String[] sourceName, String generatedName) { public void emitVariable(String[] sourceName, String generatedName) {
} }
@Override
public void emitStatementStart() {
}
@Override @Override
public DeferredCallSite emitCallSite() { public DeferredCallSite emitCallSite() {
return new DeferredCallSite() { return new DeferredCallSite() {

View File

@ -380,7 +380,7 @@ class OptimizingVisitor implements StatementVisitor, ExprVisitor {
cond.getConsequent().clear(); cond.getConsequent().clear();
cond.getConsequent().addAll(innerCond.getConsequent()); cond.getConsequent().addAll(innerCond.getConsequent());
cond.setCondition(Expr.binary(BinaryOperation.AND, cond.getCondition(), cond.setCondition(Expr.binary(BinaryOperation.AND, cond.getCondition(),
innerCond.getCondition())); innerCond.getCondition(), cond.getCondition().getLocation()));
--i; --i;
} else if (cond.getAlternative().size() != 1 || } else if (cond.getAlternative().size() != 1 ||
!(cond.getAlternative().get(0) instanceof ConditionalStatement)) { !(cond.getAlternative().get(0) instanceof ConditionalStatement)) {
@ -409,6 +409,7 @@ class OptimizingVisitor implements StatementVisitor, ExprVisitor {
} }
} }
private void normalizeConditional(ConditionalStatement stmt) { private void normalizeConditional(ConditionalStatement stmt) {
if (stmt.getConsequent().isEmpty()) { if (stmt.getConsequent().isEmpty()) {
stmt.getConsequent().addAll(stmt.getAlternative()); stmt.getConsequent().addAll(stmt.getAlternative());
@ -502,8 +503,10 @@ class OptimizingVisitor implements StatementVisitor, ExprVisitor {
if (breakStmt.getTarget() == statement) { if (breakStmt.getTarget() == statement) {
statement.getBody().remove(0); statement.getBody().remove(0);
if (statement.getCondition() != null) { if (statement.getCondition() != null) {
statement.setCondition(Expr.binary(BinaryOperation.AND, statement.getCondition(), Expr newCondition = Expr.binary(BinaryOperation.AND, statement.getCondition(),
ExprOptimizer.invert(cond.getCondition()))); ExprOptimizer.invert(cond.getCondition()));
newCondition.setLocation(statement.getCondition().getLocation());
statement.setCondition(newCondition);
} else { } else {
statement.setCondition(ExprOptimizer.invert(cond.getCondition())); statement.setCondition(ExprOptimizer.invert(cond.getCondition()));
} }

View File

@ -617,6 +617,7 @@ public class Renderer implements ExprVisitor, StatementVisitor, RenderingContext
@Override @Override
public void visit(AssignmentStatement statement) throws RenderingException { public void visit(AssignmentStatement statement) throws RenderingException {
try { try {
debugEmitter.emitStatementStart();
if (statement.getLocation() != null) { if (statement.getLocation() != null) {
pushLocation(statement.getLocation()); pushLocation(statement.getLocation());
} }
@ -652,6 +653,7 @@ public class Renderer implements ExprVisitor, StatementVisitor, RenderingContext
public void visit(ConditionalStatement statement) { public void visit(ConditionalStatement statement) {
try { try {
while (true) { while (true) {
debugEmitter.emitStatementStart();
if (statement.getCondition().getLocation() != null) { if (statement.getCondition().getLocation() != null) {
pushLocation(statement.getCondition().getLocation()); pushLocation(statement.getCondition().getLocation());
} }
@ -690,6 +692,7 @@ public class Renderer implements ExprVisitor, StatementVisitor, RenderingContext
@Override @Override
public void visit(SwitchStatement statement) { public void visit(SwitchStatement statement) {
try { try {
debugEmitter.emitStatementStart();
if (statement.getValue().getLocation() != null) { if (statement.getValue().getLocation() != null) {
pushLocation(statement.getValue().getLocation()); pushLocation(statement.getValue().getLocation());
} }
@ -730,6 +733,7 @@ public class Renderer implements ExprVisitor, StatementVisitor, RenderingContext
@Override @Override
public void visit(WhileStatement statement) { public void visit(WhileStatement statement) {
try { try {
debugEmitter.emitStatementStart();
if (statement.getCondition() != null && statement.getCondition().getLocation() != null) { if (statement.getCondition() != null && statement.getCondition().getLocation() != null) {
pushLocation(statement.getCondition().getLocation()); pushLocation(statement.getCondition().getLocation());
} }
@ -773,6 +777,7 @@ public class Renderer implements ExprVisitor, StatementVisitor, RenderingContext
@Override @Override
public void visit(BreakStatement statement) { public void visit(BreakStatement statement) {
try { try {
debugEmitter.emitStatementStart();
if (statement.getLocation() != null) { if (statement.getLocation() != null) {
pushLocation(statement.getLocation()); pushLocation(statement.getLocation());
} }
@ -792,6 +797,7 @@ public class Renderer implements ExprVisitor, StatementVisitor, RenderingContext
@Override @Override
public void visit(ContinueStatement statement) { public void visit(ContinueStatement statement) {
try { try {
debugEmitter.emitStatementStart();
if (statement.getLocation() != null) { if (statement.getLocation() != null) {
pushLocation(statement.getLocation()); pushLocation(statement.getLocation());
} }
@ -811,6 +817,7 @@ public class Renderer implements ExprVisitor, StatementVisitor, RenderingContext
@Override @Override
public void visit(ReturnStatement statement) { public void visit(ReturnStatement statement) {
try { try {
debugEmitter.emitStatementStart();
if (statement.getLocation() != null) { if (statement.getLocation() != null) {
pushLocation(statement.getLocation()); pushLocation(statement.getLocation());
} }
@ -833,6 +840,7 @@ public class Renderer implements ExprVisitor, StatementVisitor, RenderingContext
@Override @Override
public void visit(ThrowStatement statement) { public void visit(ThrowStatement statement) {
try { try {
debugEmitter.emitStatementStart();
if (statement.getLocation() != null) { if (statement.getLocation() != null) {
pushLocation(statement.getLocation()); pushLocation(statement.getLocation());
} }
@ -852,6 +860,7 @@ public class Renderer implements ExprVisitor, StatementVisitor, RenderingContext
@Override @Override
public void visit(InitClassStatement statement) { public void visit(InitClassStatement statement) {
try { try {
debugEmitter.emitStatementStart();
if (statement.getLocation() != null) { if (statement.getLocation() != null) {
pushLocation(statement.getLocation()); pushLocation(statement.getLocation());
} }

View File

@ -73,6 +73,7 @@ public abstract class Expr implements Cloneable {
UnaryExpr result = new UnaryExpr(); UnaryExpr result = new UnaryExpr();
result.setOperand(expr); result.setOperand(expr);
result.setOperation(UnaryOperation.NOT); result.setOperation(UnaryOperation.NOT);
result.setLocation(expr.getLocation());
return result; return result;
} }