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.policy; 014 015import static org.mmtk.utility.Constants.*; 016 017import org.mmtk.plan.TransitiveClosure; 018import org.mmtk.utility.heap.*; 019import org.mmtk.utility.options.Options; 020import org.mmtk.utility.ForwardingWord; 021import org.mmtk.utility.Log; 022 023import org.mmtk.vm.VM; 024 025import org.vmmagic.unboxed.*; 026import org.vmmagic.pragma.*; 027 028/** 029 * This class implements tracing functionality for a simple copying 030 * space. Since no state needs to be held globally or locally, all 031 * methods are static. 032 */ 033@Uninterruptible public final class CopySpace extends Space { 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) { 123 this.fromSpace = fromSpace; 124 } 125 126 /** 127 * Release this copy space after a collection. This means releasing 128 * all pages associated with this (now empty) space. 129 */ 130 public void release() { 131 ((MonotonePageResource) pr).reset(); 132 headDiscontiguousRegion = Address.zero(); 133 fromSpace = false; 134 } 135 136 /** 137 * Release an allocated page or pages. In this case we do nothing 138 * because we only release pages enmasse. 139 * 140 * @param start The address of the start of the page or pages 141 */ 142 @Override 143 @Inline 144 public void release(Address start) { 145 if (VM.VERIFY_ASSERTIONS) 146 VM.assertions._assert(false); // this policy only releases pages enmasse 147 } 148 149 /**************************************************************************** 150 * 151 * Tracing and forwarding 152 */ 153 154 /** 155 * Trace an object under a copying collection policy.<p> 156 * 157 * We use a tri-state algorithm to deal with races to forward 158 * the object. The tracer must wait if the object is concurrently 159 * being forwarded by another thread.<p> 160 * 161 * If the object is already forwarded, the copy is returned. 162 * Otherwise, the object is forwarded and the copy is returned. 163 * 164 * @param trace The trace being conducted. 165 * @param object The object to be forwarded. 166 * @return The forwarded object. 167 */ 168 @Override 169 @Inline 170 public ObjectReference traceObject(TransitiveClosure trace, ObjectReference object) { 171 VM.assertions.fail("CopySpace.traceLocal called without allocator"); 172 return ObjectReference.nullReference(); 173 } 174 175 /** 176 * Trace an object under a copying collection policy.<p> 177 * 178 * We use a tri-state algorithm to deal with races to forward 179 * the object. The tracer must wait if the object is concurrently 180 * being forwarded by another thread.<p> 181 * 182 * If the object is already forwarded, the copy is returned. 183 * Otherwise, the object is forwarded and the copy is returned. 184 * 185 * @param trace The trace being conducted. 186 * @param object The object to be forwarded. 187 * @param allocator The allocator to use when copying. 188 * @return The forwarded object. 189 */ 190 @Inline 191 public ObjectReference traceObject(TransitiveClosure trace, ObjectReference object, int allocator) { 192 /* If the object in question is already in to-space, then do nothing */ 193 if (!fromSpace) return object; 194 195 /* Try to forward the object */ 196 Word forwardingWord = ForwardingWord.attemptToForward(object); 197 198 if (ForwardingWord.stateIsForwardedOrBeingForwarded(forwardingWord)) { 199 /* Somebody else got to it first. */ 200 201 /* We must wait (spin) if the object is not yet fully forwarded */ 202 while (ForwardingWord.stateIsBeingForwarded(forwardingWord)) 203 forwardingWord = VM.objectModel.readAvailableBitsWord(object); 204 205 /* Now extract the object reference from the forwarding word and return it */ 206 return ForwardingWord.extractForwardingPointer(forwardingWord); 207 } else { 208 /* We are the designated copier, so forward it and enqueue it */ 209 ObjectReference newObject = VM.objectModel.copy(object, allocator); 210 ForwardingWord.setForwardingPointer(object, newObject); 211 trace.processNode(newObject); // Scan it later 212 213 if (VM.VERIFY_ASSERTIONS && Options.verbose.getValue() >= 9) { 214 Log.write("C["); Log.write(object); Log.write("/"); 215 Log.write(getName()); Log.write("] -> "); 216 Log.write(newObject); Log.write("/"); 217 Log.write(Space.getSpaceForObject(newObject).getName()); 218 Log.writeln("]"); 219 } 220 return newObject; 221 } 222 } 223 224 /** 225 * Return {@code true} if this object is live in this GC 226 * 227 * @param object The object in question 228 * @return {@code true} if this object is live in this GC (has it been forwarded?) 229 */ 230 @Override 231 public boolean isLive(ObjectReference object) { 232 return ForwardingWord.isForwarded(object); 233 } 234 235 @Override 236 public boolean isReachable(ObjectReference object) { 237 return !fromSpace || ForwardingWord.isForwarded(object); 238 } 239 240 /**************************************************************************** 241 * 242 * Header manipulation 243 */ 244 245 /** 246 * Perform any required post-allocation initialization 247 * 248 * <i>Nothing to be done in this case</i> 249 * 250 * @param object the object ref to the storage to be initialized 251 */ 252 @Inline 253 public void postAlloc(ObjectReference object) {} 254 255}