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       * Allocate memory for an object.
077       *
078       * @param bytes The number of bytes required for the object.
079       * @param align Required alignment for the object.
080       * @param offset Offset associated with the alignment.
081       * @param allocator The allocator associated with this request.
082       * @param site Allocation site
083       * @return The low address of the allocated memory.
084       */
085      @Inline
086      public final Address alloc(int bytes, int align, int offset, int allocator, int site) {
087        if (allocator == GenMS.ALLOC_MATURE) {
088          return mature.alloc(bytes, align, offset);
089        }
090        return super.alloc(bytes, align, offset, allocator, site);
091      }
092    
093      /**
094       * Perform post-allocation actions.  For many allocators none are
095       * required.
096       *
097       * @param ref The newly allocated object
098       * @param typeRef the type reference for the instance being created
099       * @param bytes The size of the space to be allocated (in bytes)
100       * @param allocator The allocator number to be used for this allocation
101       */
102      @Inline
103      public final void postAlloc(ObjectReference ref, ObjectReference typeRef,
104          int bytes, int allocator) {
105        if (allocator == GenMS.ALLOC_MATURE) {
106          GenMS.msSpace.initializeHeader(ref, true);
107        } else {
108          super.postAlloc(ref, typeRef, bytes, allocator);
109        }
110      }
111    
112      /**
113       * Return the allocator instance associated with a space
114       * <code>space</code>, for this plan instance.
115       *
116       * @param space The space for which the allocator instance is desired.
117       * @return The allocator instance associated with this plan instance
118       * which is allocating into <code>space</code>, or <code>null</code>
119       * if no appropriate allocator can be established.
120       */
121      public Allocator getAllocatorFromSpace(Space space) {
122        if (space == GenMS.msSpace) return mature;
123        return super.getAllocatorFromSpace(space);
124      }
125    
126      /*****************************************************************************
127       *
128       * Collection
129       */
130    
131      /**
132       * Perform a per-mutator collection phase.
133       *
134       * @param phaseId Collection phase to perform
135       * @param primary Is this thread to do the one-off thread-local tasks
136       */
137      @NoInline
138      public void collectionPhase(short phaseId, boolean primary) {
139        if (global().traceFullHeap()) {
140          if (phaseId == GenMS.PREPARE) {
141            super.collectionPhase(phaseId, primary);
142            if (global().gcFullHeap) mature.prepare();
143            return;
144          }
145    
146          if (phaseId == GenMS.RELEASE) {
147            if (global().gcFullHeap) mature.release();
148            super.collectionPhase(phaseId, primary);
149            return;
150          }
151        }
152    
153        super.collectionPhase(phaseId, primary);
154      }
155    
156      /**
157       * Flush mutator context, in response to a requestMutatorFlush.
158       * Also called by the default implementation of deinitMutator.
159       */
160      @Override
161      public void flush() {
162        super.flush();
163        mature.flush();
164      }
165    
166      /****************************************************************************
167       *
168       * Miscellaneous
169       */
170    
171      /** @return The active global plan as a <code>GenMS</code> instance. */
172      @Inline
173      private static GenMS global() {
174        return (GenMS) VM.activePlan.global();
175      }
176    }