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.mmtk.utility.deque;
014
015import org.mmtk.vm.VM;
016
017import org.vmmagic.unboxed.*;
018import org.vmmagic.pragma.*;
019
020/**
021 * This supports <i>unsynchronized</i> pushing and popping of object
022 * references.  In addition, this can sort the entries currently on
023 * the shared stack.
024 */
025@Uninterruptible public class SortTODObjectReferenceStack extends LocalDeque {
026
027  /****************************************************************************
028   *
029   * Public instance methods
030   */
031
032  /**
033   * Constructor
034   *
035   * @param queue The shared stack to which this stack will append
036   * its buffers (when full or flushed) and from which it will acquire new
037   * buffers when it has exhausted its own.
038   */
039  public SortTODObjectReferenceStack(SortTODSharedDeque queue) {
040    super(queue);
041  }
042
043  /**
044   * Sort the address on the shared stack.
045   */
046  public final void sort() {
047    flushLocal();
048    ((SortTODSharedDeque) queue).sort();
049  }
050
051  /**
052   * Push an address onto the address stack.
053   *
054   * @param object the object to be pushed onto the object queue
055   */
056  @Inline
057  public final void push(ObjectReference object) {
058    Address addr = object.toAddress();
059    if (VM.VERIFY_ASSERTIONS) VM.assertions._assert(!addr.isZero());
060    checkHeadInsert(1);
061    uncheckedHeadInsert(addr);
062  }
063
064  /**
065   * Pop an address from the address stack, return zero if the stack
066   * is empty.
067   *
068   * @return The next address in the address stack, or zero if the
069   * stack is empty
070   */
071  @Inline
072  public final ObjectReference pop() {
073    if (checkDequeue(1)) {
074      return uncheckedDequeue().toObjectReference();
075    } else {
076      return ObjectReference.nullReference();
077    }
078  }
079
080  /**
081   * Check if the (local and shared) stacks are empty.
082   *
083   * @return True if there are no more entries on the local &amp; shared stack,
084   *         false otherwise.
085   */
086  @Inline
087  public final boolean isEmpty() {
088    return !checkDequeue(1);
089  }
090}