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 }