Example usage for org.objectweb.asm Opcodes INVOKESPECIAL

List of usage examples for org.objectweb.asm Opcodes INVOKESPECIAL

Introduction

In this page you can find the example usage for org.objectweb.asm Opcodes INVOKESPECIAL.

Prototype

int INVOKESPECIAL

To view the source code for org.objectweb.asm Opcodes INVOKESPECIAL.

Click Source Link

Usage

From source file:de.tuberlin.uebb.jbop.access.ConstructorBuilder.java

License:Open Source License

private static MethodNode createMethodNode(final ClassNode node) {
    final MethodNode constructor = new MethodNode();
    constructor.access = Opcodes.ACC_PUBLIC;
    constructor.name = "<init>";
    constructor.exceptions = Collections.emptyList();
    final InsnList list = new InsnList();
    // currently only call to noarg super constructor is supported
    final AbstractInsnNode nThis = new VarInsnNode(Opcodes.ALOAD, 0);
    final AbstractInsnNode nSuperConstructor = new MethodInsnNode(Opcodes.INVOKESPECIAL, node.superName,
            "<init>", "()V");
    list.add(nThis);//from www .  j a  va2s  . co m
    list.add(nSuperConstructor);
    constructor.instructions = list;
    return constructor;
}

From source file:de.tuberlin.uebb.jbop.optimizer.ClassNodeBuilder.java

License:Open Source License

/**
 * Appends a Constructor with the given descriptors.
 * /* ww  w . j a  va 2s  .  co m*/
 * @param constructorDesc
 *          the constructor desc
 * @param superConstructorDesc
 *          the super constructor desc
 * @return the class node builder
 */
public ClassNodeBuilder addConstructor(final String constructorDesc, final String superConstructorDesc) {
    if (isInterface) {
        return this;
    }
    addMethod("<init>", constructorDesc);//
    lastConstructorVarIndex = 1;
    final InsnList list = new InsnList();
    list.add(new VarInsnNode(Opcodes.ALOAD, 0));
    final Type methodType = Type.getMethodType(superConstructorDesc);
    for (final Type parameterType : methodType.getArgumentTypes()) {
        list.add(new VarInsnNode(parameterType.getOpcode(ILOAD), lastConstructorVarIndex));
        lastConstructorVarIndex += parameterType.getSize();
    }
    list.add(new MethodInsnNode(Opcodes.INVOKESPECIAL, classNode.superName, "<init>", superConstructorDesc));
    list.add(new InsnNode(Opcodes.RETURN));
    addToConstructor(list);
    return this;
}

From source file:de.tuberlin.uebb.jbop.optimizer.methodsplitter.MethodSplitter.java

License:Open Source License

@Override
public InsnList optimize(final InsnList original, final MethodNode methodNode) throws JBOPClassException {

    LocalVariablesSorter sorter = new LocalVariablesSorter(methodNode.access, methodNode.desc,
            new EmptyMethodVisitor(Opcodes.ASM5));
    methodNode.accept(sorter);// www .java2  s .  co  m

    if (getLength(methodNode) < maxInsns) {
        return clean(original);
    }

    final List<Block> blocks = getBlocks(original, methodNode);

    final String baseName = methodNode.name;
    final String[] exceptions = getExceptions(methodNode);

    final InsnList returnList = new InsnList();
    InsnList list = returnList;

    Block block = blocks.get(0);
    block.renameInsns(block.getVarMap());

    final String name = baseName + "__split__part__";
    final Type endType = Type.getReturnType(methodNode.desc);
    for (int i = 1; i < blocks.size(); ++i) {
        final Map<Integer, Integer> paramRenameMap = block.getVarMap();
        add(list, block.getInstructions(), original);
        block = blocks.get(i);
        block.renameInsns(paramRenameMap);
        final String methodDescriptor = block.getDescriptor();
        final String newMethodName = name + block.getBlockNumber();
        final MethodNode splitMethod = new MethodNode(Opcodes.ASM5, ACCESS, newMethodName, methodDescriptor,
                null, exceptions);
        additionalMethods.add(splitMethod);

        list.add(new VarInsnNode(Opcodes.ALOAD, 0));
        list.add(block.getPushParameters());
        list.add(new MethodInsnNode(Opcodes.INVOKESPECIAL, classNode.name, splitMethod.name, methodDescriptor));
        list.add(new InsnNode(endType.getOpcode(IRETURN)));
        sorter = new LocalVariablesSorter(splitMethod.access, splitMethod.desc,
                new EmptyMethodVisitor(Opcodes.ASM5));
        splitMethod.accept(sorter);
        list = splitMethod.instructions;
    }
    add(list, block.getInstructions(), original);
    return returnList;
}

From source file:de.unisb.cs.st.javalanche.mutation.bytecodeMutations.removeSystemExit.RemoveSystemExitMethodAdapter.java

License:Open Source License

@Override
public void visitMethodInsn(int opcode, String owner, String name, String desc) {
    if (name.equals("exita") && owner.equals("java/lang/System")) {
        logger.info("Replacing System.exit ");

        Label mutationStartLabel = new Label();
        mutationStartLabel.info = new MutationMarker(true);
        mv.visitLabel(mutationStartLabel);

        mv.visitInsn(Opcodes.POP);/*from ww w .j a v a 2  s . c  om*/
        mv.visitTypeInsn(Opcodes.NEW, "java/lang/RuntimeException");
        mv.visitInsn(Opcodes.DUP);
        mv.visitLdcInsn("Replaced System Exit");
        mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/lang/RuntimeException", "<init>",
                "(Ljava/lang/String;)V");
        mv.visitInsn(Opcodes.ATHROW);

        Label mutationEndLabel = new Label();
        mutationEndLabel.info = new MutationMarker(false);
        mv.visitLabel(mutationEndLabel);

    } else {
        super.visitMethodInsn(opcode, owner, name, desc);
    }
}

From source file:de.unisb.cs.st.javalanche.mutation.bytecodeMutations.removeSystemExit.RemoveSystemExitMethodNode.java

License:Open Source License

@SuppressWarnings("unchecked")
// Call to pre-1.5 Code
@Override//  w w  w. j  ava 2 s  .  c  om
public void visitEnd() {
    MethodNode mn = (MethodNode) mv;
    InsnList insns = mn.instructions;
    Iterator i = insns.iterator();
    AbstractInsnNode prev = null;
    InsnList newInstrucionList = new InsnList();
    while (i.hasNext()) {
        boolean addInstruction = true;
        AbstractInsnNode i1 = (AbstractInsnNode) i.next();
        if (i1 instanceof MethodInsnNode) {
            MethodInsnNode methotInsnNode = (MethodInsnNode) i1;
            if (methotInsnNode.name.equals("exit") && methotInsnNode.owner.equals("java/lang/System")) {
                logger.info("Replacing System.exit ");
                newInstrucionList.remove(prev);
                // insns.remove(i1);
                InsnList il = new InsnList();
                Label mutationStartLabel = new Label();
                mutationStartLabel.info = new MutationMarker(true);

                il.add(new LabelNode(mutationStartLabel));
                il.add(new TypeInsnNode(Opcodes.NEW, "java/lang/RuntimeException"));
                il.add(new InsnNode(Opcodes.DUP));
                il.add(new LdcInsnNode("Replaced System.exit()"));
                il.add(new MethodInsnNode(Opcodes.INVOKESPECIAL, "java/lang/RuntimeException", "<init>",
                        "(Ljava/lang/String;)V"));
                il.add(new InsnNode(Opcodes.ATHROW));

                Label mutationEndLabel = new Label();
                mutationEndLabel.info = new MutationMarker(false);
                il.add(new LabelNode(mutationEndLabel));
                newInstrucionList.add(il);
                addInstruction = false;
            }
        }
        if (addInstruction) {
            try {
                insns.remove(i1);
                newInstrucionList.add(i1);
            } catch (Exception e) {
                logger.error(e);
            }

        }
        prev = i1;
    }
    mn.instructions = newInstrucionList;
    mn.accept(next);
}

From source file:de.unisb.cs.st.javaslicer.common.classRepresentation.instructions.MethodInvocationInstruction.java

License:Open Source License

public MethodInvocationInstruction(final ReadMethod readMethod, final int opcode, final int lineNumber,
        final String internalClassName, final String methodName, final String methodDesc) {
    super(readMethod, opcode, lineNumber);
    assert opcode == Opcodes.INVOKEVIRTUAL || opcode == Opcodes.INVOKESPECIAL || opcode == Opcodes.INVOKESTATIC
            || opcode == Opcodes.INVOKEINTERFACE;
    this.internalClassName = internalClassName;
    this.methodName = methodName;
    this.methodDesc = methodDesc;
    final org.objectweb.asm.Type[] parameterTypes = org.objectweb.asm.Type.getArgumentTypes(methodDesc);
    this.parameterIsLong = new boolean[parameterTypes.length];
    for (int i = 0; i < parameterTypes.length; ++i) {
        this.parameterIsLong[i] = parameterTypes[i].getSize() == 2;
    }/*from ww  w  .  ja  v  a  2s.  c om*/
    org.objectweb.asm.Type returnType = org.objectweb.asm.Type.getReturnType(methodDesc);
    this.returnedSize = returnType == org.objectweb.asm.Type.VOID_TYPE ? 0 : (byte) returnType.getSize();
}

From source file:de.unisb.cs.st.javaslicer.common.classRepresentation.instructions.MethodInvocationInstruction.java

License:Open Source License

private MethodInvocationInstruction(final ReadMethod readMethod, final int lineNumber, final int opcode,
        final String internalClassName, final String methodName, final String methodDesc, final int index) {
    super(readMethod, opcode, lineNumber, index);
    assert opcode == Opcodes.INVOKEVIRTUAL || opcode == Opcodes.INVOKESPECIAL || opcode == Opcodes.INVOKESTATIC
            || opcode == Opcodes.INVOKEINTERFACE;
    this.internalClassName = internalClassName;
    this.methodName = methodName;
    this.methodDesc = methodDesc;
    final org.objectweb.asm.Type[] parameterTypes = org.objectweb.asm.Type.getArgumentTypes(methodDesc);
    this.parameterIsLong = new boolean[parameterTypes.length];
    for (int i = 0; i < parameterTypes.length; ++i) {
        this.parameterIsLong[i] = parameterTypes[i].getSize() == 2;
    }//from w  w w .  j a  va  2  s . com
    org.objectweb.asm.Type returnType = org.objectweb.asm.Type.getReturnType(methodDesc);
    this.returnedSize = returnType == org.objectweb.asm.Type.VOID_TYPE ? 0 : (byte) returnType.getSize();
}

From source file:de.unisb.cs.st.javaslicer.common.classRepresentation.instructions.MethodInvocationInstruction.java

License:Open Source License

@Override
public String toString() {
    String type;/* w  w  w .  j  a  v  a 2s . c o m*/
    switch (getOpcode()) {
    case Opcodes.INVOKEVIRTUAL:
        type = "INVOKEVIRTUAL";
        break;
    case Opcodes.INVOKESPECIAL:
        type = "INVOKESPECIAL";
        break;
    case Opcodes.INVOKESTATIC:
        type = "INVOKESTATIC";
        break;
    case Opcodes.INVOKEINTERFACE:
        type = "INVOKEINTERFACE";
        break;
    default:
        assert false;
        type = "--ERROR--";
    }

    final StringBuilder sb = new StringBuilder(type.length() + this.internalClassName.length()
            + this.methodName.length() + this.methodDesc.length() + 2);
    sb.append(type).append(' ').append(this.internalClassName).append('.').append(this.methodName)
            .append(this.methodDesc);
    return sb.toString();
}

From source file:de.unisb.cs.st.javaslicer.jung.ShowJungGraph.java

License:Open Source License

protected static String getShortInstructionText(Instruction inst) {
    if (inst.getType() == InstructionType.METHODINVOCATION) {
        MethodInvocationInstruction mtdInv = (MethodInvocationInstruction) inst;
        String type;//from w  w  w .j ava 2  s . co  m
        switch (mtdInv.getOpcode()) {
        case Opcodes.INVOKEVIRTUAL:
            type = "INVOKEVIRTUAL";
            break;
        case Opcodes.INVOKESPECIAL:
            type = "INVOKESPECIAL";
            break;
        case Opcodes.INVOKESTATIC:
            type = "INVOKESTATIC";
            break;
        case Opcodes.INVOKEINTERFACE:
            type = "INVOKEINTERFACE";
            break;
        default:
            assert false;
            type = "--ERROR--";
        }

        return type + ' ' + getSimpleClassName(mtdInv.getInvokedInternalClassName()) + '.'
                + mtdInv.getInvokedMethodName();
    }
    return inst.toString();
}

From source file:de.unisb.cs.st.javaslicer.slicing.Slicer.java

License:Open Source License

public void process(ThreadId threadId, final List<SlicingCriterion> sc, boolean multithreaded)
        throws InterruptedException {
    DependencesExtractor<SlicerInstance> depExtractor = DependencesExtractor.forTrace(this.trace,
            SlicerInstanceFactory.instance);
    for (ProgressMonitor mon : this.progressMonitors)
        depExtractor.addProgressMonitor(mon);

    VisitorCapability[] capabilities = { VisitorCapability.CONTROL_DEPENDENCES,
            VisitorCapability.DATA_DEPENDENCES_READ_AFTER_WRITE, VisitorCapability.INSTRUCTION_EXECUTIONS,
            VisitorCapability.METHOD_ENTRY_LEAVE, VisitorCapability.CONTROL_DEPENDENCES };
    if (this.untracedCallVisitors.size() > 0)
        capabilities[capabilities.length - 1] = VisitorCapability.UNTRACED_METHOD_CALLS;

    final List<SliceVisitor> sliceVisitors0 = Slicer.this.sliceVisitors;
    final List<UntracedCallVisitor> untracedCallVisitors0 = Slicer.this.untracedCallVisitors;
    depExtractor.registerVisitor(new DependencesVisitorAdapter<SlicerInstance>() {
        private final List<SlicingCriterionInstance> slicingCritInst = instantiateSlicingCriteria(sc);
        @SuppressWarnings("unchecked")
        private IntegerMap<Object>[] interestingLocalVariables = (IntegerMap<Object>[]) new IntegerMap<?>[0];
        private long[] critOccurenceNumbers = new long[2]; // 0 if not in a criterion
        private final SliceVisitor[] sliceVisitorsArray = sliceVisitors0
                .toArray(new SliceVisitor[sliceVisitors0.size()]);
        private final UntracedCallVisitor[] untracedCallsVisitorsArray = untracedCallVisitors0
                .toArray(new UntracedCallVisitor[untracedCallVisitors0.size()]);

        private ReadMethod enteredMethod;

        private List<SlicingCriterionInstance> instantiateSlicingCriteria(List<SlicingCriterion> criteria) {
            if (criteria.isEmpty())
                return Collections.emptyList();
            else if (criteria.size() == 1)
                return Collections.singletonList(criteria.get(0).getInstance());
            else {
                List<SlicingCriterionInstance> instances = new ArrayList<SlicingCriterionInstance>(
                        criteria.size());
                for (SlicingCriterion crit : criteria)
                    instances.add(crit.getInstance());
                return instances;
            }//from  w  w w.j  ava2  s. c o m
        }

        @Override
        public void visitInstructionExecution(SlicerInstance instance) {
            int stackDepth = instance.getStackDepth();
            if (this.critOccurenceNumbers.length <= stackDepth) {
                long[] newCritOccurenceNumbers = new long[2
                        * Math.max(this.critOccurenceNumbers.length, stackDepth)];
                System.arraycopy(this.critOccurenceNumbers, 0, newCritOccurenceNumbers, 0,
                        this.critOccurenceNumbers.length);
                this.critOccurenceNumbers = newCritOccurenceNumbers;
            }
            Instruction instruction = instance.getInstruction();
            for (SlicingCriterionInstance crit : this.slicingCritInst) {
                if (crit.matches(instance)) {
                    this.critOccurenceNumbers[stackDepth] = crit.getOccurenceNumber();
                    assert this.critOccurenceNumbers[stackDepth] > 0;
                    // for each criterion, there are three cases:
                    //  - track all data and control dependences of the instruction
                    //  - track a given set of local variables
                    //  - track the control dependences of this instruction
                    // only in the first case, the instruction itself is added to the dynamic slice
                    instance.fullTransitiveClosure = crit.computeTransitiveClosure();
                    if (instance.fullTransitiveClosure) {
                        // first case
                        if (instruction.getType() != InstructionType.LABEL
                                && instruction.getOpcode() != Opcodes.GOTO)
                            for (SliceVisitor vis : this.sliceVisitorsArray)
                                vis.visitMatchedInstance(instance);
                        instance.onDynamicSlice = true;
                        instance.criterionDistance = 0;
                    } else if (crit.hasLocalVariables()) {
                        // second case
                        if (this.interestingLocalVariables.length <= stackDepth) {
                            @SuppressWarnings("unchecked")
                            IntegerMap<Object>[] newInterestingLocalVariables = (IntegerMap<Object>[]) new IntegerMap<?>[Math
                                    .max(stackDepth + 1, this.interestingLocalVariables.length * 3 / 2)];
                            System.arraycopy(this.interestingLocalVariables, 0, newInterestingLocalVariables, 0,
                                    this.interestingLocalVariables.length);
                            this.interestingLocalVariables = newInterestingLocalVariables;
                        }
                        List<LocalVariable> localVariables = crit.getLocalVariables();
                        if (this.interestingLocalVariables[stackDepth] == null)
                            this.interestingLocalVariables[stackDepth] = new IntegerMap<Object>(
                                    localVariables.size() * 4 / 3 + 1);
                        for (LocalVariable i : localVariables)
                            this.interestingLocalVariables[stackDepth].put(i.getIndex(), null);
                    } else {
                        // third case
                        instance.onDynamicSlice = true;
                        instance.criterionDistance = 0;
                    }
                } else if (this.critOccurenceNumbers[stackDepth] != 0) {
                    this.critOccurenceNumbers[stackDepth] = 0;
                }
            }
            if (this.interestingLocalVariables.length > stackDepth
                    && this.interestingLocalVariables[stackDepth] != null) {
                switch (instruction.getOpcode()) {
                case Opcodes.ISTORE:
                case Opcodes.ASTORE:
                case Opcodes.LSTORE:
                case Opcodes.FSTORE:
                case Opcodes.DSTORE:
                    VarInstruction varInsn = (VarInstruction) instruction;
                    if (this.interestingLocalVariables[stackDepth].containsKey(varInsn.getLocalVarIndex())) {
                        this.interestingLocalVariables[stackDepth].remove(varInsn.getLocalVarIndex());
                        if (this.interestingLocalVariables[stackDepth].isEmpty())
                            this.interestingLocalVariables[stackDepth] = null;
                        for (SliceVisitor vis : this.sliceVisitorsArray)
                            vis.visitMatchedInstance(instance);
                        instance.onDynamicSlice = true;
                        // and we want to know where the data comes from...
                        instance.fullTransitiveClosure = true;
                        instance.criterionDistance = 0;
                    }
                    break;
                case Opcodes.INVOKEINTERFACE:
                case Opcodes.INVOKESPECIAL:
                case Opcodes.INVOKESTATIC:
                case Opcodes.INVOKEVIRTUAL:
                    if (this.enteredMethod != null) {
                        MethodInvocationInstruction mtdInvInsn = (MethodInvocationInstruction) instruction;
                        int paramCount = instruction.getOpcode() == INVOKESTATIC ? 0 : 1;
                        for (int param = mtdInvInsn.getParameterCount() - 1; param >= 0; --param)
                            paramCount += mtdInvInsn.parameterIsLong(param) ? 2 : 1;
                        boolean enteredMethodMatches = this.enteredMethod.getName()
                                .equals(mtdInvInsn.getInvokedMethodName())
                                && this.enteredMethod.getDesc().equals(mtdInvInsn.getInvokedMethodDesc());
                        if (enteredMethodMatches) {
                            boolean localVarsMatched = false;
                            for (int varNr = 0; varNr < paramCount; ++varNr) {
                                if (this.interestingLocalVariables[stackDepth].containsKey(varNr)) {
                                    this.interestingLocalVariables[stackDepth].remove(varNr);
                                    if (this.interestingLocalVariables[stackDepth].isEmpty())
                                        this.interestingLocalVariables[stackDepth] = null;
                                    localVarsMatched = true;
                                    instance.onDynamicSlice = true;
                                    // and we want to know where the data comes from...
                                    // TODO
                                    instance.fullTransitiveClosure = true;
                                    instance.criterionDistance = 0;
                                }
                            }
                            if (localVarsMatched)
                                for (SliceVisitor vis : this.sliceVisitorsArray)
                                    vis.visitMatchedInstance(instance);
                        }
                    }
                }
            }
            this.enteredMethod = null;
        }

        @Override
        public void visitControlDependence(SlicerInstance from, SlicerInstance to) {
            if (from.onDynamicSlice) {
                Instruction insn = to.getInstruction();
                if (insn.getType() == InstructionType.LABEL || insn.getOpcode() == Opcodes.GOTO) {
                    if (to.predecessors == null)
                        to.predecessors = Collections.singleton(from);
                    else {
                        if (to.predecessors.size() == 1)
                            to.predecessors = new HashSet<SlicerInstance>(to.predecessors);
                        to.predecessors.add(from);
                    }
                    if (from.criterionDistance < to.criterionDistance)
                        to.criterionDistance = from.criterionDistance;
                } else if (from.predecessors != null) {
                    assert (!from.predecessors.isEmpty());
                    for (SlicerInstance pred : from.predecessors) {
                        int distance = pred.criterionDistance + 1;
                        delegateControlSliceDependence(pred, to, distance);
                        if (distance < to.criterionDistance)
                            to.criterionDistance = distance;
                    }
                } else {
                    int distance = from.criterionDistance + 1;
                    delegateControlSliceDependence(from, to, distance);
                    if (distance < to.criterionDistance)
                        to.criterionDistance = distance;
                }
                to.onDynamicSlice = true;
            }
        }

        private void delegateControlSliceDependence(SlicerInstance from, SlicerInstance to, int distance) {

            for (SliceVisitor vis : this.sliceVisitorsArray)
                vis.visitSliceDependence(from, to, null, distance);

            // since "to" controls the execution of "from", we want to track all data dependences of "to"
            // to find out why it took this decision
            // exception: method invocations; here we only want to track why the method was executed,
            // but not the data that it consumed
            // important to check that "from" comes from inside the method which is called by "from"
            boolean calledMethodDependence = false;
            if (to.getInstruction().getType() == InstructionType.METHODINVOCATION) {
                MethodInvocationInstruction mtdInv = (MethodInvocationInstruction) to.getInstruction();
                ReadMethod calledMethod = from.getInstruction().getMethod();
                if (mtdInv.getInvokedMethodName().equals(calledMethod.getName())
                        && mtdInv.getInvokedMethodDesc().equals(calledMethod.getDesc())) {
                    calledMethodDependence = true;
                }
            }
            if (!calledMethodDependence) {
                to.fullTransitiveClosure = true;
            }
        }

        @Override
        public void visitDataDependence(SlicerInstance from, SlicerInstance to,
                Collection<? extends Variable> fromVars, Variable toVar, DataDependenceType type)
                throws InterruptedException {
            assert type == DataDependenceType.READ_AFTER_WRITE;

            if (from.onDynamicSlice && // from must definitively be on the dynamic slice
            (from.fullTransitiveClosure || // and either we want to track all data dependencies
            (from.interestingVariable != null && ( // or (if the interestingVariable is set) ...
            from.interestingVariable.equals(toVar) || // the interestingVariable must be the one we are just visiting
            (from.moreInterestingVariables != null && from.moreInterestingVariables.contains(toVar)))))) { // or it must be in the set of more variables
                Instruction insn = to.getInstruction();
                assert insn.getType() != InstructionType.LABEL;
                int distance = from.criterionDistance + 1;
                if (distance < to.criterionDistance)
                    to.criterionDistance = distance;
                for (SliceVisitor vis : this.sliceVisitorsArray)
                    vis.visitSliceDependence(from, to, toVar, distance);

                if (!fromVars.isEmpty()) {
                    Iterator<? extends Variable> varIt = fromVars.iterator();
                    assert varIt
                            .hasNext() : "Iterator of a non-empty collection should have at least one element";
                    Variable first = varIt.next();
                    if (to.interestingVariable == null || to.interestingVariable.equals(first)) {
                        to.interestingVariable = first;
                        first = varIt.hasNext() ? varIt.next() : null;
                    }
                    if (first != null) {
                        if (to.moreInterestingVariables == null)
                            to.moreInterestingVariables = new HashSet<Variable>(8);
                        to.moreInterestingVariables.add(first);
                        while (varIt.hasNext())
                            to.moreInterestingVariables.add(varIt.next());
                    }
                }
                to.onDynamicSlice = true;
            }
        }

        @Override
        public void visitMethodLeave(ReadMethod method, int stackDepth) throws InterruptedException {
            if (this.interestingLocalVariables.length > stackDepth
                    && this.interestingLocalVariables[stackDepth] != null) {
                this.interestingLocalVariables[stackDepth] = null;
            }
        }

        @Override
        public void visitMethodEntry(ReadMethod method, int stackDepth) throws InterruptedException {
            if (this.interestingLocalVariables.length > stackDepth
                    && this.interestingLocalVariables[stackDepth] != null) {
                this.enteredMethod = method;
                this.interestingLocalVariables[stackDepth] = null;
            }
        }

        @Override
        public void visitUntracedMethodCall(SlicerInstance instrInstance) throws InterruptedException {
            for (UntracedCallVisitor vis : this.untracedCallsVisitorsArray)
                vis.visitUntracedMethodCall(instrInstance);
        }

    }, capabilities);

    depExtractor.processBackwardTrace(threadId, multithreaded);
}