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 */
013package org.jikesrvm.mm.mminterface;
014
015import org.jikesrvm.compilers.common.CompiledMethod;
016import org.jikesrvm.scheduler.RVMThread;
017import org.vmmagic.pragma.Uninterruptible;
018import org.vmmagic.unboxed.Address;
019import org.vmmagic.unboxed.AddressArray;
020import org.vmmagic.unboxed.Offset;
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
030public abstract class GCMapIterator {
031
032  /** thread whose stack is currently being scanned */
033  protected RVMThread thread;
034
035  /** address of stackframe currently being scanned */
036  protected Address framePtr;
037
038  /** address where each gpr register was saved by previously scanned stackframe(s) */
039  public final AddressArray registerLocations;
040
041  public GCMapIterator(AddressArray registerLocations) {
042    this.registerLocations = registerLocations;
043  }
044
045  /**
046   * Prepare to scan a thread's stack and saved registers for object references.
047   *
048   * @param thread Thread whose stack is being scanned
049   */
050  public void newStackWalk(RVMThread thread) {
051    this.thread = thread;
052  }
053
054  /**
055   * Prepare to iterate over object references and JSR return addresses held by a stackframe.
056   *
057   * @param compiledMethod     method running in the stackframe
058   * @param instructionOffset  offset of current instruction within that method's code
059   * @param framePtr           address of stackframe to be visited
060   */
061  public abstract void setupIterator(CompiledMethod compiledMethod, Offset instructionOffset, Address framePtr);
062
063  /**
064   * Get address of next object reference held by current stackframe.
065   * Returns zero when there are no more references to report.
066   * <p>
067   * Side effect: registerLocations[] updated at end of iteration.
068   * TODO: registerLocations[] update should be done via separately called
069   * method instead of as side effect.
070   * <p>
071   *
072   * @return address of word containing an object reference
073   *         zero if no more references to report
074   */
075  public abstract Address getNextReferenceAddress();
076
077  /**
078   * Get address of next JSR return address held by current stackframe.
079   *
080   * @return address of word containing a JSR return address
081   *         zero if no more return addresses to report
082   */
083  public abstract Address getNextReturnAddressAddress();
084
085  /**
086   * Prepare to re-iterate on same stackframe, and to switch between
087   * "reference" iteration and "JSR return address" iteration.
088   */
089  public abstract void reset();
090
091  /**
092   * Iteration is complete, release any internal data structures including
093   * locks acquired during setupIterator for jsr maps.
094   */
095  public abstract void cleanupPointers();
096
097  /**
098   * Get the type of this iterator (BASELINE, OPT, etc.).
099   * Called from GCMapIteratorGroup to select which iterator
100   * to use for a stackframe.  The possible types are specified
101   * in CompiledMethod.
102   *
103   * @return type code for this iterator
104   */
105  public abstract int getType();
106}