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    
056       /**
057        *
058        */
059       protected ImmixTraceLocal fastTrace;
060       protected ImmixDefragTraceLocal defragTrace;
061       protected CollectorLocal immix;
062       protected final ImmixAllocator copy;
063       protected final BumpPointer immortal;
064       protected TraceLocal currentTrace;
065    
066      /****************************************************************************
067       * Initialization
068       */
069    
070      /**
071       * Constructor
072       */
073      public ImmixCollector() {
074        fastTrace = new ImmixTraceLocal(global().immixTrace, null);
075        defragTrace = new ImmixDefragTraceLocal(global().immixTrace, null);
076        immix = new CollectorLocal(Immix.immixSpace);
077        copy = new ImmixAllocator(Immix.immixSpace, true, true);
078        immortal = new ImmortalLocal(Plan.immortalSpace);
079      }
080    
081     /****************************************************************************
082      *
083      * Collection-time allocation
084      */
085    
086      /**
087       * {@inheritDoc}
088       */
089      @Override
090      @Inline
091      public Address allocCopy(ObjectReference original, int bytes,
092          int align, int offset, int allocator) {
093        if (VM.VERIFY_ASSERTIONS) {
094          VM.assertions._assert(bytes <= Plan.MAX_NON_LOS_COPY_BYTES);
095          VM.assertions._assert(allocator == Immix.ALLOC_DEFAULT);
096        }
097        return copy.alloc(bytes, align, offset);
098      }
099    
100      @Override
101      @Inline
102      public void postCopy(ObjectReference object, ObjectReference typeRef,
103          int bytes, int allocator) {
104        if (VM.VERIFY_ASSERTIONS) VM.assertions._assert(allocator == Immix.ALLOC_DEFAULT);
105        Immix.immixSpace.postCopy(object, bytes, true);
106    
107        if (VM.VERIFY_ASSERTIONS) {
108          VM.assertions._assert(getCurrentTrace().isLive(object));
109          VM.assertions._assert(getCurrentTrace().willNotMoveInCurrentCollection(object));
110        }
111      }
112    
113      /****************************************************************************
114       *
115       * Collection
116       */
117    
118      /**
119       * {@inheritDoc}
120       */
121      @Override
122      @Inline
123      public void collectionPhase(short phaseId, boolean primary) {
124    
125        if (phaseId == Immix.PREPARE) {
126          super.collectionPhase(phaseId, primary);
127          currentTrace = Immix.immixSpace.inImmixDefragCollection() ? defragTrace : fastTrace;
128          immix.prepare(true);
129          currentTrace.prepare();
130          copy.reset();
131          return;
132        }
133    
134        if (phaseId == Immix.CLOSURE) {
135          currentTrace.completeTrace();
136          return;
137        }
138    
139        if (phaseId == Immix.RELEASE) {
140          currentTrace.release();
141          immix.release(true);
142          super.collectionPhase(phaseId, primary);
143          return;
144        }
145    
146        super.collectionPhase(phaseId, primary);
147      }
148    
149      /****************************************************************************
150       *
151       * Miscellaneous
152       */
153    
154      /** @return The active global plan as an <code>Immix</code> instance. */
155      @Inline
156      private static Immix global() {
157        return (Immix) VM.activePlan.global();
158      }
159    
160      /** @return The current fastTrace instance. */
161      @Override
162      @Inline
163      public final TraceLocal getCurrentTrace() {
164        return currentTrace;
165      }
166    }