001    /*
002     *  This file is part of the Jikes RVM project (http://jikesrvm.org).
003     *
004     *  This file is licensed to You under the Eclipse Public License (EPL);
005     *  You may not use this file except in compliance with the License. You
006     *  may obtain a copy of the License at
007     *
008     *      http://www.opensource.org/licenses/eclipse-1.0.php
009     *
010     *  See the COPYRIGHT.txt file distributed with this work for information
011     *  regarding copyright ownership.
012     */
013    package org.jikesrvm.mm.mminterface;
014    
015    import org.jikesrvm.compilers.common.CompiledMethod;
016    import org.jikesrvm.scheduler.RVMThread;
017    import org.vmmagic.pragma.Uninterruptible;
018    import org.vmmagic.unboxed.Address;
019    import org.vmmagic.unboxed.Offset;
020    import org.vmmagic.unboxed.WordArray;
021    
022    /**
023     * Base class for iterators that identify object references and JSR return addresses
024     * held in stackframes produced by each of our compilers (baseline, opt, etc.).
025     * All compiler specific GCMapIterators extend this abstract class.
026     *
027     * @see GCMapIteratorGroup
028     */
029    @Uninterruptible
030    public abstract class GCMapIterator {
031    
032      /** thread whose stack is currently being scanned */
033      public RVMThread thread;
034    
035      /** address of stackframe currently being scanned */
036      public Address framePtr;
037    
038      /** address where each gpr register was saved by previously scanned stackframe(s) */
039      public WordArray registerLocations;
040    
041      /**
042       * Prepare to scan a thread's stack and saved registers for object references.
043       *
044       * @param thread Thread whose stack is being scanned
045       */
046      public void newStackWalk(RVMThread thread) {
047        this.thread = thread;
048      }
049    
050      /**
051       * Prepare to iterate over object references and JSR return addresses held by a stackframe.
052       *
053       * @param compiledMethod     method running in the stackframe
054       * @param instructionOffset  offset of current instruction within that method's code
055       * @param framePtr           address of stackframe to be visited
056       */
057      public abstract void setupIterator(CompiledMethod compiledMethod, Offset instructionOffset, Address framePtr);
058    
059      /**
060       * Get address of next object reference held by current stackframe.
061       * Returns zero when there are no more references to report.
062       * <p>
063       * Side effect: registerLocations[] updated at end of iteration.
064       * TODO: registerLocations[] update should be done via separately called
065       * method instead of as side effect.
066       * <p>
067       *
068       * @return address of word containing an object reference
069       *         zero if no more references to report
070       */
071      public abstract Address getNextReferenceAddress();
072    
073      /**
074       * Get address of next JSR return address held by current stackframe.
075       *
076       * @return address of word containing a JSR return address
077       *         zero if no more return addresses to report
078       */
079      public abstract Address getNextReturnAddressAddress();
080    
081      /**
082       * Prepare to re-iterate on same stackframe, and to switch between
083       * "reference" iteration and "JSR return address" iteration.
084       */
085      public abstract void reset();
086    
087      /**
088       * Iteration is complete, release any internal data structures including
089       * locks acquired during setupIterator for jsr maps.
090       */
091      public abstract void cleanupPointers();
092    
093      /**
094       * Get the type of this iterator (BASELINE, OPT, etc.).
095       * Called from GCMapIteratorGroup to select which iterator
096       * to use for a stackframe.  The possible types are specified
097       * in CompiledMethod.
098       *
099       * @return type code for this iterator
100       */
101      public abstract int getType();
102    }