OSDN Git Service

f17385ef2691e864d6314a73b48f1fe97bc131a0
[stigmata/stigmata-plugins.git] / wsp / src / main / java / jp / sourceforge / stigmata / birthmarks / wsp / OpcodeWeightCalculatePreprocessor.java
1 package jp.sourceforge.stigmata.birthmarks.wsp;
2
3 /*
4  * $Id$
5  */
6
7 import java.io.IOException;
8 import java.io.InputStream;
9 import java.util.ArrayList;
10 import java.util.HashMap;
11 import java.util.List;
12 import java.util.Map;
13
14 import jp.sourceforge.stigmata.BirthmarkContext;
15 import jp.sourceforge.stigmata.birthmarks.AbstractBirthmarkPreprocessor;
16 import jp.sourceforge.stigmata.digger.ClassFileArchive;
17 import jp.sourceforge.stigmata.digger.ClassFileEntry;
18 import jp.sourceforge.stigmata.spi.BirthmarkSpi;
19
20 import org.objectweb.asm.ClassAdapter;
21 import org.objectweb.asm.ClassReader;
22 import org.objectweb.asm.ClassWriter;
23 import org.objectweb.asm.MethodVisitor;
24
25 /**
26  * 
27  * @author Haruaki Tamada
28  * @version $Revision$
29  */
30 public class OpcodeWeightCalculatePreprocessor extends AbstractBirthmarkPreprocessor{
31     public OpcodeWeightCalculatePreprocessor(BirthmarkSpi spi){
32         super(spi);
33     }
34
35     @Override
36     public void preprocess(ClassFileArchive[] targets, BirthmarkContext context){
37         Map<Integer, Integer> targetMap = new HashMap<Integer, Integer>();
38
39         int classCount = readOpcodes(targets, targetMap);
40
41         Map<Integer, Integer> weights = new HashMap<Integer, Integer>();
42         for(Map.Entry<Integer, Integer> entry: targetMap.entrySet()){
43             int opcode = entry.getKey();
44             Integer count = entry.getValue();
45             int c = 0;
46             if(count != null){
47                 c = count;
48             }
49
50             weights.put(opcode, (int)Math.log(classCount / c));
51         }
52
53         context.putProperty("birthmarks.wsp.weights", weights);
54     }
55
56     private int readOpcodes(ClassFileArchive[] targets, Map<Integer, Integer> targetMap){
57         int count = 0;
58         for(ClassFileArchive archive: targets){
59             for(ClassFileEntry entry: archive){
60                 count++;
61                 final List<Opcode> opcodes = new ArrayList<Opcode>();
62                 try{
63                     InputStream in = entry.getLocation().openStream();
64
65                     ClassReader reader = new ClassReader(in);
66                     ClassWriter writer = new ClassWriter(false);
67                     ClassAdapter opcodeExtractVisitor = new ClassAdapter(writer){
68                         @Override
69                         public MethodVisitor visitMethod(int arg0, String arg1, String arg2, String arg3, String[] arg4){
70                             OpcodeExtractionMethodVisitor visitor =
71                                 new OpcodeExtractionMethodVisitor(super.visitMethod(arg0, arg1, arg2, arg3, arg4), opcodes);
72                             return visitor;
73                         }
74                     };
75                     reader.accept(opcodeExtractVisitor, false);
76
77                     for(Opcode opcode: opcodes){
78                         if(opcode.getCategory() != Opcode.Category.TARGETER){
79                             Integer i = targetMap.get(opcode.getOpcode());
80                             if(i == null){
81                                 i = 0;
82                             }
83                             i = i + 1;
84                             targetMap.put(opcode.getOpcode(), i);
85                         }
86                     }
87
88                 } catch(IOException e){
89                 }
90             }
91         }
92         return count;
93     }
94 }