Home | History | Annotate | Download | only in optimize
      1 /*
      2  * ProGuard -- shrinking, optimization, obfuscation, and preverification
      3  *             of Java bytecode.
      4  *
      5  * Copyright (c) 2002-2014 Eric Lafortune (eric (at) 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;
     22 
     23 import proguard.classfile.*;
     24 import proguard.classfile.attribute.*;
     25 import proguard.classfile.attribute.annotation.*;
     26 import proguard.classfile.attribute.preverification.*;
     27 import proguard.classfile.attribute.visitor.AttributeVisitor;
     28 import proguard.classfile.util.ClassUtil;
     29 
     30 /**
     31  * This AttributeVisitor delegates its call to another AttributeVisitor, and
     32  * prints out the code if the other visitor has changed it.
     33  *
     34  * @author Eric Lafortune
     35  */
     36 public class ChangedCodePrinter
     37 implements   AttributeVisitor
     38 {
     39     private final AttributeVisitor attributeVisitor;
     40 
     41 
     42     public ChangedCodePrinter(AttributeVisitor attributeVisitor)
     43     {
     44         this.attributeVisitor = attributeVisitor;
     45     }
     46 
     47 
     48     // Implementations for AttributeVisitor.
     49 
     50     public void visitUnknownAttribute(Clazz clazz, UnknownAttribute unknownAttribute)
     51     {
     52         attributeVisitor.visitUnknownAttribute(clazz, unknownAttribute);
     53     }
     54 
     55 
     56     public void visitBootstrapMethodsAttribute(Clazz clazz, BootstrapMethodsAttribute bootstrapMethodsAttribute)
     57     {
     58         attributeVisitor.visitBootstrapMethodsAttribute(clazz, bootstrapMethodsAttribute);
     59     }
     60 
     61 
     62     public void visitSourceFileAttribute(Clazz clazz, SourceFileAttribute sourceFileAttribute)
     63     {
     64         attributeVisitor.visitSourceFileAttribute(clazz, sourceFileAttribute);
     65     }
     66 
     67 
     68     public void visitSourceDirAttribute(Clazz clazz, SourceDirAttribute sourceDirAttribute)
     69     {
     70         attributeVisitor.visitSourceDirAttribute(clazz, sourceDirAttribute);
     71     }
     72 
     73 
     74     public void visitInnerClassesAttribute(Clazz clazz, InnerClassesAttribute innerClassesAttribute)
     75     {
     76         attributeVisitor.visitInnerClassesAttribute(clazz, innerClassesAttribute);
     77     }
     78 
     79 
     80     public void visitEnclosingMethodAttribute(Clazz clazz, EnclosingMethodAttribute enclosingMethodAttribute)
     81     {
     82         attributeVisitor.visitEnclosingMethodAttribute(clazz, enclosingMethodAttribute);
     83     }
     84 
     85 
     86     public void visitDeprecatedAttribute(Clazz clazz, DeprecatedAttribute deprecatedAttribute)
     87     {
     88         attributeVisitor.visitDeprecatedAttribute(clazz, deprecatedAttribute);
     89     }
     90 
     91 
     92     public void visitSyntheticAttribute(Clazz clazz, SyntheticAttribute syntheticAttribute)
     93     {
     94         attributeVisitor.visitSyntheticAttribute(clazz, syntheticAttribute);
     95     }
     96 
     97 
     98     public void visitSignatureAttribute(Clazz clazz, SignatureAttribute syntheticAttribute)
     99     {
    100         attributeVisitor.visitSignatureAttribute(clazz, syntheticAttribute);
    101     }
    102 
    103 
    104     public void visitDeprecatedAttribute(Clazz clazz, Field field, DeprecatedAttribute deprecatedAttribute)
    105     {
    106         attributeVisitor.visitDeprecatedAttribute(clazz, field, deprecatedAttribute);
    107     }
    108 
    109 
    110     public void visitSyntheticAttribute(Clazz clazz, Field field, SyntheticAttribute syntheticAttribute)
    111     {
    112         attributeVisitor.visitSyntheticAttribute(clazz, field, syntheticAttribute);
    113     }
    114 
    115 
    116     public void visitSignatureAttribute(Clazz clazz, Field field, SignatureAttribute syntheticAttribute)
    117     {
    118         attributeVisitor.visitSignatureAttribute(clazz, field, syntheticAttribute);
    119     }
    120 
    121 
    122     public void visitDeprecatedAttribute(Clazz clazz, Method method, DeprecatedAttribute deprecatedAttribute)
    123     {
    124         attributeVisitor.visitDeprecatedAttribute(clazz, method, deprecatedAttribute);
    125     }
    126 
    127 
    128     public void visitSyntheticAttribute(Clazz clazz, Method method, SyntheticAttribute syntheticAttribute)
    129     {
    130         attributeVisitor.visitSyntheticAttribute(clazz, method, syntheticAttribute);
    131     }
    132 
    133 
    134     public void visitSignatureAttribute(Clazz clazz, Method method, SignatureAttribute syntheticAttribute)
    135     {
    136         attributeVisitor.visitSignatureAttribute(clazz, method, syntheticAttribute);
    137     }
    138 
    139 
    140     public void visitConstantValueAttribute(Clazz clazz, Field field, ConstantValueAttribute constantValueAttribute)
    141     {
    142         attributeVisitor.visitConstantValueAttribute(clazz, field, constantValueAttribute);
    143     }
    144 
    145 
    146     public void visitMethodParametersAttribute(Clazz clazz, Method method, MethodParametersAttribute exceptionsAttribute)
    147     {
    148         attributeVisitor.visitMethodParametersAttribute(clazz, method, exceptionsAttribute);
    149     }
    150 
    151 
    152     public void visitExceptionsAttribute(Clazz clazz, Method method, ExceptionsAttribute exceptionsAttribute)
    153     {
    154         attributeVisitor.visitExceptionsAttribute(clazz, method, exceptionsAttribute);
    155     }
    156 
    157 
    158     public void visitStackMapAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute, StackMapAttribute stackMapAttribute)
    159     {
    160         attributeVisitor.visitStackMapAttribute(clazz, method, codeAttribute, stackMapAttribute);
    161     }
    162 
    163 
    164     public void visitStackMapTableAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute, StackMapTableAttribute stackMapTableAttribute)
    165     {
    166         attributeVisitor.visitStackMapTableAttribute(clazz, method, codeAttribute, stackMapTableAttribute);
    167     }
    168 
    169 
    170     public void visitLineNumberTableAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute, LineNumberTableAttribute lineNumberTableAttribute)
    171     {
    172         attributeVisitor.visitLineNumberTableAttribute(clazz, method, codeAttribute, lineNumberTableAttribute);
    173     }
    174 
    175 
    176     public void visitLocalVariableTableAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute, LocalVariableTableAttribute localVariableTableAttribute)
    177     {
    178         attributeVisitor.visitLocalVariableTableAttribute(clazz, method, codeAttribute, localVariableTableAttribute);
    179     }
    180 
    181 
    182     public void visitLocalVariableTypeTableAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute, LocalVariableTypeTableAttribute localVariableTypeTableAttribute)
    183     {
    184         attributeVisitor.visitLocalVariableTypeTableAttribute(clazz, method, codeAttribute, localVariableTypeTableAttribute);
    185     }
    186 
    187 
    188     public void visitRuntimeVisibleAnnotationsAttribute(Clazz clazz, RuntimeVisibleAnnotationsAttribute runtimeVisibleAnnotationsAttribute)
    189     {
    190         attributeVisitor.visitRuntimeVisibleAnnotationsAttribute(clazz, runtimeVisibleAnnotationsAttribute);
    191     }
    192 
    193 
    194     public void visitRuntimeInvisibleAnnotationsAttribute(Clazz clazz, RuntimeInvisibleAnnotationsAttribute runtimeInvisibleAnnotationsAttribute)
    195     {
    196         attributeVisitor.visitRuntimeInvisibleAnnotationsAttribute(clazz, runtimeInvisibleAnnotationsAttribute);
    197     }
    198 
    199 
    200     public void visitRuntimeVisibleAnnotationsAttribute(Clazz clazz, Field field, RuntimeVisibleAnnotationsAttribute runtimeVisibleAnnotationsAttribute)
    201     {
    202         attributeVisitor.visitRuntimeVisibleAnnotationsAttribute(clazz, field, runtimeVisibleAnnotationsAttribute);
    203     }
    204 
    205 
    206     public void visitRuntimeInvisibleAnnotationsAttribute(Clazz clazz, Field field, RuntimeInvisibleAnnotationsAttribute runtimeInvisibleAnnotationsAttribute)
    207     {
    208         attributeVisitor.visitRuntimeInvisibleAnnotationsAttribute(clazz, field, runtimeInvisibleAnnotationsAttribute);
    209     }
    210 
    211 
    212     public void visitRuntimeVisibleAnnotationsAttribute(Clazz clazz, Method method, RuntimeVisibleAnnotationsAttribute runtimeVisibleAnnotationsAttribute)
    213     {
    214         attributeVisitor.visitRuntimeVisibleAnnotationsAttribute(clazz, method, runtimeVisibleAnnotationsAttribute);
    215     }
    216 
    217 
    218     public void visitRuntimeInvisibleAnnotationsAttribute(Clazz clazz, Method method, RuntimeInvisibleAnnotationsAttribute runtimeInvisibleAnnotationsAttribute)
    219     {
    220         attributeVisitor.visitRuntimeInvisibleAnnotationsAttribute(clazz, method, runtimeInvisibleAnnotationsAttribute);
    221     }
    222 
    223 
    224     public void visitRuntimeVisibleParameterAnnotationsAttribute(Clazz clazz, Method method, RuntimeVisibleParameterAnnotationsAttribute runtimeVisibleParameterAnnotationsAttribute)
    225     {
    226         attributeVisitor.visitRuntimeVisibleParameterAnnotationsAttribute(clazz, method, runtimeVisibleParameterAnnotationsAttribute);
    227     }
    228 
    229 
    230     public void visitRuntimeInvisibleParameterAnnotationsAttribute(Clazz clazz, Method method, RuntimeInvisibleParameterAnnotationsAttribute runtimeInvisibleParameterAnnotationsAttribute)
    231     {
    232         attributeVisitor.visitRuntimeInvisibleParameterAnnotationsAttribute(clazz, method, runtimeInvisibleParameterAnnotationsAttribute);
    233     }
    234 
    235 
    236     public void visitRuntimeVisibleTypeAnnotationsAttribute(Clazz clazz, RuntimeVisibleTypeAnnotationsAttribute runtimeVisibleTypeAnnotationsAttribute)
    237     {
    238         attributeVisitor.visitRuntimeVisibleTypeAnnotationsAttribute(clazz, runtimeVisibleTypeAnnotationsAttribute);
    239     }
    240 
    241 
    242     public void visitRuntimeVisibleTypeAnnotationsAttribute(Clazz clazz, Field field, RuntimeVisibleTypeAnnotationsAttribute runtimeVisibleTypeAnnotationsAttribute)
    243     {
    244         attributeVisitor.visitRuntimeVisibleTypeAnnotationsAttribute(clazz, field, runtimeVisibleTypeAnnotationsAttribute);
    245     }
    246 
    247 
    248     public void visitRuntimeVisibleTypeAnnotationsAttribute(Clazz clazz, Method method, RuntimeVisibleTypeAnnotationsAttribute runtimeVisibleTypeAnnotationsAttribute)
    249     {
    250         attributeVisitor.visitRuntimeVisibleTypeAnnotationsAttribute(clazz, method, runtimeVisibleTypeAnnotationsAttribute);
    251     }
    252 
    253 
    254     public void visitRuntimeVisibleTypeAnnotationsAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute, RuntimeVisibleTypeAnnotationsAttribute runtimeVisibleTypeAnnotationsAttribute)
    255     {
    256         attributeVisitor.visitRuntimeVisibleTypeAnnotationsAttribute(clazz, method, codeAttribute, runtimeVisibleTypeAnnotationsAttribute);
    257     }
    258 
    259 
    260     public void visitRuntimeInvisibleTypeAnnotationsAttribute(Clazz clazz, RuntimeInvisibleTypeAnnotationsAttribute runtimeInvisibleTypeAnnotationsAttribute)
    261     {
    262         attributeVisitor.visitRuntimeInvisibleTypeAnnotationsAttribute(clazz, runtimeInvisibleTypeAnnotationsAttribute);
    263     }
    264 
    265 
    266     public void visitRuntimeInvisibleTypeAnnotationsAttribute(Clazz clazz, Field field, RuntimeInvisibleTypeAnnotationsAttribute runtimeInvisibleTypeAnnotationsAttribute)
    267     {
    268         attributeVisitor.visitRuntimeInvisibleTypeAnnotationsAttribute(clazz, field, runtimeInvisibleTypeAnnotationsAttribute);
    269     }
    270 
    271 
    272     public void visitRuntimeInvisibleTypeAnnotationsAttribute(Clazz clazz, Method method, RuntimeInvisibleTypeAnnotationsAttribute runtimeInvisibleTypeAnnotationsAttribute)
    273     {
    274         attributeVisitor.visitRuntimeInvisibleTypeAnnotationsAttribute(clazz, method, runtimeInvisibleTypeAnnotationsAttribute);
    275     }
    276 
    277 
    278     public void visitRuntimeInvisibleTypeAnnotationsAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute, RuntimeInvisibleTypeAnnotationsAttribute runtimeInvisibleTypeAnnotationsAttribute)
    279     {
    280         attributeVisitor.visitRuntimeInvisibleTypeAnnotationsAttribute(clazz, method, codeAttribute, runtimeInvisibleTypeAnnotationsAttribute);
    281     }
    282 
    283 
    284     public void visitAnnotationDefaultAttribute(Clazz clazz, Method method, AnnotationDefaultAttribute annotationDefaultAttribute)
    285     {
    286         attributeVisitor.visitAnnotationDefaultAttribute(clazz, method, annotationDefaultAttribute);
    287     }
    288 
    289 
    290     public void visitCodeAttribute(Clazz clazz, Method method, CodeAttribute codeAttribute)
    291     {
    292         byte[] code    = codeAttribute.code;
    293         byte[] oldCode = new byte[code.length];
    294 
    295         // Copy the current code.
    296         System.arraycopy(code, 0, oldCode, 0, codeAttribute.u4codeLength);
    297 
    298         // Delegate to the real visitor.
    299         attributeVisitor.visitCodeAttribute(clazz, method, codeAttribute);
    300 
    301         // Check if the code has changed.
    302         if (codeHasChanged(codeAttribute, oldCode))
    303         {
    304             printChangedCode(clazz, method, codeAttribute, oldCode);
    305         }
    306     }
    307 
    308 
    309     // Small utility methods.
    310 
    311     private boolean codeHasChanged(CodeAttribute codeAttribute, byte[] oldCode)
    312     {
    313         if (oldCode.length != codeAttribute.u4codeLength)
    314         {
    315             return true;
    316         }
    317 
    318         for (int index = 0; index < codeAttribute.u4codeLength; index++)
    319         {
    320             if (oldCode[index] != codeAttribute.code[index])
    321             {
    322                 return true;
    323             }
    324         }
    325 
    326         return false;
    327     }
    328 
    329 
    330     private void printChangedCode(Clazz         clazz,
    331                                   Method        method,
    332                                   CodeAttribute codeAttribute,
    333                                   byte[]        oldCode)
    334     {
    335         System.out.println("Class "+ClassUtil.externalClassName(clazz.getName()));
    336         System.out.println("Method "+ClassUtil.externalFullMethodDescription(clazz.getName(),
    337                                                                              0,
    338                                                                              method.getName(clazz),
    339                                                                              method.getDescriptor(clazz)));
    340 
    341         for (int index = 0; index < codeAttribute.u4codeLength; index++)
    342         {
    343             System.out.println(
    344                 (oldCode[index] == codeAttribute.code[index]? "  -- ":"  => ")+
    345                 index+": "+
    346                 Integer.toHexString(0x100|oldCode[index]           &0xff).substring(1)+" "+
    347                 Integer.toHexString(0x100|codeAttribute.code[index]&0xff).substring(1));
    348         }
    349     }
    350 }
    351