List of usage examples for org.objectweb.asm.tree InsnNode getOpcode
public int getOpcode()
From source file:com.offbynull.coroutines.instrumenter.MonitorInstrumentationGenerator.java
License:Open Source License
MonitorInstrumentationInstructions generate() {
// Find monitorenter/monitorexit and create replacement instructions that keep track of which objects were entered/exited.
///*from w w w.java 2 s . c om*/
//
// Check for synchronized code blocks. Synchronized methods and Java 5 locks are okay to ignore, but synchronized blocks need to
// be instrumented. For every MONITORENTER instruction that's performed on an object, there needs to be an equivalent MONITOREXIT
// before the method exits. Otherwise, the method throws an IllegalMonitorState exception when it exits. I've confirmed by making a
// simple java class in JASMIN assembler that did 10 MONITORENTERs in a loop and returned. That code threw
// IllegalMonitorStateException when it tried to return. This link seems to explain it pretty well:
// http://mail.openjdk.java.net/pipermail/hotspot-runtime-dev/2008-April/000118.html.
//
// So that means that if we're going to instrument the code to suspend and return in places, we need to make sure to exit all
// monitors when we return and to re-enter those monitors when we come back in. We can't handle this via static analysis like we do
// with inspecting the operand stack and local variables. It looks like static analysis is what Javaflow tries to do, which will
// work in 99% of cases but won't in some edge cases like if the code was written in some JVM langauge other than Java.
//
// The following code creates replacements for every MONITORENTER and MONITOREXIT instruction such that those monitors get tracked
// in a LockState object.
List<AbstractInsnNode> monitorInsnNodes = searchForOpcodes(methodNode.instructions, Opcodes.MONITORENTER,
Opcodes.MONITOREXIT);
Map<AbstractInsnNode, InsnList> monitorInsnNodeReplacements = new HashMap<>();
// IMPORTANT NOTE: The following code only generates code if monitorInsnNodes is NOT empty. That means that there has to be at least
// one MONITORENTER or one MONITOREXIT for this method to generate instructions. Otherwise, all instruction listings will be stubbed
// out with empty instruction lists.
for (AbstractInsnNode monitorInsnNode : monitorInsnNodes) {
InsnNode insnNode = (InsnNode) monitorInsnNode;
InsnList replacementLogic;
switch (insnNode.getOpcode()) {
case Opcodes.MONITORENTER:
replacementLogic = merge(saveVar(tempObjVar), // enter monitor
loadVar(tempObjVar), cloneMonitorNode(insnNode),
call(LOCKSTATE_ENTER_METHOD, loadVar(lockStateVar), loadVar(tempObjVar)) // track after entered
);
break;
case Opcodes.MONITOREXIT:
replacementLogic = merge(saveVar(tempObjVar), // exit monitor
loadVar(tempObjVar), cloneMonitorNode(insnNode),
call(LOCKSTATE_EXIT_METHOD, loadVar(lockStateVar), loadVar(tempObjVar)) // discard after exit
);
break;
default:
throw new IllegalStateException(); // should never happen
}
monitorInsnNodeReplacements.put(monitorInsnNode, replacementLogic);
}
// Create code to create a new lockstate object
InsnList createAndStoreLockStateInsnList;
if (monitorInsnNodeReplacements.isEmpty()) { // if we don't have any MONITORENTER/MONITOREXIT, ignore this
createAndStoreLockStateInsnList = empty();
} else {
createAndStoreLockStateInsnList = merge(construct(LOCKSTATE_INIT_METHOD), saveVar(lockStateVar));
}
// Create code to load lockstate object from methodstate
InsnList loadAndStoreLockStateFromMethodStateInsnList;
if (monitorInsnNodeReplacements.isEmpty()) {
loadAndStoreLockStateFromMethodStateInsnList = empty();
} else {
loadAndStoreLockStateFromMethodStateInsnList = merge(
call(METHODSTATE_GETLOCKSTATE_METHOD, loadVar(methodStateVar)), saveVar(lockStateVar));
}
// Create code to load lockstate object to the stack
InsnList loadLockStateToStackInsnList;
if (monitorInsnNodeReplacements.isEmpty()) {
loadLockStateToStackInsnList = loadNull();
} else {
loadLockStateToStackInsnList = loadVar(lockStateVar);
}
// Create code to enter all monitors in lockstate object
InsnList enterMonitorsInLockStateInsnList;
if (monitorInsnNodeReplacements.isEmpty()) {
enterMonitorsInLockStateInsnList = empty();
} else {
enterMonitorsInLockStateInsnList = forEach(counterVar, arrayLenVar,
call(LOCKSTATE_TOARRAY_METHOD, loadVar(lockStateVar)), merge(monitorEnter() // temp monitor enter
));
}
// Create code to exit all monitors in lockstate object
InsnList exitMonitorsInLockStateInsnList;
if (monitorInsnNodeReplacements.isEmpty()) {
exitMonitorsInLockStateInsnList = empty();
} else {
exitMonitorsInLockStateInsnList = forEach(counterVar, arrayLenVar,
call(LOCKSTATE_TOARRAY_METHOD, loadVar(lockStateVar)), merge(monitorExit() // temp monitor exit
));
}
return new MonitorInstrumentationInstructions(monitorInsnNodeReplacements, createAndStoreLockStateInsnList,
loadAndStoreLockStateFromMethodStateInsnList, loadLockStateToStackInsnList,
enterMonitorsInLockStateInsnList, exitMonitorsInLockStateInsnList);
}
From source file:com.offbynull.coroutines.instrumenter.SynchronizationPoint.java
License:Open Source License
SynchronizationPoint(InsnNode monitorInstruction, Frame<BasicValue> frame) { Validate.notNull(monitorInstruction); Validate.notNull(frame);// www.jav a 2s . c o m Validate.isTrue(monitorInstruction.getOpcode() == Opcodes.MONITORENTER || monitorInstruction.getOpcode() == Opcodes.MONITOREXIT); this.monitorInstruction = monitorInstruction; this.frame = frame; }
From source file:com.retroduction.carma.transformer.asm.aor.AOR_Transition.java
License:Open Source License
@Override protected void checkNode(ClassNode classNode, MethodNode methodNode, List<Mutant> result, CRTEntry jcovInfo, AbstractInsnNode node) {/*from ww w . j a v a2 s . c o m*/ if (node instanceof InsnNode) { InsnNode sourceNode = (InsnNode) node; if (sourceNode.getOpcode() == this.sourceInstruction) { InsnNode targetNode = new InsnNode(this.targetInstruction); methodNode.instructions.set(sourceNode, targetNode); ClassWriter writer = new ClassWriter(0); classNode.accept(writer); SourceCodeMapping sourceMapping = new SourceCodeMapping(); sourceMapping.setLineStart(jcovInfo.getStartLine()); sourceMapping.setLineEnd(jcovInfo.getEndLine()); sourceMapping.setColumnStart(jcovInfo.getStartColumn()); sourceMapping.setColumnEnd(jcovInfo.getEndColumn()); Mutant mutant = new Mutant(); mutant.setByteCode(writer.toByteArray()); mutant.setSourceMapping(sourceMapping); mutant.setSurvived(true); mutant.setTransition(this); result.add(mutant); methodNode.instructions.set(targetNode, sourceNode); } } }
From source file:de.unisb.cs.st.javaslicer.tracer.instrumentation.TracingMethodInstrumenter.java
License:Open Source License
private void transformInsn(final InsnNode insn) { int arrayTraceSeqIndex = -1; int indexTraceSeqIndex = -1; final InstructionType type; switch (insn.getOpcode()) { // the not interesting ones: case NOP://w w w. j a va 2s . c o m // constants: case ACONST_NULL: case ICONST_M1: case ICONST_0: case ICONST_1: case ICONST_2: case ICONST_3: case ICONST_4: case ICONST_5: case LCONST_0: case LCONST_1: case FCONST_0: case FCONST_1: case FCONST_2: case DCONST_0: case DCONST_1: type = InstructionType.SAFE; break; // array load: case IALOAD: case LALOAD: case FALOAD: case DALOAD: case AALOAD: case BALOAD: case CALOAD: case SALOAD: type = InstructionType.UNSAFE; // to trace array manipulations, we need two traces: one for the array, one for the index arrayTraceSeqIndex = this.tracer.newLongTraceSequence(); indexTraceSeqIndex = this.tracer.newIntegerTraceSequence(); //System.out.println("seq " + arrayTraceIndex + ": array in method " + readMethod.getReadClass().getClassName() + "." + readMethod.getName()); //System.out.println("seq " + indexTraceIndex + ": array index in method " + readMethod.getReadClass().getClassName() + "." + readMethod.getName()); // the top two words on the stack are the array index and the array reference // (add instruction *before* the current one this.instructionIterator.previous(); this.instructionIterator.add(new InsnNode(DUP2)); ++TracingMethodInstrumenter.statsArrayLoad; break; // array store: case IASTORE: case LASTORE: case FASTORE: case DASTORE: case AASTORE: case BASTORE: case CASTORE: case SASTORE: type = InstructionType.UNSAFE; // to trace array manipulations, we need two traces: one for the array, one for the index arrayTraceSeqIndex = this.tracer.newLongTraceSequence(); indexTraceSeqIndex = this.tracer.newIntegerTraceSequence(); //System.out.println("seq " + arrayTraceIndex + ": array in method " + readMethod.getReadClass().getClassName() + "." + readMethod.getName()); //System.out.println("seq " + indexTraceIndex + ": arrayindex in method " + readMethod.getReadClass().getClassName() + "." + readMethod.getName()); // top three words on the stack: value, array index, array reference // after our manipulation: array index, array reference, value, array index, array reference // (add instruction *before* the current one) this.instructionIterator.previous(); if (insn.getOpcode() == LASTORE || insn.getOpcode() == DASTORE) { // 2-word values this.instructionIterator.add(new InsnNode(DUP2_X2)); this.instructionIterator.add(new InsnNode(POP2)); this.instructionIterator.add(new InsnNode(DUP2_X2)); } else { this.instructionIterator.add(new InsnNode(DUP_X2)); this.instructionIterator.add(new InsnNode(POP)); this.instructionIterator.add(new InsnNode(DUP2_X1)); } ++TracingMethodInstrumenter.statsArrayStore; break; // stack manipulation: case POP: case POP2: case DUP: case DUP2: type = InstructionType.SAFE; break; case DUP_X1: case DUP_X2: case DUP2_X1: case DUP2_X2: case SWAP: // i would like to throw an error here, since this stack manipulation is problematic. // but unfortunately, it is used in bytecode of the standard api on linux and mac, version 1.6.17. // if (this.tracer.debug) { // Transformer.printMethod(System.err, this.methodNode); // System.err.println("Error at instruction " + this.instructionIterator.previousIndex()); // } // throw new TracerException("Method "+this.classNode.name+"."+this.methodNode.name+ // " uses unsupported stack manipulation. Maybe it was compiled for JRE < 1.5?"); type = InstructionType.SAFE; break; // safe arithmetic instructions: case IADD: case LADD: case FADD: case DADD: case ISUB: case LSUB: case FSUB: case DSUB: case IMUL: case LMUL: case FMUL: case DMUL: case FDIV: case DDIV: case FREM: case DREM: case INEG: case LNEG: case FNEG: case DNEG: case ISHL: case LSHL: case ISHR: case LSHR: case IUSHR: case LUSHR: case IAND: case LAND: case IOR: case LOR: case IXOR: case LXOR: type = InstructionType.SAFE; break; // unsafe arithmetic instructions: case IDIV: case LDIV: case IREM: case LREM: type = InstructionType.UNSAFE; break; // type conversions: case I2L: case I2F: case I2D: case L2I: case L2F: case L2D: case F2I: case F2L: case F2D: case D2I: case D2L: case D2F: case I2B: case I2C: case I2S: type = InstructionType.SAFE; break; // comparison: case LCMP: case FCMPL: case FCMPG: case DCMPL: case DCMPG: type = InstructionType.SAFE; break; // control-flow statements: case IRETURN: case LRETURN: case FRETURN: case DRETURN: case ARETURN: case RETURN: type = InstructionType.METHODEXIT; break; // special things case ARRAYLENGTH: case ATHROW: case MONITORENTER: case MONITOREXIT: type = InstructionType.UNSAFE; break; default: type = InstructionType.UNSAFE; assert false; } if (arrayTraceSeqIndex != -1) { assert indexTraceSeqIndex != -1; // the top two words on the stack are the array index and the array reference this.instructionIterator.add(new VarInsnNode(ALOAD, this.tracerLocalVarIndex)); this.instructionIterator.add(new InsnNode(SWAP)); this.instructionIterator.add(getIntConstInsn(indexTraceSeqIndex)); this.instructionIterator.add(new MethodInsnNode(INVOKEINTERFACE, Type.getInternalName(ThreadTracer.class), "traceInt", "(II)V", true)); this.instructionIterator.add(new VarInsnNode(ALOAD, this.tracerLocalVarIndex)); this.instructionIterator.add(new InsnNode(SWAP)); this.instructionIterator.add(getIntConstInsn(arrayTraceSeqIndex)); this.instructionIterator.add(new MethodInsnNode(INVOKEINTERFACE, Type.getInternalName(ThreadTracer.class), "traceObject", "(Ljava/lang/Object;I)V", true)); // and move to the position where it was before entering this method this.instructionIterator.next(); registerInstruction(new ArrayInstruction(this.readMethod, insn.getOpcode(), this.currentLine, arrayTraceSeqIndex, indexTraceSeqIndex), type); } else { assert indexTraceSeqIndex == -1; registerInstruction(new SimpleInstruction(this.readMethod, insn.getOpcode(), this.currentLine), type); } }
From source file:edu.mit.streamjit.util.bytecode.MethodResolver.java
License:Open Source License
private void interpret(InsnNode insn, FrameState frame, BBInfo block) { ReturnType returnType = block.block.getParent().getType().getReturnType(); switch (insn.getOpcode()) { case Opcodes.NOP: break;//from w w w.ja v a2 s .co m //<editor-fold defaultstate="collapsed" desc="Stack manipulation opcodes (pop, dup, swap)"> case Opcodes.POP: assert frame.stack.peek().getType().getCategory() == 1; frame.stack.pop(); break; case Opcodes.POP2: final int[][][] pop2Permutations = { { { 1, 1 }, {} }, { { 2 }, {} } }; conditionallyPermute(frame, pop2Permutations); break; case Opcodes.DUP: final int[][][] dupPermutations = { { { 1 }, { 1, 1 } } }; conditionallyPermute(frame, dupPermutations); break; case Opcodes.DUP_X1: final int[][][] dup_x1Permutations = { { { 1, 1 }, { 1, 2, 1 } } }; conditionallyPermute(frame, dup_x1Permutations); break; case Opcodes.DUP_X2: final int[][][] dup_x2Permutations = { { { 1, 1, 1 }, { 1, 3, 2, 1 } }, { { 1, 2 }, { 1, 2, 1 } } }; conditionallyPermute(frame, dup_x2Permutations); break; case Opcodes.DUP2: final int[][][] dup2Permutations = { { { 1, 1 }, { 2, 1, 2, 1 } }, { { 2 }, { 1, 1 } } }; conditionallyPermute(frame, dup2Permutations); break; case Opcodes.DUP2_X1: final int[][][] dup2_x1Permutations = { { { 1, 1, 1 }, { 2, 1, 3, 2, 1 } }, { { 2, 1 }, { 1, 2, 1 } } }; conditionallyPermute(frame, dup2_x1Permutations); break; case Opcodes.DUP2_X2: final int[][][] dup2_x2Permutations = { { { 1, 1, 1, 1 }, { 2, 1, 4, 3, 2, 1 } }, { { 2, 1, 1 }, { 1, 3, 2, 1 } }, { { 3, 2, 1 }, { 2, 1, 3, 2, 1 } }, { { 2, 2 }, { 1, 2, 1 } } }; conditionallyPermute(frame, dup2_x2Permutations); break; case Opcodes.SWAP: final int[][][] swapPermutations = { { { 1, 1 }, { 1, 2 } } }; conditionallyPermute(frame, swapPermutations); break; //</editor-fold> //<editor-fold defaultstate="collapsed" desc="Constant-stacking opcodes (iconst_0, etc.; see also bipush, sipush)"> case Opcodes.ACONST_NULL: frame.stack.push(module.constants().getNullConstant()); break; case Opcodes.ICONST_M1: frame.stack.push(module.constants().getSmallestIntConstant(-1)); break; case Opcodes.ICONST_0: frame.stack.push(module.constants().getSmallestIntConstant(0)); break; case Opcodes.ICONST_1: frame.stack.push(module.constants().getSmallestIntConstant(1)); break; case Opcodes.ICONST_2: frame.stack.push(module.constants().getSmallestIntConstant(2)); break; case Opcodes.ICONST_3: frame.stack.push(module.constants().getSmallestIntConstant(3)); break; case Opcodes.ICONST_4: frame.stack.push(module.constants().getSmallestIntConstant(4)); break; case Opcodes.ICONST_5: frame.stack.push(module.constants().getSmallestIntConstant(5)); break; case Opcodes.LCONST_0: frame.stack.push(module.constants().getConstant(0L)); break; case Opcodes.LCONST_1: frame.stack.push(module.constants().getConstant(1L)); break; case Opcodes.FCONST_0: frame.stack.push(module.constants().getConstant(0f)); break; case Opcodes.FCONST_1: frame.stack.push(module.constants().getConstant(1f)); break; case Opcodes.FCONST_2: frame.stack.push(module.constants().getConstant(2f)); break; case Opcodes.DCONST_0: frame.stack.push(module.constants().getConstant(0d)); break; case Opcodes.DCONST_1: frame.stack.push(module.constants().getConstant(1d)); break; //</editor-fold> //<editor-fold defaultstate="collapsed" desc="Return opcodes"> case Opcodes.IRETURN: assert returnType.isSubtypeOf(typeFactory.getType(int.class)); assert frame.stack.peek().getType().isSubtypeOf(returnType); block.block.instructions().add(new ReturnInst(returnType, frame.stack.pop())); break; case Opcodes.LRETURN: assert returnType.isSubtypeOf(typeFactory.getType(long.class)); assert frame.stack.peek().getType().isSubtypeOf(returnType); block.block.instructions().add(new ReturnInst(returnType, frame.stack.pop())); break; case Opcodes.FRETURN: assert returnType.isSubtypeOf(typeFactory.getType(float.class)); assert frame.stack.peek().getType().isSubtypeOf(returnType); block.block.instructions().add(new ReturnInst(returnType, frame.stack.pop())); break; case Opcodes.DRETURN: assert returnType.isSubtypeOf(typeFactory.getType(double.class)); assert frame.stack.peek().getType().isSubtypeOf(returnType); block.block.instructions().add(new ReturnInst(returnType, frame.stack.pop())); break; case Opcodes.ARETURN: assert returnType.isSubtypeOf(typeFactory.getType(Object.class)); assert frame.stack.peek().getType().isSubtypeOf(returnType); block.block.instructions().add(new ReturnInst(returnType, frame.stack.pop())); break; case Opcodes.RETURN: assert returnType instanceof VoidType || method.isConstructor(); block.block.instructions().add(new ReturnInst(typeFactory.getVoidType())); break; //</editor-fold> //<editor-fold defaultstate="collapsed" desc="Unary math opcodes (negation)"> //Unary minus is rendered as a multiplication by -1. (The obvious //other choice, subtraction from 0, is not equivalent for floats and //doubles due to negative zero.) case Opcodes.INEG: frame.stack.push(module.constants().getSmallestIntConstant(-1)); binary(BinaryInst.Operation.MUL, frame, block); break; case Opcodes.LNEG: frame.stack.push(module.constants().getConstant(-1L)); binary(BinaryInst.Operation.MUL, frame, block); break; case Opcodes.FNEG: frame.stack.push(module.constants().getConstant(-1f)); binary(BinaryInst.Operation.MUL, frame, block); break; case Opcodes.DNEG: frame.stack.push(module.constants().getConstant(-1d)); binary(BinaryInst.Operation.MUL, frame, block); break; //</editor-fold> //<editor-fold defaultstate="collapsed" desc="Binary math opcodes"> case Opcodes.IADD: case Opcodes.LADD: case Opcodes.FADD: case Opcodes.DADD: binary(BinaryInst.Operation.ADD, frame, block); break; case Opcodes.ISUB: case Opcodes.LSUB: case Opcodes.FSUB: case Opcodes.DSUB: binary(BinaryInst.Operation.SUB, frame, block); break; case Opcodes.IMUL: case Opcodes.LMUL: case Opcodes.FMUL: case Opcodes.DMUL: binary(BinaryInst.Operation.MUL, frame, block); break; case Opcodes.IDIV: case Opcodes.LDIV: case Opcodes.FDIV: case Opcodes.DDIV: binary(BinaryInst.Operation.DIV, frame, block); break; case Opcodes.IREM: case Opcodes.LREM: case Opcodes.FREM: case Opcodes.DREM: binary(BinaryInst.Operation.REM, frame, block); break; case Opcodes.ISHL: case Opcodes.LSHL: binary(BinaryInst.Operation.SHL, frame, block); break; case Opcodes.ISHR: case Opcodes.LSHR: binary(BinaryInst.Operation.SHR, frame, block); break; case Opcodes.IUSHR: case Opcodes.LUSHR: binary(BinaryInst.Operation.USHR, frame, block); break; case Opcodes.IAND: case Opcodes.LAND: binary(BinaryInst.Operation.AND, frame, block); break; case Opcodes.IOR: case Opcodes.LOR: binary(BinaryInst.Operation.OR, frame, block); break; case Opcodes.IXOR: case Opcodes.LXOR: binary(BinaryInst.Operation.XOR, frame, block); break; case Opcodes.LCMP: case Opcodes.FCMPL: case Opcodes.DCMPL: binary(BinaryInst.Operation.CMP, frame, block); break; case Opcodes.FCMPG: case Opcodes.DCMPG: binary(BinaryInst.Operation.CMPG, frame, block); break; //</editor-fold> //<editor-fold defaultstate="collapsed" desc="Primitive casts"> case Opcodes.I2L: cast(int.class, long.class, frame, block); break; case Opcodes.I2F: cast(int.class, float.class, frame, block); break; case Opcodes.I2D: cast(int.class, double.class, frame, block); break; case Opcodes.L2I: cast(long.class, int.class, frame, block); break; case Opcodes.L2F: cast(long.class, float.class, frame, block); break; case Opcodes.L2D: cast(long.class, double.class, frame, block); break; case Opcodes.F2I: cast(float.class, int.class, frame, block); break; case Opcodes.F2L: cast(float.class, long.class, frame, block); break; case Opcodes.F2D: cast(float.class, double.class, frame, block); break; case Opcodes.D2I: cast(double.class, int.class, frame, block); break; case Opcodes.D2L: cast(double.class, long.class, frame, block); break; case Opcodes.D2F: cast(double.class, float.class, frame, block); break; case Opcodes.I2B: cast(int.class, byte.class, frame, block); break; case Opcodes.I2C: cast(int.class, char.class, frame, block); break; case Opcodes.I2S: cast(int.class, short.class, frame, block); break; //</editor-fold> //<editor-fold defaultstate="collapsed" desc="Array store opcodes"> case Opcodes.IASTORE: case Opcodes.LASTORE: case Opcodes.FASTORE: case Opcodes.DASTORE: case Opcodes.AASTORE: case Opcodes.BASTORE: case Opcodes.CASTORE: case Opcodes.SASTORE: Value data = frame.stack.pop(); Value index = frame.stack.pop(); Value array = frame.stack.pop(); ArrayStoreInst asi = new ArrayStoreInst(array, index, data); block.block.instructions().add(asi); break; //</editor-fold> //<editor-fold defaultstate="collapsed" desc="Array load opcodes"> case Opcodes.IALOAD: case Opcodes.LALOAD: case Opcodes.FALOAD: case Opcodes.DALOAD: case Opcodes.AALOAD: case Opcodes.BALOAD: case Opcodes.CALOAD: case Opcodes.SALOAD: Value index2 = frame.stack.pop(); Value array2 = frame.stack.pop(); ArrayLoadInst ali = new ArrayLoadInst(array2, index2); block.block.instructions().add(ali); frame.stack.push(ali); break; //</editor-fold> case Opcodes.ARRAYLENGTH: ArrayLengthInst lengthInst = new ArrayLengthInst(frame.stack.pop()); block.block.instructions().add(lengthInst); frame.stack.push(lengthInst); break; case Opcodes.ATHROW: block.block.instructions().add(new ThrowInst(frame.stack.pop())); break; default: throw new UnsupportedOperationException("" + insn.getOpcode()); } }
From source file:jaspex.speculation.newspec.RemoveOverspeculation.java
License:Open Source License
/** Scan simples para tentar eliminar overspeculation. */* w ww. j av a 2s .c o m*/ * A ideia deste mtodo determinar se entre uma operao de spawnSpeculation e o get do seu Future / * nonTransactionalActionAttempted existem instruces suficientes para valer o trabalho de fazer * especulao. * * Quando observamos um spawnSpeculation, comeamos a fazer tracking dele. Se virmos alguma * operao complexa (alguns saltos, outros mtodos, etc), paramos o tracking. Caso contrrio, se * ainda estivermos a fazer tracking quando encontramos o get / nonTransactionalActionAttempted, ento * colocamos o mtodo na lista de especulaes a rejeitar. **/ private TrackingResult scanFuture(MethodInsnNode tracking, AbstractInsnNode start) { for (AbstractInsnNode node = start; node != null; node = node.getNext()) { if (node instanceof MethodInsnNode) { MethodInsnNode mInsn = (MethodInsnNode) node; if (mInsn.owner.equals(CommonTypes.CONTSPECULATIONCONTROL.asmName()) && mInsn.name.equals("spawnSpeculation")) { // do nothing } else if (mInsn.owner.startsWith(CommonTypes.FUTURE.asmName()) && mInsn.name.equals("get")) { int futureId = Integer.parseInt(mInsn.owner.substring(mInsn.owner.lastIndexOf('$') + 1)); if (getFutureId(tracking) == futureId) { return TrackingResult.NEEDVALUE; } } else if (mInsn.owner.equals(CommonTypes.SPECULATIONCONTROL.asmName()) && (mInsn.name.equals("nonTransactionalActionAttempted") || mInsn.name.equals("blacklistedActionAttempted"))) { return TrackingResult.FORCEDSYNC; } else if (mInsn.owner.equals(CommonTypes.TRANSACTION.asmName()) || mInsn.owner.equals(CommonTypes.MARKER_BEFOREINLINEDSTORE) || mInsn.owner.equals(CommonTypes.DEBUGCLASS.asmName())) { continue; } else if (mInsn.owner.equals(CommonTypes.REPLACEMENTS.asmName())) { // do nothing } else if (mInsn.owner.startsWith("jaspex") && !CodegenHelper.isCodegenClass(Type.fromAsm(mInsn.owner))) { throw new AssertionError("Resetting tracking due to call to " + mInsn.owner + "." + mInsn.name); } return TrackingResult.OK; } else if (node instanceof JumpInsnNode) { JumpInsnNode jInsn = (JumpInsnNode) node; if (_mNode.instructions.indexOf(jInsn) > _mNode.instructions.indexOf(jInsn.label)) { // Salto para trs, no continuar tracking return TrackingResult.OK; } if (jInsn.getOpcode() == Opcodes.GOTO) return scanFuture(tracking, jInsn.label); if (jInsn.getOpcode() == Opcodes.JSR) throw new AssertionError(); // Opcode um de // IFEQ, IFNE, IFLT, IFGE, IFGT, IFLE, IF_ICMPEQ, IF_ICMPNE, IF_ICMPLT, // IF_ICMPGE, IF_ICMPGT, IF_ICMPLE, IF_ACMPEQ, IF_ACMPNE, IFNULL, IFNONNULL // Portanto vamos ter que analisar ambos os branches return TrackingResult.combine(scanFuture(tracking, jInsn.getNext()), scanFuture(tracking, jInsn.label)); } else if (node instanceof LookupSwitchInsnNode || node instanceof TableSwitchInsnNode) { List<LabelNode> targets = new UtilArrayList<LabelNode>(); // Infelizmente o ASM no tem uma classe comum entre os dois tipos de switch if (node instanceof LookupSwitchInsnNode) { LookupSwitchInsnNode sInsn = (LookupSwitchInsnNode) node; if (sInsn.dflt != null) targets.add(sInsn.dflt); targets.addAll(sInsn.labels); } else { TableSwitchInsnNode sInsn = (TableSwitchInsnNode) node; if (sInsn.dflt != null) targets.add(sInsn.dflt); targets.addAll(sInsn.labels); } // Vamos analisar todos os targets do switch e fazer merge do resultado TrackingResult mergedResult = null; for (LabelNode l : targets) { TrackingResult res = scanFuture(tracking, l); if (mergedResult == null) { mergedResult = res; } else { mergedResult = TrackingResult.combine(mergedResult, res); } } return mergedResult; } else if (node instanceof InsnNode) { InsnNode insn = (InsnNode) node; // Encontrmos fim do mtodo if (insn.getOpcode() == Opcodes.ATHROW || returnOpcodes.contains(insn.getOpcode())) { if (new InvokedMethod(_mNode).returnType().equals(Type.PRIM_VOID)) { // Caso especial: Todos os mtodos que retornam void so // escolhidos para especulao -- Uma consequncia directa // disso que ter um futuro activo aquando do retorno do // mtodo no serve para nada, j que a nica coisa que vai // acontecer a especulao acabada de criar vai tentar fazer // commit imediatamente return TrackingResult.FORCEDSYNC; } return TrackingResult.OK; } } } // FIXME: Alguma vez aqui chegamos? //return TrackingResult.OK; throw new AssertionError("FIXME"); }
From source file:net.sourceforge.cobertura.instrument.FindTouchPointsMethodAdapter.java
License:GNU General Public License
/** * We try to detect such a last 2 instructions and extract the enum signature. *//*w w w.j a va2s .c o m*/ private String tryToFindSignatureOfConditionEnum() { // mv.visitMethodInsn(INVOKESTATIC, "net/sourceforge/cobertura/instrument/FindTouchPointsMethodAdapter", "$SWITCH_TABLE$net$sourceforge$cobertura$instrument$FindTouchPointsMethodAdapter$Abc", "()[I"); // mv.visitVarInsn(ALOAD, 1); // mv.visitMethodInsn(INVOKEVIRTUAL, "net/sourceforge/cobertura/instrument/FindTouchPointsMethodAdapter$Abc", "ordinal", "()I"); // mv.visitInsn(IALOAD); if (backlog == null || backlog.size() < 4) return null; int last = backlog.size() - 1; if ((backlog.get(last) instanceof InsnNode) && (backlog.get(last - 1) instanceof MethodInsnNode) && (backlog.get(last - 2) instanceof VarInsnNode)) { VarInsnNode i2 = (VarInsnNode) backlog.get(last - 2); MethodInsnNode i3 = (MethodInsnNode) backlog.get(last - 1); InsnNode i4 = (InsnNode) backlog.get(last); if ((i2.getOpcode() == Opcodes.ALOAD) && (i3.getOpcode() == Opcodes.INVOKEVIRTUAL && i3.name.equals("ordinal")) && (i4.getOpcode() == Opcodes.IALOAD)) { return i3.owner; } } return null; }
From source file:org.evosuite.instrumentation.ComparisonTransformation.java
License:Open Source License
/** * <p>transformMethod</p>/*from w w w.j a va 2 s .co m*/ * * @param mn a {@link org.objectweb.asm.tree.MethodNode} object. */ public void transformMethod(MethodNode mn) { AbstractInsnNode node = mn.instructions.getFirst(); while (node != mn.instructions.getLast()) { AbstractInsnNode next = node.getNext(); if (node instanceof InsnNode) { InsnNode in = (InsnNode) node; if (in.getOpcode() == Opcodes.LCMP) { insertLongComparison(in, mn.instructions); TransformationStatistics.transformedComparison(); } else if (in.getOpcode() == Opcodes.DCMPG) { // TODO: Check treatment of NaN TransformationStatistics.transformedComparison(); insertDoubleComparison(in, mn.instructions); } else if (in.getOpcode() == Opcodes.DCMPL) { TransformationStatistics.transformedComparison(); insertDoubleComparison(in, mn.instructions); } else if (in.getOpcode() == Opcodes.FCMPG) { TransformationStatistics.transformedComparison(); insertFloatComparison(in, mn.instructions); } else if (in.getOpcode() == Opcodes.FCMPL) { TransformationStatistics.transformedComparison(); insertFloatComparison(in, mn.instructions); } } node = next; } }
From source file:org.evosuite.instrumentation.coverage.LCSAJsInstrumentation.java
License:Open Source License
/** {@inheritDoc} */ @SuppressWarnings("unchecked") //using external lib @Override/*ww w .j a v a 2 s . c o m*/ public void analyze(ClassLoader classLoader, MethodNode mn, String className, String methodName, int access) { Queue<LCSAJ> lcsaj_queue = new LinkedList<LCSAJ>(); HashSet<Integer> targets_reached = new HashSet<Integer>(); AbstractInsnNode start = mn.instructions.getFirst(); int startID = 0; // TODO: This should replace the hack below if (methodName.startsWith("<init>")) { Iterator<AbstractInsnNode> j = mn.instructions.iterator(); boolean constructorInvoked = false; while (j.hasNext()) { AbstractInsnNode in = j.next(); startID++; if (!constructorInvoked) { if (in.getOpcode() == Opcodes.INVOKESPECIAL) { MethodInsnNode cn = (MethodInsnNode) in; Collection<String> superClasses = DependencyAnalysis.getInheritanceTree() .getSuperclasses(className); superClasses.add(className); String classNameWithDots = ResourceList.getClassNameFromResourcePath(cn.owner); if (superClasses.contains(classNameWithDots)) { constructorInvoked = true; break; } } else { continue; } } } } /* if (methodName.startsWith("<init>")) { if (mn.instructions.size() >= 4) { start = mn.instructions.get(4); startID = 4; } } */ LCSAJ a = new LCSAJ(className, methodName, BytecodeInstructionPool.getInstance(classLoader) .getInstruction(className, methodName, startID, start)); lcsaj_queue.add(a); targets_reached.add(0); ArrayList<TryCatchBlockNode> tc_blocks = (ArrayList<TryCatchBlockNode>) mn.tryCatchBlocks; for (TryCatchBlockNode t : tc_blocks) { LCSAJ b = new LCSAJ(className, methodName, BytecodeInstructionPool.getInstance(classLoader) .getInstruction(className, methodName, mn.instructions.indexOf(t.handler), t.handler)); lcsaj_queue.add(b); } while (!lcsaj_queue.isEmpty()) { LCSAJ currentLCSAJ = lcsaj_queue.poll(); int position = mn.instructions.indexOf(currentLCSAJ.getLastNodeAccessed()); // go to next bytecode instruction position++; if (position >= mn.instructions.size()) { // New LCSAJ for current + return LCSAJPool.add_lcsaj(className, methodName, currentLCSAJ); continue; } AbstractInsnNode next = mn.instructions.get(position); currentLCSAJ.lookupInstruction(position, BytecodeInstructionPool.getInstance(classLoader) .getInstruction(className, methodName, position, next)); if (next instanceof JumpInsnNode) { JumpInsnNode jump = (JumpInsnNode) next; // New LCSAJ for current + jump to target LCSAJPool.add_lcsaj(className, methodName, currentLCSAJ); LabelNode target = jump.label; int targetPosition = mn.instructions.indexOf(target); if (jump.getOpcode() != Opcodes.GOTO) { LCSAJ copy = new LCSAJ(currentLCSAJ); lcsaj_queue.add(copy); } if (!targets_reached.contains(targetPosition)) { LCSAJ c = new LCSAJ(className, methodName, BytecodeInstructionPool.getInstance(classLoader) .getInstruction(className, methodName, targetPosition, target)); lcsaj_queue.add(c); targets_reached.add(targetPosition); } } else if (next instanceof TableSwitchInsnNode) { TableSwitchInsnNode tswitch = (TableSwitchInsnNode) next; List<LabelNode> allTargets = tswitch.labels; for (LabelNode target : allTargets) { int targetPosition = mn.instructions.indexOf(target); if (!targets_reached.contains(targetPosition)) { LCSAJ b = new LCSAJ(className, methodName, BytecodeInstructionPool.getInstance(classLoader) .getInstruction(className, methodName, targetPosition, target)); lcsaj_queue.add(b); targets_reached.add(targetPosition); } } } else if (next instanceof InsnNode) { InsnNode insn = (InsnNode) next; // New LCSAJ for current + throw / return if (insn.getOpcode() == Opcodes.ATHROW || insn.getOpcode() == Opcodes.RETURN || insn.getOpcode() == Opcodes.ARETURN || insn.getOpcode() == Opcodes.IRETURN || insn.getOpcode() == Opcodes.DRETURN || insn.getOpcode() == Opcodes.LRETURN || insn.getOpcode() == Opcodes.FRETURN) { LCSAJPool.add_lcsaj(className, methodName, currentLCSAJ); } else lcsaj_queue.add(currentLCSAJ); } else lcsaj_queue.add(currentLCSAJ); } if (Properties.STRATEGY != Strategy.EVOSUITE) addInstrumentation(classLoader, mn, className, methodName); // if (Properties.WRITE_CFG) // for (LCSAJ l : LCSAJPool.getLCSAJs(className, methodName)) { // LCSAJGraph graph = new LCSAJGraph(l, false); // String graphDestination = "evosuite-graphs/LCSAJGraphs/" + className // + "/" + methodName; // File dir = new File(graphDestination); // if (dir.mkdirs()) // graph.generate(new File(graphDestination + "/LCSAJGraph no: " // + l.getID() + ".dot")); // else if (dir.exists()) // graph.generate(new File(graphDestination + "/LCSAJGraph no: " // + l.getID() + ".dot")); // } }
From source file:org.evosuite.instrumentation.mutation.ReplaceArithmeticOperator.java
License:Open Source License
/** {@inheritDoc} */ @Override//www . j av a 2 s.c o m public List<Mutation> apply(MethodNode mn, String className, String methodName, BytecodeInstruction instruction, Frame frame) { numVariable = getNextIndex(mn); List<Mutation> mutations = new LinkedList<Mutation>(); InsnNode node = (InsnNode) instruction.getASMNode(); for (int opcode : getMutations(node.getOpcode())) { InsnNode mutation = new InsnNode(opcode); // insert mutation into pool Mutation mutationObject = MutationPool.addMutation(className, methodName, NAME + " " + getOp(node.getOpcode()) + " -> " + getOp(opcode), instruction, mutation, getInfectionDistance(node.getOpcode(), opcode)); mutations.add(mutationObject); } return mutations; }