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;
         }