예제 #1
0
 /**
  * The caller specifies the region of virtual memory to be used for this space. If this region
  * conflicts with an existing space, then the constructor will fail.
  *
  * @param name The name of this space (used when printing error messages etc)
  * @param pageBudget The number of pages this space may consume before consulting the plan
  * @param vmRequest An object describing the virtual memory requested.
  */
 public LargeObjectSpace(String name, int pageBudget, VMRequest vmRequest) {
   super(name, pageBudget, vmRequest);
   treadmill = new Treadmill(LOG_BYTES_IN_PAGE, true);
   markState = Word.zero();
 }
  /**
   * Low level copy of <code>copyBytes</code> bytes from <code>src[srcPos]</code> to <code>
   * dst[dstPos]</code>.
   *
   * <p>Assumption: <code>src != dst || (srcPos >= dstPos)</code> and element size is 2 bytes.
   *
   * @param dstPtr The destination start address
   * @param srcPtr The source start address
   * @param copyBytes The number of bytes to be copied
   */
  public static void aligned16Copy(Address dstPtr, Address srcPtr, int copyBytes) {
    if (USE_NATIVE && copyBytes > NATIVE_THRESHOLD) {
      memcopy(dstPtr, srcPtr, copyBytes);
    } else {
      if (copyBytes >= BYTES_IN_COPY
          && (srcPtr.toWord().and(Word.fromIntZeroExtend(BYTES_IN_COPY - 1))
              == (dstPtr.toWord().and(Word.fromIntZeroExtend(BYTES_IN_COPY - 1))))) {
        // relative alignment is the same
        Address endPtr = srcPtr.plus(copyBytes);
        Address wordEndPtr =
            endPtr.toWord().and(Word.fromIntZeroExtend(BYTES_IN_COPY - 1).not()).toAddress();

        if (BYTES_IN_COPY == 8) {
          if (srcPtr.toWord().and(Word.fromIntZeroExtend(2)).NE(Word.zero())) {
            copy2Bytes(dstPtr, srcPtr);
            srcPtr = srcPtr.plus(2);
            dstPtr = dstPtr.plus(2);
          }
          if (srcPtr.toWord().and(Word.fromIntZeroExtend(4)).NE(Word.zero())) {
            copy4Bytes(dstPtr, srcPtr);
            srcPtr = srcPtr.plus(4);
            dstPtr = dstPtr.plus(4);
          }
        } else {
          if (srcPtr.toWord().and(Word.fromIntZeroExtend(2)).NE(Word.zero())) {
            copy2Bytes(dstPtr, srcPtr);
            srcPtr = srcPtr.plus(2);
            dstPtr = dstPtr.plus(2);
          }
        }
        while (srcPtr.LT(wordEndPtr)) {
          if (BYTES_IN_COPY == 8) {
            copy8Bytes(dstPtr, srcPtr);
          } else {
            copy4Bytes(dstPtr, srcPtr);
          }
          srcPtr = srcPtr.plus(BYTES_IN_COPY);
          dstPtr = dstPtr.plus(BYTES_IN_COPY);
        }
        // if(VM.VerifyAssertions) VM._assert(wordEndPtr.EQ(srcPtr));
        if (BYTES_IN_COPY == 8) {
          if (endPtr.toWord().and(Word.fromIntZeroExtend(4)).NE(Word.zero())) {
            copy4Bytes(dstPtr, srcPtr);
            srcPtr = srcPtr.plus(4);
            dstPtr = dstPtr.plus(4);
          }
          if (endPtr.toWord().and(Word.fromIntZeroExtend(2)).NE(Word.zero())) {
            copy2Bytes(dstPtr, srcPtr);
          }
        } else {
          if (endPtr.toWord().and(Word.fromIntZeroExtend(2)).NE(Word.zero())) {
            copy2Bytes(dstPtr, srcPtr);
          }
        }
      } else {
        Address endPtr = srcPtr.plus(copyBytes);
        while (srcPtr.LT(endPtr)) {
          copy2Bytes(dstPtr, srcPtr);
          srcPtr = srcPtr.plus(2);
          dstPtr = dstPtr.plus(2);
        }
      }
    }
  }
예제 #3
0
/**
 * This class implements tracing for a simple immortal collection policy. Under this policy all that
 * is required is for the "collector" to propogate marks in a liveness trace. It does not actually
 * collect. This class does not hold any state, all methods are static.
 *
 * <p>$Id: ImmortalSpace.java,v 1.18 2005/01/19 02:49:02 steveb-oss Exp $
 *
 * @author Perry Cheng
 * @author <a href="http://cs.anu.edu.au/~Steve.Blackburn">Steve Blackburn</a>
 * @version $Revision: 1.18 $
 * @date $Date: 2005/01/19 02:49:02 $
 */
public final class ImmortalSpace extends Space implements Constants, Uninterruptible {

  /**
   * **************************************************************************
   *
   * <p>Class variables
   */
  static final Word GC_MARK_BIT_MASK = Word.one();

  public static Word immortalMarkState = Word.zero(); // when GC off, the initialization value

  /**
   * **************************************************************************
   *
   * <p>Initialization
   */

  /**
   * The caller specifies the region of virtual memory to be used for this space. If this region
   * conflicts with an existing space, then the constructor will fail.
   *
   * @param name The name of this space (used when printing error messages etc)
   * @param pageBudget The number of pages this space may consume before consulting the plan
   * @param start The start address of the space in virtual memory
   * @param bytes The size of the space in virtual memory, in bytes
   */
  public ImmortalSpace(String name, int pageBudget, Address start, Extent bytes) {
    super(name, false, true, start, bytes);
    pr = new MonotonePageResource(pageBudget, this, start, extent);
  }

  /**
   * Construct a space of a given number of megabytes in size.
   *
   * <p>The caller specifies the amount virtual memory to be used for this space <i>in
   * megabytes</i>. If there is insufficient address space, then the constructor will fail.
   *
   * @param name The name of this space (used when printing error messages etc)
   * @param pageBudget The number of pages this space may consume before consulting the plan
   * @param mb The size of the space in virtual memory, in megabytes (MB)
   */
  public ImmortalSpace(String name, int pageBudget, int mb) {
    super(name, false, true, mb);
    pr = new MonotonePageResource(pageBudget, this, start, extent);
  }

  /**
   * Construct a space that consumes a given fraction of the available virtual memory.
   *
   * <p>The caller specifies the amount virtual memory to be used for this space <i>as a fraction of
   * the total available</i>. If there is insufficient address space, then the constructor will
   * fail.
   *
   * @param name The name of this space (used when printing error messages etc)
   * @param pageBudget The number of pages this space may consume before consulting the plan
   * @param frac The size of the space in virtual memory, as a fraction of all available virtual
   *     memory
   */
  public ImmortalSpace(String name, int pageBudget, float frac) {
    super(name, false, true, frac);
    pr = new MonotonePageResource(pageBudget, this, start, extent);
  }

  /**
   * Construct a space that consumes a given number of megabytes of virtual memory, at either the
   * top or bottom of the available virtual memory.
   *
   * <p>The caller specifies the amount virtual memory to be used for this space <i>in
   * megabytes</i>, and whether it should be at the top or bottom of the available virtual memory.
   * If the request clashes with existing virtual memory allocations, then the constructor will
   * fail.
   *
   * @param name The name of this space (used when printing error messages etc)
   * @param pageBudget The number of pages this space may consume before consulting the plan
   * @param mb The size of the space in virtual memory, in megabytes (MB)
   * @param top Should this space be at the top (or bottom) of the available virtual memory.
   */
  public ImmortalSpace(String name, int pageBudget, int mb, boolean top) {
    super(name, false, true, mb, top);
    pr = new MonotonePageResource(pageBudget, this, start, extent);
  }

  /**
   * Construct a space that consumes a given fraction of the available virtual memory, at either the
   * top or bottom of the available virtual memory.
   *
   * <p>The caller specifies the amount virtual memory to be used for this space <i>as a fraction of
   * the total available</i>, and whether it should be at the top or bottom of the available virtual
   * memory. If the request clashes with existing virtual memory allocations, then the constructor
   * will fail.
   *
   * @param name The name of this space (used when printing error messages etc)
   * @param pageBudget The number of pages this space may consume before consulting the plan
   * @param frac The size of the space in virtual memory, as a fraction of all available virtual
   *     memory
   * @param top Should this space be at the top (or bottom) of the available virtual memory.
   */
  public ImmortalSpace(String name, int pageBudget, float frac, boolean top) {
    super(name, false, true, frac, top);
    pr = new MonotonePageResource(pageBudget, this, start, extent);
  }

  /**
   * **************************************************************************
   *
   * <p>Object header manipulations
   */

  /** test to see if the mark bit has the given value */
  private static boolean testMarkBit(ObjectReference object, Word value) {
    return !(ObjectModel.readAvailableBitsWord(object).and(value).isZero());
  }

  /** write the given value in the mark bit. */
  private static void writeMarkBit(ObjectReference object, Word value) {
    Word oldValue = ObjectModel.readAvailableBitsWord(object);
    Word newValue = oldValue.and(GC_MARK_BIT_MASK.not()).or(value);
    ObjectModel.writeAvailableBitsWord(object, newValue);
  }

  /** atomically write the given value in the mark bit. */
  private static void atomicWriteMarkBit(ObjectReference object, Word value) {
    while (true) {
      Word oldValue = ObjectModel.prepareAvailableBits(object);
      Word newValue = oldValue.and(GC_MARK_BIT_MASK.not()).or(value);
      if (ObjectModel.attemptAvailableBits(object, oldValue, newValue)) break;
    }
  }

  /**
   * Used to mark boot image objects during a parallel scan of objects during GC Returns true if
   * marking was done.
   */
  private static boolean testAndMark(ObjectReference object, Word value) throws InlinePragma {
    Word oldValue;
    do {
      oldValue = ObjectModel.prepareAvailableBits(object);
      Word markBit = oldValue.and(GC_MARK_BIT_MASK);
      if (markBit.EQ(value)) return false;
    } while (!ObjectModel.attemptAvailableBits(object, oldValue, oldValue.xor(GC_MARK_BIT_MASK)));
    return true;
  }

  /**
   * Trace a reference to an object under an immortal collection policy. If the object is not
   * already marked, enqueue the object for subsequent processing. The object is marked as (an
   * atomic) side-effect of checking whether already marked.
   *
   * @param object The object to be traced.
   */
  public final ObjectReference traceObject(ObjectReference object) throws InlinePragma {
    if (testAndMark(object, immortalMarkState)) Plan.enqueue(object);
    return object;
  }

  public static void postAlloc(ObjectReference object) throws InlinePragma {
    writeMarkBit(object, immortalMarkState);
  }

  /**
   * Prepare for a new collection increment. For the immortal collector we must flip the state of
   * the mark bit between collections.
   */
  public void prepare() {
    immortalMarkState = GC_MARK_BIT_MASK.sub(immortalMarkState);
  }

  public void release() {}

  /**
   * Release an allocated page or pages. In this case we do nothing because we only release pages
   * enmasse.
   *
   * @param start The address of the start of the page or pages
   */
  public final void release(Address start) throws InlinePragma {
    Assert._assert(false); // this policy only releases pages enmasse
  }

  public final boolean isLive(ObjectReference object) throws InlinePragma {
    return true;
  }

  /**
   * Returns if the object in question is currently thought to be reachable. This is done by
   * comparing the mark bit to the current mark state. For the immortal collector reachable and live
   * are different, making this method necessary.
   *
   * @param object The address of an object in immortal space to test
   * @return True if <code>ref</code> may be a reachable object (e.g., having the current mark
   *     state). While all immortal objects are live, some may be unreachable.
   */
  public static boolean isReachable(ObjectReference object) {
    return (ObjectModel.readAvailableBitsWord(object).and(GC_MARK_BIT_MASK).EQ(immortalMarkState));
  }
}
예제 #4
0
 /**
  * Gets all of the flags of the given object.
  *
  * @param object
  * @return the object flags
  */
 public static Word getObjectFlags(Object object) {
   return Word.zero();
 }