diff options
Diffstat (limited to 'src/main/javassist/bytecode/stackmap')
-rw-r--r-- | src/main/javassist/bytecode/stackmap/BasicBlock.java | 13 | ||||
-rw-r--r-- | src/main/javassist/bytecode/stackmap/MapMaker.java | 69 | ||||
-rw-r--r-- | src/main/javassist/bytecode/stackmap/Tracer.java | 2 |
3 files changed, 51 insertions, 33 deletions
diff --git a/src/main/javassist/bytecode/stackmap/BasicBlock.java b/src/main/javassist/bytecode/stackmap/BasicBlock.java index 6213e22a..43367307 100644 --- a/src/main/javassist/bytecode/stackmap/BasicBlock.java +++ b/src/main/javassist/bytecode/stackmap/BasicBlock.java @@ -97,6 +97,10 @@ public class BasicBlock { sbuf.append("}"); } + /** + * A Mark indicates the position of a branch instruction + * or a branch target. + */ static class Mark implements Comparable { int position; BasicBlock block; @@ -349,10 +353,11 @@ public class BasicBlock { } else { // the previous mark already has exits. - int prevPos = prev.position; - if (prevPos + prev.length < m.position) { - prev = makeBlock(prevPos + prev.length); - prev.length = m.position - prevPos; + if (prev.position + prev.length < m.position) { + // dead code is found. + prev = makeBlock(prev.position + prev.length); + blocks.add(prev); + prev.length = m.position - prev.position; // the incoming flow from dead code is not counted // bb.incoming++; prev.exit = makeArray(bb); diff --git a/src/main/javassist/bytecode/stackmap/MapMaker.java b/src/main/javassist/bytecode/stackmap/MapMaker.java index 16d3f294..b1aa7008 100644 --- a/src/main/javassist/bytecode/stackmap/MapMaker.java +++ b/src/main/javassist/bytecode/stackmap/MapMaker.java @@ -307,34 +307,63 @@ public class MapMaker extends Tracer { // Phase 1.5 /* - * Javac may generate an exception handler that catches only an exception + * Javac may generate an exception handler that catches only the exception * thrown within the handler itself. It is dead code. + * See javassist.JvstTest4.testJIRA195(). */ private void findDeadCatchers(byte[] code, TypedBlock[] blocks) throws BadBytecode { int len = blocks.length; for (int i = 0; i < len; i++) { TypedBlock block = blocks[i]; - if (block.localsTypes == null) { // if block is dead code + if (!block.alreadySet()) { + fixDeadcode(code, block); BasicBlock.Catch handler = block.toCatch; - while (handler != null) - if (handler.body == block) { - BasicBlock.Catch handler2 - = new BasicBlock.Catch(block, handler.typeIndex, null); - traceException(code, handler2); - break; + if (handler != null) { + TypedBlock tb = (TypedBlock)handler.body; + if (!tb.alreadySet()) { + // tb is a handler that catches only the exceptions + // thrown from dead code. + recordStackMap(tb, handler.typeIndex); + fixDeadcode(code, tb); + tb.incoming = 1; } - else - handler = handler.next; + } + } } } + private void fixDeadcode(byte[] code, TypedBlock block) throws BadBytecode { + int pos = block.position; + int len = block.length - 3; + if (len < 0) { + // if the dead-code length is shorter than 3 bytes. + if (len == -1) + code[pos] = Bytecode.NOP; + + code[pos + block.length - 1] = (byte)Bytecode.ATHROW; + block.incoming = 1; + recordStackMap(block, 0); + return; + } + + // if block.incomping > 0, all the incoming edges are from + // other dead code blocks. So set block.incoming to 0. + block.incoming = 0; + + for (int k = 0; k < len; k++) + code[pos + k] = Bytecode.NOP; + + code[pos + len] = (byte)Bytecode.GOTO; + ByteArray.write16bit(-len, code, pos + len + 1); + } + // Phase 2 /* * This method first finds strongly connected components (SCCs) - * on a graph made by TypeData by Tarjan's algorithm. + * in a TypeData graph by Tarjan's algorithm. * SCCs are TypeData nodes sharing the same type. * Since SCCs are found in the topologically sorted order, * their types are also fixed when they are found. @@ -345,9 +374,7 @@ public class MapMaker extends Tracer { int index = 0; for (int i = 0; i < len; i++) { TypedBlock block = blocks[i]; - if (block.localsTypes == null) // if block is dead code - fixDeadcode(code, block); - else { + if (block.alreadySet()) { // if block is not dead code int n = block.localsTypes.length; for (int j = 0; j < n; j++) index = block.localsTypes[j].dfs(preOrder, index, classPool); @@ -359,20 +386,6 @@ public class MapMaker extends Tracer { } } - private void fixDeadcode(byte[] code, TypedBlock block) throws BadBytecode { - int pos = block.position; - int len = block.length - 3; - if (len < 0) - throw new BadBytecode("dead code detected at " + pos - + ". No stackmap table generated."); - - for (int k = 0; k < len; k++) - code[pos + k] = Bytecode.NOP; - - code[pos + len] = (byte)Bytecode.GOTO; - ByteArray.write16bit(-len, code, pos + len + 1); - } - // Phase 3 public StackMapTable toStackMap(TypedBlock[] blocks) { diff --git a/src/main/javassist/bytecode/stackmap/Tracer.java b/src/main/javassist/bytecode/stackmap/Tracer.java index e5216165..4111d589 100644 --- a/src/main/javassist/bytecode/stackmap/Tracer.java +++ b/src/main/javassist/bytecode/stackmap/Tracer.java @@ -81,7 +81,7 @@ public abstract class Tracer implements TypeTag { return doOpcode148_201(pos, code, op); } catch (ArrayIndexOutOfBoundsException e) { - throw new BadBytecode("inconsistent stack height " + e.getMessage()); + throw new BadBytecode("inconsistent stack height " + e.getMessage(), e); } } |