@Inline
  private boolean acquireRecyclableBlockAddressOrder() {
    if (recyclableExhausted) {
      if (VM.VERIFY_ASSERTIONS && Options.verbose.getValue() >= 9) {
        Log.writeln("[no recyclable available]");
      }
      return false;
    }
    int markState = 0;
    boolean usable = false;
    while (!usable) {
      Address next = recyclableBlock.plus(BYTES_IN_BLOCK);
      if (recyclableBlock.isZero() || ImmixSpace.isRecycleAllocChunkAligned(next)) {
        recyclableBlock = space.acquireReusableBlocks();
        if (recyclableBlock.isZero()) {
          recyclableExhausted = true;
          if (VM.VERIFY_ASSERTIONS && Options.verbose.getValue() >= 9) {
            Log.writeln("[recyclable exhausted]");
          }
          line = LINES_IN_BLOCK;
          return false;
        }
      } else {
        recyclableBlock = next;
      }
      markState = Block.getBlockMarkState(recyclableBlock);
      usable = (markState > 0 && markState <= ImmixSpace.getReusuableMarkStateThreshold(copy));
      if (copy && Block.isDefragSource(recyclableBlock)) usable = false;
    }
    if (VM.VERIFY_ASSERTIONS) VM.assertions._assert(!Block.isUnused(recyclableBlock));
    Block.setBlockAsReused(recyclableBlock);

    lineUseCount += (LINES_IN_BLOCK - markState);
    return true; // found something good
  }
 /**
  * Push an address onto the address stack.
  *
  * @param object the object to be pushed onto the object queue
  */
 @Inline
 public final void push(ObjectReference object) {
   Address addr = object.toAddress();
   if (VM.VERIFY_ASSERTIONS) VM.assertions._assert(!addr.isZero());
   checkHeadInsert(1);
   uncheckedHeadInsert(addr);
 }
示例#3
0
 /** Sweep through the large pages, releasing all superpages on the "from space" treadmill. */
 private void sweepLargePages(boolean sweepNursery) {
   while (true) {
     Address cell = sweepNursery ? treadmill.popNursery() : treadmill.pop();
     if (cell.isZero()) break;
     release(getSuperPage(cell));
   }
   if (VM.VERIFY_ASSERTIONS)
     VM.assertions._assert(sweepNursery ? treadmill.nurseryEmpty() : treadmill.fromSpaceEmpty());
 }
  /**
   * External allocation slow path (called by superclass when slow path is actually taken. This is
   * necessary (rather than a direct call from the fast path) because of the possibility of a thread
   * switch and corresponding re-association of bump pointers to kernel threads.
   *
   * @param bytes The number of bytes allocated
   * @param align The requested alignment
   * @param offset The offset from the alignment
   * @return The address of the first byte of the allocated region or zero on failure
   */
  protected final Address allocSlowOnce(int bytes, int align, int offset) {
    Address ptr = space.getSpace(hot, copy, lineUseCount);

    if (ptr.isZero()) {
      lineUseCount = 0;
      return ptr; // failed allocation --- we will need to GC
    }

    /* we have been given a clean block */
    if (VM.VERIFY_ASSERTIONS) VM.assertions._assert(Block.isAligned(ptr));
    lineUseCount = LINES_IN_BLOCK;

    zeroBlock(ptr);
    if (requestForLarge) {
      largeCursor = ptr;
      largeLimit = ptr.plus(BYTES_IN_BLOCK);
    } else {
      cursor = ptr;
      limit = ptr.plus(BYTES_IN_BLOCK);
    }

    return alloc(bytes, align, offset);
  }
 /**
  * Push an address onto the address stack.
  *
  * @param addr the address to be pushed onto the address queue
  */
 @Inline
 public final void push(Address addr) {
   if (VM.VERIFY_ASSERTIONS) VM.assertions._assert(!addr.isZero());
   checkHeadInsert(1);
   uncheckedHeadInsert(addr);
 }