List of usage examples for org.objectweb.asm Opcodes GOTO
int GOTO
To view the source code for org.objectweb.asm Opcodes GOTO.
Click Source Link
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); }