Example usage for org.objectweb.asm Opcodes GOTO

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

Introduction

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

Prototype

int GOTO

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

Click Source Link

Usage

From source file:de.unisb.cs.st.javaslicer.dependenceAnalysis.DependencesExtractor.java

License:Open Source License

/**
 * Go backwards through the execution trace of the given threadId and extract
 * all dependences. {@link DependencesVisitor}s should have been added before
 * by calling {@link #registerVisitor(DependencesVisitor, VisitorCapability...)}.
 *
 * @param threadId identifies the thread whose trace should be analyzed
 * @param multithreaded use an extra thread to traverse the trace
 * @throws InterruptedException if the thread was interrupted during traversal
 * @throws IllegalArgumentException if the trace contains no thread with this id
 *//*from w w  w .  j  a v  a  2s. c om*/
public void processBackwardTrace(ThreadId threadId, boolean multithreaded) throws InterruptedException {

    final BackwardTraceIterator<InstanceType> backwardInsnItr = this.trace.getBackwardIterator(threadId, null,
            this.instanceFactory);

    if (backwardInsnItr == null)
        throw new IllegalArgumentException("No such thread");

    // store the current set of visitors of each capability in an array for better
    // performance and faster empty-check (null reference if empty)
    final DependencesVisitor<? super InstanceType>[] dataDependenceVisitorsReadAfterWrite0 = this.dataDependenceVisitorsReadAfterWrite
            .isEmpty() ? null
                    : this.dataDependenceVisitorsReadAfterWrite.toArray(
                            newDependencesVisitorArray(this.dataDependenceVisitorsReadAfterWrite.size()));
    final DependencesVisitor<? super InstanceType>[] dataDependenceVisitorsWriteAfterRead0 = this.dataDependenceVisitorsWriteAfterRead
            .isEmpty() ? null
                    : this.dataDependenceVisitorsWriteAfterRead.toArray(
                            newDependencesVisitorArray(this.dataDependenceVisitorsWriteAfterRead.size()));
    final DependencesVisitor<? super InstanceType>[] controlDependenceVisitors0 = this.controlDependenceVisitors
            .isEmpty() ? null
                    : this.controlDependenceVisitors
                            .toArray(newDependencesVisitorArray(this.controlDependenceVisitors.size()));
    final DependencesVisitor<? super InstanceType>[] instructionVisitors0 = this.instructionVisitors.isEmpty()
            ? null
            : this.instructionVisitors.toArray(newDependencesVisitorArray(this.instructionVisitors.size()));
    final DependencesVisitor<? super InstanceType>[] pendingDataDependenceVisitorsReadAfterWrite0 = this.pendingDataDependenceVisitorsReadAfterWrite
            .isEmpty() ? null
                    : this.pendingDataDependenceVisitorsReadAfterWrite.toArray(newDependencesVisitorArray(
                            this.pendingDataDependenceVisitorsReadAfterWrite.size()));
    final DependencesVisitor<? super InstanceType>[] pendingDataDependenceVisitorsWriteAfterRead0 = this.pendingDataDependenceVisitorsWriteAfterRead
            .isEmpty() ? null
                    : this.pendingDataDependenceVisitorsWriteAfterRead.toArray(newDependencesVisitorArray(
                            this.pendingDataDependenceVisitorsWriteAfterRead.size()));
    final DependencesVisitor<? super InstanceType>[] pendingControlDependenceVisitors0 = this.pendingControlDependenceVisitors
            .isEmpty() ? null
                    : this.pendingControlDependenceVisitors
                            .toArray(newDependencesVisitorArray(this.pendingControlDependenceVisitors.size()));
    final DependencesVisitor<? super InstanceType>[] methodEntryLeaveVisitors0 = this.methodEntryLeaveVisitors
            .isEmpty() ? null
                    : this.methodEntryLeaveVisitors
                            .toArray(newDependencesVisitorArray(this.methodEntryLeaveVisitors.size()));
    final DependencesVisitor<? super InstanceType>[] objectCreationVisitors0 = this.objectCreationVisitors
            .isEmpty() ? null
                    : this.objectCreationVisitors
                            .toArray(newDependencesVisitorArray(this.objectCreationVisitors.size()));

    @SuppressWarnings("unchecked")
    DependencesVisitor<? super InstanceType>[] allVisitors = union(dataDependenceVisitorsReadAfterWrite0,
            dataDependenceVisitorsWriteAfterRead0, controlDependenceVisitors0, instructionVisitors0,
            pendingDataDependenceVisitorsReadAfterWrite0, pendingDataDependenceVisitorsWriteAfterRead0,
            pendingControlDependenceVisitors0, methodEntryLeaveVisitors0, objectCreationVisitors0);

    IntegerMap<Set<Instruction>> controlDependences = new IntegerMap<Set<Instruction>>();

    Iterator<InstanceType> instanceIterator;
    ProgressInformationProvider progressInfoProv;
    Thread iteratorThread = null;
    final AtomicReference<Throwable> iteratorException = new AtomicReference<Throwable>(null);
    if (multithreaded) {
        final AtomicLong percentPerInstance = this.progressMonitors.isEmpty() ? null
                : new AtomicLong(Double.doubleToLongBits(0)); // this AtomicLong holds a double value!!

        final BlockwiseSynchronizedBuffer<InstanceType> buffer = new BlockwiseSynchronizedBuffer<InstanceType>(
                1 << 16, 1 << 20);
        final InstanceType firstInstance = backwardInsnItr.hasNext() ? backwardInsnItr.next() : null;
        iteratorThread = new Thread("Trace iterator") {
            @Override
            public void run() {
                try {
                    int num = 0;
                    while (backwardInsnItr.hasNext()) {
                        buffer.put(backwardInsnItr.next());
                        if ((++num & ((1 << 16) - 1)) == 0 && percentPerInstance != null) {
                            double percentPerInstance0 = backwardInsnItr.getPercentageDone() / num;
                            percentPerInstance.set(Double.doubleToLongBits(percentPerInstance0));
                        }
                    }
                } catch (Throwable t) {
                    iteratorException.compareAndSet(null, t);
                } finally {
                    try {
                        buffer.put(firstInstance); // to signal that this is the end of the trace
                        buffer.flush();
                    } catch (InterruptedException e) {
                        iteratorException.compareAndSet(null, e);
                    }
                }
            }
        };
        iteratorThread.start();
        final AtomicLong numInstancesSeen = percentPerInstance == null ? null : new AtomicLong(0);
        instanceIterator = new Iterator<InstanceType>() {

            private InstanceType next = firstInstance;

            @Override
            public boolean hasNext() {
                if (this.next == null) {
                    while (true) {
                        try {
                            this.next = buffer.take();
                            if (this.next == firstInstance) {
                                this.next = null;
                            }
                            break;
                        } catch (InterruptedException e) {
                            // this.next stays null
                            assert this.next == null;
                            Thread.currentThread().interrupt();
                        }
                    }
                }
                return this.next != null;
            }

            @Override
            public InstanceType next() {
                if (!hasNext())
                    throw new NoSuchElementException();
                InstanceType ret = this.next;
                this.next = null;
                if (numInstancesSeen != null)
                    numInstancesSeen.incrementAndGet();
                return ret;
            }

            @Override
            public void remove() {
                throw new UnsupportedOperationException();
            }

        };
        progressInfoProv = percentPerInstance == null ? null : new ProgressInformationProvider() {
            @Override
            public double getPercentageDone() {
                return Double.longBitsToDouble(percentPerInstance.get()) * numInstancesSeen.get();
            }
        };
    } else {
        instanceIterator = backwardInsnItr;
        progressInfoProv = backwardInsnItr;
    }

    // the lastWriter is needed for WAR data dependences
    Map<Variable, InstanceType> lastWriter = new HashMap<Variable, InstanceType>();
    // lastReaders are needed for RAW data dependences
    Map<Variable, List<InstanceType>> lastReaders = new HashMap<Variable, List<InstanceType>>();

    /*
    HashSet<Long> createdObjects = new HashSet<Long>();
    HashSet<Long> seenObjects = new HashSet<Long>();
    */

    InstanceType instance = null;
    Instruction instruction = null;

    for (ProgressMonitor mon : this.progressMonitors)
        mon.start(progressInfoProv);

    try {

        long nextFrameNr = 0;
        int stackDepth = 0;

        List<ReadMethod> initialStackMethods = backwardInsnItr.getInitialStackMethods();

        int allocStack = initialStackMethods.size() + 1;
        allocStack = Integer.highestOneBit(allocStack) * 2;

        @SuppressWarnings("unchecked")
        InstanceType[] atCatchBlockStart = (InstanceType[]) (new InstructionInstance[allocStack]);
        boolean[] throwsException = new boolean[allocStack];
        boolean[] interruptedControlFlow = new boolean[allocStack];
        /**
         * <code>true</code> iff this frame was aborted abnormally (NOT by a RETURN
         * instruction)
         */
        boolean[] abnormalTermination = new boolean[allocStack];
        /**
         * is set to true if the methods entry label has been passed
         */
        boolean[] finished = new boolean[allocStack];
        int[] opStack = new int[allocStack];
        int[] minOpStack = new int[allocStack];
        long[] frames = new long[allocStack];
        Instruction[] lastInstruction = new Instruction[allocStack];
        @SuppressWarnings("unchecked")
        HashSet<InstanceType>[] interestingInstances = (HashSet<InstanceType>[]) new HashSet<?>[allocStack];
        StackEntry[][] cachedStackEntries = new StackEntry[allocStack][];
        LocalVariable[][] cachedLocalVariables = new LocalVariable[allocStack][];
        ReadMethod[] method = new ReadMethod[allocStack];

        for (ReadMethod method0 : initialStackMethods) {
            ++stackDepth;
            method[stackDepth] = method0;
            interruptedControlFlow[stackDepth] = true;
            frames[stackDepth] = nextFrameNr++;
            if (methodEntryLeaveVisitors0 != null)
                for (DependencesVisitor<? super InstanceType> vis : methodEntryLeaveVisitors0)
                    vis.visitMethodLeave(method0, stackDepth);
        }

        for (int i = 1; i < allocStack; ++i) {
            interestingInstances[i] = new HashSet<InstanceType>();
            cachedStackEntries[i] = new StackEntry[8];
            cachedLocalVariables[i] = new LocalVariable[8];
        }

        SimulationEnvironment simEnv = new SimulationEnvironment(frames, opStack, minOpStack,
                cachedStackEntries, cachedLocalVariables, throwsException, lastInstruction, method,
                interruptedControlFlow);

        while (instanceIterator.hasNext()) {

            instance = instanceIterator.next();
            instruction = instance.getInstruction();

            if ((instance.getInstanceNr() & ((1 << 16) - 1)) == 0 && Thread.interrupted())
                throw new InterruptedException();

            int newStackDepth = instance.getStackDepth();
            assert newStackDepth > 0;

            simEnv.removedMethod = null;
            boolean reenter = false;
            if (newStackDepth != stackDepth
                    || (reenter = finished[stackDepth] || method[stackDepth] != instruction.getMethod())) {
                if (newStackDepth >= stackDepth) {
                    // in all steps, the stackDepth can change by at most 1 (except for the very first instruction)
                    assert newStackDepth == stackDepth + 1 || stackDepth == 0 || reenter;
                    if (newStackDepth >= atCatchBlockStart.length) {
                        int oldLen = atCatchBlockStart.length;
                        int newLen = oldLen == 0 ? 8 : 2 * oldLen;
                        atCatchBlockStart = Arrays.copyOf(atCatchBlockStart, newLen);
                        throwsException = Arrays.copyOf(throwsException, newLen);
                        interruptedControlFlow = Arrays.copyOf(interruptedControlFlow, newLen);
                        abnormalTermination = Arrays.copyOf(abnormalTermination, newLen);
                        finished = Arrays.copyOf(finished, newLen);
                        opStack = Arrays.copyOf(opStack, newLen);
                        minOpStack = Arrays.copyOf(minOpStack, newLen);
                        frames = Arrays.copyOf(frames, newLen);
                        interestingInstances = Arrays.copyOf(interestingInstances, newLen);
                        lastInstruction = Arrays.copyOf(lastInstruction, newLen);
                        cachedStackEntries = Arrays.copyOf(cachedStackEntries, newLen);
                        cachedLocalVariables = Arrays.copyOf(cachedLocalVariables, newLen);
                        method = Arrays.copyOf(method, newLen);
                        for (int i = oldLen; i < newLen; ++i) {
                            interestingInstances[i] = new HashSet<InstanceType>();
                            cachedStackEntries[i] = new StackEntry[8];
                            cachedLocalVariables[i] = new LocalVariable[8];
                        }
                        simEnv = new SimulationEnvironment(frames, opStack, minOpStack, cachedStackEntries,
                                cachedLocalVariables, throwsException, lastInstruction, method,
                                interruptedControlFlow);
                    }
                    frames[newStackDepth] = nextFrameNr++;
                    ReadMethod oldMethod = method[newStackDepth];
                    method[newStackDepth] = instruction.getMethod();
                    if (methodEntryLeaveVisitors0 != null) {
                        for (DependencesVisitor<? super InstanceType> vis : methodEntryLeaveVisitors0) {
                            if (reenter)
                                vis.visitMethodEntry(oldMethod, newStackDepth);
                            vis.visitMethodLeave(method[newStackDepth], newStackDepth);
                        }
                    }

                    if (reenter) {
                        cleanUpExecutionFrame(simEnv, stackDepth, lastReaders, lastWriter,
                                pendingDataDependenceVisitorsWriteAfterRead0,
                                pendingDataDependenceVisitorsReadAfterWrite0,
                                dataDependenceVisitorsWriteAfterRead0, dataDependenceVisitorsReadAfterWrite0);
                    }

                    atCatchBlockStart[newStackDepth] = null;
                    if (instruction == method[newStackDepth].getAbnormalTerminationLabel()) {
                        throwsException[newStackDepth] = interruptedControlFlow[newStackDepth] = abnormalTermination[newStackDepth] = true;
                        interruptedControlFlow[stackDepth] = true;
                    } else {
                        throwsException[newStackDepth] = interruptedControlFlow[newStackDepth] = abnormalTermination[newStackDepth] = false;
                    }
                    finished[newStackDepth] = false;
                    opStack[newStackDepth] = 0;
                    minOpStack[newStackDepth] = 0;
                    interestingInstances[newStackDepth].clear();
                    if (cachedLocalVariables[newStackDepth].length > 128)
                        cachedLocalVariables[newStackDepth] = new LocalVariable[8];
                    else
                        Arrays.fill(cachedLocalVariables[newStackDepth], null);
                    if (cachedStackEntries[newStackDepth].length > 128)
                        cachedStackEntries[newStackDepth] = new StackEntry[8];
                    else
                        Arrays.fill(cachedStackEntries[newStackDepth], null);

                } else {
                    assert newStackDepth == stackDepth - 1;
                    if (methodEntryLeaveVisitors0 != null) {
                        for (DependencesVisitor<? super InstanceType> vis : methodEntryLeaveVisitors0) {
                            vis.visitMethodEntry(method[stackDepth], stackDepth);
                        }
                    }
                    simEnv.removedMethod = method[stackDepth];
                }
            }
            stackDepth = newStackDepth;

            if (simEnv.removedMethod == null && (this.untracedMethodsVisitors != null)
                    && (instruction.getType() == InstructionType.METHODINVOCATION)) {
                for (DependencesVisitor<? super InstanceType> vis : this.untracedMethodsVisitors)
                    vis.visitUntracedMethodCall(instance);
            }

            if (instruction == instruction.getMethod().getMethodEntryLabel())
                finished[stackDepth] = true;
            lastInstruction[stackDepth] = instruction;

            if (atCatchBlockStart[stackDepth] != null)
                throwsException[stackDepth] = true;

            DynamicInformation dynInfo = this.simulator.simulateInstruction(instance, simEnv);

            if (instructionVisitors0 != null)
                for (DependencesVisitor<? super InstanceType> vis : instructionVisitors0)
                    vis.visitInstructionExecution(instance);

            // the computation of control dependences only has to be performed
            // if there are any controlDependenceVisitors
            if (controlDependenceVisitors0 != null) {
                if (simEnv.removedMethod != null && !interestingInstances[stackDepth + 1].isEmpty()) {
                    // ok, we have a control dependence since the method was called by (or for) this instruction
                    // checking if this is the instr. that directly called the method is impossible
                    for (InstanceType depend : interestingInstances[stackDepth + 1]) {
                        for (DependencesVisitor<? super InstanceType> vis : controlDependenceVisitors0) {
                            vis.visitControlDependence(depend, instance);
                        }
                    }
                    interestingInstances[stackDepth].add(instance);
                }

                Set<Instruction> instrControlDependences = controlDependences.get(instruction.getIndex());
                if (instrControlDependences == null) {
                    computeControlDependences(instruction.getMethod(), controlDependences);
                    instrControlDependences = controlDependences.get(instruction.getIndex());
                    assert instrControlDependences != null;
                }
                boolean isExceptionsThrowingInstruction = throwsException[stackDepth]
                        && (instruction.getType() != InstructionType.LABEL
                                || !((LabelMarker) instruction).isAdditionalLabel())
                        && (instruction.getOpcode() != Opcodes.GOTO);
                // assert: every ATHROW must be an exception throwing instance
                assert (instruction.getOpcode() != Opcodes.ATHROW || isExceptionsThrowingInstruction);
                // get all interesting instructions, that are dependent on the current one
                Set<InstanceType> dependantInterestingInstances = getInstanceIntersection(
                        instrControlDependences, interestingInstances[stackDepth]);
                if (isExceptionsThrowingInstruction) {
                    throwsException[stackDepth] = false;
                    // in this case, we have an additional control dependence from the catching to
                    // the throwing instruction, and a data dependence on the thrown instruction
                    for (int i = stackDepth; i > 0; --i) {
                        if (atCatchBlockStart[i] != null) {
                            if (interestingInstances[i].contains(atCatchBlockStart[i])) {
                                if (dependantInterestingInstances.isEmpty())
                                    dependantInterestingInstances = Collections.singleton(atCatchBlockStart[i]);
                                else
                                    dependantInterestingInstances.add(atCatchBlockStart[i]);
                            }
                            atCatchBlockStart[i] = null;

                            // data dependence:
                            // (the stack height has already been decremented when entering the catch block)
                            Variable definedException = simEnv.getOpStackEntry(i, opStack[i]);
                            dynInfo = AdditionalDataDependence.annotate(dynInfo, definedException,
                                    dynInfo.getUsedVariables());

                            break;
                        }
                    }
                }
                if (!dependantInterestingInstances.isEmpty()) {
                    for (InstanceType depend : dependantInterestingInstances) {
                        for (DependencesVisitor<? super InstanceType> vis : controlDependenceVisitors0) {
                            vis.visitControlDependence(depend, instance);
                        }
                    }
                    interestingInstances[stackDepth].removeAll(dependantInterestingInstances);
                }
                interestingInstances[stackDepth].add(instance);
            }
            // TODO check this:
            if (pendingControlDependenceVisitors0 != null) {
                interestingInstances[stackDepth].add(instance);
                for (DependencesVisitor<? super InstanceType> vis : pendingControlDependenceVisitors0)
                    vis.visitPendingControlDependence(instance);
            }

            Collection<? extends Variable> definedVariables = dynInfo.getDefinedVariables();
            if (!definedVariables.isEmpty()) {
                /*
                for (Variable definedVariable: dynInfo.getDefinedVariables()) {
                if (definedVariable instanceof ObjectField) {
                    seenObjects.add(((ObjectField)definedVariable).getObjectId());
                    assert !createdObjects.contains(((ObjectField)definedVariable).getObjectId());
                }
                if (definedVariable instanceof ArrayElement) {
                    seenObjects.add(((ArrayElement)definedVariable).getArrayId());
                    assert !createdObjects.contains(((ArrayElement)definedVariable).getArrayId());
                }
                }
                */
                if (dataDependenceVisitorsReadAfterWrite0 != null
                        || dataDependenceVisitorsWriteAfterRead0 != null
                        || pendingDataDependenceVisitorsWriteAfterRead0 != null) {
                    for (Variable definedVariable : definedVariables) {
                        if (!(definedVariable instanceof StackEntry)) {
                            // we ignore WAR dependences over the stack!
                            if (pendingDataDependenceVisitorsWriteAfterRead0 != null) {
                                // for each defined variable, we have a pending WAR dependence
                                // if the lastWriter is not null, we first discard old pending dependences
                                InstanceType varLastWriter = lastWriter.put(definedVariable, instance);
                                for (DependencesVisitor<? super InstanceType> vis : pendingDataDependenceVisitorsWriteAfterRead0) {
                                    if (varLastWriter != null)
                                        vis.discardPendingDataDependence(varLastWriter, definedVariable,
                                                DataDependenceType.WRITE_AFTER_READ);
                                    vis.visitPendingDataDependence(instance, definedVariable,
                                            DataDependenceType.WRITE_AFTER_READ);
                                }
                                // otherwise, if there are WAR visitors, we only update the lastWriter
                            } else if (dataDependenceVisitorsWriteAfterRead0 != null) {
                                lastWriter.put(definedVariable, instance);
                            }
                        }
                        // if we have RAW visitors, we need to analyse the lastReaders
                        if (dataDependenceVisitorsReadAfterWrite0 != null
                                || pendingDataDependenceVisitorsReadAfterWrite0 != null) {
                            List<InstanceType> readers = lastReaders.remove(definedVariable);
                            if (readers != null) {
                                Collection<? extends Variable> usedVariables = dataDependenceVisitorsReadAfterWrite0 != null
                                        ? dynInfo.getUsedVariables(definedVariable)
                                        : null;
                                for (InstanceType reader : readers) {
                                    if (dataDependenceVisitorsReadAfterWrite0 != null) {
                                        for (DependencesVisitor<? super InstanceType> vis : dataDependenceVisitorsReadAfterWrite0)
                                            vis.visitDataDependence(reader, instance, usedVariables,
                                                    definedVariable, DataDependenceType.READ_AFTER_WRITE);
                                    }
                                    if (pendingDataDependenceVisitorsReadAfterWrite0 != null)
                                        for (DependencesVisitor<? super InstanceType> vis : pendingDataDependenceVisitorsReadAfterWrite0)
                                            vis.discardPendingDataDependence(reader, definedVariable,
                                                    DataDependenceType.READ_AFTER_WRITE);
                                }
                            }
                        }
                    }
                }
            }

            Collection<? extends Variable> usedVariables = dynInfo.getUsedVariables();
            if (!usedVariables.isEmpty()) {
                /*
                for (Variable usedVariable: dynInfo.getUsedVariables()) {
                if (usedVariable instanceof ObjectField) {
                    seenObjects.add(((ObjectField)usedVariable).getObjectId());
                    assert !createdObjects.contains(((ObjectField)usedVariable).getObjectId());
                }
                if (usedVariable instanceof ArrayElement) {
                    seenObjects.add(((ArrayElement)usedVariable).getArrayId());
                    assert !createdObjects.contains(((ArrayElement)usedVariable).getArrayId());
                }
                }
                */

                if (dataDependenceVisitorsWriteAfterRead0 != null
                        || dataDependenceVisitorsReadAfterWrite0 != null
                        || pendingDataDependenceVisitorsReadAfterWrite0 != null) {
                    for (Variable usedVariable : usedVariables) {
                        // if we have WAR visitors, we inform them about a new dependence
                        if (dataDependenceVisitorsWriteAfterRead0 != null
                                && !(usedVariable instanceof StackEntry)) {
                            InstanceType lastWriterInst = lastWriter.get(usedVariable);

                            // avoid self-loops in the DDG (e.g. for IINC, which reads and writes to the same variable)
                            if (lastWriterInst != null && lastWriterInst != instance) {
                                for (DependencesVisitor<? super InstanceType> vis : dataDependenceVisitorsWriteAfterRead0)
                                    vis.visitDataDependence(lastWriterInst, instance, null, usedVariable,
                                            DataDependenceType.WRITE_AFTER_READ);
                            }
                        }

                        // for RAW visitors, update the lastReaders
                        if (dataDependenceVisitorsReadAfterWrite0 != null
                                || pendingDataDependenceVisitorsReadAfterWrite0 != null) {
                            List<InstanceType> readers = lastReaders.get(usedVariable);
                            if (readers == null) {
                                readers = new ArrayList<InstanceType>(4);
                                lastReaders.put(usedVariable, readers);
                            }
                            readers.add(instance);
                            // for each used variable, we have a pending RAW dependence
                            if (pendingDataDependenceVisitorsReadAfterWrite0 != null) {
                                for (DependencesVisitor<? super InstanceType> vis : pendingDataDependenceVisitorsReadAfterWrite0)
                                    vis.visitPendingDataDependence(instance, usedVariable,
                                            DataDependenceType.READ_AFTER_WRITE);
                            }
                        }
                    }
                }
            }

            for (Entry<Long, Collection<? extends Variable>> e : dynInfo.getCreatedObjects().entrySet()) {
                /*
                boolean added = createdObjects.add(e.getKey());
                assert added;
                */

                for (Variable var : e.getValue()) {
                    assert var instanceof ObjectField || var instanceof ArrayElement;
                    // clean up lastWriter if we have any WAR visitors
                    if (pendingDataDependenceVisitorsWriteAfterRead0 != null) {
                        InstanceType inst;
                        if ((inst = lastWriter.remove(var)) != null)
                            for (DependencesVisitor<? super InstanceType> vis : pendingDataDependenceVisitorsWriteAfterRead0)
                                vis.discardPendingDataDependence(inst, var,
                                        DataDependenceType.WRITE_AFTER_READ);
                    } else if (dataDependenceVisitorsWriteAfterRead0 != null)
                        lastWriter.remove(var);
                    // clean up lastReaders if we have any RAW visitors
                    if (dataDependenceVisitorsReadAfterWrite0 != null
                            || pendingDataDependenceVisitorsReadAfterWrite0 != null) {
                        List<InstanceType> instList;
                        if ((instList = lastReaders.remove(var)) != null) {
                            if (dataDependenceVisitorsReadAfterWrite0 != null)
                                for (DependencesVisitor<? super InstanceType> vis : dataDependenceVisitorsReadAfterWrite0)
                                    for (InstanceType instrInst : instList)
                                        vis.visitDataDependence(instrInst, instance,
                                                Collections.<Variable>emptySet(), var,
                                                DataDependenceType.READ_AFTER_WRITE);
                            if (pendingDataDependenceVisitorsReadAfterWrite0 != null)
                                for (DependencesVisitor<? super InstanceType> vis : pendingDataDependenceVisitorsReadAfterWrite0)
                                    for (InstanceType instrInst : instList)
                                        vis.discardPendingDataDependence(instrInst, var,
                                                DataDependenceType.READ_AFTER_WRITE);
                        }
                    }
                }
                if (objectCreationVisitors0 != null)
                    for (DependencesVisitor<? super InstanceType> vis : objectCreationVisitors0)
                        vis.visitObjectCreation(e.getKey(), instance);
            }

            if (dynInfo.isCatchBlock()) {
                atCatchBlockStart[stackDepth] = instance;
                interruptedControlFlow[stackDepth] = true;
            } else if (atCatchBlockStart[stackDepth] != null) {
                atCatchBlockStart[stackDepth] = null;
            }

            if (simEnv.removedMethod != null) {
                cleanUpExecutionFrame(simEnv, stackDepth + 1, lastReaders, lastWriter,
                        pendingDataDependenceVisitorsWriteAfterRead0,
                        pendingDataDependenceVisitorsReadAfterWrite0, dataDependenceVisitorsWriteAfterRead0,
                        dataDependenceVisitorsReadAfterWrite0);
            }

            /*
            if (instance.getInstanceNr() % 1000000 == 0) {
            for (Variable var: lastReaders.keySet()) {
                if (var instanceof ObjectField) {
                    assert seenObjects.contains(((ObjectField)var).getObjectId());
                    assert !createdObjects.contains(((ObjectField)var).getObjectId());
                }
                if (var instanceof ArrayElement) {
                    assert seenObjects.contains(((ArrayElement)var).getArrayId());
                    assert !createdObjects.contains(((ArrayElement)var).getArrayId());
                }
                if (var instanceof StackEntry)
                    assert frames.contains(((StackEntry)var).getFrame());
                if (var instanceof LocalVariable) {
                    assert frames.contains(((LocalVariable)var).getFrame());
                }
            }
            for (Variable var: lastWriter.keySet()) {
                if (var instanceof ObjectField) {
                    assert seenObjects.contains(((ObjectField)var).getObjectId());
                    assert !createdObjects.contains(((ObjectField)var).getObjectId());
                }
                if (var instanceof ArrayElement) {
                    assert seenObjects.contains(((ArrayElement)var).getArrayId());
                    assert !createdObjects.contains(((ArrayElement)var).getArrayId());
                }
                // we do not store the last writer of a stack entry
                assert !(var instanceof StackEntry);
                if (var instanceof LocalVariable) {
                    assert frames.contains(((LocalVariable)var).getFrame());
                }
            }
            }
            */
        }
        Throwable t = iteratorException.get();
        if (t != null) {
            if (t instanceof RuntimeException)
                throw (RuntimeException) t;
            if (t instanceof Error)
                throw (Error) t;
            if (t instanceof InterruptedException)
                throw (InterruptedException) t;
            throw new TracerException("Iterator should not throw anything but RuntimeExceptions", t);
        }

        if (Thread.interrupted())
            throw new InterruptedException();

        cleanUpMaps(lastWriter, lastReaders, pendingDataDependenceVisitorsWriteAfterRead0,
                pendingDataDependenceVisitorsReadAfterWrite0);

        for (DependencesVisitor<? super InstanceType> vis : allVisitors)
            vis.visitEnd(instance == null ? 0 : instance.getInstanceNr());

        if (Thread.interrupted())
            throw new InterruptedException();
    } catch (InterruptedException e) {
        for (DependencesVisitor<? super InstanceType> vis : allVisitors)
            vis.interrupted();
        throw e;
    } finally {
        if (iteratorThread != null)
            iteratorThread.interrupt();
        for (ProgressMonitor mon : this.progressMonitors)
            mon.end();
    }
}

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

License:Open Source License

public Set<Instruction> getDynamicSlice(ThreadId threadId, List<SlicingCriterion> sc) {
    BackwardTraceIterator<InstructionInstance> backwardInsnItr = this.trace.getBackwardIterator(threadId, null);

    IntegerMap<Set<Instruction>> controlDependences = new IntegerMap<Set<Instruction>>();

    Set<Variable> interestingVariables = new HashSet<Variable>();
    Set<Instruction> dynamicSlice = new HashSet<Instruction>();

    long nextFrameNr = 0;
    int stackDepth = 0;

    List<ReadMethod> initialStackMethods = backwardInsnItr.getInitialStackMethods();

    int allocStack = initialStackMethods.size() + 1;
    allocStack = Integer.highestOneBit(allocStack) * 2;

    Instruction[] atCatchBlockStart = new Instruction[allocStack];
    boolean[] throwsException = new boolean[allocStack];
    boolean[] interruptedControlFlow = new boolean[allocStack];
    /**/*from w  ww  .j  av  a 2  s .co  m*/
     * <code>true</code> iff this frame was aborted abnormally (NOT by a RETURN
     * instruction)
     */
    boolean[] abnormalTermination = new boolean[allocStack];
    /**
     * is set to true if the methods entry label has been passed
     */
    boolean[] finished = new boolean[allocStack];
    int[] opStack = new int[allocStack];
    int[] minOpStack = new int[allocStack];
    long[] frames = new long[allocStack];
    Instruction[] lastInstruction = new Instruction[allocStack];
    @SuppressWarnings("unchecked")
    HashSet<Instruction>[] interestingInstructions = (HashSet<Instruction>[]) new HashSet<?>[allocStack];
    StackEntry[][] cachedStackEntries = new StackEntry[allocStack][];
    LocalVariable[][] cachedLocalVariables = new LocalVariable[allocStack][];
    ReadMethod[] method = new ReadMethod[allocStack];

    for (ReadMethod method0 : initialStackMethods) {
        ++stackDepth;
        method[stackDepth] = method0;
        interruptedControlFlow[stackDepth] = true;
        frames[stackDepth] = nextFrameNr++;
    }

    for (int i = 1; i < allocStack; ++i) {
        interestingInstructions[i] = new HashSet<Instruction>();
        cachedStackEntries[i] = new StackEntry[8];
        cachedLocalVariables[i] = new LocalVariable[8];
    }

    SimulationEnvironment simEnv = new SimulationEnvironment(frames, opStack, minOpStack, cachedStackEntries,
            cachedLocalVariables, throwsException, lastInstruction, method, interruptedControlFlow);

    List<SlicingCriterionInstance> slicingCriteria;
    if (sc.isEmpty())
        slicingCriteria = Collections.emptyList();
    else if (sc.size() == 1)
        slicingCriteria = Collections.singletonList(sc.get(0).getInstance());
    else {
        slicingCriteria = new ArrayList<SlicingCriterionInstance>(sc.size());
        for (SlicingCriterion crit : sc)
            slicingCriteria.add(crit.getInstance());
    }

    for (ProgressMonitor mon : this.progressMonitors)
        mon.start(backwardInsnItr);
    try {

        while (backwardInsnItr.hasNext()) {
            InstructionInstance instance = backwardInsnItr.next();
            Instruction instruction = instance.getInstruction();

            int newStackDepth = instance.getStackDepth();
            assert newStackDepth > 0;

            simEnv.removedMethod = null;
            boolean reenter = false;
            if (newStackDepth != stackDepth
                    || (reenter = finished[stackDepth] || method[stackDepth] != instruction.getMethod())) {
                if (newStackDepth >= stackDepth) {
                    // in all steps, the stackDepth can change by at most 1 (except for the very first instruction)
                    assert newStackDepth == stackDepth + 1 || stackDepth == 0 || reenter;
                    if (newStackDepth >= atCatchBlockStart.length) {
                        int oldLen = atCatchBlockStart.length;
                        int newLen = oldLen == 0 ? 8 : 2 * oldLen;
                        atCatchBlockStart = Arrays.copyOf(atCatchBlockStart, newLen);
                        throwsException = Arrays.copyOf(throwsException, newLen);
                        interruptedControlFlow = Arrays.copyOf(interruptedControlFlow, newLen);
                        abnormalTermination = Arrays.copyOf(abnormalTermination, newLen);
                        finished = Arrays.copyOf(finished, newLen);
                        opStack = Arrays.copyOf(opStack, newLen);
                        minOpStack = Arrays.copyOf(minOpStack, newLen);
                        frames = Arrays.copyOf(frames, newLen);
                        interestingInstructions = Arrays.copyOf(interestingInstructions, newLen);
                        lastInstruction = Arrays.copyOf(lastInstruction, newLen);
                        cachedStackEntries = Arrays.copyOf(cachedStackEntries, newLen);
                        cachedLocalVariables = Arrays.copyOf(cachedLocalVariables, newLen);
                        method = Arrays.copyOf(method, newLen);
                        for (int i = oldLen; i < newLen; ++i) {
                            interestingInstructions[i] = new HashSet<Instruction>();
                            cachedStackEntries[i] = new StackEntry[8];
                            cachedLocalVariables[i] = new LocalVariable[8];
                        }
                        simEnv.reallocate(frames, opStack, minOpStack, cachedStackEntries, cachedLocalVariables,
                                throwsException, lastInstruction, method, interruptedControlFlow);
                    }
                    frames[newStackDepth] = nextFrameNr++;
                    method[newStackDepth] = instruction.getMethod();

                    atCatchBlockStart[newStackDepth] = null;
                    if (instruction == method[newStackDepth].getAbnormalTerminationLabel()) {
                        throwsException[newStackDepth] = interruptedControlFlow[newStackDepth] = abnormalTermination[newStackDepth] = true;
                        interruptedControlFlow[stackDepth] = true;
                    } else {
                        throwsException[newStackDepth] = interruptedControlFlow[newStackDepth] = abnormalTermination[newStackDepth] = false;
                    }
                    finished[newStackDepth] = false;
                    opStack[newStackDepth] = 0;
                    minOpStack[newStackDepth] = 0;
                    interestingInstructions[newStackDepth].clear();
                    if (cachedLocalVariables[newStackDepth].length > 128)
                        cachedLocalVariables[newStackDepth] = new LocalVariable[8];
                    else
                        Arrays.fill(cachedLocalVariables[newStackDepth], null);
                    if (cachedStackEntries[newStackDepth].length > 128)
                        cachedStackEntries[newStackDepth] = new StackEntry[8];
                    else
                        Arrays.fill(cachedStackEntries[newStackDepth], null);
                } else {
                    assert newStackDepth == stackDepth - 1;
                    simEnv.removedMethod = method[stackDepth];
                }
            }
            stackDepth = newStackDepth;

            if (atCatchBlockStart[stackDepth] != null)
                throwsException[stackDepth] = true;

            if (instruction == instruction.getMethod().getMethodEntryLabel())
                finished[stackDepth] = true;
            lastInstruction[stackDepth] = instruction;

            DynamicInformation dynInfo = this.simulator.simulateInstruction(instance, simEnv);

            if (simEnv.removedMethod != null && !interestingInstructions[stackDepth + 1].isEmpty()) {
                // ok, we have a control dependence since the method was called by (or for) this instruction
                // checking if this is the instr. that directly called the method is impossible
                dynamicSlice.add(instruction);
                interestingInstructions[stackDepth].add(instruction);
            }

            for (SlicingCriterionInstance crit : slicingCriteria) {
                if (crit.matches(instance)) {
                    if (crit.computeTransitiveClosure()) {
                        interestingVariables.addAll(dynInfo.getUsedVariables());
                        dynamicSlice.add(instruction);
                        interestingInstructions[stackDepth].add(instance.getInstruction());
                    } else if (crit.hasLocalVariables()) {
                        for (de.unisb.cs.st.javaslicer.common.classRepresentation.LocalVariable var : crit
                                .getLocalVariables())
                            interestingVariables.add(simEnv.getLocalVariable(stackDepth, var.getIndex()));
                    } else {
                        interestingInstructions[stackDepth].add(instance.getInstruction());
                    }
                }
            }

            boolean isExceptionsThrowingInstance = throwsException[stackDepth]
                    && (instruction.getType() != InstructionType.LABEL
                            || !((LabelMarker) instruction).isAdditionalLabel())
                    && (instruction.getOpcode() != Opcodes.GOTO);
            if (!interestingInstructions[stackDepth].isEmpty() || isExceptionsThrowingInstance) {
                Set<Instruction> instrControlDependences = controlDependences.get(instruction.getIndex());
                if (instrControlDependences == null) {
                    computeControlDependences(instruction.getMethod(), controlDependences);
                    instrControlDependences = controlDependences.get(instruction.getIndex());
                    assert instrControlDependences != null;
                }
                // get all interesting instructions, that are dependent on the current one
                Set<Instruction> dependantInterestingInstructions = intersect(instrControlDependences,
                        interestingInstructions[stackDepth]);
                if (isExceptionsThrowingInstance) {
                    throwsException[stackDepth] = false;
                    // in this case, we have an additional control dependence from the catching to
                    // the throwing instruction, and a data dependence on the thrown instruction
                    for (int i = stackDepth; i > 0; --i) {
                        if (atCatchBlockStart[i] != null) {
                            if (interestingInstructions[i].contains(atCatchBlockStart[i])) {
                                if (dependantInterestingInstructions.isEmpty())
                                    dependantInterestingInstructions = Collections
                                            .singleton(atCatchBlockStart[i]);
                                else
                                    dependantInterestingInstructions.add(atCatchBlockStart[i]);
                            }
                            atCatchBlockStart[i] = null;

                            // data dependence:
                            // (the stack height has already been decremented when entering the catch block)
                            Variable definedException = simEnv.getOpStackEntry(i, opStack[i]);
                            if (interestingVariables.contains(definedException)) {
                                interestingInstructions[stackDepth].add(instruction);
                                dynamicSlice.add(instruction);
                                interestingVariables.remove(definedException);
                                interestingVariables.addAll(dynInfo.getUsedVariables());
                            }

                            break;
                        }
                    }
                }
                if (!dependantInterestingInstructions.isEmpty()) {
                    dynamicSlice.add(instruction);
                    interestingInstructions[stackDepth].removeAll(dependantInterestingInstructions);
                    interestingInstructions[stackDepth].add(instruction);
                    interestingVariables.addAll(dynInfo.getUsedVariables());
                }
            }

            if (!interestingVariables.isEmpty()) {
                for (Variable definedVariable : dynInfo.getDefinedVariables()) {
                    if (interestingVariables.contains(definedVariable)) {
                        interestingInstructions[stackDepth].add(instruction);
                        dynamicSlice.add(instruction);
                        interestingVariables.remove(definedVariable);
                        interestingVariables.addAll(dynInfo.getUsedVariables(definedVariable));
                    }
                }
            }

            if (dynInfo.isCatchBlock()) {
                atCatchBlockStart[stackDepth] = instance.getInstruction();
                interruptedControlFlow[stackDepth] = true;
            } else if (atCatchBlockStart[stackDepth] != null) {
                atCatchBlockStart[stackDepth] = null;
            }

        }
    } finally {
        for (ProgressMonitor mon : this.progressMonitors)
            mon.end();
    }

    for (Iterator<Instruction> it = dynamicSlice.iterator(); it.hasNext();) {
        Instruction instr = it.next();
        if (instr.getType() == InstructionType.LABEL || instr.getOpcode() == Opcodes.GOTO)
            it.remove();
    }

    return dynamicSlice;
}

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;
            }/* w  ww  .  j ava  2s.  c  om*/
        }

        @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);
}

From source file:de.zib.sfs.instrument.FileChannelImplAdapter.java

License:BSD License

protected void wrapFileChannelImplMethod(int access, String name, Type returnType, Type[] argumentTypes,
        String signature, String[] exceptions, String callbackName, String oppositeCallbackName,
        Type additionalCallbackArgumentType, int bufferArgumentTypeIndex, boolean isTransferMethod) {
    String methodDescriptor = Type.getMethodDescriptor(returnType, argumentTypes);

    // <access> <returnType> <name>(<argumentTypes> arguments) throws
    // <exceptions> {
    MethodVisitor mv = this.cv.visitMethod(access, name, methodDescriptor, signature, exceptions);
    mv.visitCode();/* w w w .  ja v a  2s  .  c  om*/

    // if (isInstrumentationActive()) {
    isInstrumentationActive(mv);
    Label instrumentationActiveLabel = new Label();
    mv.visitJumpInsn(Opcodes.IFEQ, instrumentationActiveLabel);

    // return methodPrefix<name>(arguments);
    mv.visitVarInsn(Opcodes.ALOAD, 0);
    int argumentIndex = 1;
    for (Type argument : argumentTypes) {
        mv.visitVarInsn(argument.getOpcode(Opcodes.ILOAD), argumentIndex);
        argumentIndex += argument.getSize();
    }
    mv.visitMethodInsn(Opcodes.INVOKESPECIAL, this.instrumentedTypeInternalName, this.methodPrefix + name,
            methodDescriptor, false);
    mv.visitInsn(returnType.getOpcode(Opcodes.IRETURN));

    // }
    mv.visitLabel(instrumentationActiveLabel);

    // setInstrumentationActive(true);
    setInstrumentationActive(mv, true);

    // we need to set the instrumentation flag for the source/destination
    // buffer(s) as well

    // boolean bufferInstrumentationActive = false;
    int bufferInstrumentationActiveIndex = 1;
    for (Type argument : argumentTypes) {
        bufferInstrumentationActiveIndex += argument.getSize();
    }
    mv.visitInsn(Opcodes.ICONST_0);
    mv.visitVarInsn(Opcodes.ISTORE, bufferInstrumentationActiveIndex);

    // obtain actual index of the buffer(s) in the argument list
    int bufferArgumentIndex = 1;
    for (int i = 0; i < bufferArgumentTypeIndex; ++i) {
        bufferArgumentIndex += argumentTypes[i].getSize();
    }

    if (argumentTypes[bufferArgumentTypeIndex].getSort() == Type.ARRAY) {
        // If the first buffer in the array is a MappedByteBuffer, assume
        // they all are. If not, this will crash the users' program.

        // if (<buffers>[0] instanceof MappedByteBuffer) {
        mv.visitVarInsn(Opcodes.ALOAD, bufferArgumentIndex);
        mv.visitInsn(Opcodes.ICONST_0);
        mv.visitInsn(Opcodes.AALOAD);
        mv.visitTypeInsn(Opcodes.INSTANCEOF, Type.getInternalName(MappedByteBuffer.class));
        Label bufferInstanceofMappedByteBufferLabel = new Label();
        mv.visitJumpInsn(Opcodes.IFEQ, bufferInstanceofMappedByteBufferLabel);

        // only trace mmapped file channels if desired
        if (this.traceMmap) {
            // if (<buffers>[0].isFromFileChannel()) {
            mv.visitVarInsn(Opcodes.ALOAD, bufferArgumentIndex);
            mv.visitInsn(Opcodes.ICONST_0);
            mv.visitInsn(Opcodes.AALOAD);
            mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, Type.getInternalName(MappedByteBuffer.class),
                    "isFromFileChannel", Type.getMethodDescriptor(Type.BOOLEAN_TYPE), false);
            Label fromFileChannelLabel = new Label();
            mv.visitJumpInsn(Opcodes.IFEQ, fromFileChannelLabel);

            int iIndex = bufferInstrumentationActiveIndex + 1;

            // for (int i = 0; i < <buffers>.length; ++i) {
            // <buffers>[i].setInstrumentationActive(true);
            // }
            mv.visitInsn(Opcodes.ICONST_0);
            mv.visitVarInsn(Opcodes.ISTORE, iIndex);
            Label loopConditionLabel = new Label();
            mv.visitJumpInsn(Opcodes.GOTO, loopConditionLabel);
            Label loopStartLabel = new Label();
            mv.visitLabel(loopStartLabel);
            mv.visitVarInsn(Opcodes.ALOAD, bufferArgumentIndex);
            mv.visitVarInsn(Opcodes.ILOAD, iIndex);
            mv.visitInsn(Opcodes.AALOAD);
            mv.visitInsn(Opcodes.ICONST_1);
            mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, Type.getInternalName(MappedByteBuffer.class),
                    "setInstrumentationActive", Type.getMethodDescriptor(Type.VOID_TYPE, Type.BOOLEAN_TYPE),
                    false);
            mv.visitIincInsn(iIndex, 1);
            mv.visitLabel(loopConditionLabel);
            mv.visitVarInsn(Opcodes.ILOAD, iIndex);
            mv.visitVarInsn(Opcodes.ALOAD, bufferArgumentIndex);
            mv.visitInsn(Opcodes.ARRAYLENGTH);
            mv.visitJumpInsn(Opcodes.IF_ICMPLT, loopStartLabel);

            // bufferInstrumentationActive = true;
            mv.visitInsn(Opcodes.ICONST_1);
            mv.visitVarInsn(Opcodes.ISTORE, bufferInstrumentationActiveIndex);

            // }
            mv.visitLabel(fromFileChannelLabel);
        }

        // }
        mv.visitLabel(bufferInstanceofMappedByteBufferLabel);
    } else {
        // We need to handle the transferFrom/transferTo methods a little
        // differently. Their "buffers" only need to be FileChannelImpls,
        // the rest remains the same.

        // if (buffer instanceof MappedByteBuffer) {
        // if (buffer instanceof FileChannelImpl) {
        mv.visitVarInsn(Opcodes.ALOAD, bufferArgumentIndex);
        if (!isTransferMethod) {
            mv.visitTypeInsn(Opcodes.INSTANCEOF, Type.getInternalName(MappedByteBuffer.class));
        } else {
            mv.visitTypeInsn(Opcodes.INSTANCEOF, Type.getInternalName(FileChannelImpl.class));
        }
        Label bufferInstanceofMappedByteBufferLabel = new Label();
        mv.visitJumpInsn(Opcodes.IFEQ, bufferInstanceofMappedByteBufferLabel);

        // additional check required if the buffer is a MappedByteBuffer,
        // and we want to trace those
        Label fromFileChannelLabel = new Label();
        if (!isTransferMethod && this.traceMmap) {
            // if (buffer.isFromFileChannel()) {
            mv.visitVarInsn(Opcodes.ALOAD, bufferArgumentIndex);
            mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, Type.getInternalName(MappedByteBuffer.class),
                    "isFromFileChannel", Type.getMethodDescriptor(Type.BOOLEAN_TYPE), false);
            mv.visitJumpInsn(Opcodes.IFEQ, fromFileChannelLabel);
        }

        // either we're dealing with a FileChannelImpl (in a
        // transferTo/transferFrom method), or this is a regular read or
        // write and we want to count in mmapped buffers
        if (isTransferMethod || this.traceMmap) {
            // buffer.setInstrumentationActive(true);
            mv.visitVarInsn(Opcodes.ALOAD, bufferArgumentIndex);
            mv.visitInsn(Opcodes.ICONST_1);
            mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL,
                    !isTransferMethod ? Type.getInternalName(MappedByteBuffer.class)
                            : Type.getInternalName(FileChannelImpl.class),
                    "setInstrumentationActive", Type.getMethodDescriptor(Type.VOID_TYPE, Type.BOOLEAN_TYPE),
                    false);

            // bufferInstrumentationActive = true;
            mv.visitInsn(Opcodes.ICONST_1);
            mv.visitVarInsn(Opcodes.ISTORE, bufferInstrumentationActiveIndex);
        }

        if (!isTransferMethod && this.traceMmap) {
            // }
            mv.visitLabel(fromFileChannelLabel);
        }

        // }
        mv.visitLabel(bufferInstanceofMappedByteBufferLabel);
    }

    // long startTime = System.nanoTime();
    int startTimeIndex = bufferInstrumentationActiveIndex + 1;
    storeTime(mv, startTimeIndex);

    // <returnType> result = methodPrefix<name>(arguments);
    mv.visitVarInsn(Opcodes.ALOAD, 0);
    argumentIndex = 1;
    for (Type argument : argumentTypes) {
        mv.visitVarInsn(argument.getOpcode(Opcodes.ILOAD), argumentIndex);
        argumentIndex += argument.getSize();
    }
    mv.visitMethodInsn(Opcodes.INVOKESPECIAL, this.instrumentedTypeInternalName, this.methodPrefix + name,
            methodDescriptor, false);
    int resultIndex = startTimeIndex + 2;
    mv.visitVarInsn(returnType.getOpcode(Opcodes.ISTORE), resultIndex);
    int endTimeIndex = resultIndex + returnType.getSize();

    // long endTime = System.nanoTime();
    storeTime(mv, endTimeIndex);

    // if map(...) was involved in this, then it may have reset the
    // instrumentationActive flag if we don't trace mmap calls, so we need
    // to check again whether instrumentation is still active, and only
    // report the data then

    // if (isInstrumentationActive()) {
    isInstrumentationActive(mv);
    Label instrumentationStillActiveLabel = new Label();
    mv.visitJumpInsn(Opcodes.IFEQ, instrumentationStillActiveLabel);

    // callback.<callbackName>(startTime, endTime, result);
    mv.visitVarInsn(Opcodes.ALOAD, 0);
    mv.visitFieldInsn(Opcodes.GETFIELD, this.instrumentedTypeInternalName, "callback",
            this.callbackTypeDescriptor);
    mv.visitVarInsn(Opcodes.LLOAD, startTimeIndex);
    mv.visitVarInsn(Opcodes.LLOAD, endTimeIndex);
    mv.visitVarInsn(returnType.getOpcode(Opcodes.ILOAD), resultIndex);
    mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, this.callbackTypeInternalName, callbackName,
            Type.getMethodDescriptor(Type.VOID_TYPE, Type.LONG_TYPE, Type.LONG_TYPE,
                    additionalCallbackArgumentType),
            false);

    // }
    mv.visitLabel(instrumentationStillActiveLabel);

    // same for the buffer

    if (argumentTypes[bufferArgumentTypeIndex].getSort() != Type.ARRAY) {
        // if (buffer instanceof MappedByteBuffer) {
        // if (buffer instanceof FileChannelImpl) {
        mv.visitVarInsn(Opcodes.ALOAD, bufferArgumentIndex);
        if (!isTransferMethod) {
            mv.visitTypeInsn(Opcodes.INSTANCEOF, Type.getInternalName(MappedByteBuffer.class));
        } else {
            mv.visitTypeInsn(Opcodes.INSTANCEOF, Type.getInternalName(FileChannelImpl.class));
        }
        Label bufferInstanceofMappedByteBufferLabel = new Label();
        mv.visitJumpInsn(Opcodes.IFEQ, bufferInstanceofMappedByteBufferLabel);

        // additional check required if the buffer is a MappedByteBuffer,
        // and we want to trace those
        Label fromFileChannelLabel = new Label();
        if (!isTransferMethod && this.traceMmap) {
            // if (buffer.isFromFileChannel()) {
            mv.visitVarInsn(Opcodes.ALOAD, bufferArgumentIndex);
            mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, Type.getInternalName(MappedByteBuffer.class),
                    "isFromFileChannel", Type.getMethodDescriptor(Type.BOOLEAN_TYPE), false);
            mv.visitJumpInsn(Opcodes.IFEQ, fromFileChannelLabel);
        }

        // either we're dealing with a FileChannelImpl (in a
        // transferTo/transferFrom method), which might have flipped its
        // instrumentationActive flag because mmap was used, or this is a
        // regular read or write and we want to count in mmapped buffers
        if (isTransferMethod || this.traceMmap) {
            // if traceMmap is true, then we could actually just set
            // bufferInstrumentationActive to true

            // bufferInstrumentationActive =
            // buffer.isInstrumentationActive();
            mv.visitVarInsn(Opcodes.ALOAD, bufferArgumentIndex);
            mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL,
                    !isTransferMethod ? Type.getInternalName(MappedByteBuffer.class)
                            : Type.getInternalName(FileChannelImpl.class),
                    "isInstrumentationActive", Type.getMethodDescriptor(Type.BOOLEAN_TYPE), false);
            mv.visitVarInsn(Opcodes.ISTORE, bufferInstrumentationActiveIndex);
        }

        if (!isTransferMethod && this.traceMmap) {
            // }
            mv.visitLabel(fromFileChannelLabel);
        }

        // }
        mv.visitLabel(bufferInstanceofMappedByteBufferLabel);
    }

    // if (bufferInstrumentationActive) {
    mv.visitVarInsn(Opcodes.ILOAD, bufferInstrumentationActiveIndex);
    Label bufferInstrumentationActiveLabel = new Label();
    mv.visitJumpInsn(Opcodes.IFEQ, bufferInstrumentationActiveLabel);

    // callback.<oppositeCallbackName>(buffer.getFileDescriptor(),
    // startTime, endTime, result);
    if (!isTransferMethod) {
        if (argumentTypes[bufferArgumentTypeIndex].getSort() == Type.ARRAY) {
            // TODO this calls the opposite callback only on the first
            // element in the buffer array, but there is not really a way to
            // tell which buffer has received how many bytes, and thus which
            // file
            mv.visitVarInsn(Opcodes.ALOAD, bufferArgumentIndex);
            mv.visitInsn(Opcodes.ICONST_0);
            mv.visitInsn(Opcodes.AALOAD);
        } else {
            mv.visitVarInsn(Opcodes.ALOAD, bufferArgumentIndex);
        }
        mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, Type.getInternalName(MappedByteBuffer.class),
                "getFileDescriptor", Type.getMethodDescriptor(Type.getType(FileDescriptor.class)), false);
    } else {
        mv.visitVarInsn(Opcodes.ALOAD, bufferArgumentIndex);
        mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, Type.getInternalName(FileChannelImpl.class),
                "getFileDescriptor", Type.getMethodDescriptor(Type.getType(FileDescriptor.class)), false);
    }
    mv.visitVarInsn(Opcodes.LLOAD, startTimeIndex);
    mv.visitVarInsn(Opcodes.LLOAD, endTimeIndex);
    mv.visitVarInsn(returnType.getOpcode(Opcodes.ILOAD), resultIndex);
    mv.visitMethodInsn(Opcodes.INVOKESTATIC, this.callbackTypeInternalName, oppositeCallbackName,
            Type.getMethodDescriptor(Type.VOID_TYPE, Type.getType(FileDescriptor.class), Type.LONG_TYPE,
                    Type.LONG_TYPE, additionalCallbackArgumentType),
            false);

    // revert the active instrumentation flag for the buffer
    if (argumentTypes[bufferArgumentTypeIndex].getSort() == Type.ARRAY) {
        int iIndex = bufferInstrumentationActiveIndex + 1;

        // for (int i = 0; i < <buffers>.length; ++i) {
        // <buffers>[i].setInstrumentationActive(false);
        // }
        mv.visitInsn(Opcodes.ICONST_0);
        mv.visitVarInsn(Opcodes.ISTORE, iIndex);
        Label loopConditionLabel = new Label();
        mv.visitJumpInsn(Opcodes.GOTO, loopConditionLabel);
        Label loopStartLabel = new Label();
        mv.visitLabel(loopStartLabel);
        mv.visitVarInsn(Opcodes.ALOAD, bufferArgumentIndex);
        mv.visitVarInsn(Opcodes.ILOAD, iIndex);
        mv.visitInsn(Opcodes.AALOAD);
        mv.visitInsn(Opcodes.ICONST_0);
        mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, Type.getInternalName(MappedByteBuffer.class),
                "setInstrumentationActive", Type.getMethodDescriptor(Type.VOID_TYPE, Type.BOOLEAN_TYPE), false);
        mv.visitIincInsn(iIndex, 1);
        mv.visitLabel(loopConditionLabel);
        mv.visitVarInsn(Opcodes.ILOAD, iIndex);
        mv.visitVarInsn(Opcodes.ALOAD, bufferArgumentIndex);
        mv.visitInsn(Opcodes.ARRAYLENGTH);
        mv.visitJumpInsn(Opcodes.IF_ICMPLT, loopStartLabel);
    } else {
        // buffer.setInstrumentationActive(false);
        mv.visitVarInsn(Opcodes.ALOAD, bufferArgumentIndex);
        mv.visitInsn(Opcodes.ICONST_0);
        mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL,
                !isTransferMethod ? Type.getInternalName(MappedByteBuffer.class)
                        : Type.getInternalName(FileChannelImpl.class),
                "setInstrumentationActive", Type.getMethodDescriptor(Type.VOID_TYPE, Type.BOOLEAN_TYPE), false);
    }

    // }
    mv.visitLabel(bufferInstrumentationActiveLabel);

    // setInstrumentationActive(false);
    setInstrumentationActive(mv, false);

    // return result;
    // }
    mv.visitVarInsn(returnType.getOpcode(Opcodes.ILOAD), resultIndex);
    mv.visitInsn(returnType.getOpcode(Opcodes.IRETURN));
    mv.visitMaxs(0, 0);
    mv.visitEnd();
}

From source file:edu.illinois.nondex.instr.IdentityHashMapShufflingAdder.java

License:Open Source License

public void addNextIndex() {
    MethodVisitor mv = super.visitMethod(Opcodes.ACC_PROTECTED, "nextIndex", "()I", null, null);
    mv.visitCode();/*from   w  ww  .j ava 2s . com*/
    mv.visitVarInsn(Opcodes.ALOAD, 0);
    mv.visitFieldInsn(Opcodes.GETFIELD, "java/util/IdentityHashMap$IdentityHashMapIterator", "this$0",
            "Ljava/util/IdentityHashMap;");
    mv.visitFieldInsn(Opcodes.GETFIELD, "java/util/IdentityHashMap", "modCount", "I");
    mv.visitVarInsn(Opcodes.ALOAD, 0);
    mv.visitFieldInsn(Opcodes.GETFIELD, "java/util/IdentityHashMap$IdentityHashMapIterator", "expectedModCount",
            "I");
    Label l0 = new Label();
    mv.visitJumpInsn(Opcodes.IF_ICMPEQ, l0);
    mv.visitTypeInsn(Opcodes.NEW, "java/util/ConcurrentModificationException");
    mv.visitInsn(Opcodes.DUP);
    mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/util/ConcurrentModificationException", "<init>", "()V",
            false);
    mv.visitInsn(Opcodes.ATHROW);
    mv.visitLabel(l0);
    mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null);
    mv.visitVarInsn(Opcodes.ALOAD, 0);
    mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/util/IdentityHashMap$IdentityHashMapIterator", "hasNext",
            "()Z", false);
    Label l1 = new Label();
    mv.visitJumpInsn(Opcodes.IFNE, l1);
    mv.visitTypeInsn(Opcodes.NEW, "java/util/NoSuchElementException");
    mv.visitInsn(Opcodes.DUP);
    mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/util/NoSuchElementException", "<init>", "()V", false);
    mv.visitInsn(Opcodes.ATHROW);
    mv.visitLabel(l1);
    mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null);
    mv.visitVarInsn(Opcodes.ALOAD, 0);
    mv.visitFieldInsn(Opcodes.GETFIELD, "java/util/IdentityHashMap$IdentityHashMapIterator", "keys",
            "Ljava/util/List;");
    mv.visitVarInsn(Opcodes.ALOAD, 0);
    mv.visitInsn(Opcodes.DUP);
    mv.visitFieldInsn(Opcodes.GETFIELD, "java/util/IdentityHashMap$IdentityHashMapIterator", "idx", "I");
    mv.visitInsn(Opcodes.DUP_X1);
    mv.visitInsn(Opcodes.ICONST_1);
    mv.visitInsn(Opcodes.IADD);
    mv.visitFieldInsn(Opcodes.PUTFIELD, "java/util/IdentityHashMap$IdentityHashMapIterator", "idx", "I");
    mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, "java/util/List", "get", "(I)Ljava/lang/Object;", true);
    mv.visitVarInsn(Opcodes.ASTORE, 1);
    mv.visitInsn(Opcodes.ICONST_0);
    mv.visitVarInsn(Opcodes.ISTORE, 2);
    Label l2 = new Label();
    mv.visitLabel(l2);
    mv.visitFrame(Opcodes.F_APPEND, 2, new Object[] { "java/lang/Object", Opcodes.INTEGER }, 0, null);
    mv.visitVarInsn(Opcodes.ILOAD, 2);
    mv.visitVarInsn(Opcodes.ALOAD, 0);
    mv.visitFieldInsn(Opcodes.GETFIELD, "java/util/IdentityHashMap$IdentityHashMapIterator", "this$0",
            "Ljava/util/IdentityHashMap;");
    mv.visitFieldInsn(Opcodes.GETFIELD, "java/util/IdentityHashMap", "table", "[Ljava/lang/Object;");
    mv.visitInsn(Opcodes.ARRAYLENGTH);
    Label l3 = new Label();
    mv.visitJumpInsn(Opcodes.IF_ICMPGE, l3);
    mv.visitVarInsn(Opcodes.ALOAD, 0);
    mv.visitFieldInsn(Opcodes.GETFIELD, "java/util/IdentityHashMap$IdentityHashMapIterator", "this$0",
            "Ljava/util/IdentityHashMap;");
    mv.visitFieldInsn(Opcodes.GETFIELD, "java/util/IdentityHashMap", "table", "[Ljava/lang/Object;");
    mv.visitVarInsn(Opcodes.ILOAD, 2);
    mv.visitInsn(Opcodes.AALOAD);
    mv.visitVarInsn(Opcodes.ALOAD, 1);
    Label l4 = new Label();
    mv.visitJumpInsn(Opcodes.IF_ACMPNE, l4);
    mv.visitVarInsn(Opcodes.ALOAD, 0);
    mv.visitVarInsn(Opcodes.ILOAD, 2);
    mv.visitFieldInsn(Opcodes.PUTFIELD, "java/util/IdentityHashMap$IdentityHashMapIterator",
            "lastReturnedIndex", "I");
    mv.visitJumpInsn(Opcodes.GOTO, l3);
    mv.visitLabel(l4);
    mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null);
    mv.visitIincInsn(2, 2);
    mv.visitJumpInsn(Opcodes.GOTO, l2);
    mv.visitLabel(l3);
    mv.visitFrame(Opcodes.F_CHOP, 1, null, 0, null);
    mv.visitVarInsn(Opcodes.ALOAD, 0);
    mv.visitFieldInsn(Opcodes.GETFIELD, "java/util/IdentityHashMap$IdentityHashMapIterator",
            "lastReturnedIndex", "I");
    mv.visitInsn(Opcodes.IRETURN);
    mv.visitMaxs(5, 3);
    mv.visitEnd();
}

From source file:edu.illinois.nondex.instr.IdentityHashMapShufflingAdder.java

License:Open Source License

public void addHasNext() {
    MethodVisitor mv = super.visitMethod(Opcodes.ACC_PUBLIC, "hasNext", "()Z", null, null);
    mv.visitCode();/*from  w ww .  j  av  a2  s.co m*/
    mv.visitVarInsn(Opcodes.ALOAD, 0);
    mv.visitFieldInsn(Opcodes.GETFIELD, "java/util/IdentityHashMap$IdentityHashMapIterator", "idx", "I");
    mv.visitVarInsn(Opcodes.ALOAD, 0);
    mv.visitFieldInsn(Opcodes.GETFIELD, "java/util/IdentityHashMap$IdentityHashMapIterator", "order",
            "Ljava/util/List;");
    mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, "java/util/List", "size", "()I", true);
    Label l0 = new Label();
    mv.visitJumpInsn(Opcodes.IF_ICMPGE, l0);
    mv.visitInsn(Opcodes.ICONST_1);
    Label l1 = new Label();
    mv.visitJumpInsn(Opcodes.GOTO, l1);
    mv.visitLabel(l0);
    mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null);
    mv.visitInsn(Opcodes.ICONST_0);
    mv.visitLabel(l1);
    mv.visitFrame(Opcodes.F_SAME1, 0, null, 1, new Object[] { Opcodes.INTEGER });
    mv.visitInsn(Opcodes.IRETURN);
    mv.visitMaxs(2, 1);
    mv.visitEnd();
}

From source file:edu.illinois.nondex.instr.IdentityHashMapShufflingAdder.java

License:Open Source License

@Override
public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) {
    if ("hasNext".equals(name)) {
        return super.visitMethod(access, "originalHasNext", desc, signature, exceptions);
    }/*from   w w w  .java  2 s  .  co m*/
    if ("nextIndex".equals(name)) {
        return super.visitMethod(access, "originalNextIndex", desc, signature, exceptions);
    }
    if ("<init>".equals(name)) {
        return new MethodVisitor(Opcodes.ASM5, super.visitMethod(access, name, desc, signature, exceptions)) {
            @Override
            public void visitInsn(int opcode) {
                if (opcode == Opcodes.RETURN) {
                    super.visitVarInsn(Opcodes.ALOAD, 0);
                    super.visitVarInsn(Opcodes.ALOAD, 1);
                    super.visitFieldInsn(Opcodes.PUTFIELD, "java/util/IdentityHashMap$IdentityHashMapIterator",
                            "this$0", "Ljava/util/IdentityHashMap;");
                    super.visitVarInsn(Opcodes.ALOAD, 0);
                    super.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/lang/Object", "<init>", "()V", false);
                    super.visitVarInsn(Opcodes.ALOAD, 0);
                    super.visitVarInsn(Opcodes.ALOAD, 0);
                    super.visitFieldInsn(Opcodes.GETFIELD, "java/util/IdentityHashMap$IdentityHashMapIterator",
                            "this$0", "Ljava/util/IdentityHashMap;");
                    super.visitFieldInsn(Opcodes.GETFIELD, "java/util/IdentityHashMap", "size", "I");
                    Label l0 = new Label();
                    super.visitJumpInsn(Opcodes.IFEQ, l0);
                    super.visitInsn(Opcodes.ICONST_0);
                    Label l1 = new Label();
                    super.visitJumpInsn(Opcodes.GOTO, l1);
                    super.visitLabel(l0);
                    super.visitFrame(Opcodes.F_FULL, 2,
                            new Object[] { "java/util/IdentityHashMap$IdentityHashMapIterator",
                                    "java/util/IdentityHashMap" },
                            1, new Object[] { "java/util/IdentityHashMap$IdentityHashMapIterator" });
                    super.visitVarInsn(Opcodes.ALOAD, 0);
                    super.visitFieldInsn(Opcodes.GETFIELD, "java/util/IdentityHashMap$IdentityHashMapIterator",
                            "this$0", "Ljava/util/IdentityHashMap;");
                    super.visitFieldInsn(Opcodes.GETFIELD, "java/util/IdentityHashMap", "table",
                            "[Ljava/lang/Object;");
                    super.visitInsn(Opcodes.ARRAYLENGTH);
                    super.visitLabel(l1);
                    super.visitFrame(Opcodes.F_FULL, 2,
                            new Object[] { "java/util/IdentityHashMap$IdentityHashMapIterator",
                                    "java/util/IdentityHashMap" },
                            2, new Object[] { "java/util/IdentityHashMap$IdentityHashMapIterator",
                                    Opcodes.INTEGER });
                    super.visitFieldInsn(Opcodes.PUTFIELD, "java/util/IdentityHashMap$IdentityHashMapIterator",
                            "index", "I");
                    super.visitVarInsn(Opcodes.ALOAD, 0);
                    super.visitVarInsn(Opcodes.ALOAD, 0);
                    super.visitFieldInsn(Opcodes.GETFIELD, "java/util/IdentityHashMap$IdentityHashMapIterator",
                            "this$0", "Ljava/util/IdentityHashMap;");
                    super.visitFieldInsn(Opcodes.GETFIELD, "java/util/IdentityHashMap", "modCount", "I");
                    super.visitFieldInsn(Opcodes.PUTFIELD, "java/util/IdentityHashMap$IdentityHashMapIterator",
                            "expectedModCount", "I");
                    super.visitVarInsn(Opcodes.ALOAD, 0);
                    super.visitInsn(Opcodes.ICONST_M1);
                    super.visitFieldInsn(Opcodes.PUTFIELD, "java/util/IdentityHashMap$IdentityHashMapIterator",
                            "lastReturnedIndex", "I");
                    super.visitVarInsn(Opcodes.ALOAD, 0);
                    super.visitVarInsn(Opcodes.ALOAD, 0);
                    super.visitFieldInsn(Opcodes.GETFIELD, "java/util/IdentityHashMap$IdentityHashMapIterator",
                            "this$0", "Ljava/util/IdentityHashMap;");
                    super.visitFieldInsn(Opcodes.GETFIELD, "java/util/IdentityHashMap", "table",
                            "[Ljava/lang/Object;");
                    super.visitFieldInsn(Opcodes.PUTFIELD, "java/util/IdentityHashMap$IdentityHashMapIterator",
                            "traversalTable", "[Ljava/lang/Object;");
                    super.visitVarInsn(Opcodes.ALOAD, 0);
                    super.visitTypeInsn(Opcodes.NEW, "java/util/ArrayList");
                    super.visitInsn(Opcodes.DUP);
                    super.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/util/ArrayList", "<init>", "()V", false);
                    super.visitFieldInsn(Opcodes.PUTFIELD, "java/util/IdentityHashMap$IdentityHashMapIterator",
                            "order", "Ljava/util/List;");
                    super.visitVarInsn(Opcodes.ALOAD, 0);
                    super.visitTypeInsn(Opcodes.NEW, "java/util/ArrayList");
                    super.visitInsn(Opcodes.DUP);
                    super.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/util/ArrayList", "<init>", "()V", false);
                    super.visitFieldInsn(Opcodes.PUTFIELD, "java/util/IdentityHashMap$IdentityHashMapIterator",
                            "keys", "Ljava/util/List;");
                    super.visitVarInsn(Opcodes.ALOAD, 0);
                    super.visitInsn(Opcodes.ICONST_0);
                    super.visitFieldInsn(Opcodes.PUTFIELD, "java/util/IdentityHashMap$IdentityHashMapIterator",
                            "idx", "I");
                    Label l2 = new Label();
                    super.visitLabel(l2);
                    super.visitFrame(Opcodes.F_SAME, 0, null, 0, null);
                    super.visitVarInsn(Opcodes.ALOAD, 0);
                    super.visitMethodInsn(Opcodes.INVOKEVIRTUAL,
                            "java/util/IdentityHashMap$IdentityHashMapIterator", "originalHasNext", "()Z",
                            false);
                    Label l3 = new Label();
                    super.visitJumpInsn(Opcodes.IFEQ, l3);
                    super.visitVarInsn(Opcodes.ALOAD, 0);
                    super.visitFieldInsn(Opcodes.GETFIELD, "java/util/IdentityHashMap$IdentityHashMapIterator",
                            "order", "Ljava/util/List;");
                    super.visitVarInsn(Opcodes.ALOAD, 0);
                    super.visitMethodInsn(Opcodes.INVOKEVIRTUAL,
                            "java/util/IdentityHashMap$IdentityHashMapIterator", "originalNextIndex", "()I",
                            false);
                    super.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Integer", "valueOf",
                            "(I)Ljava/lang/Integer;", false);
                    super.visitMethodInsn(Opcodes.INVOKEINTERFACE, "java/util/List", "add",
                            "(Ljava/lang/Object;)Z", true);
                    super.visitInsn(Opcodes.POP);
                    super.visitJumpInsn(Opcodes.GOTO, l2);
                    super.visitLabel(l3);
                    super.visitFrame(Opcodes.F_SAME, 0, null, 0, null);
                    super.visitVarInsn(Opcodes.ALOAD, 0);
                    super.visitVarInsn(Opcodes.ALOAD, 0);
                    super.visitFieldInsn(Opcodes.GETFIELD, "java/util/IdentityHashMap$IdentityHashMapIterator",
                            "order", "Ljava/util/List;");
                    super.visitMethodInsn(Opcodes.INVOKESTATIC,
                            "edu/illinois/nondex/shuffling/ControlNondeterminism", "shuffle",
                            "(Ljava/util/List;)Ljava/util/List;", false);
                    super.visitFieldInsn(Opcodes.PUTFIELD, "java/util/IdentityHashMap$IdentityHashMapIterator",
                            "order", "Ljava/util/List;");
                    super.visitVarInsn(Opcodes.ALOAD, 0);
                    super.visitFieldInsn(Opcodes.GETFIELD, "java/util/IdentityHashMap$IdentityHashMapIterator",
                            "order", "Ljava/util/List;");
                    super.visitMethodInsn(Opcodes.INVOKEINTERFACE, "java/util/List", "iterator",
                            "()Ljava/util/Iterator;", true);
                    super.visitVarInsn(Opcodes.ASTORE, 2);
                    Label l4 = new Label();
                    super.visitLabel(l4);
                    super.visitFrame(Opcodes.F_APPEND, 1, new Object[] { "java/util/Iterator" }, 0, null);
                    super.visitVarInsn(Opcodes.ALOAD, 2);
                    super.visitMethodInsn(Opcodes.INVOKEINTERFACE, "java/util/Iterator", "hasNext", "()Z",
                            true);
                    Label l5 = new Label();
                    super.visitJumpInsn(Opcodes.IFEQ, l5);
                    super.visitVarInsn(Opcodes.ALOAD, 2);
                    super.visitMethodInsn(Opcodes.INVOKEINTERFACE, "java/util/Iterator", "next",
                            "()Ljava/lang/Object;", true);
                    super.visitTypeInsn(Opcodes.CHECKCAST, "java/lang/Integer");
                    super.visitVarInsn(Opcodes.ASTORE, 3);
                    super.visitVarInsn(Opcodes.ALOAD, 0);
                    super.visitFieldInsn(Opcodes.GETFIELD, "java/util/IdentityHashMap$IdentityHashMapIterator",
                            "keys", "Ljava/util/List;");
                    super.visitVarInsn(Opcodes.ALOAD, 0);
                    super.visitFieldInsn(Opcodes.GETFIELD, "java/util/IdentityHashMap$IdentityHashMapIterator",
                            "this$0", "Ljava/util/IdentityHashMap;");
                    super.visitFieldInsn(Opcodes.GETFIELD, "java/util/IdentityHashMap", "table",
                            "[Ljava/lang/Object;");
                    super.visitVarInsn(Opcodes.ALOAD, 3);
                    super.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Integer", "intValue", "()I", false);
                    super.visitInsn(Opcodes.AALOAD);
                    super.visitMethodInsn(Opcodes.INVOKEINTERFACE, "java/util/List", "add",
                            "(Ljava/lang/Object;)Z", true);
                    super.visitInsn(Opcodes.POP);
                    super.visitJumpInsn(Opcodes.GOTO, l4);
                    super.visitLabel(l5);
                    super.visitFrame(Opcodes.F_CHOP, 1, null, 0, null);
                }
                super.visitInsn(opcode);
            }
        };
    }
    return super.visitMethod(access, name, desc, signature, exceptions);
}

From source file:edu.illinois.nondex.instr.MethodShufflingAdder.java

License:Open Source License

@Override
public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) {
    if ("getExceptionTypes".equals(name)) {
        return new MethodVisitor(Opcodes.ASM5, super.visitMethod(access, name, desc, signature, exceptions)) {
            @Override/*  w  ww . j a va  2  s  .  c o m*/
            public void visitInsn(int opcode) {
                if (opcode == Opcodes.ARETURN) {
                    super.visitMethodInsn(Opcodes.INVOKESTATIC,
                            "edu/illinois/nondex/shuffling/ControlNondeterminism", "shuffle",
                            "([Ljava/lang/Object;)[Ljava/lang/Object;", false);
                    super.visitTypeInsn(Opcodes.CHECKCAST, "[Ljava/lang/Class;");
                }
                super.visitInsn(opcode);
            }
        };
    }
    if ("getGenericExceptionTypes".equals(name)) {
        return new MethodVisitor(Opcodes.ASM5, super.visitMethod(access, name, desc, signature, exceptions)) {
            @Override
            public void visitInsn(int opcode) {
                if (opcode == Opcodes.ARETURN) {
                    super.visitMethodInsn(Opcodes.INVOKESTATIC,
                            "edu/illinois/nondex/shuffling/ControlNondeterminism", "shuffle",
                            "([Ljava/lang/Object;)[Ljava/lang/Object;", false);
                    super.visitTypeInsn(Opcodes.CHECKCAST, "[Ljava/lang/reflect/Type;");
                }
                super.visitInsn(opcode);
            }
        };
    }
    if ("getDeclaredAnnotations".equals(name)) {
        return new MethodVisitor(Opcodes.ASM5, super.visitMethod(access, name, desc, signature, exceptions)) {
            @Override
            public void visitInsn(int opcode) {
                if (opcode == Opcodes.ARETURN) {
                    super.visitMethodInsn(Opcodes.INVOKESTATIC,
                            "edu/illinois/nondex/shuffling/ControlNondeterminism", "shuffle",
                            "([Ljava/lang/Object;)[Ljava/lang/Object;", false);
                    super.visitTypeInsn(Opcodes.CHECKCAST, "[Ljava/lang/annotation/Annotation;");
                }
                super.visitInsn(opcode);
            }
        };
    }
    if ("getParameterAnnotations".equals(name)) {
        return new MethodVisitor(Opcodes.ASM5, super.visitMethod(access, name, desc, signature, exceptions)) {
            @Override
            public void visitInsn(int opcode) {
                if (opcode == Opcodes.ARETURN) {
                    super.visitVarInsn(Opcodes.ASTORE, 1);
                    super.visitInsn(Opcodes.ICONST_0);
                    super.visitVarInsn(Opcodes.ISTORE, 2);
                    Label l0 = new Label();
                    super.visitLabel(l0);
                    super.visitFrame(Opcodes.F_APPEND, 2,
                            new Object[] { "[[Ljava/lang/annotation/Annotation;", Opcodes.INTEGER }, 0, null);
                    super.visitVarInsn(Opcodes.ILOAD, 2);
                    super.visitVarInsn(Opcodes.ALOAD, 1);
                    super.visitInsn(Opcodes.ARRAYLENGTH);
                    Label l1 = new Label();
                    super.visitJumpInsn(Opcodes.IF_ICMPGE, l1);
                    super.visitVarInsn(Opcodes.ALOAD, 1);
                    super.visitVarInsn(Opcodes.ILOAD, 2);
                    super.visitVarInsn(Opcodes.ALOAD, 1);
                    super.visitVarInsn(Opcodes.ILOAD, 2);
                    super.visitInsn(Opcodes.AALOAD);
                    super.visitMethodInsn(Opcodes.INVOKESTATIC,
                            "edu/illinois/nondex/shuffling/ControlNondeterminism", "shuffle",
                            "([Ljava/lang/Object;)[Ljava/lang/Object;", false);
                    super.visitTypeInsn(Opcodes.CHECKCAST, "[Ljava/lang/annotation/Annotation;");
                    super.visitInsn(Opcodes.AASTORE);
                    super.visitIincInsn(2, 1);
                    super.visitJumpInsn(Opcodes.GOTO, l0);
                    super.visitLabel(l1);
                    super.visitFrame(Opcodes.F_CHOP, 1, null, 0, null);
                    super.visitVarInsn(Opcodes.ALOAD, 1);
                }
                super.visitInsn(opcode);
            }
        };
    }

    return super.visitMethod(access, name, desc, signature, exceptions);
}

From source file:edu.illinois.nondex.instr.PriorityBlockingQueueShufflingAdder.java

License:Open Source License

public void addToString() {
    MethodVisitor mv = super.visitMethod(Opcodes.ACC_PUBLIC, "toString", "()Ljava/lang/String;", null, null);
    mv.visitCode();/*from w  w  w .j a  v a 2  s  . c o  m*/
    Label l0 = new Label();
    Label l1 = new Label();
    Label l2 = new Label();
    mv.visitTryCatchBlock(l0, l1, l2, null);
    Label l3 = new Label();
    Label l4 = new Label();
    mv.visitTryCatchBlock(l3, l4, l2, null);
    Label l5 = new Label();
    mv.visitTryCatchBlock(l2, l5, l2, null);
    mv.visitVarInsn(Opcodes.ALOAD, 0);
    mv.visitFieldInsn(Opcodes.GETFIELD, "java/util/concurrent/PriorityBlockingQueue", "lock",
            "Ljava/util/concurrent/locks/ReentrantLock;");
    mv.visitVarInsn(Opcodes.ASTORE, 1);
    mv.visitVarInsn(Opcodes.ALOAD, 1);
    mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/util/concurrent/locks/ReentrantLock", "lock", "()V", false);
    mv.visitLabel(l0);
    mv.visitVarInsn(Opcodes.ALOAD, 0);
    mv.visitFieldInsn(Opcodes.GETFIELD, "java/util/concurrent/PriorityBlockingQueue", "size", "I");
    mv.visitVarInsn(Opcodes.ISTORE, 2);
    mv.visitVarInsn(Opcodes.ILOAD, 2);
    mv.visitJumpInsn(Opcodes.IFNE, l3);
    mv.visitLdcInsn("[]");
    mv.visitVarInsn(Opcodes.ASTORE, 3);
    mv.visitLabel(l1);
    mv.visitVarInsn(Opcodes.ALOAD, 1);
    mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/util/concurrent/locks/ReentrantLock", "unlock", "()V",
            false);
    mv.visitVarInsn(Opcodes.ALOAD, 3);
    mv.visitInsn(Opcodes.ARETURN);
    mv.visitLabel(l3);
    mv.visitFrame(Opcodes.F_APPEND, 2,
            new Object[] { "java/util/concurrent/locks/ReentrantLock", Opcodes.INTEGER }, 0, null);
    mv.visitTypeInsn(Opcodes.NEW, "java/lang/StringBuilder");
    mv.visitInsn(Opcodes.DUP);
    mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/lang/StringBuilder", "<init>", "()V", false);
    mv.visitVarInsn(Opcodes.ASTORE, 3);
    mv.visitVarInsn(Opcodes.ALOAD, 3);
    mv.visitIntInsn(Opcodes.BIPUSH, 91);
    mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/StringBuilder", "append",
            "(C)Ljava/lang/StringBuilder;", false);
    mv.visitInsn(Opcodes.POP);
    mv.visitVarInsn(Opcodes.ALOAD, 0);
    mv.visitFieldInsn(Opcodes.GETFIELD, "java/util/concurrent/PriorityBlockingQueue", "queue",
            "[Ljava/lang/Object;");
    mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "[Ljava/lang/Object;", "clone", "()Ljava/lang/Object;", false);
    mv.visitTypeInsn(Opcodes.CHECKCAST, "[Ljava/lang/Object;");
    mv.visitVarInsn(Opcodes.ASTORE, 4);
    mv.visitVarInsn(Opcodes.ALOAD, 4);
    mv.visitMethodInsn(Opcodes.INVOKESTATIC, "edu/illinois/nondex/shuffling/ControlNondeterminism", "shuffle",
            "([Ljava/lang/Object;)[Ljava/lang/Object;", false);
    mv.visitVarInsn(Opcodes.ASTORE, 4);
    mv.visitInsn(Opcodes.ICONST_0);
    mv.visitVarInsn(Opcodes.ISTORE, 5);
    Label l6 = new Label();
    mv.visitLabel(l6);
    mv.visitFrame(Opcodes.F_APPEND, 3,
            new Object[] { "java/lang/StringBuilder", "[Ljava/lang/Object;", Opcodes.INTEGER }, 0, null);
    mv.visitVarInsn(Opcodes.ILOAD, 5);
    mv.visitVarInsn(Opcodes.ILOAD, 2);
    Label l7 = new Label();
    mv.visitJumpInsn(Opcodes.IF_ICMPGE, l7);
    mv.visitVarInsn(Opcodes.ALOAD, 4);
    mv.visitVarInsn(Opcodes.ILOAD, 5);
    mv.visitInsn(Opcodes.AALOAD);
    mv.visitVarInsn(Opcodes.ASTORE, 6);
    mv.visitVarInsn(Opcodes.ALOAD, 3);
    mv.visitVarInsn(Opcodes.ALOAD, 6);
    mv.visitVarInsn(Opcodes.ALOAD, 0);
    Label l8 = new Label();
    mv.visitJumpInsn(Opcodes.IF_ACMPNE, l8);
    mv.visitLdcInsn("(this Collection)");
    Label l9 = new Label();
    mv.visitJumpInsn(Opcodes.GOTO, l9);
    mv.visitLabel(l8);
    mv.visitFrame(Opcodes.F_FULL, 7,
            new Object[] { "java/util/concurrent/PriorityBlockingQueue",
                    "java/util/concurrent/locks/ReentrantLock", Opcodes.INTEGER, "java/lang/StringBuilder",
                    "[Ljava/lang/Object;", Opcodes.INTEGER, "java/lang/Object" },
            1, new Object[] { "java/lang/StringBuilder" });
    mv.visitVarInsn(Opcodes.ALOAD, 6);
    mv.visitLabel(l9);
    mv.visitFrame(Opcodes.F_FULL, 7,
            new Object[] { "java/util/concurrent/PriorityBlockingQueue",
                    "java/util/concurrent/locks/ReentrantLock", Opcodes.INTEGER, "java/lang/StringBuilder",
                    "[Ljava/lang/Object;", Opcodes.INTEGER, "java/lang/Object" },
            2, new Object[] { "java/lang/StringBuilder", "java/lang/Object" });
    mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/StringBuilder", "append",
            "(Ljava/lang/Object;)Ljava/lang/StringBuilder;", false);
    mv.visitInsn(Opcodes.POP);
    mv.visitVarInsn(Opcodes.ILOAD, 5);
    mv.visitVarInsn(Opcodes.ILOAD, 2);
    mv.visitInsn(Opcodes.ICONST_1);
    mv.visitInsn(Opcodes.ISUB);
    Label l10 = new Label();
    mv.visitJumpInsn(Opcodes.IF_ICMPEQ, l10);
    mv.visitVarInsn(Opcodes.ALOAD, 3);
    mv.visitIntInsn(Opcodes.BIPUSH, 44);
    mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/StringBuilder", "append",
            "(C)Ljava/lang/StringBuilder;", false);
    mv.visitIntInsn(Opcodes.BIPUSH, 32);
    mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/StringBuilder", "append",
            "(C)Ljava/lang/StringBuilder;", false);
    mv.visitInsn(Opcodes.POP);
    mv.visitLabel(l10);
    mv.visitFrame(Opcodes.F_CHOP, 1, null, 0, null);
    mv.visitIincInsn(5, 1);
    mv.visitJumpInsn(Opcodes.GOTO, l6);
    mv.visitLabel(l7);
    mv.visitFrame(Opcodes.F_CHOP, 1, null, 0, null);
    mv.visitVarInsn(Opcodes.ALOAD, 3);
    mv.visitIntInsn(Opcodes.BIPUSH, 93);
    mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/StringBuilder", "append",
            "(C)Ljava/lang/StringBuilder;", false);
    mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/StringBuilder", "toString", "()Ljava/lang/String;",
            false);
    mv.visitVarInsn(Opcodes.ASTORE, 5);
    mv.visitLabel(l4);
    mv.visitVarInsn(Opcodes.ALOAD, 1);
    mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/util/concurrent/locks/ReentrantLock", "unlock", "()V",
            false);
    mv.visitVarInsn(Opcodes.ALOAD, 5);
    mv.visitInsn(Opcodes.ARETURN);
    mv.visitLabel(l2);
    mv.visitFrame(Opcodes.F_FULL, 2, new Object[] { "java/util/concurrent/PriorityBlockingQueue",
            "java/util/concurrent/locks/ReentrantLock" }, 1, new Object[] { "java/lang/Throwable" });
    mv.visitVarInsn(Opcodes.ASTORE, 7);
    mv.visitLabel(l5);
    mv.visitVarInsn(Opcodes.ALOAD, 1);
    mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/util/concurrent/locks/ReentrantLock", "unlock", "()V",
            false);
    mv.visitVarInsn(Opcodes.ALOAD, 7);
    mv.visitInsn(Opcodes.ATHROW);
    mv.visitMaxs(3, 8);
    mv.visitEnd();
}

From source file:edu.illinois.nondex.instr.PriorityQueueShufflingAdder.java

License:Open Source License

@Override
public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) {
    if ("hasNext".equals(name)) {
        return super.visitMethod(access, "originalHasNext", desc, signature, exceptions);
    }/*from  ww w . j a va 2  s  . co  m*/
    if ("next".equals(name)) {
        return super.visitMethod(access, "originalNext", desc, signature, exceptions);
    }
    if ("<init>".equals(name)) {
        return new MethodVisitor(Opcodes.ASM5, super.visitMethod(access, name, desc, signature, exceptions)) {
            @Override
            public void visitInsn(int opcode) {
                if (opcode == Opcodes.RETURN) {
                    super.visitVarInsn(Opcodes.ALOAD, 0);
                    super.visitVarInsn(Opcodes.ALOAD, 1);
                    super.visitFieldInsn(Opcodes.PUTFIELD, "java/util/PriorityQueue$Itr", "this$0",
                            "Ljava/util/PriorityQueue;");
                    super.visitVarInsn(Opcodes.ALOAD, 0);
                    super.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/lang/Object", "<init>", "()V", false);
                    super.visitVarInsn(Opcodes.ALOAD, 0);
                    super.visitInsn(Opcodes.ICONST_0);
                    super.visitFieldInsn(Opcodes.PUTFIELD, "java/util/PriorityQueue$Itr", "cursor", "I");
                    super.visitVarInsn(Opcodes.ALOAD, 0);
                    super.visitInsn(Opcodes.ICONST_M1);
                    super.visitFieldInsn(Opcodes.PUTFIELD, "java/util/PriorityQueue$Itr", "lastRet", "I");
                    super.visitVarInsn(Opcodes.ALOAD, 0);
                    super.visitInsn(Opcodes.ACONST_NULL);
                    super.visitFieldInsn(Opcodes.PUTFIELD, "java/util/PriorityQueue$Itr", "forgetMeNot",
                            "Ljava/util/ArrayDeque;");
                    super.visitVarInsn(Opcodes.ALOAD, 0);
                    super.visitInsn(Opcodes.ACONST_NULL);
                    super.visitFieldInsn(Opcodes.PUTFIELD, "java/util/PriorityQueue$Itr", "lastRetElt",
                            "Ljava/lang/Object;");
                    super.visitVarInsn(Opcodes.ALOAD, 0);
                    super.visitVarInsn(Opcodes.ALOAD, 0);
                    super.visitFieldInsn(Opcodes.GETFIELD, "java/util/PriorityQueue$Itr", "this$0",
                            "Ljava/util/PriorityQueue;");
                    super.visitFieldInsn(Opcodes.GETFIELD, "java/util/PriorityQueue", "modCount", "I");
                    super.visitFieldInsn(Opcodes.PUTFIELD, "java/util/PriorityQueue$Itr", "expectedModCount",
                            "I");
                    super.visitVarInsn(Opcodes.ALOAD, 0);
                    super.visitVarInsn(Opcodes.ALOAD, 0);
                    super.visitTypeInsn(Opcodes.NEW, "java/util/ArrayList");
                    super.visitInsn(Opcodes.DUP);
                    super.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/util/ArrayList", "<init>", "()V", false);
                    super.visitFieldInsn(Opcodes.PUTFIELD, "java/util/PriorityQueue$Itr", "elements",
                            "Ljava/util/List;");
                    Label l0 = new Label();
                    super.visitLabel(l0);
                    super.visitFrame(Opcodes.F_FULL, 2,
                            new Object[] { "java/util/PriorityQueue$Itr", "java/util/PriorityQueue" }, 0,
                            new Object[] {});
                    super.visitVarInsn(Opcodes.ALOAD, 0);
                    super.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/util/PriorityQueue$Itr",
                            "originalHasNext", "()Z", false);
                    Label l1 = new Label();
                    super.visitJumpInsn(Opcodes.IFEQ, l1);
                    super.visitVarInsn(Opcodes.ALOAD, 0);
                    super.visitFieldInsn(Opcodes.GETFIELD, "java/util/PriorityQueue$Itr", "elements",
                            "Ljava/util/List;");
                    super.visitVarInsn(Opcodes.ALOAD, 0);
                    super.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/util/PriorityQueue$Itr", "originalNext",
                            "()Ljava/lang/Object;", false);
                    super.visitMethodInsn(Opcodes.INVOKEINTERFACE, "java/util/List", "add",
                            "(Ljava/lang/Object;)Z", true);
                    super.visitInsn(Opcodes.POP);
                    super.visitJumpInsn(Opcodes.GOTO, l0);
                    super.visitLabel(l1);
                    super.visitFrame(Opcodes.F_SAME, 0, null, 0, null);
                    super.visitVarInsn(Opcodes.ALOAD, 0);
                    super.visitVarInsn(Opcodes.ALOAD, 0);
                    super.visitFieldInsn(Opcodes.GETFIELD, "java/util/PriorityQueue$Itr", "elements",
                            "Ljava/util/List;");
                    super.visitMethodInsn(Opcodes.INVOKESTATIC,
                            "edu/illinois/nondex/shuffling/ControlNondeterminism", "shuffle",
                            "(Ljava/util/List;)Ljava/util/List;", false);
                    super.visitFieldInsn(Opcodes.PUTFIELD, "java/util/PriorityQueue$Itr", "elements",
                            "Ljava/util/List;");
                    super.visitVarInsn(Opcodes.ALOAD, 0);
                    super.visitVarInsn(Opcodes.ALOAD, 0);
                    super.visitFieldInsn(Opcodes.GETFIELD, "java/util/PriorityQueue$Itr", "elements",
                            "Ljava/util/List;");
                    super.visitMethodInsn(Opcodes.INVOKEINTERFACE, "java/util/List", "iterator",
                            "()Ljava/util/Iterator;", true);
                    super.visitFieldInsn(Opcodes.PUTFIELD, "java/util/PriorityQueue$Itr", "iter",
                            "Ljava/util/Iterator;");
                    super.visitVarInsn(Opcodes.ALOAD, 0);
                    super.visitInsn(Opcodes.ICONST_M1);
                    super.visitFieldInsn(Opcodes.PUTFIELD, "java/util/PriorityQueue$Itr", "lastRet", "I");
                    super.visitVarInsn(Opcodes.ALOAD, 0);
                    super.visitInsn(Opcodes.ACONST_NULL);
                    super.visitFieldInsn(Opcodes.PUTFIELD, "java/util/PriorityQueue$Itr", "lastRetElt",
                            "Ljava/lang/Object;");
                }
                super.visitInsn(opcode);
            }
        };
    }
    return super.visitMethod(access, name, desc, signature, exceptions);
}