void setCGed(ThreadInfo ti, Instruction insn) { ti = null; // Remove IDE warning about unused variable. // Hmm, we have to store the bb set at this point BitSet bb = getBasicBlocks(); Instruction next = insn.getNext(); if (next != null) { // insn might be a sync return bb.set(next.getInstructionIndex()); } }
BitSet getBasicBlocks() { if (basicBlocks == null) { Instruction[] code = mi.getInstructions(); BitSet bb = new BitSet(code.length); bb.set(0); // first insn is always a bb start // first, look at the insn type for (int i = 0; i < code.length; i++) { Instruction insn = code[i]; if (insn instanceof IfInstruction) { IfInstruction ifInsn = (IfInstruction) insn; Instruction tgt = ifInsn.getTarget(); bb.set(tgt.getInstructionIndex()); tgt = ifInsn.getNext(); bb.set(tgt.getInstructionIndex()); } else if (insn instanceof GOTO) { Instruction tgt = ((GOTO) insn).getTarget(); bb.set(tgt.getInstructionIndex()); } else if (insn instanceof InvokeInstruction) { // hmm, this might be a bit too conservative, but who says we // don't jump out of a caller into a handler, or even that we // ever return from the call? Instruction tgt = insn.getNext(); bb.set(tgt.getInstructionIndex()); } } // and now look at the handlers (every first insn is a bb start) ExceptionHandler[] handlers = mi.getExceptions(); if (handlers != null) { for (int i = 0; i < handlers.length; i++) { Instruction tgt = mi.getInstructionAt(handlers[i].getHandler()); bb.set(tgt.getInstructionIndex()); } } basicBlocks = bb; /** dump * System.out.println(); * System.out.println(mi.getFullName()); * for (int i=0; i<code.length; i++) { * System.out.print(String.format("%1$2d %2$c ",i, bb.get(i) ? '>' : ' ')); * System.out.println(code[i]); * } **/ } return basicBlocks; }