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->[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 * & 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}