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.generational.marksweep;
014    
015    import org.mmtk.plan.generational.*;
016    import org.mmtk.policy.MarkSweepLocal;
017    import org.mmtk.policy.Space;
018    import org.mmtk.utility.alloc.Allocator;
019    
020    import org.mmtk.vm.VM;
021    
022    import org.vmmagic.pragma.*;
023    import org.vmmagic.unboxed.*;
024    
025    /**
026     * This class implements <i>per-mutator thread</i> behavior and state for
027     * the <code>GenMS</code> two-generational copying collector.<p>
028     *
029     * Specifically, this class defines mutator-time semantics specific to the
030     * mature generation (<code>GenMutator</code> defines nursery semantics).
031     * In particular the mature space allocator is defined (for mutator-time
032     * allocation into the mature space via pre-tenuring), and the mature space
033     * per-mutator thread collection time semantics are defined (rebinding
034     * the mature space allocator).<p>
035     *
036     * See {@link GenMS} for a description of the <code>GenMS</code> algorithm.
037     *
038     * @see GenMS
039     * @see GenMSCollector
040     * @see GenMutator
041     * @see org.mmtk.plan.StopTheWorldMutator
042     * @see org.mmtk.plan.MutatorContext
043     */
044    @Uninterruptible
045    public class GenMSMutator extends GenMutator {
046      /******************************************************************
047       * Instance fields
048       */
049    
050      /**
051       * The allocator for the mark-sweep mature space (the mutator may
052       * "pretenure" objects into this space which is otherwise used
053       * only by the collector)
054       */
055      private final MarkSweepLocal mature;
056    
057    
058      /****************************************************************************
059       *
060       * Initialization
061       */
062    
063      /**
064       * Constructor
065       */
066      public GenMSMutator() {
067        mature = new MarkSweepLocal(GenMS.msSpace);
068      }
069    
070      /****************************************************************************
071       *
072       * Mutator-time allocation
073       */
074    
075      /**
076       * {@inheritDoc}
077       */
078      @Override
079      @Inline
080      public final Address alloc(int bytes, int align, int offset, int allocator, int site) {
081        if (allocator == GenMS.ALLOC_MATURE) {
082          return mature.alloc(bytes, align, offset);
083        }
084        return super.alloc(bytes, align, offset, allocator, site);
085      }
086    
087      @Override
088      @Inline
089      public final void postAlloc(ObjectReference ref, ObjectReference typeRef,
090          int bytes, int allocator) {
091        if (allocator == GenMS.ALLOC_MATURE) {
092          GenMS.msSpace.initializeHeader(ref, true);
093        } else {
094          super.postAlloc(ref, typeRef, bytes, allocator);
095        }
096      }
097    
098      @Override
099      public Allocator getAllocatorFromSpace(Space space) {
100        if (space == GenMS.msSpace) return mature;
101        return super.getAllocatorFromSpace(space);
102      }
103    
104      /*****************************************************************************
105       *
106       * Collection
107       */
108    
109      /**
110       * {@inheritDoc}
111       */
112      @Override
113      @NoInline
114      public void collectionPhase(short phaseId, boolean primary) {
115        if (global().traceFullHeap()) {
116          if (phaseId == GenMS.PREPARE) {
117            super.collectionPhase(phaseId, primary);
118            if (global().gcFullHeap) mature.prepare();
119            return;
120          }
121    
122          if (phaseId == GenMS.RELEASE) {
123            if (global().gcFullHeap) mature.release();
124            super.collectionPhase(phaseId, primary);
125            return;
126          }
127        }
128    
129        super.collectionPhase(phaseId, primary);
130      }
131    
132      @Override
133      public void flush() {
134        super.flush();
135        mature.flush();
136      }
137    
138      /****************************************************************************
139       *
140       * Miscellaneous
141       */
142    
143      /** @return The active global plan as a <code>GenMS</code> instance. */
144      @Inline
145      private static GenMS global() {
146        return (GenMS) VM.activePlan.global();
147      }
148    }