more-detailed source mapping information

This commit is contained in:
Julian Dolby 2018-05-08 08:01:35 -04:00
parent 8005b665b9
commit 6b2db3e190
2 changed files with 116 additions and 36 deletions

View File

@ -500,11 +500,15 @@ public abstract class AstTranslator extends CAstVisitor<AstTranslator.WalkContex
private Position[] instructionPositions;
AstDebuggingInformation(Position codeBodyPosition, Position[] instructionPositions, String[] names) {
private Position[][] operandPositions;
AstDebuggingInformation(Position codeBodyPosition, Position[] instructionPositions, Position[][] operandPositions, String[] names) {
this.codeBodyPosition = codeBodyPosition;
this.instructionPositions = instructionPositions;
this.operandPositions = operandPositions;
valueNumberNames = new String[names.length][];
for (int i = 0; i < names.length; i++) {
if (names[i] != null) {
@ -525,6 +529,15 @@ public abstract class AstTranslator extends CAstVisitor<AstTranslator.WalkContex
return instructionPositions[instructionOffset];
}
@Override
public Position getOperandPosition(int instructionOffset, int operand) {
if (operandPositions[instructionOffset] != null && operandPositions[instructionOffset].length > operand) {
return operandPositions[instructionOffset][operand];
} else {
return null;
}
}
@Override
public String[][] getSourceNamesForValues() {
return valueNumberNames;
@ -837,6 +850,8 @@ public abstract class AstTranslator extends CAstVisitor<AstTranslator.WalkContex
private Position[] linePositions = new Position[10];
private Position[][] operandPositions = new Position[10][];
private boolean hasCatchBlock = false;
/**
@ -1067,15 +1082,26 @@ public abstract class AstTranslator extends CAstVisitor<AstTranslator.WalkContex
* mark the current position as the position for the instruction
*/
private void noteLinePosition(int instruction) {
if (linePositions.length < (instruction + 1)) {
Position[] newData = new Position[instruction * 2 + 1];
System.arraycopy(linePositions, 0, newData, 0, linePositions.length);
linePositions = newData;
}
ensurePositionSpace(instruction);
linePositions[instruction] = getCurrentPosition();
}
private void ensurePositionSpace(int instruction) {
if (linePositions.length < (instruction + 1)) {
Position[] newData = new Position[instruction * 2 + 1];
Position[][] newOperands = new Position[instruction * 2 + 1][];
System.arraycopy(linePositions, 0, newData, 0, linePositions.length);
linePositions = newData;
System.arraycopy(operandPositions, 0, newOperands, 0, operandPositions.length);
operandPositions = newOperands;
}
}
public void noteOperands(int instruction, Position... operands) {
ensurePositionSpace(instruction);
operandPositions[instruction] = operands;
}
public void addInstruction(SSAInstruction n) {
deadBlocks.remove(currentBlock);
@ -1087,7 +1113,7 @@ public abstract class AstTranslator extends CAstVisitor<AstTranslator.WalkContex
currentBlock.setFirstIndex(inst);
} else {
for(SSAInstruction priorInst : currentBlock.instructions()) {
assert ! (priorInst instanceof SSAGotoInstruction);
assert !(priorInst instanceof SSAGotoInstruction);
}
assert !(n instanceof SSAGetCaughtExceptionInstruction);
}
@ -1118,6 +1144,10 @@ public abstract class AstTranslator extends CAstVisitor<AstTranslator.WalkContex
}
return sb.toString();
}
public Position[][] getOperandPositionMap() {
return operandPositions;
}
}
/**
@ -3310,6 +3340,7 @@ public abstract class AstTranslator extends CAstVisitor<AstTranslator.WalkContex
Map<IBasicBlock<SSAInstruction>,TypeReference[]> catchTypes = functionContext.getCatchTypes();
AstCFG cfg = new AstCFG(n, functionContext.cfg(), symtab, insts);
Position[] line = functionContext.cfg().getLinePositionMap();
Position[][] operand = functionContext.cfg().getOperandPositionMap();
boolean katch = functionContext.cfg().hasCatchBlock();
boolean monitor = functionContext.cfg().hasMonitorOp();
String[] nms = makeNameMap(n, functionContext.entityScopes(), cfg.getInstructions());
@ -3328,7 +3359,7 @@ public abstract class AstTranslator extends CAstVisitor<AstTranslator.WalkContex
functionContext.exposeNameSet(n, true),
functionContext.getAccesses(n));
DebuggingInformation DBG = new AstDebuggingInformation(n.getPosition(), line, nms);
DebuggingInformation DBG = new AstDebuggingInformation(n.getPosition(), line, operand, nms);
// actually make code body
defineFunction(n, parentContext, cfg, symtab, katch, catchTypes, monitor, LI, DBG);
@ -3669,10 +3700,12 @@ public abstract class AstTranslator extends CAstVisitor<AstTranslator.WalkContex
boolean mayBeInteger = handleBinaryOpThrow(n, n.getChild(0), context);
int currentInstruction = context.cfg().currentInstruction;
context.cfg().addInstruction(
insts.BinaryOpInstruction(context.cfg().currentInstruction, translateBinaryOpcode(n.getChild(0)), false, false, result, c.getValue(l), c.getValue(r),
insts.BinaryOpInstruction(currentInstruction, translateBinaryOpcode(n.getChild(0)), false, false, result, c.getValue(l), c.getValue(r),
mayBeInteger));
context.cfg().noteOperands(currentInstruction, context.getSourceMap().getPosition(l), context.getSourceMap().getPosition(r));
if (mayBeInteger) {
context.cfg().newBlock(true);
}
@ -3691,7 +3724,9 @@ public abstract class AstTranslator extends CAstVisitor<AstTranslator.WalkContex
WalkContext context = c;
int result = c.getValue(n);
CAstNode v = n.getChild(1);
context.cfg().addInstruction(insts.UnaryOpInstruction(context.cfg().currentInstruction, translateUnaryOpcode(n.getChild(0)), result, c.getValue(v)));
int currentInstruction = context.cfg().currentInstruction;
context.cfg().addInstruction(insts.UnaryOpInstruction(currentInstruction, translateUnaryOpcode(n.getChild(0)), result, c.getValue(v)));
context.cfg().noteOperands(currentInstruction, context.getSourceMap().getPosition(v));
}
@Override
@ -3706,8 +3741,11 @@ public abstract class AstTranslator extends CAstVisitor<AstTranslator.WalkContex
protected void leaveArrayLength(CAstNode n, WalkContext c, CAstVisitor<WalkContext> visitor) {
WalkContext context = c;
int result = c.getValue(n);
int arrayValue = c.getValue(n.getChild(0));
context.cfg().addInstruction(insts.ArrayLengthInstruction(context.cfg().currentInstruction, result, arrayValue));
CAstNode arrayExpr = n.getChild(0);
int arrayValue = c.getValue(arrayExpr);
int currentInstruction = context.cfg().currentInstruction;
context.cfg().addInstruction(insts.ArrayLengthInstruction(currentInstruction, result, arrayValue));
context.cfg().noteOperands(currentInstruction, context.getSourceMap().getPosition(arrayExpr));
}
@Override
@ -3760,10 +3798,13 @@ public abstract class AstTranslator extends CAstVisitor<AstTranslator.WalkContex
@Override
protected void leaveReturn(CAstNode n, WalkContext c, CAstVisitor<WalkContext> visitor) {
WalkContext context = c;
int currentInstruction = context.cfg().currentInstruction;
if (n.getChildCount() > 0) {
context.cfg().addInstruction(insts.ReturnInstruction(context.cfg().currentInstruction, c.getValue(n.getChild(0)), false));
CAstNode returnExpr = n.getChild(0);
context.cfg().addInstruction(insts.ReturnInstruction(currentInstruction, c.getValue(returnExpr), false));
context.cfg().noteOperands(currentInstruction, context.getSourceMap().getPosition(returnExpr));
} else {
context.cfg().addInstruction(insts.ReturnInstruction(context.cfg().currentInstruction));
context.cfg().addInstruction(insts.ReturnInstruction(currentInstruction));
}
context.cfg().addPreNode(n, context.getUnwindState());
@ -3779,14 +3820,21 @@ public abstract class AstTranslator extends CAstVisitor<AstTranslator.WalkContex
@Override
protected void leaveIfgoto(CAstNode n, WalkContext c, CAstVisitor<WalkContext> visitor) {
WalkContext context = c;
int currentInstruction = context.cfg().currentInstruction;
if (n.getChildCount() == 1) {
CAstNode arg = n.getChild(0);
context.cfg().addInstruction(
insts.ConditionalBranchInstruction(context.cfg().currentInstruction, translateConditionOpcode(CAstOperator.OP_NE), null, c.getValue(n.getChild(0)), context
insts.ConditionalBranchInstruction(currentInstruction, translateConditionOpcode(CAstOperator.OP_NE), null, c.getValue(arg), context
.currentScope().getConstantValue(new Integer(0)), -1));
context.cfg().noteOperands(currentInstruction, context.getSourceMap().getPosition(arg));
} else if (n.getChildCount() == 3) {
CAstNode op = n.getChild(0);
CAstNode leftExpr = n.getChild(1);
CAstNode rightExpr = n.getChild(2);
context.cfg().addInstruction(
insts.ConditionalBranchInstruction(context.cfg().currentInstruction, translateConditionOpcode(n.getChild(0)), null, c.getValue(n.getChild(1)),
c.getValue(n.getChild(2)), -1));
insts.ConditionalBranchInstruction(currentInstruction, translateConditionOpcode(op), null, c.getValue(leftExpr),
c.getValue(rightExpr), -1));
context.cfg().noteOperands(currentInstruction, context.getSourceMap().getPosition(leftExpr), context.getSourceMap().getPosition(rightExpr));
} else {
Assertions.UNREACHABLE();
}
@ -3838,16 +3886,21 @@ public abstract class AstTranslator extends CAstVisitor<AstTranslator.WalkContex
// conditional
CAstNode l = n.getChild(0);
visitor.visit(l, context, visitor);
int currentInstruction = context.cfg().getCurrentInstruction();
context.cfg().addInstruction(
insts.ConditionalBranchInstruction(context.cfg().currentInstruction, translateConditionOpcode(CAstOperator.OP_EQ), null, c.getValue(l), context.currentScope()
insts.ConditionalBranchInstruction(currentInstruction, translateConditionOpcode(CAstOperator.OP_EQ), null, c.getValue(l), context.currentScope()
.getConstantValue(new Integer(0)), -1));
context.cfg().noteOperands(currentInstruction, context.getSourceMap().getPosition(l));
PreBasicBlock srcB = context.cfg().getCurrentBlock();
// true clause
context.cfg().newBlock(true);
CAstNode r = n.getChild(1);
visitor.visit(r, context, visitor);
if (isExpr)
context.cfg().addInstruction(new AssignInstruction(context.cfg().currentInstruction, c.getValue(n), c.getValue(r)));
if (isExpr) {
currentInstruction = context.cfg().getCurrentInstruction();
context.cfg().addInstruction(new AssignInstruction(currentInstruction, c.getValue(n), c.getValue(r)));
context.cfg().noteOperands(currentInstruction, context.getSourceMap().getPosition(r));
}
if (n.getChildCount() == 3) {
if (!context.cfg().isDeadBlock(context.cfg().getCurrentBlock())) {
context.cfg().addInstruction(insts.GotoInstruction(context.cfg().currentInstruction, -1));
@ -3861,8 +3914,11 @@ public abstract class AstTranslator extends CAstVisitor<AstTranslator.WalkContex
CAstNode f = n.getChild(2);
context.cfg().deadBlocks.remove(falseB);
visitor.visit(f, context, visitor);
if (isExpr)
context.cfg().addInstruction(new AssignInstruction(context.cfg().currentInstruction, c.getValue(n), c.getValue(f)));
if (isExpr) {
currentInstruction = context.cfg().currentInstruction;
context.cfg().addInstruction(new AssignInstruction(currentInstruction, c.getValue(n), c.getValue(f)));
context.cfg().noteOperands(currentInstruction, context.getSourceMap().getPosition(f));
}
}
// end
@ -4027,9 +4083,11 @@ public abstract class AstTranslator extends CAstVisitor<AstTranslator.WalkContex
boolean mayBeInteger = handleBinaryOpThrow(a, op, context);
int currentInstruction = context.cfg().getCurrentInstruction();
context.cfg().addInstruction(
insts.BinaryOpInstruction(context.cfg().currentInstruction, translateBinaryOpcode(op), false, false, temp2, temp, rval, mayBeInteger));
insts.BinaryOpInstruction(currentInstruction, translateBinaryOpcode(op), false, false, temp2, temp, rval, mayBeInteger));
context.cfg().noteOperands(currentInstruction, context.getSourceMap().getPosition(a.getChild(0)), context.getSourceMap().getPosition(v));
if (mayBeInteger) {
context.cfg().newBlock(true);
}
@ -4166,7 +4224,9 @@ public abstract class AstTranslator extends CAstVisitor<AstTranslator.WalkContex
if (!pre) {
int ret = context.currentScope().allocateTempValue();
context.cfg().addInstruction(new AssignInstruction(context.cfg().currentInstruction, ret, temp));
int currentInstruction = context.cfg().getCurrentInstruction();
context.cfg().addInstruction(new AssignInstruction(currentInstruction, ret, temp));
context.cfg().noteOperands(currentInstruction, context.getSourceMap().getPosition(n.getChild(0)));
c.setValue(n, ret);
}
@ -4232,7 +4292,9 @@ public abstract class AstTranslator extends CAstVisitor<AstTranslator.WalkContex
int defaultBlock = context.cfg().getCurrentBlock().getGraphNodeId() + 1;
context.cfg().addInstruction(insts.SwitchInstruction(context.cfg().currentInstruction, v, defaultBlock, casesAndLabels));
int currentInstruction = context.cfg().getCurrentInstruction();
context.cfg().addInstruction(insts.SwitchInstruction(currentInstruction, v, defaultBlock, casesAndLabels));
context.cfg().noteOperands(currentInstruction, context.getSourceMap().getPosition(switchValue));
context.cfg().addPreNode(n, context.getUnwindState());
// PreBasicBlock switchB = context.cfg().getCurrentBlock();
context.cfg().newBlock(true);
@ -4278,8 +4340,10 @@ public abstract class AstTranslator extends CAstVisitor<AstTranslator.WalkContex
for (Object x : caseLabels) {
if (x != CAstControlFlowMap.SWITCH_DEFAULT) {
visitor.visit((CAstNode) x, context, visitor);
int currentInstruction = context.cfg().getCurrentInstruction();
context.cfg().addInstruction(
insts.ConditionalBranchInstruction(context.cfg().currentInstruction, translateConditionOpcode(CAstOperator.OP_EQ), null, v, context.getValue((CAstNode) x), -1));
insts.ConditionalBranchInstruction(currentInstruction, translateConditionOpcode(CAstOperator.OP_EQ), null, v, context.getValue((CAstNode) x), -1));
context.cfg().noteOperands(currentInstruction, context.getSourceMap().getPosition(switchValue), context.getSourceMap().getPosition((CAstNode)x));
labelToBlock.put(x, context.cfg().getCurrentBlock());
context.cfg().newBlock(true);
}
@ -4501,13 +4565,16 @@ public abstract class AstTranslator extends CAstVisitor<AstTranslator.WalkContex
protected void leaveAssert(CAstNode n, WalkContext c, CAstVisitor<WalkContext> visitor) {
WalkContext context = c;
boolean fromSpec = true;
int result = c.getValue(n.getChild(0));
CAstNode assertion = n.getChild(0);
int result = c.getValue(assertion);
if (n.getChildCount() == 2) {
assert n.getChild(1).getKind() == CAstNode.CONSTANT;
assert n.getChild(1).getValue() instanceof Boolean;
fromSpec = n.getChild(1).getValue().equals(Boolean.TRUE);
}
context.cfg().addInstruction(new AstAssertInstruction(context.cfg().currentInstruction, result, fromSpec));
int currentInstruction = context.cfg().currentInstruction;
context.cfg().addInstruction(new AstAssertInstruction(currentInstruction, result, fromSpec));
context.cfg().noteOperands(currentInstruction, context.getSourceMap().getPosition(assertion));
}
@Override
@ -4519,7 +4586,9 @@ public abstract class AstTranslator extends CAstVisitor<AstTranslator.WalkContex
protected void leaveEachElementGet(CAstNode n, WalkContext c, CAstVisitor<WalkContext> visitor) {
int result = c.currentScope().allocateTempValue();
c.setValue(n, result);
c.cfg().addInstruction(new EachElementGetInstruction(c.cfg().currentInstruction, result, c.getValue(n.getChild(0)), c.getValue(n.getChild(1))));
int currentInstruction = c.cfg().getCurrentInstruction();
c.cfg().addInstruction(new EachElementGetInstruction(currentInstruction, result, c.getValue(n.getChild(0)), c.getValue(n.getChild(1))));
c.cfg().noteOperands(currentInstruction, c.getSourceMap().getPosition(n.getChild(0)), c.getSourceMap().getPosition(n.getChild(1)));
}
@Override
@ -4531,7 +4600,9 @@ public abstract class AstTranslator extends CAstVisitor<AstTranslator.WalkContex
protected void leaveEachElementHasNext(CAstNode n, WalkContext c, CAstVisitor<WalkContext> visitor) {
int result = c.currentScope().allocateTempValue();
c.setValue(n, result);
c.cfg().addInstruction(new EachElementHasNextInstruction(c.cfg().currentInstruction, result, c.getValue(n.getChild(0)), c.getValue(n.getChild(1))));
int currentInstruction = c.cfg().getCurrentInstruction();
c.cfg().addInstruction(new EachElementHasNextInstruction(currentInstruction, result, c.getValue(n.getChild(0)), c.getValue(n.getChild(1))));
c.cfg().noteOperands(currentInstruction, c.getSourceMap().getPosition(n.getChild(0)), c.getSourceMap().getPosition(n.getChild(1)));
}
@Override
@ -4561,11 +4632,14 @@ public abstract class AstTranslator extends CAstVisitor<AstTranslator.WalkContex
@Override
protected void leaveIsDefinedExpr(CAstNode n, WalkContext c, CAstVisitor<WalkContext> visitor) {
WalkContext wc = c;
int ref = c.getValue(n.getChild(0));
CAstNode refExpr = n.getChild(0);
int ref = c.getValue(refExpr);
int result = wc.currentScope().allocateTempValue();
c.setValue(n, result);
if (n.getChildCount() == 1) {
wc.cfg().addInstruction(new AstIsDefinedInstruction(wc.cfg().currentInstruction, result, ref));
int currentInstruction = wc.cfg().getCurrentInstruction();
wc.cfg().addInstruction(new AstIsDefinedInstruction(currentInstruction, result, ref));
wc.cfg().noteOperands(currentInstruction, wc.getSourceMap().getPosition(refExpr));
} else {
doIsFieldDefined(wc, result, ref, n.getChild(1));
}
@ -4581,11 +4655,15 @@ public abstract class AstTranslator extends CAstVisitor<AstTranslator.WalkContex
WalkContext wc = c;
int rvals[] = new int[n.getChildCount()];
Position rposs[] = new Position[n.getChildCount()];
for (int i = 0; i < n.getChildCount(); i++) {
rvals[i] = c.getValue(n.getChild(i));
rposs[i] = c.getSourceMap().getPosition(n.getChild(i));
}
wc.cfg().addInstruction(new AstEchoInstruction(wc.cfg().currentInstruction, rvals));
int currentInstruction = wc.cfg().getCurrentInstruction();
wc.cfg().addInstruction(new AstEchoInstruction(currentInstruction, rvals));
wc.cfg().noteOperands(currentInstruction, rposs);
}
public CAstEntity getIncludedEntity(CAstNode n) {

View File

@ -50,6 +50,8 @@ public abstract class AstMethod implements IMethod {
String[][] getSourceNamesForValues();
Position getOperandPosition(int instructionOffset, int operand);
}
/**