List of usage examples for org.objectweb.asm.tree JumpInsnNode getNext
public AbstractInsnNode getNext()
From source file:jaspex.speculation.newspec.RemoveOverspeculation.java
License:Open Source License
/** Scan simples para tentar eliminar overspeculation. *//from w w w .j av a2 s . co 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:org.evosuite.instrumentation.testability.transformer.ImplicitElseTransformer.java
License:Open Source License
private void handleDependency(ControlDependency dependency, ControlDependenceGraph cdg, MethodNode mn, VarInsnNode varNode, BytecodeInstruction parentLevel) { if (addedNodes.contains(dependency)) return;// w w w.j a v a 2 s . c o m // 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(); //if (dependencies.size() == 1) { // 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; } } // The Flag assignment is is the dependency evaluates to the given value // We thus need to insert the tautoligical assignment either directly after the IF (if the value is true) // or before the jump target (if the value is false) 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); } } } }