Mercurial > hg > icedrobot > daneel
changeset 61:818050257c69
Added JavaDoc comment to the abstract interpreter.
Reviewed-by: Remi Forax
* rewriter/Interpreter.java: Added JavaDoc throughout the code.
* (Interpreter): Use Arrays.fill() instead of loop for initialization.
author | Michael Starzinger <michi@complang.tuwien.ac.at> |
---|---|
date | Tue, 22 Mar 2011 01:20:12 +0100 |
parents | cb2a2dc8c451 |
children | 387a3d5f9695 |
files | src/main/java/org/icedrobot/daneel/rewriter/Interpreter.java |
diffstat | 1 files changed, 77 insertions(+), 5 deletions(-) [+] |
line wrap: on
line diff
--- a/src/main/java/org/icedrobot/daneel/rewriter/Interpreter.java Tue Mar 22 01:08:25 2011 +0100 +++ b/src/main/java/org/icedrobot/daneel/rewriter/Interpreter.java Tue Mar 22 01:20:12 2011 +0100 @@ -40,27 +40,58 @@ import java.util.Arrays; import java.util.HashMap; +/** + * An abstract interpreter for virtual registers. It is used to infer the + * register type information by tracking all load and store operations on them. + */ public class Interpreter { private final Register[] registers; private final HashMap<Object, Register[]> joinPointMap = new HashMap<Object, Register[]>(); private boolean isDead; + /** + * Creates a new abstract interpreter capable of tracking a given number of + * virtual registers. + * + * @param maxRegisters The number of registers to handle. + */ public Interpreter(int maxRegisters) { Register[] registers = new Register[maxRegisters]; - for (int i = 0; i < maxRegisters; i++) { - registers[i] = Register.UNINITIALIZED; - } + Arrays.fill(registers, Register.UNINITIALIZED); this.registers = registers; } + /** + * Returns the tracked register for a given register number. + * + * @param vregister The register number of a tracked register. + * @return The tracked register object. + */ public Register getRegister(int vregister) { return registers[vregister]; } + /** + * Tracks a load operation on the given register. The expected type has to + * be a concrete (non-arbitrary) type. This might trigger the register to + * change from an arbitrary to the given concrete type and in turn trigger + * operation patching. + * + * @param vregister The register number of a tracked register. + * @param expectedType The expected (non-arbitrary) type of the register. + */ public void load(int vregister, int expectedType) { registers[vregister] = registers[vregister].load(expectedType); } + /** + * Tracks a store operation on the given register. The expected type has to + * be a concrete (non-arbitrary) type. The previous content of the given + * register will be destroyed. + * + * @param vregister The register number of a tracked register. + * @param type The (non-arbitrary) type of the operation. + */ public void store(int vregister, int type) { if (Register.isArbitrary(type)) { throw new IllegalArgumentException("invalid type"); @@ -69,6 +100,16 @@ registers[vregister] = new Register(type, null); } + /** + * Tracks an arbitrary typed store operation on the given register. Since + * the operation is not yet concretely typed, the operation has to be + * "patchable" to change it's type later on. The previous content of the + * given register will be destroyed. + * + * @param vregister The register number of a tracked register. + * @param arbitraryType The (arbitrary) type of the operation. + * @param patchable The patcher to change the operation type. + */ public void storeArbitraryType(int vregister, int arbitraryType, Patchable patchable) { if (!Register.isArbitrary(arbitraryType)) { @@ -78,28 +119,59 @@ registers[vregister] = new Register(arbitraryType, patchable); } + /** + * Marks a possible join-point in the control flow. Each branch target + * (basic block boundary) is a candidate for a join-point. The current + * register information is preserved and associated with the given + * join-point identity. + * + * @param label An object identity representing the join-point. + */ public void cloneJoinPoint(Object label) { joinPointMap.put(label, registers.clone()); } + /** + * Queries a previously marked join-point in the control flow. If the given + * join-point identity hasn't been marked before, {@code null} will be + * returned. + * + * @param label An object identity representing the join-point. + * @return The register information at the join-point or {@code null}. + */ public Register[] getJoinPoint(Object label) { return joinPointMap.get(label); } + /** + * Marks all tracked registers as dead. This can be useful for code after + * unconditional branch instructions. + */ public void setDead() { this.isDead = true; } + /** + * Checks if all registers are marked as dead. + * + * @return True if all registers are dead, false otherwise. + */ public boolean isDead() { return isDead; } + /** + * Merges the current and a given set of register information. This is done + * at join-points in the control flow. It merges each register, thus + * changing each register to the most concrete type known at that point. + * + * @param registers The given set of register information. + */ public void merge(Register[] registers) { assert this.registers.length == registers.length; if (isDead) { - System.arraycopy(registers, 0, this.registers, 0, - registers.length); + System.arraycopy(registers, 0, this.registers, 0, registers.length); isDead = false; return; }