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.markcompact;
014    
015    import org.mmtk.plan.*;
016    import org.mmtk.policy.MarkCompactCollector;
017    
018    import org.mmtk.vm.VM;
019    
020    import org.vmmagic.pragma.*;
021    import org.vmmagic.unboxed.*;
022    
023    /**
024     * This class implements <i>per-collector thread</i> behavior
025     * and state for the <i>MC</i> plan, which implements a full-heap
026     * mark-compact collector.<p>
027     *
028     * Specifically, this class defines <i>MC</i> collection behavior
029     * (through <code>trace</code> and the <code>collectionPhase</code>
030     * method), and collection-time allocation.<p>
031     *
032     * @see MC for an overview of the mark-compact algorithm.<p>
033     * @see MCMutator
034     * @see StopTheWorldCollector
035     * @see CollectorContext
036     */
037    @Uninterruptible public class MCCollector extends StopTheWorldCollector {
038    
039      private static final boolean TRACE_MARK = false;
040      private static final boolean TRACE_FORWARD = true;
041    
042      /****************************************************************************
043       * Instance fields
044       */
045    
046      private final MCMarkTraceLocal markTrace;
047      private final MCForwardTraceLocal forwardTrace;
048      private final MarkCompactCollector mc;
049      private boolean currentTrace;
050    
051      /****************************************************************************
052       *
053       * Initialization
054       */
055    
056      /**
057       * Constructor
058       */
059      public MCCollector() {
060        markTrace = new MCMarkTraceLocal(global().markTrace);
061        forwardTrace = new MCForwardTraceLocal(global().forwardTrace);
062        mc = new MarkCompactCollector(MC.mcSpace);
063      }
064    
065    
066      /****************************************************************************
067       *
068       * Collection-time allocation
069       */
070    
071      /**
072       * Allocate space for copying an object (this method <i>does not</i>
073       * copy the object, it only allocates space)
074       *
075       * @param original A reference to the original object
076       * @param bytes The size of the space to be allocated (in bytes)
077       * @param align The requested alignment.
078       * @param offset The alignment offset.
079       * @return The address of the first byte of the allocated region
080       */
081      @Override
082      @Inline
083      public Address allocCopy(ObjectReference original, int bytes,
084          int align, int offset, int allocator) {
085        if (VM.VERIFY_ASSERTIONS) VM.assertions._assert(allocator == MC.ALLOC_IMMORTAL);
086    
087        return immortal.alloc(bytes, align, offset);
088      }
089    
090      /**
091       * Perform any post-copy actions.
092       *
093       * @param object The newly allocated object
094       * @param typeRef the type reference for the instance being created
095       * @param bytes The size of the space to be allocated (in bytes)
096       */
097      @Override
098      @Inline
099      public void postCopy(ObjectReference object, ObjectReference typeRef,
100          int bytes, int allocator) {
101        MC.immortalSpace.initializeHeader(object);
102      }
103    
104      /****************************************************************************
105       *
106       * Collection
107       */
108    
109      /**
110       * Perform a per-collector collection phase.
111       *
112       * @param phaseId The collection phase to perform
113       * @param primary Perform any single-threaded activities using this thread.
114       */
115      @Override
116      @Inline
117      public final void collectionPhase(short phaseId, boolean primary) {
118        if (phaseId == MC.PREPARE) {
119          currentTrace = TRACE_MARK;
120          super.collectionPhase(phaseId, primary);
121          markTrace.prepare();
122          return;
123        }
124    
125        if (phaseId == MC.CLOSURE) {
126          markTrace.completeTrace();
127          return;
128        }
129    
130        if (phaseId == MC.CALCULATE_FP) {
131          mc.calculateForwardingPointers();
132          return;
133        }
134    
135        if (phaseId == MC.COMPACT) {
136          mc.compact();
137          return;
138        }
139    
140        if (phaseId == MC.RELEASE) {
141          markTrace.release();
142          super.collectionPhase(phaseId, primary);
143          return;
144        }
145    
146        if (phaseId == MC.PREPARE_FORWARD) {
147          currentTrace = TRACE_FORWARD;
148          super.collectionPhase(MC.PREPARE, primary);
149          forwardTrace.prepare();
150          return;
151        }
152    
153        if (phaseId == MC.FORWARD_CLOSURE) {
154          forwardTrace.completeTrace();
155          return;
156        }
157    
158        if (phaseId == MC.RELEASE_FORWARD) {
159          forwardTrace.release();
160          super.collectionPhase(MC.RELEASE, primary);
161          return;
162        }
163    
164        super.collectionPhase(phaseId, primary);
165      }
166    
167      /****************************************************************************
168       *
169       * Miscellaneous
170       */
171    
172      /** @return The current trace instance. */
173      @Override
174      public final TraceLocal getCurrentTrace() {
175        if (currentTrace == TRACE_MARK) {
176          return markTrace;
177        }
178        return forwardTrace;
179      }
180    
181      /** @return The active global plan as an <code>MC</code> instance. */
182      @Inline
183      private static MC global() {
184        return (MC) VM.activePlan.global();
185      }
186    }