001    package edu.rice.cs.cunit.instrumentors.record;
002    
003    import edu.rice.cs.cunit.SyncPointBuffer;
004    import edu.rice.cs.cunit.classFile.ClassFile;
005    import edu.rice.cs.cunit.classFile.MethodInfo;
006    import edu.rice.cs.cunit.classFile.code.InstructionList;
007    import edu.rice.cs.cunit.classFile.code.Opcode;
008    import edu.rice.cs.cunit.classFile.code.instructions.ReferenceInstruction;
009    import edu.rice.cs.cunit.classFile.constantPool.MethodPoolInfo;
010    import edu.rice.cs.cunit.classFile.constantPool.visitors.CheckMethodVisitor;
011    import edu.rice.cs.cunit.util.IPredicate;
012    
013    /**
014     * Instrumentation strategy that adds code to java.lang.Thread.start to call SyncPointBuffer.compactAdd.
015     *
016     * @author Mathias Ricken
017     */
018    public class CompactRecordThreadStartStrategy extends CompactRecordBufferCodeStrategy {
019        /**
020         * Create a new strategy.
021         */
022        public CompactRecordThreadStartStrategy() {
023            super(new IPredicate<ClassFile>() {
024                public Boolean apply(ClassFile param) {
025                    return param.getThisClassName().equals("java.lang.Thread");
026                }
027            }, new IPredicate.Binary<ClassFile, MethodInfo>() {
028                public Boolean apply(ClassFile cf, MethodInfo param) {
029                    return param.getName().toString().equals("start");
030                }
031            }, new IPredicate.Ternary<ClassFile, MethodInfo, InstructionList>() {
032                public Boolean apply(ClassFile cf, MethodInfo mi, InstructionList il) {
033                    if (il.getOpcode() != Opcode.INVOKESPECIAL) return false;
034                    int methodIndex = ((ReferenceInstruction)il.getInstr()).getReference();
035                    MethodPoolInfo mpi = cf.getConstantPoolItem(methodIndex).execute(CheckMethodVisitor.singleton(), null);
036                    return (mpi.getClassInfo().getName().toString().equals("java/lang/Thread")) && (mpi.getNameAndType().getName().toString().equals("start0")) && (mpi.getNameAndType().getDescriptor().toString().equals("()V"));
037                }
038            }, SyncPointBuffer.SP.THREADSTART.intValue());
039        }
040    }