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; 014 015 import org.mmtk.utility.alloc.Allocator; 016 import org.mmtk.utility.Constants; 017 import org.mmtk.utility.Log; 018 019 import org.mmtk.vm.VM; 020 021 import org.vmmagic.pragma.*; 022 import org.vmmagic.unboxed.*; 023 024 /** 025 * This class (and its sub-classes) implement <i>per-collector thread</i> 026 * behavior. We assume <i>N</i> collector threads and <i>M</i> 027 * mutator threads, where <i>N</i> is often equal to the number of 028 * available processors, P (for P-way parallelism at GC-time), and 029 * <i>M</i> may simply be the number of mutator (application) threads. 030 * Both <i>N</i> and <i>M</i> are determined by the VM, not MMTk. In 031 * the case where a VM uses posix threads (pthreads) for each mutator 032 * ("1:1" threading), <i>M</i> will typically be equal to the number of 033 * mutator threads. When a uses "green threads" or a hybrid threading 034 * scheme (such as Jikes RVM), <i>M</i> will typically be equal to the 035 * level of <i>true</i> parallelism (ie the number of underlying 036 * kernel threads).</p> 037 * 038 * <p>Collector operations are separated into <i>per-collector thread</i> 039 * operations (the bulk of the GC), and <i>per-mutator thread</i> operations 040 * (important in flushing and restoring per-mutator state such as allocator 041 * state and write buffer/remset state). {@link SimplePhase} 042 * ensures that per-collector thread GC phases are performed by each 043 * collector thread, and that the <i>M</i> per-mutator thread operations 044 * are multiplexed across the <i>N</i> active collector threads.</p> 045 * 046 * <p>MMTk assumes that the VM instantiates instances of {@link CollectorContext} 047 * in thread local storage (TLS) for each thread participating in 048 * collection. Accesses to this state are therefore assumed to be 049 * low-cost at GC time.</p> 050 * 051 * <p>MMTk explicitly separates thread-local (this class) and global 052 * operations (See {@link Plan}), so that syncrhonization is localized 053 * and explicit, and thus hopefully minimized (See {@link Plan}). Global (Plan) 054 * and per-thread (this class) state are also explicitly separated. 055 * Operations in this class (and its children) are therefore strictly 056 * local to each collector thread, and synchronized operations always 057 * happen via access to explicitly global classes such as Plan and its 058 * children.</p> 059 * 060 * <p>This class (and its children) therefore typically implement per-collector 061 * thread structures such as collection work queues.</p> 062 * 063 * @see MutatorContext 064 * @see org.mmtk.vm.ActivePlan 065 * @see Plan 066 */ 067 @Uninterruptible 068 public abstract class CollectorContext implements Constants { 069 070 /**************************************************************************** 071 * Instance fields 072 */ 073 074 /** Unique identifier. */ 075 private int id; 076 077 /** Used for printing log information in a thread safe manner */ 078 protected final Log log = new Log(); 079 080 /**************************************************************************** 081 * 082 * Initialization 083 */ 084 085 /** 086 * Notify that the collector context is registered and ready to execute. 087 * 088 * @param id The id of this collector context. 089 */ 090 @Interruptible 091 public void initCollector(int id) { 092 this.id = id; 093 } 094 095 /**************************************************************************** 096 * Collection-time allocation. 097 */ 098 099 /** 100 * Allocate space for copying an object (this method <i>does not</i> 101 * copy the object, it only allocates space) 102 * 103 * @param original The object that is being copied. 104 * @param bytes The size of the space to be allocated (in bytes) 105 * @param align Required alignment for the copy 106 * @param offset Offset associated with the alignment. 107 * @param allocator The allocator associated with this request 108 * @return The address of the first byte of the allocated region 109 */ 110 public Address allocCopy(ObjectReference original, int bytes, int align, int offset, int allocator) { 111 VM.assertions.fail("Collector has not implemented allocCopy"); 112 return Address.max(); 113 } 114 115 /** 116 * Perform any post-copy actions. 117 * 118 * @param ref The newly allocated object. 119 * @param typeRef the type reference for the instance being created. 120 * @param bytes The size of the space to be allocated (in bytes). 121 * @param allocator The allocator statically assigned to this allocation. 122 */ 123 public void postCopy(ObjectReference ref, ObjectReference typeRef, int bytes, int allocator) { 124 VM.assertions.fail("Collector has not implemented postCopy"); 125 } 126 127 /** 128 * Run-time check of the allocator to use for a given copy allocation. 129 * <p> 130 * At the moment this method assumes that allocators will use the simple 131 * (worst) method of aligning to determine if the object is a large object 132 * to ensure that no objects are larger than other allocators can handle. 133 * 134 * @param from The object that is being copied. 135 * @param bytes The number of bytes to be allocated. 136 * @param align The requested alignment. 137 * @param allocator The allocator statically assigned to this allocation. 138 * @return The allocator dynamically assigned to this allocation. 139 */ 140 @Inline 141 public int copyCheckAllocator(ObjectReference from, int bytes, int align, int allocator) { 142 boolean large = Allocator.getMaximumAlignedSize(bytes, align) > Plan.MAX_NON_LOS_COPY_BYTES; 143 return large ? Plan.ALLOC_LOS : allocator; 144 } 145 146 /**************************************************************************** 147 * Collection. 148 */ 149 150 /** 151 * Entry point for the collector context. 152 */ 153 @Unpreemptible 154 public abstract void run(); 155 156 /** 157 * The number of parallel workers currently executing with this collector 158 * context. This can be queried from anywhere within a collector context 159 * to determine how best to perform load-balancing. 160 * 161 * @return The number of parallel workers. 162 */ 163 public int parallelWorkerCount() { 164 return 1; 165 } 166 167 /** 168 * The ordinal of the current worker. This is in the range of 0 to the result 169 * of parallelWorkerCount() exclusive. 170 * 171 * @return The ordinal of this collector context, starting from 0. 172 */ 173 public int parallelWorkerOrdinal() { 174 return 0; 175 } 176 177 /** 178 * Get the executing context to rendezvous with other contexts working 179 * in parallel. 180 * 181 * @return The order this context reached the rendezvous, starting from 0. 182 */ 183 public int rendezvous() { 184 return 0; 185 } 186 187 /**************************************************************************** 188 * Miscellaneous. 189 */ 190 191 /** @return the <code>Log</code> instance for this collector context. */ 192 public final Log getLog() { 193 return log; 194 } 195 196 /** 197 * @return The unique identifier for this collector context. 198 */ 199 @Inline 200 public int getId() { 201 return id; 202 } 203 }