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 }