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.StopTheWorldMutator;
016    import org.mmtk.policy.MarkCompactLocal;
017    import org.mmtk.policy.Space;
018    
019    import org.mmtk.utility.alloc.Allocator;
020    
021    import org.vmmagic.pragma.*;
022    import org.vmmagic.unboxed.*;
023    
024    /**
025     * This class implements <i>per-mutator thread</i> behavior
026     * and state for the <i>MC</i> plan, which implements a full-heap
027     * mark-compact collector.<p>
028     *
029     * Specifically, this class defines <i>MC</i> mutator-time allocation
030     * and per-mutator thread collection semantics (flushing and restoring
031     * per-mutator allocator state).<p>
032     *
033     * See {@link MC} for an overview of the mark-compact algorithm.<p>
034     *
035     * @see MC
036     * @see MCCollector
037     * @see org.mmtk.plan.StopTheWorldMutator
038     * @see org.mmtk.plan.MutatorContext
039     */
040    @Uninterruptible public class MCMutator extends StopTheWorldMutator {
041    
042      /****************************************************************************
043       * Instance fields
044       */
045      private final MarkCompactLocal mc;
046    
047      /****************************************************************************
048       *
049       * Initialization
050       */
051    
052      /**
053       * Constructor
054       */
055      public MCMutator() {
056        mc = new MarkCompactLocal(MC.mcSpace);
057      }
058    
059      /****************************************************************************
060       *
061       * Mutator-time allocation
062       */
063    
064      /**
065       * {@inheritDoc}<p>
066       *
067       * This class handles the default allocator from the mark sweep space,
068       * and delegates everything else to the superclass.
069       */
070      @Override
071      @Inline
072      public Address alloc(int bytes, int align, int offset, int allocator, int site) {
073        if (allocator == MC.ALLOC_DEFAULT) {
074          return mc.alloc(bytes, align, offset);
075        }
076        return super.alloc(bytes, align, offset, allocator, site);
077      }
078    
079      /**
080       * {@inheritDoc}<p>
081       *
082       * Initialize the object header for objects in the mark-sweep space,
083       * and delegate to the superclass for other objects.
084       */
085      @Override
086      @Inline
087      public void postAlloc(ObjectReference ref, ObjectReference typeRef,
088          int bytes, int allocator) {
089        if (allocator == MC.ALLOC_DEFAULT)
090          MC.mcSpace.initializeHeader(ref);
091        else
092          super.postAlloc(ref, typeRef, bytes, allocator);
093      }
094    
095      @Override
096      public Allocator getAllocatorFromSpace(Space space) {
097        if (space == MC.mcSpace) return mc;
098        return super.getAllocatorFromSpace(space);
099      }
100    
101    
102      /****************************************************************************
103       *
104       * Collection
105       */
106    
107      /**
108       * {@inheritDoc}
109       */
110      @Override
111      @Inline
112      public final void collectionPhase(short phaseId, boolean primary) {
113        if (phaseId == MC.PREPARE) {
114          mc.prepare();
115          super.collectionPhase(phaseId, primary);
116          return;
117        }
118    
119        if (phaseId == MC.RELEASE) {
120          super.collectionPhase(phaseId, primary);
121          return;
122        }
123        super.collectionPhase(phaseId, primary);
124      }
125    
126      /**
127       * Flush the pages this mutator has allocated back to the global
128       * dirty page list, where the collectors can find them.
129       */
130      @Override
131      public void flush() {
132        super.flush();
133        mc.flush();
134      }
135    
136    
137    
138    }