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

import org.mmtk.plan.TransitiveClosure;
import org.mmtk.plan.immix.Immix;
import org.mmtk.utility.Log;
import org.mmtk.utility.deque.SharedDeque;
import org.mmtk.utility.options.Options;
import org.mmtk.utility.statistics.BooleanCounter;
import org.mmtk.utility.statistics.Stats;
import org.mmtk.vm.Collection;

import org.vmmagic.pragma.*;

/**
 * This class implements the global state of a simple sticky mark bits collector,
 * based on an immix collector.  The sticky mark bits algorithm is
 * due to Demmers et al. (http://doi.acm.org/10.1145/96709.96735), and allows
 * generational collection to be performed in a non-moving heap by overloading
 * the role of mark bits to also indicate whether an object is new (nursery) or
 * not.  Thus nursery objects are identified by a bit in their header, not by
 * where they lie within the address space.  While Demmers et al. did their work
 * in a conservative collector, here we have an exact collector, so we can use
 * a regular write barrier, and don't need to use page protection etc.
 *
 * See the PLDI'08 paper by Blackburn and McKinley for a description
 * of the algorithm: http://doi.acm.org/10.1145/1375581.1375586
 *
 * All plans make a clear distinction between <i>global</i> and
 * <i>thread-local</i> activities, and divides global and local state
 * into separate class hierarchies.  Global activities must be
 * synchronized, whereas no synchronization is required for
 * thread-local activities.  There is a single instance of Plan (or the
 * appropriate sub-class), and a 1:1 mapping of PlanLocal to "kernel
 * threads" (aka CPUs or in Jikes RVM, Processors).  Thus instance
 * methods of PlanLocal allow fast, unsychronized access to functions such as
 * allocation and collection.
 *
 * The global instance defines and manages static resources
 * (such as memory and virtual memory resources).  This mapping of threads to
 * instances is crucial to understanding the correctness and
 * performance properties of MMTk plans.
 */
@Uninterruptible
public class StickyImmix extends Immix {

  /****************************************************************************
   * Constants
   */
  /** If true, then new PLOS objects are collected at each nursery GC */
  static final boolean NURSERY_COLLECT_PLOS = true;
  /** If true then we only do full heap GCs---so we're like MarkSweep (+ write barrier) */
  static final boolean MAJOR_GC_ONLY = false;
  /** estimated collection yield */
  protected static final float SURVIVAL_ESTIMATE = (float) 0.8;

  public static int SCAN_NURSERY = 2;

  /****************************************************************************
   * Class variables
   */
  private static int lastCommittedImmixPages = 0;

  /* statistics */
  public static BooleanCounter fullHeap = new BooleanCounter("majorGC", true, true);

  /****************************************************************************
   * Instance variables
   */
  /* Remset pool */
  public final SharedDeque modPool = new SharedDeque("msgen mod objects", metaDataSpace, 1);

  /**
   * Constructor.
   *
   */
  public StickyImmix() {
    collectWholeHeap = nextGCWholeHeap = false;
  }

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

  /**
   * A user-triggered GC has been initiated.
   */
  public void userTriggeredGC() {
    nextGCWholeHeap |= Options.fullHeapSystemGC.getValue();
  }

  /**
   * Force the next collection to be full heap.
   */
  @Override
  public void forceFullHeapCollection() {
    nextGCWholeHeap = true;
  }

  /**
   * Perform a (global) collection phase.
   *
   * @param phaseId Collection phase to execute.
   */
  @Inline
  @Override
  public final void collectionPhase(short phaseId) {

    if (phaseId == SET_COLLECTION_KIND) {
      collectWholeHeap = requiresFullHeapCollection();
      if (Stats.gatheringStats() && collectWholeHeap) fullHeap.set();
      super.collectionPhase(phaseId);
      return;
    }

    if (!collectWholeHeap && phaseId == PREPARE) {
      immixTrace.prepare();
      immixSpace.prepare(false);
      return;
    }

    if (phaseId == RELEASE) {
      if (collectWholeHeap) {
        super.collectionPhase(RELEASE);
      } else {
        immixTrace.release();
        lastGCWasDefrag = immixSpace.release(false);
      }
      modPool.reset();
      lastCommittedImmixPages = immixSpace.committedPages();
      nextGCWholeHeap = (getPagesAvail() < Options.nurserySize.getMinNursery());
      return;
    }

    super.collectionPhase(phaseId);
  }

  /*****************************************************************************
   *
   * Accounting
   */

  /**
   * This method controls the triggering of a GC. It is called periodically
   * during allocation. Returns true to trigger a collection.
   *
   * @param spaceFull Space request failed, must recover pages within 'space'.
   * @return True if a collection is requested by the plan.
   */
  public final boolean collectionRequired(boolean spaceFull) {
    boolean nurseryFull = immixSpace.getPagesAllocated() > Options.nurserySize.getMaxNursery();
    return super.collectionRequired(spaceFull) || nurseryFull;
  }

  /**
   * Determine whether this GC should be a full heap collection.
   *
   * @return True if this GC should be a full heap collection.
   */
  protected boolean requiresFullHeapCollection() {
    if (collectionTrigger == Collection.EXTERNAL_GC_TRIGGER && Options.fullHeapSystemGC.getValue()) {
      return true;
    }
    if (nextGCWholeHeap || collectionAttempt > 1) {
      // Forces full heap collection
      return true;
    }
    if (loSpace.allocationFailed()) {
      // We need space from the nursery
      return true;
    }

    // Estimate the yield from small nursery pages
    int smallNurseryPages = immixSpace.committedPages() - lastCommittedImmixPages;
    int smallNurseryYield = (int)(smallNurseryPages * SURVIVAL_ESTIMATE);

    if (smallNurseryYield < getPagesRequired()) {
      // Our total yield is insufficient.
      return true;
    }

    if (immixSpace.allocationFailed()) {
      if (smallNurseryYield < immixSpace.requiredPages()) {
        // We have run out of VM pages in the nursery
        return true;
      }
    }

    return false;
  }

  /**
   * Print pre-collection statistics. In this class we prefix the output
   * indicating whether the collection was full heap or not.
   */
  @Override
  public void printPreStats() {
    if ((Options.verbose.getValue() >= 1) && (collectWholeHeap))
      Log.write("[Full heap]");
    super.printPreStats();
  }

  /**
   * @return Is current GC only collecting objects allocated since last GC.
   */
  public final boolean isCurrentGCNursery() {
    return !collectWholeHeap;
  }

  /**
   * @return Is last GC a full collection?
   */
  public final boolean isLastGCFull() {
    return collectWholeHeap;
  }

  /**
   * Register specialized methods.
   */
  @Interruptible
  protected void registerSpecializedMethods() {
    TransitiveClosure.registerSpecializedScan(SCAN_NURSERY, StickyImmixNurseryTraceLocal.class);
    super.registerSpecializedMethods();
  }
}
