use of org.evosuite.graphs.cfg.BytecodeInstruction in project evosuite by EvoSuite.
the class ImplicitElseTransformer method handleDependency.
private void handleDependency(ControlDependency dependency, ControlDependenceGraph cdg, MethodNode mn, VarInsnNode varNode, BytecodeInstruction parentLevel) {
if (addedNodes.contains(dependency))
return;
// Get the basic blocks reachable if the dependency would evaluate different
Set<BasicBlock> blocks = cdg.getAlternativeBlocks(dependency);
addedNodes.add(dependency);
Set<ControlDependency> dependencies = dependency.getBranch().getInstruction().getControlDependencies();
// ControlDependency dep = dependencies.iterator().next();
for (ControlDependency dep : dependencies) {
if (!addedNodes.contains(dep) && dep != dependency)
handleDependency(dep, cdg, mn, varNode, dependency.getBranch().getInstruction());
}
// TODO: Need to check that there is an assignment in every alternative path through CDG
boolean hasAssignment = false;
for (BasicBlock block : blocks) {
// If this block also assigns a value to the same variable
for (BytecodeInstruction instruction : block) {
if (instruction.getASMNode().getOpcode() == Opcodes.ISTORE) {
VarInsnNode otherVarNode = (VarInsnNode) instruction.getASMNode();
VarInsnNode thisVarNode = varNode;
if (otherVarNode.var == thisVarNode.var) {
hasAssignment = true;
break;
}
}
}
if (hasAssignment) {
break;
}
}
if (!hasAssignment) {
TransformationStatistics.transformedImplicitElse();
if (dependency.getBranch().getInstruction().isSwitch()) {
BooleanTestabilityTransformation.logger.warn("Don't know how to handle Switches yet");
return;
}
JumpInsnNode jumpNode = (JumpInsnNode) dependency.getBranch().getInstruction().getASMNode();
VarInsnNode newStore = new VarInsnNode(Opcodes.ISTORE, varNode.var);
VarInsnNode newLoad = new VarInsnNode(Opcodes.ILOAD, varNode.var);
if (dependency.getBranchExpressionValue()) {
BooleanTestabilityTransformation.logger.info("Inserting else branch directly after if");
// Insert directly after if
if (isDefinedBefore(mn, varNode, jumpNode)) {
mn.instructions.insert(jumpNode, newStore);
mn.instructions.insert(jumpNode, newLoad);
registerInstruction(mn, varNode, newStore);
registerInstruction(mn, varNode, newLoad);
}
} else {
BooleanTestabilityTransformation.logger.info("Inserting else branch as jump target");
// Insert as jump target
if (isDefinedBefore(mn, varNode, jumpNode)) {
LabelNode target = jumpNode.label;
LabelNode newTarget = new LabelNode(new Label());
// jumpNode or target?
registerInstruction(mn, jumpNode.getNext(), newStore);
registerInstruction(mn, jumpNode.getNext(), newLoad);
InsnList assignment = new InsnList();
assignment.add(new JumpInsnNode(Opcodes.GOTO, target));
assignment.add(newTarget);
assignment.add(newLoad);
assignment.add(newStore);
jumpNode.label = newTarget;
mn.instructions.insertBefore(target, assignment);
}
}
}
}
use of org.evosuite.graphs.cfg.BytecodeInstruction in project evosuite by EvoSuite.
the class ImplicitElseTransformer method registerInstruction.
private void registerInstruction(MethodNode mn, AbstractInsnNode oldValue, AbstractInsnNode newValue) {
BytecodeInstruction oldInstruction = BytecodeInstructionPool.getInstance(this.booleanTestabilityTransformation.classLoader).getInstruction(this.booleanTestabilityTransformation.className, mn.name + mn.desc, oldValue);
BytecodeInstruction instruction = BytecodeInstructionFactory.createBytecodeInstruction(this.booleanTestabilityTransformation.classLoader, this.booleanTestabilityTransformation.className, mn.name + mn.desc, oldInstruction.getInstructionId(), 0, newValue);
instruction.setBasicBlock(oldInstruction.getBasicBlock());
BytecodeInstructionPool.getInstance(this.booleanTestabilityTransformation.classLoader).registerInstruction(instruction);
}
use of org.evosuite.graphs.cfg.BytecodeInstruction in project evosuite by EvoSuite.
the class ImplicitElseTransformer method handleDependency.
private void handleDependency(ControlDependency dependency, ControlDependenceGraph cdg, MethodNode mn, FieldInsnNode varNode, BytecodeInstruction parentLevel) {
if (addedNodes.contains(dependency))
return;
// Get the basic blocks reachable if the dependency would evaluate different
Set<BasicBlock> blocks = cdg.getAlternativeBlocks(dependency);
addedNodes.add(dependency);
Set<ControlDependency> dependencies = dependency.getBranch().getInstruction().getControlDependencies();
// ControlDependency dep = dependencies.iterator().next();
for (ControlDependency dep : dependencies) {
if (!addedNodes.contains(dep) && dep != dependency)
handleDependency(dep, cdg, mn, varNode, dependency.getBranch().getInstruction());
}
// TODO: Need to check that there is an assignment in every alternative path through CDG
boolean hasAssignment = false;
for (BasicBlock block : blocks) {
// If this block also assigns a value to the same variable
for (BytecodeInstruction instruction : block) {
if (instruction.getASMNode().getOpcode() == Opcodes.PUTFIELD || instruction.getASMNode().getOpcode() == Opcodes.PUTSTATIC) {
FieldInsnNode otherFieldNode = (FieldInsnNode) instruction.getASMNode();
FieldInsnNode thisFieldNode = varNode;
if (otherFieldNode.owner.equals(thisFieldNode.owner) && otherFieldNode.name.equals(thisFieldNode.name)) {
hasAssignment = true;
break;
}
}
}
if (hasAssignment) {
break;
}
}
if (!hasAssignment) {
if (dependency.getBranch().getInstruction().isSwitch()) {
BooleanTestabilityTransformation.logger.warn("Don't know how to handle Switches yet");
return;
}
TransformationStatistics.transformedImplicitElse();
JumpInsnNode jumpNode = (JumpInsnNode) dependency.getBranch().getInstruction().getASMNode();
FieldInsnNode newLoad = new FieldInsnNode(varNode.getOpcode() == Opcodes.PUTSTATIC ? Opcodes.GETSTATIC : Opcodes.GETFIELD, varNode.owner, varNode.name, varNode.desc);
FieldInsnNode newStore = new FieldInsnNode(varNode.getOpcode(), varNode.owner, varNode.name, varNode.desc);
AbstractInsnNode newOwnerLoad1 = null;
AbstractInsnNode newOwnerLoad2 = null;
if (varNode.getOpcode() == Opcodes.PUTFIELD) {
// Need to copy the bloody owner
// Check for VarInsn
// if (varNode.getPrevious().getOpcode() == Opcodes.ALOAD) {
newOwnerLoad1 = new VarInsnNode(Opcodes.ALOAD, 0);
newOwnerLoad2 = new VarInsnNode(Opcodes.ALOAD, 0);
/*
} else {
// Else use helper function
// Insert DUP and
logger.info("Wargh");
System.exit(0);
fieldOwnerId++;
InsnNode dupNode = new InsnNode(Opcodes.DUP);
mn.instructions.insertBefore(varNode, new LdcInsnNode(
fieldOwnerId));
mn.instructions.insertBefore(varNode, dupNode);
registerInstruction(mn, varNode, dupNode);
MethodInsnNode storeOwner = new MethodInsnNode(
Opcodes.INVOKESTATIC,
"org/evosuite/instrumentation/BooleanHelper",
"setFieldOwner", "(ILjava/lang/Object;)V");
mn.instructions.insertBefore(varNode, storeOwner);
registerInstruction(mn, varNode, storeOwner);
newOwnerLoad1 = new MethodInsnNode(Opcodes.INVOKESTATIC,
"org/evosuite/instrumentation/BooleanHelper",
"getFieldOwner", "(I)Ljava/lang/Object;");
newOwnerLoad2 = new MethodInsnNode(Opcodes.INVOKESTATIC,
"org/evosuite/instrumentation/BooleanHelper",
"getFieldOwner", "(I)Ljava/lang/Object;");
}
*/
}
if (dependency.getBranchExpressionValue()) {
BooleanTestabilityTransformation.logger.info("Inserting after if");
// Insert directly after if
mn.instructions.insert(jumpNode, newStore);
mn.instructions.insert(jumpNode, newLoad);
if (newOwnerLoad1 != null) {
mn.instructions.insert(jumpNode, newOwnerLoad1);
registerInstruction(mn, varNode, newOwnerLoad1);
}
if (newOwnerLoad2 != null) {
mn.instructions.insert(jumpNode, newOwnerLoad2);
registerInstruction(mn, varNode, newOwnerLoad2);
}
registerInstruction(mn, varNode, newStore);
registerInstruction(mn, varNode, newLoad);
} else {
BooleanTestabilityTransformation.logger.info("Inserting as jump target");
// Insert as jump target
LabelNode target = jumpNode.label;
LabelNode newTarget = new LabelNode(new Label());
registerInstruction(mn, target, newStore);
registerInstruction(mn, target, newLoad);
InsnList assignment = new InsnList();
assignment.add(new JumpInsnNode(Opcodes.GOTO, target));
assignment.add(newTarget);
if (newOwnerLoad1 != null) {
assignment.add(newOwnerLoad1);
registerInstruction(mn, target, newOwnerLoad1);
}
if (newOwnerLoad2 != null) {
assignment.add(newOwnerLoad2);
registerInstruction(mn, target, newOwnerLoad2);
}
assignment.add(newLoad);
assignment.add(newStore);
jumpNode.label = newTarget;
mn.instructions.insertBefore(target, assignment);
}
addedInsns.add(newStore);
addedInsns.add(newLoad);
}
}
use of org.evosuite.graphs.cfg.BytecodeInstruction in project evosuite by EvoSuite.
the class MutationInstrumentation method analyze.
/* (non-Javadoc)
* @see org.evosuite.cfg.instrumentation.MethodInstrumentation#analyze(org.objectweb.asm.tree.MethodNode, java.lang.String, java.lang.String, int)
*/
/**
* {@inheritDoc}
*/
@SuppressWarnings("unchecked")
@Override
public void analyze(ClassLoader classLoader, MethodNode mn, String className, String methodName, int access) {
if (methodName.startsWith("<clinit>"))
return;
if (methodName.startsWith(ClassResetter.STATIC_RESET))
return;
RawControlFlowGraph graph = GraphPool.getInstance(classLoader).getRawCFG(className, methodName);
Iterator<AbstractInsnNode> j = mn.instructions.iterator();
getFrames(mn, className);
boolean constructorInvoked = false;
if (!methodName.startsWith("<init>"))
constructorInvoked = true;
logger.info("Applying mutation operators ");
int frameIndex = 0;
int numMutants = 0;
if (frames.length != mn.instructions.size()) {
logger.error("Number of frames does not match number number of bytecode instructions: " + frames.length + "/" + mn.instructions.size());
logger.error("Skipping mutation of method " + className + "." + methodName);
return;
}
// + " vs " + mn.instructions.size();
while (j.hasNext()) {
Frame currentFrame = frames[frameIndex++];
AbstractInsnNode in = j.next();
if (!constructorInvoked) {
if (in.getOpcode() == Opcodes.INVOKESPECIAL) {
if (className.matches(".*\\$\\d+$")) {
// so best not mutate the constructor
continue;
}
MethodInsnNode cn = (MethodInsnNode) in;
Set<String> superClasses = new HashSet<String>();
if (DependencyAnalysis.getInheritanceTree() != null && DependencyAnalysis.getInheritanceTree().hasClass(className))
superClasses.addAll(DependencyAnalysis.getInheritanceTree().getSuperclasses(className));
superClasses.add(className);
String classNameWithDots = ResourceList.getClassNameFromResourcePath(cn.owner);
if (superClasses.contains(classNameWithDots)) {
constructorInvoked = true;
}
} else {
continue;
}
}
boolean inInstrumentation = false;
for (BytecodeInstruction v : graph.vertexSet()) {
// If the bytecode is instrumented by EvoSuite, then don't mutate
if (v.isLabel()) {
LabelNode labelNode = (LabelNode) v.getASMNode();
if (labelNode.getLabel() instanceof AnnotatedLabel) {
AnnotatedLabel aLabel = (AnnotatedLabel) labelNode.getLabel();
if (aLabel.isStartTag()) {
inInstrumentation = true;
} else {
inInstrumentation = false;
}
}
}
if (inInstrumentation) {
continue;
}
// If this is in the CFG
if (in.equals(v.getASMNode())) {
logger.info(v.toString());
List<Mutation> mutations = new LinkedList<Mutation>();
// TODO: More than one mutation operator might apply to the same instruction
for (MutationOperator mutationOperator : mutationOperators) {
if (numMutants++ > Properties.MAX_MUTANTS_PER_METHOD) {
logger.info("Reached maximum number of mutants per method");
break;
}
// logger.info("Checking mutation operator on instruction " + v);
if (mutationOperator.isApplicable(v)) {
logger.info("Applying mutation operator " + mutationOperator.getClass().getSimpleName());
mutations.addAll(mutationOperator.apply(mn, className, methodName, v, currentFrame));
}
}
if (!mutations.isEmpty()) {
logger.info("Adding instrumentation for mutation");
// InsnList instrumentation = getInstrumentation(in, mutations);
addInstrumentation(mn, in, mutations);
}
}
if (numMutants > Properties.MAX_MUTANTS_PER_METHOD) {
break;
}
}
}
j = mn.instructions.iterator();
logger.info("Result of mutation: ");
while (j.hasNext()) {
AbstractInsnNode in = j.next();
logger.info(new BytecodeInstruction(classLoader, className, methodName, 0, 0, in).toString());
}
logger.info("Done.");
// mn.maxStack += 3;
}
use of org.evosuite.graphs.cfg.BytecodeInstruction in project evosuite by EvoSuite.
the class DefUseInstrumentation method analyze.
/*
* (non-Javadoc)
*
* @see org.evosuite.cfg.MethodInstrumentation#analyze(org.objectweb
* .asm.tree.MethodNode, org.jgrapht.Graph, java.lang.String,
* java.lang.String)
*/
/**
* {@inheritDoc}
*/
@SuppressWarnings("unchecked")
@Override
public void analyze(ClassLoader classLoader, MethodNode mn, String className, String methodName, int access) {
RawControlFlowGraph completeCFG = GraphPool.getInstance(classLoader).getRawCFG(className, methodName);
logger.info("Applying DefUse instrumentation on CFG with " + completeCFG.vertexCount() + " nodes");
Iterator<AbstractInsnNode> j = mn.instructions.iterator();
while (j.hasNext()) {
AbstractInsnNode in = j.next();
for (BytecodeInstruction v : completeCFG.vertexSet()) {
if ((ArrayUtil.contains(Properties.CRITERION, Criterion.DEFUSE) || ArrayUtil.contains(Properties.CRITERION, Criterion.ALLDEFS)) && in.equals(v.getASMNode()) && v.isDefUse()) {
boolean isValidDU = false;
if (v.isMethodCallOfField()) {
// keep track of field method calls, though we do not
// know
// how to handle them at this point during the analysis
// (need complete CCFGs first)
isValidDU = DefUsePool.addAsFieldMethodCall(v);
} else {
// keep track of uses
if (v.isUse())
isValidDU = DefUsePool.addAsUse(v);
// keep track of definitions
if (v.isDefinition())
isValidDU = DefUsePool.addAsDefinition(v) || isValidDU;
}
if (isValidDU) {
boolean staticContext = v.isStaticDefUse() || ((access & Opcodes.ACC_STATIC) > 0);
// adding instrumentation for defuse-coverage
InsnList instrumentation = getInstrumentation(v, staticContext, className, methodName, mn);
if (instrumentation == null)
throw new IllegalStateException("error instrumenting node " + v.toString());
if (v.isMethodCallOfField())
mn.instructions.insertBefore(v.getASMNode(), instrumentation);
else if (v.isArrayStoreInstruction())
mn.instructions.insertBefore(v.getSourceOfArrayReference().getASMNode(), instrumentation);
else // mn.instructions.insertBefore(v.getSourceOfArrayReference().getASMNode(), instrumentation);
if (v.isUse())
mn.instructions.insert(v.getASMNode(), instrumentation);
else
mn.instructions.insertBefore(v.getASMNode(), instrumentation);
}
}
}
}
}
Aggregations