/*
 *  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.Plan;
import org.mmtk.plan.TransitiveClosure;
import org.mmtk.utility.heap.MonotonePageResource;
import org.mmtk.utility.heap.VMRequest;
import org.mmtk.utility.Constants;
import org.mmtk.utility.HeaderByte;

import org.mmtk.vm.VM;

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

/**
 * 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.
 */
@Uninterruptible public final class ImmortalSpace extends Space
  implements Constants {

  /****************************************************************************
   *
   * Class variables
   */
  static final byte GC_MARK_BIT_MASK = 1;
  private static final int META_DATA_PAGES_PER_REGION = CARD_META_PAGES_PER_REGION;

  /****************************************************************************
   *
   * Instance variables
   */
  private byte markState = 0; // when GC off, the initialization value

  /****************************************************************************
   *
   * 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 vmRequest An object describing the virtual memory requested.
   */
  public ImmortalSpace(String name, int pageBudget, VMRequest vmRequest) {
    super(name, false, true, vmRequest);
    if (vmRequest.isDiscontiguous()) {
      pr = new MonotonePageResource(pageBudget, this, META_DATA_PAGES_PER_REGION);
    } else {
      pr = new MonotonePageResource(pageBudget, this, start, extent, META_DATA_PAGES_PER_REGION);
    }
  }

  /** @return the current mark state */
  @Inline
  public Word getMarkState() { return Word.fromIntZeroExtend(markState); }

  /****************************************************************************
   *
   * Object header manipulations
   */

  /**
   * Initialize the object header post-allocation.  We need to set the mark state
   * correctly and set the logged bit if necessary.
   *
   * @param object The newly allocated object instance whose header we are initializing
   */
  public void initializeHeader(ObjectReference object) {
    byte oldValue = VM.objectModel.readAvailableByte(object);
    byte newValue = (byte) ((oldValue & GC_MARK_BIT_MASK) | markState);
    if (HeaderByte.NEEDS_UNLOGGED_BIT) newValue |= HeaderByte.UNLOGGED_BIT;
    VM.objectModel.writeAvailableByte(object, newValue);
  }

  /**
   * Used to mark boot image objects during a parallel scan of objects during GC
   * Returns true if marking was done.
   */
  @Inline
  private static boolean testAndMark(ObjectReference object, byte value) {
    Word oldValue;
    do {
      oldValue = VM.objectModel.prepareAvailableBits(object);
      byte markBit = (byte) (oldValue.toInt() & GC_MARK_BIT_MASK);
      if (markBit == value) return false;
    } while (!VM.objectModel.attemptAvailableBits(object, oldValue,
        oldValue.xor(Word.fromIntZeroExtend(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 trace The trace being conducted.
   * @param object The object to be traced.
   */
  @Inline
  public ObjectReference traceObject(TransitiveClosure trace, ObjectReference object) {
    if (testAndMark(object, markState))
      trace.processNode(object);
    return object;
  }

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

  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
   */
  @Inline
  public void release(Address start) {
    if (VM.VERIFY_ASSERTIONS)
      VM.assertions._assert(false); // this policy only releases pages enmasse
  }

  @Inline
  public boolean isLive(ObjectReference object) {
    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 boolean isReachable(ObjectReference object) {
    if (Plan.SCAN_BOOT_IMAGE && this == Plan.vmSpace)
      return true;  // ignore boot image "reachabilty" if we're not tracing it
    else
      return (VM.objectModel.readAvailableByte(object) & GC_MARK_BIT_MASK) == markState;
  }
}
