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.policy;
014
015 import org.mmtk.plan.TransitiveClosure;
016 import org.mmtk.utility.heap.*;
017 import org.mmtk.utility.options.Options;
018 import org.mmtk.utility.Constants;
019 import org.mmtk.utility.ForwardingWord;
020 import org.mmtk.utility.Log;
021
022 import org.mmtk.vm.VM;
023
024 import org.vmmagic.unboxed.*;
025 import org.vmmagic.pragma.*;
026
027 /**
028 * This class implements tracing functionality for a simple copying
029 * space. Since no state needs to be held globally or locally, all
030 * methods are static.
031 */
032 @Uninterruptible public final class CopySpace extends Space
033 implements Constants {
034
035 /****************************************************************************
036 *
037 * Class variables
038 */
039
040 /**
041 *
042 */
043 public static final int LOCAL_GC_BITS_REQUIRED = 2;
044 public static final int GLOBAL_GC_BITS_REQUIRED = 0;
045 public static final int GC_HEADER_WORDS_REQUIRED = 0;
046
047 private static final int META_DATA_PAGES_PER_REGION = CARD_META_PAGES_PER_REGION;
048
049
050 /****************************************************************************
051 *
052 * Instance variables
053 */
054
055 /**
056 *
057 */
058 private boolean fromSpace = true;
059
060 public boolean isFromSpace() {
061 return fromSpace;
062 }
063
064 /** fromSpace CopySpace can always move, toSpace will not move during current GC */
065 @Override
066 public boolean isMovable() {
067 return fromSpace;
068 }
069
070 /****************************************************************************
071 *
072 * Initialization
073 */
074
075 /**
076 * The caller specifies the region of virtual memory to be used for
077 * this space. If this region conflicts with an existing space,
078 * then the constructor will fail.
079 *
080 * @param name The name of this space (used when printing error messages etc)
081 * @param fromSpace The does this instance start life as from-space
082 * (or to-space)?
083 * @param vmRequest An object describing the virtual memory requested.
084 */
085 public CopySpace(String name, boolean fromSpace, VMRequest vmRequest) {
086 this(name, fromSpace, true, vmRequest);
087 }
088
089 /**
090 * The caller specifies the region of virtual memory to be used for
091 * this space. If this region conflicts with an existing space,
092 * then the constructor will fail.
093 *
094 * @param name The name of this space (used when printing error messages etc)
095 * @param fromSpace The does this instance start life as from-space
096 * @param zeroed if true, allocations return zeroed memory.
097 * (or to-space)?
098 * @param vmRequest An object describing the virtual memory requested.
099 */
100 public CopySpace(String name, boolean fromSpace, boolean zeroed, VMRequest vmRequest) {
101 super(name, true, false, zeroed, vmRequest);
102 this.fromSpace = fromSpace;
103 if (vmRequest.isDiscontiguous()) {
104 pr = new MonotonePageResource(this, META_DATA_PAGES_PER_REGION);
105 } else {
106 pr = new MonotonePageResource(this, start, extent, META_DATA_PAGES_PER_REGION);
107 }
108 }
109
110 /****************************************************************************
111 *
112 * Prepare and release
113 */
114
115 /**
116 * Prepare this space instance for a collection. Set the
117 * "fromSpace" field according to whether this space is the
118 * source or target of the collection.
119 *
120 * @param fromSpace Set the fromSpace field to this value
121 */
122 public void prepare(boolean fromSpace) { this.fromSpace = fromSpace; }
123
124 /**
125 * Release this copy space after a collection. This means releasing
126 * all pages associated with this (now empty) space.
127 */
128 public void release() {
129 ((MonotonePageResource) pr).reset();
130 headDiscontiguousRegion = Address.zero();
131 fromSpace = false;
132 }
133
134 /**
135 * Release an allocated page or pages. In this case we do nothing
136 * because we only release pages enmasse.
137 *
138 * @param start The address of the start of the page or pages
139 */
140 @Override
141 @Inline
142 public void release(Address start) {
143 if (VM.VERIFY_ASSERTIONS)
144 VM.assertions._assert(false); // this policy only releases pages enmasse
145 }
146
147 /****************************************************************************
148 *
149 * Tracing and forwarding
150 */
151
152 /**
153 * Trace an object under a copying collection policy.<p>
154 *
155 * We use a tri-state algorithm to deal with races to forward
156 * the object. The tracer must wait if the object is concurrently
157 * being forwarded by another thread.<p>
158 *
159 * If the object is already forwarded, the copy is returned.
160 * Otherwise, the object is forwarded and the copy is returned.
161 *
162 * @param trace The trace being conducted.
163 * @param object The object to be forwarded.
164 * @return The forwarded object.
165 */
166 @Override
167 @Inline
168 public ObjectReference traceObject(TransitiveClosure trace, ObjectReference object) {
169 VM.assertions.fail("CopySpace.traceLocal called without allocator");
170 return ObjectReference.nullReference();
171 }
172
173 /**
174 * Trace an object under a copying collection policy.<p>
175 *
176 * We use a tri-state algorithm to deal with races to forward
177 * the object. The tracer must wait if the object is concurrently
178 * being forwarded by another thread.<p>
179 *
180 * If the object is already forwarded, the copy is returned.
181 * Otherwise, the object is forwarded and the copy is returned.
182 *
183 * @param trace The trace being conducted.
184 * @param object The object to be forwarded.
185 * @param allocator The allocator to use when copying.
186 * @return The forwarded object.
187 */
188 @Inline
189 public ObjectReference traceObject(TransitiveClosure trace, ObjectReference object, int allocator) {
190 /* If the object in question is already in to-space, then do nothing */
191 if (!fromSpace) return object;
192
193 /* Try to forward the object */
194 Word forwardingWord = ForwardingWord.attemptToForward(object);
195
196 if (ForwardingWord.stateIsForwardedOrBeingForwarded(forwardingWord)) {
197 /* Somebody else got to it first. */
198
199 /* We must wait (spin) if the object is not yet fully forwarded */
200 while (ForwardingWord.stateIsBeingForwarded(forwardingWord))
201 forwardingWord = VM.objectModel.readAvailableBitsWord(object);
202
203 /* Now extract the object reference from the forwarding word and return it */
204 return ForwardingWord.extractForwardingPointer(forwardingWord);
205 } else {
206 /* We are the designated copier, so forward it and enqueue it */
207 ObjectReference newObject = VM.objectModel.copy(object, allocator);
208 ForwardingWord.setForwardingPointer(object, newObject);
209 trace.processNode(newObject); // Scan it later
210
211 if (VM.VERIFY_ASSERTIONS && Options.verbose.getValue() >= 9) {
212 Log.write("C["); Log.write(object); Log.write("/");
213 Log.write(getName()); Log.write("] -> ");
214 Log.write(newObject); Log.write("/");
215 Log.write(Space.getSpaceForObject(newObject).getName());
216 Log.writeln("]");
217 }
218 return newObject;
219 }
220 }
221
222 /**
223 * Return {@code true} if this object is live in this GC
224 *
225 * @param object The object in question
226 * @return {@code true} if this object is live in this GC (has it been forwarded?)
227 */
228 @Override
229 public boolean isLive(ObjectReference object) {
230 return ForwardingWord.isForwarded(object);
231 }
232
233 @Override
234 public boolean isReachable(ObjectReference object) {
235 return !fromSpace || ForwardingWord.isForwarded(object);
236 }
237
238 /****************************************************************************
239 *
240 * Header manipulation
241 */
242
243 /**
244 * Perform any required post-allocation initialization
245 *
246 * <i>Nothing to be done in this case</i>
247 *
248 * @param object the object ref to the storage to be initialized
249 */
250 @Inline
251 public void postAlloc(ObjectReference object) {}
252
253 }