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.immix;
014    
015    import org.mmtk.plan.*;
016    import org.mmtk.policy.ImmortalLocal;
017    import org.mmtk.policy.immix.CollectorLocal;
018    import org.mmtk.utility.alloc.BumpPointer;
019    import org.mmtk.utility.alloc.ImmixAllocator;
020    import org.mmtk.vm.VM;
021    
022    import org.vmmagic.pragma.*;
023    import org.vmmagic.unboxed.Address;
024    import org.vmmagic.unboxed.ObjectReference;
025    
026    /**
027     * This class implements <i>per-collector thread</i> behavior
028     * and state for the <i>Immix</i> plan, which implements a full-heap
029     * immix collector.<p>
030     *
031     * Specifically, this class defines <i>Immix</i> collection behavior
032     * (through <code>fastTrace</code> and the <code>collectionPhase</code>
033     * method).<p>
034     *
035     * @see Immix for an overview of the immix algorithm.<p>
036     *
037     * FIXME The SegregatedFreeList class (and its decendents such as
038     * MarkSweepLocal) does not properly separate mutator and collector
039     * behaviors, so the immix field below should really not exist in
040     * this class as there is no collection-time allocation in this
041     * collector.
042     *
043     * @see Immix
044     * @see org.mmtk.policy.immix.MutatorLocal
045     * @see StopTheWorldCollector
046     * @see CollectorContext
047     * @see Phase
048     */
049    @Uninterruptible
050    public class ImmixCollector extends StopTheWorldCollector {
051    
052      /****************************************************************************
053       * Instance fields
054       */
055       protected ImmixTraceLocal fastTrace;
056       protected ImmixDefragTraceLocal defragTrace;
057       protected CollectorLocal immix;
058       protected final ImmixAllocator copy;
059       protected final BumpPointer immortal;
060       protected TraceLocal currentTrace;
061    
062      /****************************************************************************
063       * Initialization
064       */
065    
066      /**
067       * Constructor
068       */
069      public ImmixCollector() {
070        fastTrace = new ImmixTraceLocal(global().immixTrace, null);
071        defragTrace = new ImmixDefragTraceLocal(global().immixTrace, null);
072        immix = new CollectorLocal(Immix.immixSpace);
073        copy = new ImmixAllocator(Immix.immixSpace, true, true);
074        immortal = new ImmortalLocal(Plan.immortalSpace);
075      }
076    
077     /****************************************************************************
078      *
079      * Collection-time allocation
080      */
081    
082     /**
083      * Allocate space for copying an object (this method <i>does not</i>
084      * copy the object, it only allocates space)
085      *
086      * @param original A reference to the original object
087      * @param bytes The size of the space to be allocated (in bytes)
088      * @param align The requested alignment.
089      * @param offset The alignment offset.
090      * @return The address of the first byte of the allocated region
091      */
092      @Inline
093      public Address allocCopy(ObjectReference original, int bytes,
094          int align, int offset, int allocator) {
095        if (VM.VERIFY_ASSERTIONS) {
096          VM.assertions._assert(bytes <= Plan.MAX_NON_LOS_COPY_BYTES);
097          VM.assertions._assert(allocator == Immix.ALLOC_DEFAULT);
098        }
099        return copy.alloc(bytes, align, offset);
100      }
101    
102     /**
103      * Perform any post-copy actions.
104      *
105      * @param object The newly allocated object
106      * @param typeRef the type reference for the instance being created
107      * @param bytes The size of the space to be allocated (in bytes)
108      */
109      @Inline
110      public void postCopy(ObjectReference object, ObjectReference typeRef,
111          int bytes, int allocator) {
112        if (VM.VERIFY_ASSERTIONS) VM.assertions._assert(allocator == Immix.ALLOC_DEFAULT);
113        Immix.immixSpace.postCopy(object, bytes, true);
114    
115        if (VM.VERIFY_ASSERTIONS) {
116          VM.assertions._assert(getCurrentTrace().isLive(object));
117          VM.assertions._assert(getCurrentTrace().willNotMoveInCurrentCollection(object));
118        }
119      }
120    
121      /****************************************************************************
122       *
123       * Collection
124       */
125    
126      /**
127       * Perform a per-collector collection phase.
128       *
129       * @param phaseId The collection phase to perform
130       * @param primary Perform any single-threaded activities using this thread.
131       */
132      @Inline
133      public void collectionPhase(short phaseId, boolean primary) {
134    
135        if (phaseId == Immix.PREPARE) {
136          super.collectionPhase(phaseId, primary);
137          currentTrace = Immix.immixSpace.inImmixDefragCollection() ? defragTrace : fastTrace;
138          immix.prepare(true);
139          currentTrace.prepare();
140          copy.reset();
141          return;
142        }
143    
144        if (phaseId == Immix.CLOSURE) {
145          currentTrace.completeTrace();
146          return;
147        }
148    
149        if (phaseId == Immix.RELEASE) {
150          currentTrace.release();
151          immix.release(true);
152          super.collectionPhase(phaseId, primary);
153          return;
154        }
155    
156        super.collectionPhase(phaseId, primary);
157      }
158    
159      /****************************************************************************
160       *
161       * Miscellaneous
162       */
163    
164      /** @return The active global plan as an <code>Immix</code> instance. */
165      @Inline
166      private static Immix global() {
167        return (Immix) VM.activePlan.global();
168      }
169    
170      /** @return The current fastTrace instance. */
171      @Inline
172      public final TraceLocal getCurrentTrace() {
173        return currentTrace;
174      }
175    }