• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * ProGuard -- shrinking, optimization, obfuscation, and preverification
3  *             of Java bytecode.
4  *
5  * Copyright (c) 2002-2009 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.obfuscate;
22 
23 import proguard.classfile.*;
24 import proguard.classfile.constant.Constant;
25 import proguard.classfile.editor.ConstantPoolRemapper;
26 import proguard.classfile.visitor.ClassVisitor;
27 
28 
29 /**
30  * This ClassVisitor removes NameAndType constant pool entries
31  * that are not marked as being used.
32  *
33  * @see NameAndTypeUsageMarker
34  *
35  * @author Eric Lafortune
36  */
37 public class NameAndTypeShrinker implements ClassVisitor
38 {
39     private int[]                constantIndexMap;
40     private final ConstantPoolRemapper constantPoolRemapper = new ConstantPoolRemapper();
41 
42 
43     // Implementations for ClassVisitor.
44 
visitProgramClass(ProgramClass programClass)45     public void visitProgramClass(ProgramClass programClass)
46     {
47         // Shift the used constant pool entries together, filling out the
48         // index map.
49         programClass.u2constantPoolCount =
50             shrinkConstantPool(programClass.constantPool,
51                                programClass.u2constantPoolCount);
52 
53 
54         // Remap all constant pool references.
55         constantPoolRemapper.setConstantIndexMap(constantIndexMap);
56         constantPoolRemapper.visitProgramClass(programClass);
57     }
58 
59 
visitLibraryClass(LibraryClass libraryClass)60     public void visitLibraryClass(LibraryClass libraryClass)
61     {
62     }
63 
64 
65     // Small utility methods.
66 
67     /**
68      * Removes all NameAndType entries that are not marked as being used
69      * from the given constant pool.
70      * @return the new number of entries.
71      */
shrinkConstantPool(Constant[] constantPool, int length)72     private int shrinkConstantPool(Constant[] constantPool, int length)
73     {
74         // Create a new index map, if necessary.
75         if (constantIndexMap == null ||
76             constantIndexMap.length < length)
77         {
78             constantIndexMap = new int[length];
79         }
80 
81         int     counter = 1;
82         boolean isUsed  = false;
83 
84         // Shift the used constant pool entries together.
85         for (int index = 1; index < length; index++)
86         {
87             constantIndexMap[index] = counter;
88 
89             Constant constant = constantPool[index];
90 
91             // Don't update the flag if this is the second half of a long entry.
92             if (constant != null)
93             {
94                 isUsed = constant.getTag() != ClassConstants.CONSTANT_NameAndType ||
95                          NameAndTypeUsageMarker.isUsed(constant);
96             }
97 
98             if (isUsed)
99             {
100                 constantPool[counter++] = constant;
101             }
102         }
103 
104         // Clear the remaining constant pool elements.
105         for (int index = counter; index < length; index++)
106         {
107             constantPool[index] = null;
108         }
109 
110         return counter;
111     }
112 }
113