changeset 5031:4d152e5e34ba

Use BytecodeStream in BciBlockMapping instead of hand-crafted byte-array accesses
author Christian Wimmer <Christian.Wimmer@Oracle.com>
date Mon, 05 Mar 2012 18:22:31 -0800
parents f4fb1af02e4c
children e2de9649f0a9 b4f548d49f96
files graal/com.oracle.max.graal.java/src/com/oracle/max/graal/java/BciBlockMapping.java graal/com.oracle.max.graal.java/src/com/oracle/max/graal/java/GraphBuilderPhase.java graal/com.oracle.max.graal.java/src/com/oracle/max/graal/java/bytecode/BytecodeLookupSwitch.java graal/com.oracle.max.graal.java/src/com/oracle/max/graal/java/bytecode/BytecodeStream.java graal/com.oracle.max.graal.java/src/com/oracle/max/graal/java/bytecode/BytecodeSwitch.java graal/com.oracle.max.graal.java/src/com/oracle/max/graal/java/bytecode/BytecodeTableSwitch.java graal/com.oracle.max.graal.java/src/com/oracle/max/graal/java/bytecode/Bytecodes.java
diffstat 7 files changed, 79 insertions(+), 165 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.max.graal.java/src/com/oracle/max/graal/java/BciBlockMapping.java	Mon Mar 05 17:36:34 2012 -0800
+++ b/graal/com.oracle.max.graal.java/src/com/oracle/max/graal/java/BciBlockMapping.java	Mon Mar 05 18:22:31 2012 -0800
@@ -268,11 +268,12 @@
         // iterate over the bytecodes top to bottom.
         // mark the entrypoints of basic blocks and build lists of successors for
         // all bytecodes that end basic blocks (i.e. goto, ifs, switches, throw, jsr, returns, ret)
-        byte[] code = method.code();
         RiProfilingInfo profilingInfo = method.profilingInfo();
         Block current = null;
-        int bci = 0;
-        while (bci < code.length) {
+        stream.setBCI(0);
+        while (stream.currentBC() != Bytecodes.END) {
+            int bci = stream.currentBCI();
+
             if (current == null || blockMap[bci] != null) {
                 Block b = makeBlock(bci);
                 if (current != null) {
@@ -283,8 +284,7 @@
             blockMap[bci] = current;
             current.endBci = bci;
 
-            int opcode = Bytes.beU1(code, bci);
-            switch (opcode) {
+            switch (stream.currentBC()) {
                 case IRETURN: // fall through
                 case LRETURN: // fall through
                 case FRETURN: // fall through
@@ -316,41 +316,37 @@
                 case IFNULL:    // fall through
                 case IFNONNULL: {
                     current = null;
-                    Block b1 = makeBlock(bci + Bytes.beS2(code, bci + 1));
-                    Block b2 = makeBlock(bci + 3);
-                    setSuccessors(bci, b1, b2);
+                    setSuccessors(bci, makeBlock(stream.readBranchDest()), makeBlock(stream.nextBCI()));
                     break;
                 }
                 case GOTO:
                 case GOTO_W: {
                     current = null;
-                    int target = bci + Bytes.beSVar(code, bci + 1, opcode == GOTO_W);
-                    Block b1 = makeBlock(target);
-                    setSuccessors(bci, b1);
+                    setSuccessors(bci, makeBlock(stream.readBranchDest()));
                     break;
                 }
                 case TABLESWITCH: {
                     current = null;
-                    BytecodeTableSwitch sw = new BytecodeTableSwitch(code, bci);
+                    BytecodeTableSwitch sw = new BytecodeTableSwitch(stream, bci);
                     setSuccessors(bci, makeSwitchSuccessors(sw));
                     break;
                 }
                 case LOOKUPSWITCH: {
                     current = null;
-                    BytecodeLookupSwitch sw = new BytecodeLookupSwitch(code, bci);
+                    BytecodeLookupSwitch sw = new BytecodeLookupSwitch(stream, bci);
                     setSuccessors(bci, makeSwitchSuccessors(sw));
                     break;
                 }
                 case JSR:
                 case JSR_W: {
                     hasJsrBytecodes = true;
-                    int target = bci + Bytes.beSVar(code, bci + 1, opcode == JSR_W);
+                    int target = stream.readBranchDest();
                     if (target == 0) {
                         throw new JsrNotSupportedBailout("jsr target bci 0 not allowed");
                     }
                     Block b1 = makeBlock(target);
                     current.jsrSuccessor = b1;
-                    current.jsrReturnBci = bci + lengthOf(opcode);
+                    current.jsrReturnBci = stream.nextBCI();
                     current = null;
                     setSuccessors(bci, b1);
                     break;
@@ -360,66 +356,42 @@
                     current = null;
                     break;
                 }
-                case WIDE: {
-                    int opcode2 = Bytes.beU1(code, bci);
-                    switch (opcode2) {
-                        case RET: {
-                            current.endsWithRet = true;
-                            current = null;
-                            break;
-                        }
-                    }
-                    break;
-                }
                 case INVOKEINTERFACE:
                 case INVOKESPECIAL:
                 case INVOKESTATIC:
                 case INVOKEVIRTUAL: {
                     current = null;
-                    int target = bci + lengthOf(code, bci);
-                    Block b1 = makeBlock(target);
-                    setSuccessors(bci, b1);
+                    setSuccessors(bci, makeBlock(stream.nextBCI()));
                     canTrap.set(bci);
                     break;
                 }
-                default: {
-                    if (canTrap(opcode, bci, profilingInfo)) {
+                case IASTORE:
+                case LASTORE:
+                case FASTORE:
+                case DASTORE:
+                case AASTORE:
+                case BASTORE:
+                case CASTORE:
+                case SASTORE:
+                case IALOAD:
+                case LALOAD:
+                case FALOAD:
+                case DALOAD:
+                case AALOAD:
+                case BALOAD:
+                case CALOAD:
+                case SALOAD:
+                case PUTFIELD:
+                case GETFIELD: {
+                    if (GraalOptions.AllowExplicitExceptionChecks && profilingInfo.getExceptionSeen(bci) != RiExceptionSeen.FALSE) {
                         canTrap.set(bci);
                     }
                 }
             }
-            bci += lengthOf(code, bci);
+            stream.next();
         }
     }
 
-    private static boolean canTrap(int opcode, int bci, RiProfilingInfo profilingInfo) {
-        switch (opcode) {
-            case IASTORE:
-            case LASTORE:
-            case FASTORE:
-            case DASTORE:
-            case AASTORE:
-            case BASTORE:
-            case CASTORE:
-            case SASTORE:
-            case IALOAD:
-            case LALOAD:
-            case FALOAD:
-            case DALOAD:
-            case AALOAD:
-            case BALOAD:
-            case CALOAD:
-            case SALOAD:
-            case PUTFIELD:
-            case GETFIELD: {
-                if (GraalOptions.AllowExplicitExceptionChecks) {
-                    return profilingInfo.getExceptionSeen(bci) != RiExceptionSeen.FALSE;
-                }
-            }
-        }
-        return false;
-    }
-
     private Block makeBlock(int startBci) {
         Block oldBlock = blockMap[startBci];
         if (oldBlock == null) {
--- a/graal/com.oracle.max.graal.java/src/com/oracle/max/graal/java/GraphBuilderPhase.java	Mon Mar 05 17:36:34 2012 -0800
+++ b/graal/com.oracle.max.graal.java/src/com/oracle/max/graal/java/GraphBuilderPhase.java	Mon Mar 05 18:22:31 2012 -0800
@@ -1723,7 +1723,7 @@
             case IFNULL         : genIfNull(Condition.EQ); break;
             case IFNONNULL      : genIfNull(Condition.NE); break;
             case GOTO_W         : genGoto(); break;
-            case JSR_W          : genJsr(stream.readFarBranchDest()); break;
+            case JSR_W          : genJsr(stream.readBranchDest()); break;
             case BREAKPOINT:
                 throw new CiBailout("concurrent setting of breakpoint");
             default:
--- a/graal/com.oracle.max.graal.java/src/com/oracle/max/graal/java/bytecode/BytecodeLookupSwitch.java	Mon Mar 05 17:36:34 2012 -0800
+++ b/graal/com.oracle.max.graal.java/src/com/oracle/max/graal/java/bytecode/BytecodeLookupSwitch.java	Mon Mar 05 18:22:31 2012 -0800
@@ -40,33 +40,24 @@
         super(stream, bci);
     }
 
-    /**
-     * Constructor for a bytecode array.
-     * @param code the bytecode array containing the switch instruction.
-     * @param bci the index in the array of the switch instruction
-     */
-    public BytecodeLookupSwitch(byte[] code, int bci) {
-        super(code, bci);
-    }
-
     @Override
     public int defaultOffset() {
-        return readWord(alignedBci);
+        return stream.readInt(alignedBci);
     }
 
     @Override
     public int offsetAt(int i) {
-        return readWord(alignedBci + OFFSET_TO_FIRST_PAIR_OFFSET + PAIR_SIZE * i);
+        return stream.readInt(alignedBci + OFFSET_TO_FIRST_PAIR_OFFSET + PAIR_SIZE * i);
     }
 
     @Override
     public int keyAt(int i) {
-        return readWord(alignedBci + OFFSET_TO_FIRST_PAIR_MATCH + PAIR_SIZE * i);
+        return stream.readInt(alignedBci + OFFSET_TO_FIRST_PAIR_MATCH + PAIR_SIZE * i);
     }
 
     @Override
     public int numberOfCases() {
-        return readWord(alignedBci + OFFSET_TO_NUMBER_PAIRS);
+        return stream.readInt(alignedBci + OFFSET_TO_NUMBER_PAIRS);
     }
 
     @Override
--- a/graal/com.oracle.max.graal.java/src/com/oracle/max/graal/java/bytecode/BytecodeStream.java	Mon Mar 05 17:36:34 2012 -0800
+++ b/graal/com.oracle.max.graal.java/src/com/oracle/max/graal/java/bytecode/BytecodeStream.java	Mon Mar 05 18:22:31 2012 -0800
@@ -120,16 +120,11 @@
      */
     public int readBranchDest() {
         // reads the destination for a branch bytecode
-        return curBCI + Bytes.beS2(code, curBCI + 1);
-    }
-
-    /**
-     * Read the destination of a {@link Bytecodes#GOTO_W} or {@link Bytecodes#JSR_W} instructions.
-     * @return the destination bytecode index
-     */
-    public int readFarBranchDest() {
-        // reads the destination for a wide branch bytecode
-        return curBCI + Bytes.beS4(code, curBCI + 1);
+        if (opcode == Bytecodes.GOTO_W || opcode == Bytecodes.JSR_W) {
+            return curBCI + Bytes.beS4(code, curBCI + 1);
+        } else {
+            return curBCI + Bytes.beS2(code, curBCI + 1);
+        }
     }
 
     /**
@@ -188,10 +183,40 @@
         curBCI = bci;
         if (curBCI < code.length) {
             opcode = Bytes.beU1(code, bci);
-            nextBCI = bci + Bytecodes.lengthOf(code, bci);
+            nextBCI = bci + lengthOf();
         } else {
             opcode = Bytecodes.END;
             nextBCI = curBCI;
         }
     }
+
+    /**
+     * Gets the length of the current bytecode.
+     */
+    private int lengthOf() {
+        int length = Bytecodes.lengthOf(opcode);
+        if (length == 0) {
+            switch (opcode) {
+                case Bytecodes.TABLESWITCH: {
+                    return new BytecodeTableSwitch(this, curBCI).size();
+                }
+                case Bytecodes.LOOKUPSWITCH: {
+                    return new BytecodeLookupSwitch(this, curBCI).size();
+                }
+                case Bytecodes.WIDE: {
+                    int opc = Bytes.beU1(code, curBCI + 1);
+                    if (opc == Bytecodes.RET) {
+                        return 4;
+                    } else if (opc == Bytecodes.IINC) {
+                        return 6;
+                    } else {
+                        return 4; // a load or store bytecode
+                    }
+                }
+                default:
+                    throw new Error("unknown variable-length bytecode: " + opcode);
+            }
+        }
+        return length;
+    }
 }
--- a/graal/com.oracle.max.graal.java/src/com/oracle/max/graal/java/bytecode/BytecodeSwitch.java	Mon Mar 05 17:36:34 2012 -0800
+++ b/graal/com.oracle.max.graal.java/src/com/oracle/max/graal/java/bytecode/BytecodeSwitch.java	Mon Mar 05 18:22:31 2012 -0800
@@ -28,13 +28,9 @@
  */
 public abstract class BytecodeSwitch {
     /**
-     * The {@link BytecodeStream} containing bytecode array or {@code null} if {@link #code} is not {@code null}.
+     * The {@link BytecodeStream} containing the bytecode array.
      */
-    private final BytecodeStream stream;
-    /**
-     * The bytecode array or {@code null} if {@link #stream} is not {@code null}.
-     */
-    private final byte[] code;
+    protected final BytecodeStream stream;
     /**
      * Index of start of switch instruction.
      */
@@ -50,22 +46,9 @@
      * @param bci the index in the stream of the switch instruction
      */
     public BytecodeSwitch(BytecodeStream stream, int bci) {
-        this.alignedBci = (bci + 4) & 0xfffffffc;
         this.stream = stream;
-        this.code = null;
         this.bci = bci;
-    }
-
-    /**
-     * Constructor for a bytecode array.
-     * @param code the bytecode array containing the switch instruction.
-     * @param bci the index in the array of the switch instruction
-     */
-    public BytecodeSwitch(byte[] code, int bci) {
         this.alignedBci = (bci + 4) & 0xfffffffc;
-        this.stream = null;
-        this.code = code;
-        this.bci = bci;
     }
 
     /**
@@ -124,16 +107,4 @@
      * @return the total size in bytes of the switch instruction
      */
     public abstract int size();
-
-    /**
-     * Reads the signed value at given bytecode index.
-     * @param readBci the start index of the value to retrieve
-     * @return the signed, 4-byte value in the bytecode array starting at {@code bci}
-     */
-    protected int readWord(int readBci) {
-        if (code != null) {
-            return Bytes.beS4(code, readBci);
-        }
-        return stream.readInt(readBci);
-    }
 }
--- a/graal/com.oracle.max.graal.java/src/com/oracle/max/graal/java/bytecode/BytecodeTableSwitch.java	Mon Mar 05 17:36:34 2012 -0800
+++ b/graal/com.oracle.max.graal.java/src/com/oracle/max/graal/java/bytecode/BytecodeTableSwitch.java	Mon Mar 05 18:22:31 2012 -0800
@@ -41,20 +41,11 @@
     }
 
     /**
-     * Constructor for a bytecode array.
-     * @param code the bytecode array containing the switch instruction.
-     * @param bci the index in the array of the switch instruction
-     */
-    public BytecodeTableSwitch(byte[] code, int bci) {
-        super(code, bci);
-    }
-
-    /**
      * Gets the low key of the table switch.
      * @return the low key
      */
     public int lowKey() {
-        return readWord(alignedBci + OFFSET_TO_LOW_KEY);
+        return stream.readInt(alignedBci + OFFSET_TO_LOW_KEY);
     }
 
     /**
@@ -62,7 +53,7 @@
      * @return the high key
      */
     public int highKey() {
-        return readWord(alignedBci + OFFSET_TO_HIGH_KEY);
+        return stream.readInt(alignedBci + OFFSET_TO_HIGH_KEY);
     }
 
     @Override
@@ -72,12 +63,12 @@
 
     @Override
     public int defaultOffset() {
-        return readWord(alignedBci);
+        return stream.readInt(alignedBci);
     }
 
     @Override
     public int offsetAt(int i) {
-        return readWord(alignedBci + OFFSET_TO_FIRST_JUMP_OFFSET + JUMP_OFFSET_SIZE * i);
+        return stream.readInt(alignedBci + OFFSET_TO_FIRST_JUMP_OFFSET + JUMP_OFFSET_SIZE * i);
     }
 
     @Override
--- a/graal/com.oracle.max.graal.java/src/com/oracle/max/graal/java/bytecode/Bytecodes.java	Mon Mar 05 17:36:34 2012 -0800
+++ b/graal/com.oracle.max.graal.java/src/com/oracle/max/graal/java/bytecode/Bytecodes.java	Mon Mar 05 18:22:31 2012 -0800
@@ -591,42 +591,6 @@
     }
 
     /**
-     * Gets the length of an instruction at a given position in a given bytecode array.
-     * This methods handles variable length and {@linkplain #WIDE widened} instructions.
-     *
-     * @param code an array of bytecode
-     * @param bci the position in {@code code} of an instruction's opcode
-     * @return the length of the instruction at position {@code bci} in {@code code}
-     */
-    public static int lengthOf(byte[] code, int bci) {
-        int opcode = Bytes.beU1(code, bci);
-        int length = Bytecodes.lengthArray[opcode & 0xff];
-        if (length == 0) {
-            switch (opcode) {
-                case TABLESWITCH: {
-                    return new BytecodeTableSwitch(code, bci).size();
-                }
-                case LOOKUPSWITCH: {
-                    return new BytecodeLookupSwitch(code, bci).size();
-                }
-                case WIDE: {
-                    int opc = Bytes.beU1(code, bci + 1);
-                    if (opc == RET) {
-                        return 4;
-                    } else if (opc == IINC) {
-                        return 6;
-                    } else {
-                        return 4; // a load or store bytecode
-                    }
-                }
-                default:
-                    throw new Error("unknown variable-length bytecode: " + opcode);
-            }
-        }
-        return length;
-    }
-
-    /**
      * Gets the compilation complexity for a given opcode.
      * @param opcode an opcode
      * @return a value >= 0