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;
014
015 import org.mmtk.plan.*;
016 import org.mmtk.policy.CopyLocal;
017 import org.mmtk.policy.LargeObjectLocal;
018 import org.mmtk.policy.Space;
019 import org.mmtk.utility.ForwardingWord;
020 import org.mmtk.vm.VM;
021
022 import org.vmmagic.unboxed.*;
023 import org.vmmagic.pragma.*;
024
025 /**
026 * This class implements <i>per-collector thread</i> behavior
027 * and state for the <i>SS</i> plan, which implements a full-heap
028 * semi-space collector.<p>
029 *
030 * Specifically, this class defines <i>SS</i> collection behavior
031 * (through <code>trace</code> and the <code>collectionPhase</code>
032 * method), and collection-time allocation (copying of objects).<p>
033 *
034 * See {@link SS} for an overview of the semi-space algorithm.<p>
035 *
036 * @see SS
037 * @see SSMutator
038 * @see StopTheWorldCollector
039 * @see CollectorContext
040 */
041 @Uninterruptible
042 public class SSCollector extends StopTheWorldCollector {
043
044 /****************************************************************************
045 * Instance fields
046 */
047
048 protected final SSTraceLocal trace;
049 protected final CopyLocal ss;
050 protected final LargeObjectLocal los;
051
052 /****************************************************************************
053 *
054 * Initialization
055 */
056
057 /**
058 * Constructor
059 */
060 public SSCollector() {
061 this(new SSTraceLocal(global().ssTrace));
062 }
063
064 /**
065 * Constructor
066 * @param tr The trace to use
067 */
068 protected SSCollector(SSTraceLocal tr) {
069 ss = new CopyLocal();
070 los = new LargeObjectLocal(Plan.loSpace);
071 trace = tr;
072 }
073
074 /****************************************************************************
075 *
076 * Collection-time allocation
077 */
078
079 /**
080 * Allocate space for copying an object (this method <i>does not</i>
081 * copy the object, it only allocates space)
082 *
083 * @param original A reference to the original object
084 * @param bytes The size of the space to be allocated (in bytes)
085 * @param align The requested alignment.
086 * @param offset The alignment offset.
087 * @return The address of the first byte of the allocated region
088 */
089 @Inline
090 public Address allocCopy(ObjectReference original, int bytes,
091 int align, int offset, int allocator) {
092 if (allocator == Plan.ALLOC_LOS) {
093 if (VM.VERIFY_ASSERTIONS) VM.assertions._assert(bytes > Plan.MAX_NON_LOS_COPY_BYTES);
094 return los.alloc(bytes, align, offset);
095 } else {
096 if (VM.VERIFY_ASSERTIONS) {
097 VM.assertions._assert(bytes <= Plan.MAX_NON_LOS_COPY_BYTES);
098 VM.assertions._assert(allocator == SS.ALLOC_SS);
099 }
100 return ss.alloc(bytes, align, offset);
101 }
102 }
103
104 /**
105 * Perform any post-copy actions.
106 *
107 * @param object The newly allocated object
108 * @param typeRef the type reference for the instance being created
109 * @param bytes The size of the space to be allocated (in bytes)
110 */
111 @Inline
112 public void postCopy(ObjectReference object, ObjectReference typeRef,
113 int bytes, int allocator) {
114 ForwardingWord.clearForwardingBits(object);
115 if (allocator == Plan.ALLOC_LOS)
116 Plan.loSpace.initializeHeader(object, false);
117 }
118
119 /****************************************************************************
120 *
121 * Collection
122 */
123
124 /**
125 * Perform a per-collector collection phase.
126 *
127 * @param phaseId The collection phase to perform
128 * @param primary Perform any single-threaded activities using this thread.
129 */
130 @Inline
131 public void collectionPhase(short phaseId, boolean primary) {
132 if (phaseId == SS.PREPARE) {
133 // rebind the copy bump pointer to the appropriate semispace.
134 ss.rebind(SS.toSpace());
135 los.prepare(true);
136 super.collectionPhase(phaseId, primary);
137 return;
138 }
139
140 if (phaseId == SS.CLOSURE) {
141 trace.completeTrace();
142 return;
143 }
144
145 if (phaseId == SS.RELEASE) {
146 trace.release();
147 los.release(true);
148 super.collectionPhase(phaseId, primary);
149 return;
150 }
151
152 super.collectionPhase(phaseId, primary);
153 }
154
155
156 /****************************************************************************
157 *
158 * Object processing and tracing
159 */
160
161 /**
162 * Return true if the given reference is to an object that is within
163 * one of the semi-spaces.
164 *
165 * @param object The object in question
166 * @return True if the given reference is to an object that is within
167 * one of the semi-spaces.
168 */
169 public static boolean isSemiSpaceObject(ObjectReference object) {
170 return Space.isInSpace(SS.SS0, object) || Space.isInSpace(SS.SS1, object);
171 }
172
173 /****************************************************************************
174 *
175 * Miscellaneous
176 */
177
178 /** @return The active global plan as an <code>SS</code> instance. */
179 @Inline
180 private static SS global() {
181 return (SS) VM.activePlan.global();
182 }
183
184 /** @return the current trace object. */
185 public TraceLocal getCurrentTrace() {
186 return trace;
187 }
188 }