001/*
002 *  This file is part of the Jikes RVM project (http://jikesrvm.org).
003 *
004 *  This file is licensed to You under the Eclipse Public License (EPL);
005 *  You may not use this file except in compliance with the License. You
006 *  may obtain a copy of the License at
007 *
008 *      http://www.opensource.org/licenses/eclipse-1.0.php
009 *
010 *  See the COPYRIGHT.txt file distributed with this work for information
011 *  regarding copyright ownership.
012 */
013package org.mmtk.plan.semispace.gctrace;
014
015import org.mmtk.plan.Trace;
016import org.mmtk.plan.semispace.*;
017import org.mmtk.policy.Space;
018import org.mmtk.utility.TraceGenerator;
019
020import org.vmmagic.unboxed.*;
021import org.vmmagic.pragma.*;
022
023/**
024 * This plan has been modified slightly to perform the processing necessary
025 * for GC trace generation.  To maximize performance, it attempts to remain
026 * as faithful as possible to semiSpace/Plan.java.
027 * <pre>
028 * The generated trace format is as follows:
029 *    B 345678 12
030 *      (Object 345678 was created in the boot image with a size of 12 bytes)
031 *    U 59843 234 47298
032 *      (Update object 59843 at the slot at offset 234 to refer to 47298)
033 *    S 1233 12345
034 *      (Update static slot 1233 to refer to 12345)
035 *    T 4567 78924
036 *      (The TIB of 4567 is set to refer to 78924)
037 *    D 342789
038 *      (Object 342789 became unreachable)
039 *    A 6860 24 346648 3
040 *      (Object 6860 was allocated, requiring 24 bytes, with fp 346648 on
041 *        thread 3; this allocation has perfect knowledge)
042 *    a 6884 24 346640 5
043 *      (Object 6864 was allocated, requiring 24 bytes, with fp 346640 on
044 * thread 5; this allocation DOES NOT have perfect knowledge)
045 *    I 6860 24 346648 3
046 *      (Object 6860 was allocated into immortal space, requiring 24 bytes,
047 *        with fp 346648 on thread 3; this allocation has perfect knowledge)
048 *    i 6884 24 346640 5
049 *      (Object 6864 was allocated into immortal space, requiring 24 bytes,
050 *        with fp 346640 on thread 5; this allocation DOES NOT have perfect
051 *        knowledge)
052 *    48954-&gt;[345]LObject;:blah()V:23   Ljava/lang/Foo;
053 *      (Citation for: a) where the was allocated, fp of 48954,
054 *         at the method with ID 345 -- or void Object.blah() -- and bytecode
055 *         with offset 23; b) the object allocated is of type java.lang.Foo)
056 *    D 342789 361460
057 *      (Object 342789 became unreachable after 361460 was allocated)
058 * </pre>
059 * This class implements a simple semi-space collector. See the Jones
060 * &amp; Lins GC book, section 2.2 for an overview of the basic
061 * algorithm. This implementation also includes a large object space
062 * (LOS), and an uncollected "immortal" space.<p>
063 *
064 * All plans make a clear distinction between <i>global</i> and
065 * <i>thread-local</i> activities.  Global activities must be
066 * synchronized, whereas no synchronization is required for
067 * thread-local activities.  Instances of Plan map 1:1 to "kernel
068 * threads" (aka CPUs).  Thus instance
069 * methods allow fast, unsychronized access to Plan utilities such as
070 * allocation and collection.  Each instance rests on static resources
071 * (such as memory and virtual memory resources) which are "global"
072 * and therefore "static" members of Plan.  This mapping of threads to
073 * instances is crucial to understanding the correctness and
074 * performance properties of this plan.
075 */
076@Uninterruptible
077public final class GCTraceTraceLocal extends SSTraceLocal {
078
079  /**
080   * Constructor
081   *
082   * @param trace The global trace to use.
083   */
084  public GCTraceTraceLocal(Trace trace) {
085    super(trace, false);
086  }
087
088  /****************************************************************************
089   *
090   * Object processing and tracing
091   */
092
093  /**
094   * Trace a reference during GC.  This involves determining which
095   * collection policy applies (such as those needed for trace generation)
096   * and taking the appropriate actions.
097   *
098   * @param object The object reference to be traced.  In certain
099   * cases, this should <i>NOT</i> be an interior pointer.
100   * @return The possibly moved reference.
101   */
102  @Override
103  @Inline
104  public ObjectReference traceObject(ObjectReference object) {
105    if (object.isNull()) return object;
106    if (GCTrace.traceInducedGC) {
107      /* We are performing a root scan following an allocation. */
108      TraceGenerator.rootEnumerate(object);
109      return object;
110    } else if (GCTrace.deathScan) {
111      /* We are performing the last scan before program termination. */
112      TraceGenerator.propagateDeathTime(object);
113      return object;
114    } else {
115      /* *gasp* We are actually performing garbage collection */
116      return super.traceObject(object);
117    }
118  }
119
120  @Override
121  @Inline
122  public ObjectReference getForwardedReference(ObjectReference object) {
123    if (object.isNull()) return object;
124    if (SS.hi && Space.isInSpace(SS.SS0, object)) {
125      return SS.copySpace0.traceObject(this, object, GCTrace.ALLOC_SS);
126    } else if (!SS.hi && Space.isInSpace(SS.SS1, object)) {
127      return SS.copySpace1.traceObject(this, object, GCTrace.ALLOC_SS);
128    }
129    return object;
130  }
131
132  @Override
133  public boolean isLive(ObjectReference object) {
134      if (object.isNull()) return false;
135      else if (GCTrace.traceInducedGC) return true;
136      else return super.isLive(object);
137  }
138
139  /**
140   * Return true if <code>obj</code> is a reachable object.
141   *
142   * @param object The object in question
143   * @return True if <code>obj</code> is a reachable object;
144   * unreachable objects may still be live, however
145   */
146  @Override
147  public boolean isReachable(ObjectReference object) {
148    if (GCTrace.finalDead) return false;
149    else if (object.isNull()) return false;
150    else {
151      Space space = Space.getSpaceForObject(object);
152      return space.isReachable(object);
153    }
154  }
155
156  /**
157   * Is this object guaranteed not to move during the collection.
158   *
159   * @param object The object to check.
160   * @return True if the object is guaranteed not to move.
161   */
162  @Override
163  public boolean willNotMoveInCurrentCollection(ObjectReference object) {
164    if (GCTrace.traceInducedGC) return true;
165    else return super.willNotMoveInCurrentCollection(object);
166  }
167}