KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > jode > decompiler > DeadCodeAnalysis


1 /* DeadCodeAnalysis Copyright (C) 1999-2002 Jochen Hoenicke.
2  *
3  * This program is free software; you can redistribute it and/or modify
4  * it under the terms of the GNU Lesser General Public License as published by
5  * the Free Software Foundation; either version 2, or (at your option)
6  * any later version.
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  * GNU General Public License for more details.
12  *
13  * You should have received a copy of the GNU Lesser General Public License
14  * along with this program; see the file COPYING.LESSER. If not, write to
15  * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
16  *
17  * $Id: DeadCodeAnalysis.java.in,v 4.1.2.1 2002/05/28 17:34:03 hoenicke Exp $
18  */

19
20 package jode.decompiler;
21 import jode.bytecode.BytecodeInfo;
22 import jode.bytecode.Instruction;
23 import jode.bytecode.Handler;
24
25 import java.util.Iterator JavaDoc;
26
27 public class DeadCodeAnalysis {
28
29     private final static String JavaDoc REACHABLE = "R";
30     private final static String JavaDoc REACHCHANGED = "C";
31
32     private static void propagateReachability(BytecodeInfo code) {
33     boolean changed;
34     do {
35         changed = false;
36         for (Iterator JavaDoc iter = code.getInstructions().iterator();
37          iter.hasNext(); ) {
38         Instruction instr = (Instruction) iter.next();
39         if (instr.getTmpInfo() == REACHCHANGED) {
40             changed = true;
41             instr.setTmpInfo(REACHABLE);
42             Instruction[] succs = instr.getSuccs();
43             if (succs != null)
44             for (int i=0; i< succs.length; i++)
45                 if (succs[i].getTmpInfo() == null)
46                 succs[i].setTmpInfo(REACHCHANGED);
47             if (!instr.doesAlwaysJump()
48             && instr.getNextByAddr() != null)
49             if (instr.getNextByAddr().getTmpInfo() == null)
50                 instr.getNextByAddr().setTmpInfo(REACHCHANGED);
51             /*XXX code after jsr reachable iff ret is reachable...*/
52             if (instr.getOpcode() == Opcodes.opc_jsr)
53             if (instr.getNextByAddr().getTmpInfo() == null)
54                 instr.getNextByAddr().setTmpInfo(REACHCHANGED);
55         }
56         }
57     } while (changed);
58     }
59
60     public static void removeDeadCode(BytecodeInfo code) {
61     ((Instruction) code.getInstructions().get(0)).setTmpInfo(REACHCHANGED);
62     propagateReachability(code);
63     Handler[] handlers = code.getExceptionHandlers();
64     boolean changed;
65     do {
66         changed = false;
67         for (int i=0; i < handlers.length; i++) {
68         if (handlers[i].catcher.getTmpInfo() == null) {
69             /* check if the try block is somewhere reachable
70              * and mark the catcher as reachable then.
71              */

72             for (Instruction instr = handlers[i].start;
73              instr != null; instr = instr.getNextByAddr()) {
74             if (instr.getTmpInfo() != null) {
75                 handlers[i].catcher.setTmpInfo(REACHCHANGED);
76                 propagateReachability(code);
77                 changed = true;
78                 break;
79             }
80             if (instr == handlers[i].end)
81                 break;
82             }
83         }
84         }
85     } while (changed);
86
87     for (int i=0; i< handlers.length; i++) {
88         /* A handler is not reachable iff the catcher is not reachable */
89         if (handlers[i].catcher.getTmpInfo() == null) {
90         /* This is very seldom, so we can make it slow */
91         Handler[] newHandlers = new Handler[handlers.length - 1];
92         System.arraycopy(handlers, 0, newHandlers, 0, i);
93         System.arraycopy(handlers, i+1, newHandlers, i,
94                  handlers.length - (i+1));
95         handlers = newHandlers;
96         code.setExceptionHandlers(newHandlers);
97         i--;
98         } else {
99         /* This works! */
100         while (handlers[i].start.getTmpInfo() == null)
101             handlers[i].start = handlers[i].start.getNextByAddr();
102         while (handlers[i].end.getTmpInfo() == null)
103             handlers[i].end = handlers[i].end.getPrevByAddr();
104         }
105     }
106
107     /* Now remove the dead code and clean up tmpInfo */
108     for (Iterator JavaDoc i = code.getInstructions().iterator(); i.hasNext(); ) {
109         Instruction instr = (Instruction) i.next();
110         if (instr.getTmpInfo() != null)
111         instr.setTmpInfo(null);
112         else
113         i.remove();
114     }
115     }
116 }
117
Popular Tags