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.copyms;
014    
015    import org.mmtk.plan.StopTheWorldMutator;
016    import org.mmtk.policy.CopyLocal;
017    import org.mmtk.policy.MarkSweepLocal;
018    import org.mmtk.policy.Space;
019    
020    import org.mmtk.utility.alloc.Allocator;
021    
022    import org.vmmagic.pragma.*;
023    import org.vmmagic.unboxed.*;
024    
025    /**
026     * This class implements <i>per-mutator thread</i> behavior
027     * and state for the <i>CopyMS</i> plan.<p>
028     *
029     * Specifically, this class defines <i>CopyMS</i> mutator-time
030     * allocation into the nursery and mature space (through pre-tenuring).
031     * Per-mutator thread collection semantics are also defined (flushing
032     * and restoring per-mutator allocator state).
033     *
034     * @see CopyMS
035     * @see CopyMSCollector
036     * @see org.mmtk.plan.StopTheWorldMutator
037     * @see org.mmtk.plan.MutatorContext
038     */
039    @Uninterruptible
040    public class CopyMSMutator extends StopTheWorldMutator {
041    
042      /****************************************************************************
043       * Instance fields
044       */
045    
046      /**
047       *
048       */
049      private final MarkSweepLocal mature;
050      private final CopyLocal nursery;
051    
052      /****************************************************************************
053       *
054       * Initialization
055       */
056    
057      /**
058       * Constructor
059       */
060      public CopyMSMutator() {
061        mature = new MarkSweepLocal(CopyMS.msSpace);
062        nursery = new CopyLocal(CopyMS.nurserySpace);
063      }
064    
065      /****************************************************************************
066       *
067       * Mutator-time allocation
068       */
069    
070      /**
071       * {@inheritDoc}<p>
072       *
073       * This class handles the default allocator from the mark sweep space,
074       * and delegates everything else to the superclass.
075       */
076      @Override
077      @Inline
078      public Address alloc(int bytes, int align, int offset, int allocator, int site) {
079        if (allocator == CopyMS.ALLOC_DEFAULT)
080          return nursery.alloc(bytes, align, offset);
081        if (allocator == CopyMS.ALLOC_MS)
082          return mature.alloc(bytes, align, offset);
083    
084        return super.alloc(bytes, align, offset, allocator, site);
085      }
086    
087      /**
088       * {@inheritDoc}<p>
089       *
090       * Initialize the object header for objects in the mark-sweep space,
091       * and delegate to the superclass for other objects.
092       */
093      @Override
094      @SuppressWarnings({"UnnecessaryReturnStatement"})
095      @Inline
096      public void postAlloc(ObjectReference ref, ObjectReference typeRef,
097          int bytes, int allocator) {
098        if (allocator == CopyMS.ALLOC_DEFAULT)
099          return;
100        else if (allocator == CopyMS.ALLOC_MS)
101          CopyMS.msSpace.initializeHeader(ref, true);
102        else
103          super.postAlloc(ref, typeRef, bytes, allocator);
104      }
105    
106      @Override
107      public Allocator getAllocatorFromSpace(Space space) {
108        if (space == CopyMS.nurserySpace) return nursery;
109        if (space == CopyMS.msSpace) return mature;
110        return super.getAllocatorFromSpace(space);
111      }
112    
113      /****************************************************************************
114       *
115       * Collection
116       */
117    
118      /**
119       * {@inheritDoc}
120       */
121      @Override
122      @Inline
123      public final void collectionPhase(short phaseId, boolean primary) {
124        if (phaseId == CopyMS.PREPARE) {
125          super.collectionPhase(phaseId, primary);
126          mature.prepare();
127          return;
128        }
129    
130        if (phaseId == CopyMS.RELEASE) {
131          nursery.reset();
132          mature.release();
133          super.collectionPhase(phaseId, primary);
134          return;
135        }
136    
137        super.collectionPhase(phaseId, primary);
138      }
139    
140      @Override
141      public void flush() {
142        super.flush();
143        mature.flush();
144      }
145    }