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    }