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

import org.mmtk.plan.Trace;
import org.mmtk.plan.semispace.*;
import org.mmtk.policy.Space;
import org.mmtk.utility.TraceGenerator;

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

/**
 * This plan has been modified slightly to perform the processing necessary
 * for GC trace generation.  To maximize performance, it attempts to remain
 * as faithful as possible to semiSpace/Plan.java.
 *
 * The generated trace format is as follows:
 *    B 345678 12
 *      (Object 345678 was created in the boot image with a size of 12 bytes)
 *    U 59843 234 47298
 *      (Update object 59843 at the slot at offset 234 to refer to 47298)
 *    S 1233 12345
 *      (Update static slot 1233 to refer to 12345)
 *    T 4567 78924
 *      (The TIB of 4567 is set to refer to 78924)
 *    D 342789
 *      (Object 342789 became unreachable)
 *    A 6860 24 346648 3
 *      (Object 6860 was allocated, requiring 24 bytes, with fp 346648 on
 *        thread 3; this allocation has perfect knowledge)
 *    a 6884 24 346640 5
 *      (Object 6864 was allocated, requiring 24 bytes, with fp 346640 on
 * thread 5; this allocation DOES NOT have perfect knowledge)
 *    I 6860 24 346648 3
 *      (Object 6860 was allocated into immortal space, requiring 24 bytes,
 *        with fp 346648 on thread 3; this allocation has perfect knowledge)
 *    i 6884 24 346640 5
 *      (Object 6864 was allocated into immortal space, requiring 24 bytes,
 *        with fp 346640 on thread 5; this allocation DOES NOT have perfect
 *        knowledge)
 *    48954->[345]LObject;:blah()V:23   Ljava/lang/Foo;
 *      (Citation for: a) where the was allocated, fp of 48954,
 *         at the method with ID 345 -- or void Object.blah() -- and bytecode
 *         with offset 23; b) the object allocated is of type java.lang.Foo)
 *    D 342789 361460
 *      (Object 342789 became unreachable after 361460 was allocated)
 *
 * This class implements a simple semi-space collector. See the Jones
 * & Lins GC book, section 2.2 for an overview of the basic
 * algorithm. This implementation also includes a large object space
 * (LOS), and an uncollected "immortal" space.<p>
 *
 * All plans make a clear distinction between <i>global</i> and
 * <i>thread-local</i> activities.  Global activities must be
 * synchronized, whereas no synchronization is required for
 * thread-local activities.  Instances of Plan map 1:1 to "kernel
 * threads" (aka CPUs).  Thus instance
 * methods allow fast, unsychronized access to Plan utilities such as
 * allocation and collection.  Each instance rests on static resources
 * (such as memory and virtual memory resources) which are "global"
 * and therefore "static" members of Plan.  This mapping of threads to
 * instances is crucial to understanding the correctness and
 * performance proprties of this plan.
 */
@Uninterruptible
public final class GCTraceTraceLocal extends SSTraceLocal {

  /**
   * Constructor
   *
   * @param trace The global trace to use.
   */
  public GCTraceTraceLocal(Trace trace) {
    super(trace, false);
  }

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

  /**
   * Trace a reference during GC.  This involves determining which
   * collection policy applies (such as those needed for trace generation)
   * and taking the appropriate actions.
   *
   * @param object The object reference to be traced.  In certain
   * cases, this should <i>NOT</i> be an interior pointer.
   * @return The possibly moved reference.
   */
  @Inline
  public ObjectReference traceObject(ObjectReference object) {
    if (object.isNull()) return object;
    if (GCTrace.traceInducedGC) {
      /* We are performing a root scan following an allocation. */
      TraceGenerator.rootEnumerate(object);
      return object;
    } else if (GCTrace.deathScan) {
      /* We are performing the last scan before program termination. */
      TraceGenerator.propagateDeathTime(object);
      return object;
    } else {
      /* *gasp* We are actually performing garbage collection */
      return super.traceObject(object);
    }
  }

  /**
   * Ensure that the referenced object will not move during a collection
   * by 'precopying' it at the beginning.
   *
   * @param object The object to ensure will not move.
   */
  @Inline
  public ObjectReference precopyObject(ObjectReference object) {
    if (object.isNull()) return object;
    if (GCTrace.traceInducedGC) {
      /* We are performing a root scan following an allocation. */
      TraceGenerator.rootEnumerate(object);
      return object;
    } else if (GCTrace.deathScan) {
      /* We are performing the last scan before program termination. */
      TraceGenerator.propagateDeathTime(object);
      return object;
    } else {
      return super.precopyObject(object);
    }
  }


  /**
   * If the referenced object has moved, return the new location.
   *
   * Some copying collectors will need to override this method.
   *
   * @param object The object which may have been forwarded.
   * @return The new location of <code>object</code>.
   */
  @Inline
  public ObjectReference getForwardedReference(ObjectReference object) {
    if (object.isNull()) return object;
    if (SS.hi && Space.isInSpace(SS.SS0, object)) {
      return SS.copySpace0.traceObject(this, object, GCTrace.ALLOC_SS);
    } else if (!SS.hi && Space.isInSpace(SS.SS1, object)) {
      return SS.copySpace1.traceObject(this, object, GCTrace.ALLOC_SS);
    }
    return object;
  }

  /**
   * Return true if <code>obj</code> is a live object.
   *
   * @param object The object in question
   * @return True if <code>obj</code> is a live object.
   */
  public boolean isLive(ObjectReference object) {
      if (object.isNull()) return false;
      else if (GCTrace.traceInducedGC) return true;
      else return super.isLive(object);
  }

  /**
   * Return true if <code>obj</code> is a reachable object.
   *
   * @param object The object in question
   * @return True if <code>obj</code> is a reachable object;
   * unreachable objects may still be live, however
   */
  public boolean isReachable(ObjectReference object) {
    if (GCTrace.finalDead) return false;
    else if (object.isNull()) return false;
    else {
      Space space = Space.getSpaceForObject(object);
      return space.isReachable(object);
    }
  }

  /**
   * Is this object guaranteed not to move during the collection.
   *
   * @param object The object to check.
   * @return True if the object is guaranteed not to move.
   */
  public boolean willNotMoveInCurrentCollection(ObjectReference object) {
    if (GCTrace.traceInducedGC) return true;
    else return super.willNotMoveInCurrentCollection(object);
  }
}
