/*
 *  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.policy;

import org.mmtk.plan.TransitiveClosure;
import org.mmtk.utility.heap.*;
import org.mmtk.utility.options.Options;
import org.mmtk.utility.options.MarkSweepMarkBits;
import org.mmtk.utility.options.EagerCompleteSweep;
import org.mmtk.utility.Constants;
import org.mmtk.utility.HeaderByte;

import org.mmtk.vm.VM;

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

/**
 * Each instance of this class corresponds to one mark-sweep *space*.
 * Each of the instance methods of this class may be called by any
 * thread (i.e. synchronization must be explicit in any instance or
 * class method).  This contrasts with the MarkSweepLocal, where
 * instances correspond to *plan* instances and therefore to kernel
 * threads.  Thus unlike this class, synchronization is not necessary
 * in the instance methods of MarkSweepLocal.
 */
@Uninterruptible
public final class MarkSweepSpace extends SegregatedFreeListSpace implements Constants {

  /****************************************************************************
   *
   * Class variables
   */
  /**
   * Select between using mark bits in a side bitmap, or mark bits
   * in the headers of object (or other sub-class scheme), and a single
   * mark bit per block.
   */
  public static final boolean HEADER_MARK_BITS = VM.config.HEADER_MARK_BITS;
  /** highest bit bits we may use */
  private static final int AVAILABLE_LOCAL_BITS = 8 - HeaderByte.USED_GLOBAL_BITS;

  /* mark bits */
  private static final int COUNT_BASE = 0;

  public static final int DEFAULT_MARKCOUNT_BITS = 4;
  public static final int MAX_MARKCOUNT_BITS = AVAILABLE_LOCAL_BITS - COUNT_BASE;
  private static final byte MARK_COUNT_INCREMENT = (byte) (1<<COUNT_BASE);
  private static final byte MARK_COUNT_MASK = (byte) (((1<<MAX_MARKCOUNT_BITS)-1) << COUNT_BASE);

  private static final boolean EAGER_MARK_CLEAR = HeaderByte.NEEDS_UNLOGGED_BIT;

  /* header requirements */
  public static final int LOCAL_GC_BITS_REQUIRED = MAX_MARKCOUNT_BITS;
  public static final int GLOBAL_GC_BITS_REQUIRED = 0;
  public static final int GC_HEADER_WORDS_REQUIRED = 0;


  /****************************************************************************
   *
   * Instance variables
   */
  private byte markState = 1;
  private byte allocState = 0;
  private boolean inMSCollection;
  private static final boolean usingStickyMarkBits = VM.activePlan.constraints().needsLogBitInHeader(); /* are sticky mark bits in use? */
  private boolean isAgeSegregated = false; /* is this space a nursery space? */

  /****************************************************************************
   *
   * Initialization
   */

  static {
    Options.markSweepMarkBits = new MarkSweepMarkBits();
    Options.eagerCompleteSweep = new EagerCompleteSweep();
  }

  /**
   * 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 MarkSweepSpace(String name, int pageBudget, VMRequest vmRequest) {
    super(name, pageBudget, 0, vmRequest);
    if (usingStickyMarkBits) allocState |= HeaderByte.UNLOGGED_BIT;
  }

  /**
   * This instance will be age-segregated using the sticky mark bits
   * algorithm. Perform appropriate initialization
   */
  public void makeAgeSegregatedSpace() {
    /* we must be using sticky mark bits */
    if (VM.VERIFY_ASSERTIONS) VM.assertions._assert(usingStickyMarkBits);
    allocState &= ~HeaderByte.UNLOGGED_BIT; /* clear the unlogged bit for nursery allocs */
    isAgeSegregated = true;
  }

  /**
   * Should SegregatedFreeListSpace manage a side bitmap to keep track of live objects?
   */
  @Inline
  protected boolean maintainSideBitmap() {
    return !HEADER_MARK_BITS;
  }

  /**
   * Do we need to preserve free lists as we move blocks around.
   */
  @Inline
  protected boolean preserveFreeList() {
    return !LAZY_SWEEP;
  }

  /****************************************************************************
   *
   * Allocation
   */

  /**
   * Prepare the next block in the free block list for use by the free
   * list allocator.  In the case of lazy sweeping this involves
   * sweeping the available cells.  <b>The sweeping operation must
   * ensure that cells are pre-zeroed</b>, as this method must return
   * pre-zeroed cells.
   *
   * @param block The block to be prepared for use
   * @param sizeClass The size class of the block
   * @return The address of the first pre-zeroed cell in the free list
   * for this block, or zero if there are no available cells.
   */
  protected Address advanceToBlock(Address block, int sizeClass) {
    if (HEADER_MARK_BITS) {
      if (inMSCollection) markBlock(block);
    }

    if (LAZY_SWEEP) {
      return makeFreeList(block, sizeClass);
    } else {
      return getFreeList(block);
    }
  }

  /**
   * Notify that a new block has been installed. This is to ensure that
   * appropriate collection state can be initialized for the block
   *
   * @param block The new block
   * @param sizeClass The block's sizeclass.
   */
  protected void notifyNewBlock(Address block, int sizeClass) {
    if (HEADER_MARK_BITS) {
      if (inMSCollection) markBlock(block);
    }
  }

  /****************************************************************************
   *
   * Collection
   */

  /**
   * Prepare for a new collection increment.  For the mark-sweep
   * collector we must flip the state of the mark bit between
   * collections.
   *
   * @param gcWholeMS True if we are going to collect the whole marksweep space
   */
  public void prepare(boolean gcWholeMS) {
    if (HEADER_MARK_BITS && Options.eagerCompleteSweep.getValue()) {
      consumeBlocks();
    } else {
      flushAvailableBlocks();
    }
    if (HEADER_MARK_BITS) {
      if (gcWholeMS) {
        allocState = markState;
        if (usingStickyMarkBits && !isAgeSegregated) /* if true, we allocate as "mature", not nursery */
          allocState |= HeaderByte.UNLOGGED_BIT;
        markState = deltaMarkState(true);
        if (EAGER_MARK_CLEAR)
          clearAllBlockMarks();
      }
    } else {
      zeroLiveBits();
    }
    inMSCollection = true;
  }

  /**
   * A new collection increment has completed.  For the mark-sweep
   * collector this means we can perform the sweep phase.
 */
  public void release() {
    sweepConsumedBlocks(!EAGER_MARK_CLEAR);
    inMSCollection = false;
  }

  /**
   * Release an allocated page or pages
   *
   * @param start The address of the start of the page or pages
   */
  @Inline
  public void release(Address start) {
    ((FreeListPageResource) pr).releasePages(start);
  }

  /**
   * Should the sweep reclaim the cell containing this object. Is this object
   * live. This is only used when maintainSideBitmap is false.
   *
   * @param object The object to query
   * @return True if the cell should be reclaimed
   */
  @Inline
  protected boolean isCellLive(ObjectReference object) {
    if (!HEADER_MARK_BITS) {
      return super.isCellLive(object);
    }
    return testMarkState(object);
  }

  /****************************************************************************
   *
   * Object processing and tracing
   */

  /**
   * Trace a reference to an object under a mark sweep collection
   * policy.  If the object header is not already marked, mark the
   * object in either the bitmap or by moving it off the treadmill,
   * and 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.
   * @return The object (there is no object forwarding in this
   * collector, so we always return the same object: this could be a
   * void method but for compliance to a more general interface).
   */
  @Inline
  public ObjectReference traceObject(TransitiveClosure trace, ObjectReference object) {
    if (HEADER_MARK_BITS) {
      if (testAndMark(object)) {
        markBlock(object);
        trace.processNode(object);
      }
    } else {
      if (testAndSetLiveBit(object)) {
        trace.processNode(object);
      }
    }
    return object;
  }

  /**
   *
   * @param object The object in question
   * @return True if this object is known to be live (i.e. it is marked)
   */
  @Inline
  public boolean isLive(ObjectReference object) {
    if (HEADER_MARK_BITS) {
      return testMarkState(object);
    } else {
      return liveBitSet(object);
    }
  }

  /**
   * Get the previous mark state.
   *
   * @return The previous mark state.
   */
  @Inline
  public byte getPreviousMarkState() {
    return deltaMarkState(false);
  }

  /**
   * Return the mark state incremented or decremented by one.
   *
   * @param increment If true, then return the incremented value else return the decremented value
   * @return the mark state incremented or decremented by one.
   */
  private byte deltaMarkState(boolean increment) {
    byte mask = (byte) (((1 << Options.markSweepMarkBits.getValue()) - 1)<<COUNT_BASE);
    byte rtn = (byte) (increment ? markState + MARK_COUNT_INCREMENT : markState - MARK_COUNT_INCREMENT);
    rtn &= mask;
    if (VM.VERIFY_ASSERTIONS) VM.assertions._assert((markState & ~MARK_COUNT_MASK) == 0);
    return rtn;
  }

  /****************************************************************************
   *
   * Header manipulation
   */

  /**
   * Perform any required post allocation initialization
   *
   * @param object the object ref to the storage to be initialized
   */
  @Inline
  public void postAlloc(ObjectReference object) {
    initializeHeader(object, true);
  }

  /**
   * Perform any required post copy (i.e. in-GC allocation) initialization.
   * This is relevant (for example) when MS is used as the mature space in
   * a copying GC.
   *
   * @param object the object ref to the storage to be initialized
   * @param majorGC Is this copy happening during a major gc?
   */
  @Inline
  public void postCopy(ObjectReference object, boolean majorGC) {
    initializeHeader(object, false);
    if (!HEADER_MARK_BITS) {
      testAndSetLiveBit(object);
    }
  }

  /**
   * Perform any required initialization of the GC portion of the header.
   *
   * @param object the object ref to the storage to be initialized
   * @param alloc is this initialization occuring due to (initial) allocation
   * (true) or due to copying (false)?
   */
  @Inline
  public void initializeHeader(ObjectReference object, boolean alloc) {
    if (HEADER_MARK_BITS) {
      byte oldValue = VM.objectModel.readAvailableByte(object);
      byte newValue = (byte) ((oldValue & ~MARK_COUNT_MASK) | (alloc ? allocState : markState));
      if (HeaderByte.NEEDS_UNLOGGED_BIT) newValue |= HeaderByte.UNLOGGED_BIT;
      VM.objectModel.writeAvailableByte(object, newValue);
    } else if (HeaderByte.NEEDS_UNLOGGED_BIT)
      HeaderByte.markAsUnlogged(object);
  }

  /**
   * Atomically attempt to set the mark bit of an object.  Return true
   * if successful, false if the mark bit was already set.
   *
   * @param object The object whose mark bit is to be written
   * @param value The value to which the mark bits will be set
   */
  @Inline
  private boolean testAndMark(ObjectReference object) {
    byte oldValue, markBits;
    oldValue = VM.objectModel.readAvailableByte(object);
    markBits = (byte) (oldValue & MARK_COUNT_MASK);
    if (markBits == markState) return false;
    VM.objectModel.writeAvailableByte(object, (byte)((oldValue & ~MARK_COUNT_MASK) | markState));
    return true;
  }

  /**
   * Return true if the mark count for an object has the given value.
   *
   * @param object The object whose mark bit is to be tested
   * @param value The value against which the mark bit will be tested
   * @return True if the mark bit for the object has the given value.
   */
  @Inline
  private boolean testMarkState(ObjectReference object) {
    if (VM.VERIFY_ASSERTIONS) VM.assertions._assert((markState & ~MARK_COUNT_MASK) == 0);
    return (VM.objectModel.readAvailableByte(object) & MARK_COUNT_MASK) == markState;
  }
}
