From f5431c3bb14854025dc1f0ec470b77497f79494c Mon Sep 17 00:00:00 2001 From: Roman Shevchenko Date: Fri, 29 Aug 2014 21:58:12 +0400 Subject: java-decompiler: post-import cleanup (common fixes and optimizations) --- .../java/decompiler/code/cfg/ControlFlowGraph.java | 117 +++++++++++---------- 1 file changed, 62 insertions(+), 55 deletions(-) (limited to 'src/org/jetbrains/java/decompiler/code/cfg/ControlFlowGraph.java') diff --git a/src/org/jetbrains/java/decompiler/code/cfg/ControlFlowGraph.java b/src/org/jetbrains/java/decompiler/code/cfg/ControlFlowGraph.java index 1e395ed..44c58f0 100644 --- a/src/org/jetbrains/java/decompiler/code/cfg/ControlFlowGraph.java +++ b/src/org/jetbrains/java/decompiler/code/cfg/ControlFlowGraph.java @@ -45,9 +45,9 @@ public class ControlFlowGraph implements CodeConstants { private List exceptions; - private HashMap subroutines; + private Map subroutines; - private HashSet finallyExits = new HashSet(); + private Set finallyExits = new HashSet(); // ***************************************************************************** // constructors @@ -85,16 +85,16 @@ public class ControlFlowGraph implements CodeConstants { String new_line_separator = DecompilerContext.getNewLineSeparator(); - StringBuffer buf = new StringBuffer(); + StringBuilder buf = new StringBuilder(); for (BasicBlock block : blocks) { - buf.append("----- Block " + block.id + " -----" + new_line_separator); + buf.append("----- Block ").append(block.id).append(" -----").append(new_line_separator); buf.append(block.toString()); - buf.append("----- Edges -----" + new_line_separator); + buf.append("----- Edges -----").append(new_line_separator); List suc = block.getSuccs(); for (int j = 0; j < suc.size(); j++) { - buf.append(">>>>>>>>(regular) Block " + suc.get(j).id + new_line_separator); + buf.append(">>>>>>>>(regular) Block ").append(suc.get(j).id).append(new_line_separator); } suc = block.getSuccExceptions(); for (int j = 0; j < suc.size(); j++) { @@ -102,21 +102,22 @@ public class ControlFlowGraph implements CodeConstants { ExceptionRangeCFG range = getExceptionRange(handler, block); if (range == null) { - buf.append(">>>>>>>>(exception) Block " + handler.id + "\t" + "ERROR: range not found!" + new_line_separator); + buf.append(">>>>>>>>(exception) Block ").append(handler.id).append("\t").append("ERROR: range not found!") + .append(new_line_separator); } else { List exceptionTypes = range.getExceptionTypes(); if (exceptionTypes == null) { - buf.append(">>>>>>>>(exception) Block " + handler.id + "\t" + "NULL" + new_line_separator); + buf.append(">>>>>>>>(exception) Block ").append(handler.id).append("\t").append("NULL").append(new_line_separator); } else { for (String exceptionType : exceptionTypes) { - buf.append(">>>>>>>>(exception) Block " + handler.id + "\t" + exceptionType + new_line_separator); + buf.append(">>>>>>>>(exception) Block ").append(handler.id).append("\t").append(exceptionType).append(new_line_separator); } } } } - buf.append("----- ----- -----" + new_line_separator); + buf.append("----- ----- -----").append(new_line_separator); } return buf.toString(); @@ -223,7 +224,7 @@ public class ControlFlowGraph implements CodeConstants { short[] states = findStartInstructions(instrseq); - HashMap mapInstrBlocks = new HashMap(); + Map mapInstrBlocks = new HashMap(); VBStyleCollection colBlocks = createBasicBlocks(states, instrseq, mapInstrBlocks); blocks = colBlocks; @@ -237,12 +238,12 @@ public class ControlFlowGraph implements CodeConstants { setFirstAndLastBlocks(); } - private short[] findStartInstructions(InstructionSequence seq) { + private static short[] findStartInstructions(InstructionSequence seq) { int len = seq.length(); short[] inststates = new short[len]; - HashSet excSet = new HashSet(); + Set excSet = new HashSet(); for (ExceptionHandler handler : seq.getExceptionTable().getHandlers()) { excSet.add(handler.from_instr); @@ -287,8 +288,9 @@ public class ControlFlowGraph implements CodeConstants { } - private VBStyleCollection createBasicBlocks(short[] startblock, InstructionSequence instrseq, - HashMap mapInstrBlocks) { + private VBStyleCollection createBasicBlocks(short[] startblock, + InstructionSequence instrseq, + Map mapInstrBlocks) { VBStyleCollection col = new VBStyleCollection(); @@ -329,7 +331,7 @@ public class ControlFlowGraph implements CodeConstants { } - private void connectBlocks(List lstbb, HashMap mapInstrBlocks) { + private static void connectBlocks(List lstbb, Map mapInstrBlocks) { for (int i = 0; i < lstbb.size(); i++) { @@ -365,7 +367,7 @@ public class ControlFlowGraph implements CodeConstants { } } - private void setExceptionEdges(InstructionSequence instrseq, HashMap instrBlocks) { + private void setExceptionEdges(InstructionSequence instrseq, Map instrBlocks) { exceptions = new ArrayList(); @@ -404,7 +406,7 @@ public class ControlFlowGraph implements CodeConstants { private void setSubroutineEdges() { - final HashMap subroutines = new HashMap(); + final Map subroutines = new HashMap(); for (BasicBlock block : blocks) { @@ -413,7 +415,7 @@ public class ControlFlowGraph implements CodeConstants { LinkedList stack = new LinkedList(); LinkedList> stackJsrStacks = new LinkedList>(); - HashSet setVisited = new HashSet(); + Set setVisited = new HashSet(); stack.add(block); stackJsrStacks.add(new LinkedList()); @@ -461,53 +463,64 @@ public class ControlFlowGraph implements CodeConstants { } private void processJsr() { + while (true) { + if (processJsrRanges() == 0) break; + } + } + + private static class JsrRecord { + private final BasicBlock jsr; + private final Set range; + private final BasicBlock ret; - while (processJsrRanges() != 0) ; + private JsrRecord(BasicBlock jsr, Set range, BasicBlock ret) { + this.jsr = jsr; + this.range = range; + this.ret = ret; + } } private int processJsrRanges() { - List lstJsrAll = new ArrayList(); + List lstJsrAll = new ArrayList(); // get all jsr ranges for (Entry ent : subroutines.entrySet()) { BasicBlock jsr = ent.getKey(); BasicBlock ret = ent.getValue(); - lstJsrAll.add(new Object[]{jsr, getJsrRange(jsr, ret), ret}); + lstJsrAll.add(new JsrRecord(jsr, getJsrRange(jsr, ret), ret)); } // sort ranges // FIXME: better sort order - List lstJsr = new ArrayList(); - for (Object[] arr : lstJsrAll) { + List lstJsr = new ArrayList(); + for (JsrRecord arr : lstJsrAll) { int i = 0; for (; i < lstJsr.size(); i++) { - Object[] arrJsr = lstJsr.get(i); - - if (((HashSet)arrJsr[1]).contains(arr[0])) { + JsrRecord arrJsr = lstJsr.get(i); + if (arrJsr.range.contains(arr.jsr)) { break; } } - lstJsr.add(i, arr); } // find the first intersection for (int i = 0; i < lstJsr.size(); i++) { - Object[] arr = lstJsr.get(i); - HashSet set = (HashSet)arr[1]; + JsrRecord arr = lstJsr.get(i); + Set set = arr.range; for (int j = i + 1; j < lstJsr.size(); j++) { - Object[] arr1 = lstJsr.get(j); - HashSet set1 = (HashSet)arr1[1]; + JsrRecord arr1 = lstJsr.get(j); + Set set1 = arr1.range; - if (!set.contains(arr1[0]) && !set1.contains(arr[0])) { // rang 0 doesn't contain entry 1 and vice versa - HashSet setc = new HashSet(set); + if (!set.contains(arr1.jsr) && !set1.contains(arr.jsr)) { // rang 0 doesn't contain entry 1 and vice versa + Set setc = new HashSet(set); setc.retainAll(set1); if (!setc.isEmpty()) { - splitJsrRange((BasicBlock)arr[0], (BasicBlock)arr[2], setc); + splitJsrRange(arr.jsr, arr.ret, setc); return 1; } } @@ -517,11 +530,11 @@ public class ControlFlowGraph implements CodeConstants { return 0; } - private HashSet getJsrRange(BasicBlock jsr, BasicBlock ret) { + private Set getJsrRange(BasicBlock jsr, BasicBlock ret) { - HashSet blocks = new HashSet(); + Set blocks = new HashSet(); - LinkedList lstNodes = new LinkedList(); + List lstNodes = new LinkedList(); lstNodes.add(jsr); BasicBlock dom = jsr.getSuccs().get(0); @@ -581,10 +594,10 @@ public class ControlFlowGraph implements CodeConstants { return blocks; } - private void splitJsrRange(BasicBlock jsr, BasicBlock ret, HashSet common_blocks) { + private void splitJsrRange(BasicBlock jsr, BasicBlock ret, Set common_blocks) { - LinkedList lstNodes = new LinkedList(); - HashMap mapNewNodes = new HashMap(); + List lstNodes = new LinkedList(); + Map mapNewNodes = new HashMap(); lstNodes.add(jsr); mapNewNodes.put(jsr.id, jsr); @@ -662,7 +675,7 @@ public class ControlFlowGraph implements CodeConstants { splitJsrExceptionRanges(common_blocks, mapNewNodes); } - private void splitJsrExceptionRanges(HashSet common_blocks, HashMap mapNewNodes) { + private void splitJsrExceptionRanges(Set common_blocks, Map mapNewNodes) { for (int i = exceptions.size() - 1; i >= 0; i--) { @@ -696,7 +709,7 @@ public class ControlFlowGraph implements CodeConstants { removeJsrInstructions(mt.getClassStruct().getPool(), first, DataPoint.getInitialDataPoint(mt)); } - private void removeJsrInstructions(ConstantPool pool, BasicBlock block, DataPoint data) { + private static void removeJsrInstructions(ConstantPool pool, BasicBlock block, DataPoint data) { ListStack stack = data.getStack(); @@ -765,18 +778,18 @@ public class ControlFlowGraph implements CodeConstants { public List getReversePostOrder() { - LinkedList res = new LinkedList(); + List res = new LinkedList(); addToReversePostOrderListIterative(first, res); return res; } - private void addToReversePostOrderListIterative(BasicBlock root, List lst) { + private static void addToReversePostOrderListIterative(BasicBlock root, List lst) { LinkedList stackNode = new LinkedList(); LinkedList stackIndex = new LinkedList(); - HashSet setVisited = new HashSet(); + Set setVisited = new HashSet(); stackNode.add(root); stackIndex.add(0); @@ -845,32 +858,26 @@ public class ControlFlowGraph implements CodeConstants { this.exceptions = exceptions; } - public BasicBlock getLast() { return last; } - public void setLast(BasicBlock last) { this.last = last; } - - public HashMap getSubroutines() { + public Map getSubroutines() { return subroutines; } - - public void setSubroutines(HashMap subroutines) { + public void setSubroutines(Map subroutines) { this.subroutines = subroutines; } - - public HashSet getFinallyExits() { + public Set getFinallyExits() { return finallyExits; } - public void setFinallyExits(HashSet finallyExits) { this.finallyExits = finallyExits; } -- cgit v1.2.3