Mercurial > hg > truffle
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