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     */
013    package org.mmtk.plan.semispace.gctrace;
014    
015    import org.mmtk.plan.Trace;
016    import org.mmtk.plan.semispace.*;
017    import org.mmtk.policy.Space;
018    import org.mmtk.utility.TraceGenerator;
019    
020    import org.vmmagic.unboxed.*;
021    import 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     *
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->[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     *
059     * This class implements a simple semi-space collector. See the Jones
060     * & 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 proprties of this plan.
075     */
076    @Uninterruptible
077    public 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      @Inline
103      public ObjectReference traceObject(ObjectReference object) {
104        if (object.isNull()) return object;
105        if (GCTrace.traceInducedGC) {
106          /* We are performing a root scan following an allocation. */
107          TraceGenerator.rootEnumerate(object);
108          return object;
109        } else if (GCTrace.deathScan) {
110          /* We are performing the last scan before program termination. */
111          TraceGenerator.propagateDeathTime(object);
112          return object;
113        } else {
114          /* *gasp* We are actually performing garbage collection */
115          return super.traceObject(object);
116        }
117      }
118    
119      /**
120       * Ensure that the referenced object will not move during a collection
121       * by 'precopying' it at the beginning.
122       *
123       * @param object The object to ensure will not move.
124       */
125      @Inline
126      public ObjectReference precopyObject(ObjectReference object) {
127        if (object.isNull()) return object;
128        if (GCTrace.traceInducedGC) {
129          /* We are performing a root scan following an allocation. */
130          TraceGenerator.rootEnumerate(object);
131          return object;
132        } else if (GCTrace.deathScan) {
133          /* We are performing the last scan before program termination. */
134          TraceGenerator.propagateDeathTime(object);
135          return object;
136        } else {
137          return super.precopyObject(object);
138        }
139      }
140    
141    
142      /**
143       * If the referenced object has moved, return the new location.
144       *
145       * Some copying collectors will need to override this method.
146       *
147       * @param object The object which may have been forwarded.
148       * @return The new location of <code>object</code>.
149       */
150      @Inline
151      public ObjectReference getForwardedReference(ObjectReference object) {
152        if (object.isNull()) return object;
153        if (SS.hi && Space.isInSpace(SS.SS0, object)) {
154          return SS.copySpace0.traceObject(this, object, GCTrace.ALLOC_SS);
155        } else if (!SS.hi && Space.isInSpace(SS.SS1, object)) {
156          return SS.copySpace1.traceObject(this, object, GCTrace.ALLOC_SS);
157        }
158        return object;
159      }
160    
161      /**
162       * Return true if <code>obj</code> is a live object.
163       *
164       * @param object The object in question
165       * @return True if <code>obj</code> is a live object.
166       */
167      public boolean isLive(ObjectReference object) {
168          if (object.isNull()) return false;
169          else if (GCTrace.traceInducedGC) return true;
170          else return super.isLive(object);
171      }
172    
173      /**
174       * Return true if <code>obj</code> is a reachable object.
175       *
176       * @param object The object in question
177       * @return True if <code>obj</code> is a reachable object;
178       * unreachable objects may still be live, however
179       */
180      public boolean isReachable(ObjectReference object) {
181        if (GCTrace.finalDead) return false;
182        else if (object.isNull()) return false;
183        else {
184          Space space = Space.getSpaceForObject(object);
185          return space.isReachable(object);
186        }
187      }
188    
189      /**
190       * Is this object guaranteed not to move during the collection.
191       *
192       * @param object The object to check.
193       * @return True if the object is guaranteed not to move.
194       */
195      public boolean willNotMoveInCurrentCollection(ObjectReference object) {
196        if (GCTrace.traceInducedGC) return true;
197        else return super.willNotMoveInCurrentCollection(object);
198      }
199    }