/*
 *  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.markcompact.MC;
import org.mmtk.utility.Log;
import org.mmtk.utility.alloc.Allocator;
import org.mmtk.utility.alloc.BumpPointer;
import org.mmtk.vm.VM;
import org.vmmagic.pragma.Inline;
import org.vmmagic.pragma.Uninterruptible;
import org.vmmagic.unboxed.Address;
import org.vmmagic.unboxed.Extent;
import org.vmmagic.unboxed.ObjectReference;

/**
 * This class implements unsynchronized (local) per-collector-thread elements of a
 * sliding mark-compact collector.
 *
 * Specifically, this class provides the methods that
 * - Calculate the forwarding pointers for heap objects, in a linear pass over
 *   (part of) the heap
 * - Performs the compaction pass over the heap.
 *
 * Each collector thread maintains a private list of the pages that it compacts.
 * If it runs out of work during the calculateForwardingPointers pass, it requests
 * a new region from the global MarkCompactSpace.  Regions compacted by a collector
 * remain local to the collector.
 *
 * @see MarkCompactSpace
 * @see MarkCompactLocal
 */
@Uninterruptible
public final class MarkCompactCollector {

  static final boolean VERBOSE = false;

  static final boolean VERY_VERBOSE = VERBOSE && false;

  private final MarkCompactSpace space;

  /**
   * This collector's work list
   */
  private Address regions = Address.zero();

  private final FromCursor fromCursor = new FromCursor();
  private final ToCursor toCursor = new ToCursor();

  /**
   * Constructor
   *
   * @param space The space to bump point into.
   */
  public MarkCompactCollector(MarkCompactSpace space) {
    this.space = space;
  }

  /* ********************************************************************************
   *
   *                Cursor classes
   *
   */

  /**
   * Both the 'compact' and 'calculate' phases can be thought of as sweeping
   * a pair of cursors across a linked list of regions.  Each cursor requires
   * maintaining pointers to the current region, the current address and the end of
   * the region.  The regionCursor class maintains these 3 pointers, while the
   * subclasses ToCursor and FromCursor provide methods specific to the
   * read and write pointers.
   */
  @Uninterruptible
  private abstract static class RegionCursor {

    /** Name of the cursor - for debugging messages */
    private final String name;

    /**
     * The current region, or zero if the cursor is invalid (eg after advancing
     * past the end of the current work list
     */
    protected Address region;

    /**
     * The limit of the current region. When reading a populated region, this is the
     * address of the last used byte.  When writing to a fresh region, this is the last
     * byte in the region.
     */
    protected Address limit;

    /** The current address */
    protected Address cursor;

    /**
     * @param name The name of the region - for debugging messages.
     */
    public RegionCursor(String name) {
      this.name = name;
    }

    /**
     * Hook to allow subclasses to initialize the cursor in different ways.
     *
     * @param region The region to be processed.
     */
    abstract void init(Address region);

    /**
     * Assert that the cursor is within the bounds of the region.  Calls to this
     * must be guarded by {@code if (VM.VERIFY_ASSERTIONS)}
     */
    protected void assertCursorInBounds() {
      VM.assertions._assert(!region.isZero());
      VM.assertions._assert(cursor.GE(BumpPointer.getDataStart(region)),
      "Cursor is below start of region");
      VM.assertions._assert(cursor.LE(limit),"Cursor beyond end of region");
    }

    /**
     * Increment the cursor.
     * @param size Bytes to increment by
     */
    void inc(int size) {
      this.cursor = cursor.plus(size);
      if (VM.VERIFY_ASSERTIONS) assertCursorInBounds();
    }

    /**
     * Increment the cursor to a specific address
     * @param cursor Destination address
     */
    public void incTo(Address cursor) {
      if (VM.VERIFY_ASSERTIONS) assertCursorInBounds();
      if (VM.VERIFY_ASSERTIONS) VM.assertions._assert(cursor.GE(this.cursor));
      this.cursor = cursor;
    }

    /**
     * @param other Other region
     * @return {@code true} if this cursor points to the same region as {@code other}
     */
    boolean sameRegion(RegionCursor other) {
      return region.EQ(other.getRegion());
    }

    /**
     * @param size Size in bytes
     * @return {@code true} if {@code size} bytes are available in the current region
     */
    boolean isAvailable(int size) {
      return cursor.plus(size).LE(limit);
    }

    /**
     * @return The current cursor
     */
    public Address get() {
      return cursor;
    }

    /**
     * @return The current region pointer
     */
    public Address getRegion() {
      return region;
    }

    /**
     * @return The current region limit
     */
    public Address getLimit() {
      return limit;
    }

    /**
     * Follow the linked-list of regions to the next region.
     */
    void advanceToNextRegion() {
      Address nextRegion = MarkCompactLocal.getNextRegion(region);
      if (nextRegion.isZero()) {
        region = Address.zero();
      } else {
        init(nextRegion);
        if (VM.VERIFY_ASSERTIONS) assertCursorInBounds();
      }
    }

    /**
     * @return {@code true} if we haven't advanced beyond the end of the region list
     */
    boolean isValid() {
      return !region.isZero();
    }

    /**
     * @param ref The object in question
     * @return {@code true} if the object's start address is in this region
     */
    @Inline
    boolean isInRegion(ObjectReference ref) {
      Address addr = VM.objectModel.refToAddress(ref);
      return addr.GE(BumpPointer.getDataStart(region)) && addr.LE(limit);
    }

    /**
     * Print the cursor - for debugging
     */
    void print() {
      Log.write(name); Log.write(" cursor:");
      Log.write(" region="); Log.write(region);
      Log.write(" limit="); Log.write(limit);
      Log.write(" cursor="); Log.write(cursor);
      Log.writeln();

    }
  }

  /**
   * Subclass for the read-only cursor that leads the scan of regions.
   */
  @Uninterruptible
  private static final class FromCursor extends RegionCursor {
    public FromCursor() {
      super("from");
    }

    /**
     * Initialize the cursor - the limit is the end of the allocated data
     */
    @Override
    void init(Address region) {
      if (VM.VERIFY_ASSERTIONS) BumpPointer.checkRegionMetadata(region);
      this.region = region;
      this.cursor = MarkCompactLocal.getDataStart(region);
      this.limit = MarkCompactLocal.getDataEnd(region);
    }

    /**
     * Advance from the cursor to the start of the next object.
     * @return The object reference of the next object.
     */
    @Inline
    ObjectReference advanceToObject() {
      ObjectReference current = VM.objectModel.getObjectFromStartAddress(cursor);
      cursor = VM.objectModel.objectStartRef(current);
      if (VM.VERIFY_ASSERTIONS) {
        Address lowBound = BumpPointer.getDataStart(region);
        VM.assertions._assert(cursor.GE(lowBound) && cursor.LE(limit),"Cursor outside region");
      }
      return current;
    }

    /**
     * Advance the cursor to the end of the given object.
     * @return The object reference of the next object.
     */
    @Inline
    void advanceToObjectEnd(ObjectReference current) {
      cursor = VM.objectModel.getObjectEndAddress(current);
      if (VM.VERIFY_ASSERTIONS) assertCursorInBounds();
    }

    /**
     * Advance the cursor either to the next region in the list,
     * or to a new region allocated from the global list.
     * @param m
     */
    void advanceToNextForwardableRegion(MarkCompactSpace space) {
      if (VM.VERIFY_ASSERTIONS) VM.assertions._assert(get().EQ(getLimit()));
      Address nextRegion = BumpPointer.getNextRegion(region);
      if (nextRegion.isZero()) {
        nextRegion = space.getNextRegion();
        if (nextRegion.isZero()) {
          region = Address.zero();
          return;
        }
        MarkCompactLocal.setNextRegion(region,nextRegion);
        MarkCompactLocal.clearNextRegion(nextRegion);
      }
      init(nextRegion);
      if (VM.VERIFY_ASSERTIONS) assertCursorInBounds();
    }

    /**
     * Override the superclass with an additional assertion - we only advance
     * when we have read to the end, and the cursor must point *precisely*
     * to the last allocated byte in the region.
     */
    @Override
    void advanceToNextRegion() {
      if (VM.VERIFY_ASSERTIONS) VM.assertions._assert(get().EQ(getLimit()));
      super.advanceToNextRegion();
    }

    /**
     * @return {@code true} if there are more objects in this region
     */
    boolean hasMoreObjects() {
      return cursor.LT(limit);
    }
  }

  /**
   * Subclass for the read-only cursor that follows the 'from' cursor,
   * writing or calculating the position of copied objects
   */
  @Uninterruptible
  private static final class ToCursor extends RegionCursor {
    public ToCursor() {
      super("to");
    }

    /**
     * Initialize the cursor to a given region.  The limit is the limit of
     * available space in the region.
     */
    @Override
    void init(Address region) {
      if (VM.VERIFY_ASSERTIONS) BumpPointer.checkRegionMetadata(region);
      this.region = region;
      this.cursor = MarkCompactLocal.getDataStart(region);
      this.limit = MarkCompactLocal.getRegionLimit(region);
      if (VM.VERIFY_ASSERTIONS) assertCursorInBounds();
    }

    /**
     * Update the metadata of the current region with the current value
     * of the cursor.  Zero the region from here to the end.
     */
    void finish() {
      if (VM.VERIFY_ASSERTIONS) assertCursorInBounds();
      Extent zeroBytes = limit.diff(cursor).toWord().toExtent();
      VM.memory.zero(cursor, zeroBytes);
      MarkCompactLocal.setDataEnd(region, cursor);
      MarkCompactLocal.checkRegionMetadata(region);
    }

    /**
     * Terminate the list of regions here.
     * @return The address of the (old) next region in the list.
     */
    Address snip() {
      Address nextRegion = BumpPointer.getNextRegion(region);
      BumpPointer.clearNextRegion(region);
      finish();
      return nextRegion;
    }

    /**
     * Copy an object to an address within this cursor's region.
     * @param from The source object
     * @param to The target object
     */
    @Inline
    void copy(ObjectReference from, ObjectReference to) {
      if (VM.VERIFY_ASSERTIONS) {
        VM.assertions._assert(MarkCompactSpace.getForwardingPointer(from).toAddress().EQ(to.toAddress()));
        VM.assertions._assert(cursor.GT(region) && cursor.LE(limit));
      }
      Address savedCursor = Address.zero();
      if (VM.VERIFY_ASSERTIONS) savedCursor = cursor;
      cursor = VM.objectModel.copyTo(from, to, cursor);
      if (VM.VERIFY_ASSERTIONS) {
        if (cursor.LT(BumpPointer.getDataStart(region)) || cursor.GT(limit)) {
          Log.write("Copy of "); Log.write(from);
          Log.write(" to "); Log.write(to);
          Log.write(" puts cursor at "); Log.write(cursor);
          Log.write(" (was: "); Log.write(savedCursor);
          Log.writeln(")");
        }
        VM.assertions._assert(cursor.GT(region) && cursor.LE(limit));
      }
      MarkCompactSpace.setForwardingPointer(to, ObjectReference.nullReference());
      if (VM.VERIFY_ASSERTIONS)
        VM.assertions._assert(VM.objectModel.getObjectEndAddress(to).LE(limit));
    }

    /**
     * Move to the next region, updating the metadata with the current 'write' state.
     */
    void finishAndAdvanceToNextRegion() {
      finish();
      advanceToNextRegion();
    }

    /**
     * Move to the next region, in read-only mode.  Add the assertion of validity,
     * since we shouldn't be able to fall off the end of the list while writing.
     */
    @Override
    void advanceToNextRegion() {
      super.advanceToNextRegion();
      if (VM.VERIFY_ASSERTIONS) VM.assertions._assert(isValid());
    }
  }

  /* ***************************************************************************************** */

  /**
   * Perform a linear scan through the objects allocated by this bump pointer,
   * calculating where each live object will be post collection.
   *
   * We maintain two cursors, {@code fromCursor} and {@code toCursor}, and simulate
   * copying live objects from the former to the latter.  Initially, the cursors
   * point to the first region in this collector's local list, and increment in
   * lockstep until the first dead object is encountered.  After that, the to cursor
   * trails the from cursor.
   *
   * The outer loop advances the 'from' pointer
   */
  public void calculateForwardingPointers() {
    if (regions.isZero()) {
      regions = space.getNextRegion();
    }

    if (regions.isZero())
      return;

    fromCursor.init(regions);
    toCursor.init(regions);

    if (VM.VERIFY_ASSERTIONS) VM.assertions._assert(true);

    /* Loop through active regions or until the last region */
    while (fromCursor.isValid()) {
      if (VERBOSE) {
        fromCursor.print();
        toCursor.print();
      }

      /* Loop through the objects in the current 'from' region */
      while (fromCursor.hasMoreObjects()) {
        ObjectReference current = fromCursor.advanceToObject();
        fromCursor.advanceToObjectEnd(current);

        if (MarkCompactSpace.toBeCompacted(current)) {
          if (VM.VERIFY_ASSERTIONS) VM.assertions._assert(MarkCompactSpace.getForwardingPointer(current).isNull());

          // Fake - allocate it.
          int size = VM.objectModel.getSizeWhenCopied(current);
          int align = VM.objectModel.getAlignWhenCopied(current);
          int offset = VM.objectModel.getAlignOffsetWhenCopied(current);
          // Move to the (aligned) start of the next object
          toCursor.incTo(Allocator.alignAllocationNoFill(toCursor.get(), align, offset));

          /*
           * If we're allocating into separate regions, and we've allocated beyond the end of the
           * current region, advance to the next one.  We always allocate into regions we have
           * scanned in this collector.
           */
          if (!toCursor.sameRegion(fromCursor) && !toCursor.isAvailable(size)) {
            // The 'to' pointer always trails the 'from' pointer, guaranteeing that
            // there's a next region to advance to.
            toCursor.advanceToNextRegion();
            toCursor.incTo(Allocator.alignAllocationNoFill(toCursor.get(), align, offset));
          }

          ObjectReference target = VM.objectModel.getReferenceWhenCopiedTo(current, toCursor.get());
          if (toCursor.sameRegion(fromCursor) && target.toAddress().GE(current.toAddress())) {
            // Don't move the object.
            MarkCompactSpace.setForwardingPointer(current, current);
            toCursor.incTo(VM.objectModel.getObjectEndAddress(current));
          } else {
            MarkCompactSpace.setForwardingPointer(current, target);
            toCursor.inc(size);
          }
        }
      }
      fromCursor.advanceToNextForwardableRegion(space);
    }
  }


  /**
   * Perform the compacting phase of the collection.
   */
  public void compact() {
    if (regions.isZero()) return;

    toCursor.init(regions);
    fromCursor.init(regions);

    /* Loop through active regions or until the last region */
    while (fromCursor.isValid()) {
      if (VERBOSE) {
        Log.write("Compacting from region "); Log.write(fromCursor.getRegion());
        Log.write(" to region "); Log.writeln(toCursor.getRegion());
      }

      /* Loop through the objects in the region */
      while (fromCursor.hasMoreObjects()) {
        ObjectReference current = fromCursor.advanceToObject();
        fromCursor.advanceToObjectEnd(current);

        ObjectReference copyTo = MarkCompactSpace.getForwardingPointer(current);
        if (VM.VERIFY_ASSERTIONS) VM.assertions._assert(!copyTo.toAddress().EQ(Address.fromIntZeroExtend(VM.ALIGNMENT_VALUE)));

        if (!copyTo.isNull() && Space.isInSpace(MC.MARK_COMPACT, copyTo)) {
          if (VM.VERIFY_ASSERTIONS) {
            if (MarkCompactSpace.isMarked(current)) {
              Log.write("Object "); Log.write(current);
              Log.writeln(" is marked during the compact phase");
            }
            VM.assertions._assert(!MarkCompactSpace.isMarked(current));
          }
          if (!toCursor.isInRegion(copyTo)) {
            // Update metadata and move on
            toCursor.finishAndAdvanceToNextRegion();
          }
          if (VM.VERIFY_ASSERTIONS) VM.assertions._assert(toCursor.isInRegion(copyTo));
          toCursor.copy(current, copyTo);
          if (VM.VERIFY_ASSERTIONS) VM.assertions._assert(toCursor.isInRegion(copyTo));
          MarkCompactSpace.setForwardingPointer(copyTo, ObjectReference.nullReference());
        }
      }
      fromCursor.advanceToNextRegion();
    }

    /* Fix up the last object pointer etc */
    toCursor.finish();


    /*
     * Return unused pages to the global page resource
     */
    Address region = toCursor.snip();
    while (!region.isZero()) {
      Address nextRegion = MarkCompactLocal.getNextRegion(region);
      space.release(region);
      region = nextRegion;
    }
  }
}
