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