KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > proguard > optimize > peephole > UnreachableCodeRemover


1 /*
2  * ProGuard -- shrinking, optimization, obfuscation, and preverification
3  * of Java bytecode.
4  *
5  * Copyright (c) 2002-2007 Eric Lafortune (eric@graphics.cornell.edu)
6  *
7  * This program is free software; you can redistribute it and/or modify it
8  * under the terms of the GNU General Public License as published by the Free
9  * Software Foundation; either version 2 of the License, or (at your option)
10  * any later version.
11  *
12  * This program is distributed in the hope that it will be useful, but WITHOUT
13  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
15  * more details.
16  *
17  * You should have received a copy of the GNU General Public License along
18  * with this program; if not, write to the Free Software Foundation, Inc.,
19  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20  */

21 package proguard.optimize.peephole;
22
23 import proguard.classfile.*;
24 import proguard.classfile.visitor.ClassPrinter;
25 import proguard.classfile.attribute.*;
26 import proguard.classfile.attribute.visitor.AttributeVisitor;
27 import proguard.classfile.editor.CodeAttributeEditor;
28 import proguard.classfile.instruction.*;
29 import proguard.classfile.instruction.visitor.InstructionVisitor;
30 import proguard.classfile.util.SimplifiedVisitor;
31
32 /**
33  * This InstructionVisitor deletes blocks of code that can never be reached by
34  * regular calls or branches.
35  *
36  * @author Eric Lafortune
37  */

38 public class UnreachableCodeRemover
39 extends SimplifiedVisitor
40 implements AttributeVisitor,
41              InstructionVisitor
42 {
43     //*
44
private static final boolean DEBUG = false;
45     /*/
46     private static boolean DEBUG = true;
47     //*/

48
49     private InstructionVisitor extraInstructionVisitor;
50
51     private ReachableCodeMarker reachableCodeMarker = new ReachableCodeMarker();
52     private CodeAttributeEditor codeAttributeEditor = new CodeAttributeEditor();
53
54
55     /**
56      * Creates a new UnreachableCodeRemover.
57      */

58     public UnreachableCodeRemover()
59     {
60         this(null);
61     }
62
63
64     /**
65      * Creates a new UnreachableCodeRemover.
66      * @param extraInstructionVisitor an optional extra visitor for all
67      * deleted instructions.
68      */

69     public UnreachableCodeRemover(InstructionVisitor extraInstructionVisitor)
70     {
71         this.extraInstructionVisitor = extraInstructionVisitor;
72     }
73
74
75     // Implementations for AttributeVisitor.
76

77     public void visitAnyAttribute(Clazz clazz, Attribute attribute) {}
78
79
80     public void visitCodeAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute)
81     {
82 // DEBUG =
83
// clazz.getName().equals("abc/Def") &&
84
// method.getName(clazz).equals("abc");
85

86         // TODO: Remove this when the code has stabilized.
87
// Catch any unexpected exceptions from the actual visiting method.
88
try
89         {
90             // Process the code.
91
visitCodeAttribute0(clazz, method, codeAttribute);
92         }
93         catch (RuntimeException JavaDoc ex)
94         {
95             System.err.println("Unexpected error while removing unreachable code:");
96             System.err.println(" Class = ["+clazz.getName()+"]");
97             System.err.println(" Method = ["+method.getName(clazz)+method.getDescriptor(clazz)+"]");
98             System.err.println(" Exception = ["+ex.getClass().getName()+"] ("+ex.getMessage()+")");
99
100             throw ex;
101         }
102     }
103
104
105     public void visitCodeAttribute0(Clazz clazz, Method method, CodeAttribute codeAttribute)
106     {
107         if (DEBUG)
108         {
109             System.out.println("UnreachableCodeRemover: "+clazz.getName()+"."+method.getName(clazz)+method.getDescriptor(clazz));
110         }
111
112         reachableCodeMarker.visitCodeAttribute(clazz, method, codeAttribute);
113
114         codeAttributeEditor.reset(codeAttribute.u4codeLength);
115
116         codeAttribute.instructionsAccept(clazz, method, this);
117
118         codeAttributeEditor.visitCodeAttribute(clazz, method, codeAttribute);
119     }
120
121
122     // Implementations for InstructionVisitor.
123

124     public void visitAnyInstruction(Clazz clazz, Method method, CodeAttribute codeAttribute, int offset, Instruction instruction)
125     {
126         if (DEBUG)
127         {
128             System.out.println(" "+(reachableCodeMarker.isReachable(offset) ? "+" : "-")+" "+instruction.toString(offset));
129         }
130
131         // Is this instruction unreachable?
132
if (!reachableCodeMarker.isReachable(offset))
133         {
134             // Then delete it.
135
codeAttributeEditor.deleteInstruction(offset);
136
137             // Visit the instruction, if required.
138
if (extraInstructionVisitor != null)
139             {
140                 instruction.accept(clazz, method, codeAttribute, offset, extraInstructionVisitor);
141             }
142         }
143     }
144 }
145
Popular Tags