package jp.sourceforge.stigmata.birthmarks.wsp;
+/*
+ * $Id$
+ */
+
+/**
+ *
+ * @author Haruaki Tamada
+ * @version $Revision$
+ */
public class CurrentDepth{
private Opcode opcode;
private int depth;
private String name;
private int argumentCount;
private int act;
+ private int weight;
private Category category;
private List<Label> labels = new ArrayList<Label>();
this.category = category;
}
+ Opcode(int opcode, String name, int argumentCount, int act, Category category, int weight){
+ this(opcode, name, argumentCount, act, category);
+ setWeight(weight);
+ }
+
public int getOpcode(){
return opcode;
}
public Category getCategory(){
return category;
}
+
+ public void setWeight(int weight){
+ this.weight = weight;
+ }
+
+ public int getWeight(){
+ return weight;
+ }
}
*/
import jp.sourceforge.stigmata.Birthmark;
+import jp.sourceforge.stigmata.BirthmarkContext;
import jp.sourceforge.stigmata.birthmarks.comparators.AbstractBirthmarkComparator;
import jp.sourceforge.stigmata.spi.BirthmarkSpi;
}
@Override
- public double compare(Birthmark b1, Birthmark b2){
+ public double compare(Birthmark b1, Birthmark b2, BirthmarkContext context){
// TODO implement this method.
return 0;
}
import java.util.Map;
import jp.sourceforge.stigmata.Birthmark;
+import jp.sourceforge.stigmata.BirthmarkContext;
import jp.sourceforge.stigmata.BirthmarkElement;
-import jp.sourceforge.stigmata.BirthmarkEnvironment;
import jp.sourceforge.stigmata.ExtractionUnit;
import jp.sourceforge.stigmata.birthmarks.ASMBirthmarkExtractor;
import jp.sourceforge.stigmata.birthmarks.BirthmarkExtractVisitor;
}
@Override
- public BirthmarkExtractVisitor createExtractVisitor(ClassWriter writer, Birthmark birthmark, BirthmarkEnvironment environment){
- return new Visitor(writer, birthmark, environment);
+ public BirthmarkExtractVisitor createExtractVisitor(ClassWriter writer, Birthmark birthmark, BirthmarkContext context){
+ return new Visitor(writer, birthmark, context);
}
@Override
public ExtractionUnit[] getAcceptableUnits(){
return new ExtractionUnit[] {
- ExtractionUnit.ARCHIVE, ExtractionUnit.PACKAGE, ExtractionUnit.CLASS,
+ ExtractionUnit.CLASS,
};
}
- private BirthmarkElement[] buildElement(List<Opcode> opcodes){
- StackPattern pattern = buildStackPattern(opcodes);
+ private BirthmarkElement[] buildElement(List<Opcode> opcodes, BirthmarkContext context){
+ StackPattern pattern = buildStackPattern(opcodes, context);
List<BirthmarkElement> elements = new ArrayList<BirthmarkElement>();
StackPattern subpattern = new StackPattern();
return elements.toArray(new BirthmarkElement[elements.size()]);
}
- private StackPattern buildStackPattern(List<Opcode> opcodes){
+ @SuppressWarnings("unchecked")
+ private StackPattern buildStackPattern(List<Opcode> opcodes, BirthmarkContext context){
Map<Label, Integer> tableMap = new HashMap<Label, Integer>();
StackPattern pattern = new StackPattern();
+ Map<Integer, Integer> weights = (Map<Integer, Integer>)context.getProperty("birthmarks.wsp.weights");
int currentDepth = 0;
Integer forwardedStatus = null;
for(Opcode opcode: opcodes){
+ opcode.setWeight(weights.get(opcode.getOpcode()));
if(opcode.getCategory() == Opcode.Category.TARGETER){
forwardedStatus = tableMap.get(((LabelOpcode)opcode).getLabel());
}
private class Visitor extends BirthmarkExtractVisitor{
private List<Opcode> opcodeList = new ArrayList<Opcode>();
- public Visitor(ClassVisitor visitor, Birthmark birthmark, BirthmarkEnvironment environment){
- super(visitor, birthmark, environment);
+ public Visitor(ClassVisitor visitor, Birthmark birthmark, BirthmarkContext context){
+ super(visitor, birthmark, context);
}
public void visitEnd(){
- BirthmarkElement[] elements = buildElement(opcodeList);
+ BirthmarkElement[] elements = buildElement(opcodeList, getContext());
for(BirthmarkElement element: elements){
addElement(element);
}
--- /dev/null
+package jp.sourceforge.stigmata.birthmarks.wsp;
+
+/*
+ * $Id$
+ */
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import jp.sourceforge.stigmata.BirthmarkContext;
+import jp.sourceforge.stigmata.birthmarks.AbstractBirthmarkPreprocessor;
+import jp.sourceforge.stigmata.digger.ClassFileArchive;
+import jp.sourceforge.stigmata.digger.ClassFileEntry;
+import jp.sourceforge.stigmata.spi.BirthmarkSpi;
+
+import org.objectweb.asm.ClassAdapter;
+import org.objectweb.asm.ClassReader;
+import org.objectweb.asm.ClassWriter;
+import org.objectweb.asm.MethodVisitor;
+
+/**
+ *
+ * @author Haruaki Tamada
+ * @version $Revision$
+ */
+public class StackPatternBasedBirthmarkPreprocessor extends AbstractBirthmarkPreprocessor{
+ public StackPatternBasedBirthmarkPreprocessor(BirthmarkSpi spi){
+ super(spi);
+ }
+
+ @Override
+ public void preprocess(ClassFileArchive[] targets, BirthmarkContext context){
+ Map<Integer, Integer> targetMap = new HashMap<Integer, Integer>();
+
+ int classCount = readOpcodes(targets, targetMap);
+
+ Map<Integer, Integer> weights = new HashMap<Integer, Integer>();
+ for(Map.Entry<Integer, Integer> entry: targetMap.entrySet()){
+ int opcode = entry.getKey();
+ Integer count = entry.getValue();
+ int c = 0;
+ if(count != null){
+ c = count;
+ }
+
+ weights.put(opcode, (int)Math.log(classCount / c));
+ }
+
+ context.putProperty("birthmarks.wsp.weights", weights);
+ }
+
+ private int readOpcodes(ClassFileArchive[] targets, Map<Integer, Integer> targetMap){
+ int count = 0;
+ for(ClassFileArchive archive: targets){
+ for(ClassFileEntry entry: archive){
+ count++;
+ final List<Opcode> opcodes = new ArrayList<Opcode>();
+ try{
+ InputStream in = entry.getLocation().openStream();
+
+ ClassReader reader = new ClassReader(in);
+ ClassWriter writer = new ClassWriter(false);
+ ClassAdapter opcodeExtractVisitor = new ClassAdapter(writer){
+ @Override
+ public MethodVisitor visitMethod(int arg0, String arg1, String arg2, String arg3, String[] arg4){
+ OpcodeExtractionMethodVisitor visitor =
+ new OpcodeExtractionMethodVisitor(super.visitMethod(arg0, arg1, arg2, arg3, arg4), opcodes);
+ return visitor;
+ }
+ };
+ reader.accept(opcodeExtractVisitor, false);
+
+ for(Opcode opcode: opcodes){
+ if(opcode.getCategory() != Opcode.Category.TARGETER){
+ Integer i = targetMap.get(opcode.getOpcode());
+ if(i == null){
+ i = 0;
+ }
+ i = i + 1;
+ targetMap.put(opcode.getOpcode(), i);
+ }
+ }
+
+ } catch(IOException e){
+ }
+ }
+ }
+ return count;
+ }
+}
import jp.sourceforge.stigmata.BirthmarkComparator;
import jp.sourceforge.stigmata.BirthmarkExtractor;
+import jp.sourceforge.stigmata.BirthmarkPreprocessor;
import jp.sourceforge.stigmata.birthmarks.AbstractBirthmarkService;
/**
public class StackPatternBasedBirthmarkService extends AbstractBirthmarkService{
private BirthmarkComparator comparator = new StackPatternBasedBirthmarkComparator(this);
private BirthmarkExtractor extractor = new StackPatternBasedBirthmarkExtractor(this);
+ private BirthmarkPreprocessor preprocessor = new StackPatternBasedBirthmarkPreprocessor(this);
@Override
public String getDefaultDescription(){
return extractor;
}
+ @Override
+ public BirthmarkPreprocessor getPreprocessor(){
+ return preprocessor;
+ }
}