/*
 *  This file is part of the Jikes RVM project (http://jikesrvm.org).
 *
 *  This file is licensed to You under the Eclipse Public License (EPL);
 *  You may not use this file except in compliance with the License. You
 *  may obtain a copy of the License at
 *
 *      http://www.opensource.org/licenses/eclipse-1.0.php
 *
 *  See the COPYRIGHT.txt file distributed with this work for information
 *  regarding copyright ownership.
 */
package org.mmtk.utility.deque;

import org.mmtk.plan.Plan;
import org.mmtk.utility.Constants;

import org.mmtk.vm.VM;

import org.vmmagic.pragma.*;
import org.vmmagic.unboxed.*;

/**
 * This class implements a local (<i>unsynchronized</i>) sequential
 * store buffer.  An SSB is strictly FIFO (although this class does
 * not implement dequeuing).<p>
 *
 * Each instance stores word-sized values into a local buffer.  When
 * the buffer is full, or if the <code>flushLocal()</code> method is
 * called, the buffer enqueued at the tail of a
 * <code>SharedDeque</code>.  This class provides no mechanism for
 * dequeing.<p>
 *
 * The implementation is intended to be as efficient as possible, in
 * time and space, as it is used in critical code such as the GC work
 * queue and the write buffer used by many "remembering"
 * collectors. Each instance has just two fields: a bump pointer and a
 * pointer to the <code>SharedDeque</code><p>
 *
 * Preconditions: Buffers are always aligned on buffer-size address
 * boundaries.<p>
 *
 * Invariants: Buffers are filled such that tuples (of the specified
 * arity) are packed to the low end of the buffer.  Thus buffer
 * overflows on inserts and pops (underflow actually) will always arise
 * when then cursor is buffer-size aligned.
 */
@Uninterruptible class LocalSSB extends Deque implements Constants {

  /****************************************************************************
   *
   * Public instance methods
   */

  /**
   * Constructor
   *
   * @param queue The shared queue to which this local ssb will append
   * its buffers (when full or flushed).
   */
  LocalSSB(SharedDeque queue) {
    this.queue = queue;
    resetLocal();
  }

  /**
   * Flush the buffer and add it to the shared queue (this will
   * make any entries in the buffer visible to any consumer associated
   * with the shared queue).
   */
  public void flushLocal() {
    if (tail.NE(Deque.TAIL_INITIAL_VALUE)) {
      closeAndEnqueueTail(queue.getArity());
      tail = Deque.TAIL_INITIAL_VALUE;
      tailBufferEnd = Deque.TAIL_INITIAL_VALUE;
    }
  }

  public void reset() {
    resetLocal();
  }

 /****************************************************************************
   *
   * Protected instance methods and fields
   */
  @Entrypoint
  protected Address tail; // the location in the buffer
  protected Address tailBufferEnd; // the end of the buffer
  protected final SharedDeque queue; // the shared queue

  /**
   * Reset the local buffer (throwing away any local entries).
   */
  public void resetLocal() {
    tail = Deque.TAIL_INITIAL_VALUE;
    tailBufferEnd = Deque.TAIL_INITIAL_VALUE;
  }

  /**
   * Check whether there is space in the buffer for a pending insert.
   * If there is not sufficient space, allocate a new buffer
   * (dispatching the full buffer to the shared queue if not null).
   *
   * @param arity The arity of the values stored in this SSB: the
   * buffer must contain enough space for this many words.
   */
  @Inline(value=Inline.When.AssertionsDisabled)
  protected final void checkTailInsert(int arity) {
    if (bufferOffset(tail).isZero())
      tailOverflow(arity);
    else if (VM.VERIFY_ASSERTIONS) VM.assertions._assert(bufferOffset(tail).sGE(Word.fromIntZeroExtend(arity).lsh(LOG_BYTES_IN_ADDRESS).toOffset()));
  }

  /**
   * Insert a value into the buffer.  This is <i>unchecked</i>.  The
   * caller must first call <code>checkInsert()</code> to ensure the
   * buffer can accommodate the insertion.
   *
   * @param value the value to be inserted.
   */
  @Inline(value=Inline.When.AssertionsDisabled)
  protected final void uncheckedTailInsert(Address value) {
    if (VM.VERIFY_ASSERTIONS) VM.assertions._assert(bufferOffset(tail).sGE(Offset.fromIntZeroExtend(BYTES_IN_ADDRESS)));
    tail = tail.minus(BYTES_IN_ADDRESS);
    tail.store(value);
    // if (Interface.VerifyAssertions) enqueued++;
  }

  /**
   * In the case where a buffer must be flushed before being
   * filled (either to the queue or to the head), the entries must be
   * slid to the base of the buffer in order to preserve the invariant
   * that all non-tail buffers will have entries starting at the base
   * (which allows a simple test against the base to be used when
   * popping entries).  This is <i>expensive</i>, so should be
   * avoided.
   *
   * @param arity The arity of the buffer in question
   * @return The last slot in the normalized buffer that contains an entry
   */
  protected final Address normalizeTail(int arity) {
    Address src = tail;
    Address tgt = bufferFirst(tail);
    Address last = tgt.plus(bufferLastOffset(arity).minus(bufferOffset(tail)));
    while (tgt.LE(last)) {
      tgt.store(src.loadAddress());
      src = src.plus(BYTES_IN_ADDRESS);
      tgt = tgt.plus(BYTES_IN_ADDRESS);
    }
    return last;
  }

  /**
   * Return the sentinel offset for a buffer of a given arity.  This is used
   * both to compute the address at the end of the buffer.
   *
   * @param arity The arity of this buffer
   * @return The sentinel offset value for a buffer of the given arity.
   */
  @Inline
  protected final Offset bufferSentinel(int arity) {
    return bufferLastOffset(arity).plus(BYTES_IN_ADDRESS);
  }

  /****************************************************************************
   *
   * Private instance methods
   */

  /**
   * Buffer space has been exhausted, allocate a new buffer and enqueue
   * the existing buffer (if any).
   *
   * @param arity The arity of this buffer (used for sanity test only).
   */
  private void tailOverflow(int arity) {
    if (VM.VERIFY_ASSERTIONS) VM.assertions._assert(arity == queue.getArity());
    if (tail.NE(Deque.TAIL_INITIAL_VALUE)) {
      closeAndEnqueueTail(arity);
    }
    tail = queue.alloc().plus(bufferSentinel(arity));
    tailBufferEnd = tail;
    Plan.checkForAsyncCollection(); // possible side-effect of alloc()
  }

  /**
   * Close the tail buffer (normalizing if necessary), and enqueue it
   * at the tail of the shared buffer queue.
   *
   *  @param arity The arity of this buffer.
   */
  @NoInline
  private void closeAndEnqueueTail(int arity) {
    Address last;
    if (!bufferOffset(tail).isZero()) {
      // prematurely closed
      last = normalizeTail(arity);
    } else {
      // a full tail buffer
      last = tailBufferEnd.minus(BYTES_IN_ADDRESS);
    }
    queue.enqueue(last.plus(BYTES_IN_ADDRESS), arity, true);
  }

  /**
   * Return true if this SSB is locally empty
   *
   * @return true if this SSB is locally empty
   */
  public final boolean isFlushed() {
    return tail.EQ(Deque.TAIL_INITIAL_VALUE);
  }
}
