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.immix;
014    
015    import org.mmtk.plan.generational.*;
016    import org.mmtk.policy.Space;
017    import org.mmtk.policy.immix.MutatorLocal;
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>GenImmix</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 GenImmix} for a description of the <code>GenImmix</code> algorithm.
037     *
038     * @see GenImmix
039     * @see GenImmixCollector
040     * @see org.mmtk.plan.generational.GenMutator
041     * @see org.mmtk.plan.StopTheWorldMutator
042     * @see org.mmtk.plan.MutatorContext
043     * @see org.mmtk.plan.Phase
044     */
045    @Uninterruptible
046    public class GenImmixMutator extends GenMutator {
047    
048      /******************************************************************
049       * Instance fields
050       */
051    
052      /**
053       * The allocator for the mark-sweep mature space (the mutator may
054       * "pretenure" objects into this space which is otherwise used
055       * only by the collector)
056       */
057      private final MutatorLocal mature;
058    
059    
060      /****************************************************************************
061       *
062       * Initialization
063       */
064    
065      /**
066       * Constructor
067       */
068      public GenImmixMutator() {
069        mature = new MutatorLocal(GenImmix.immixSpace, false);
070      }
071    
072      /****************************************************************************
073       *
074       * Mutator-time allocation
075       */
076    
077      /**
078       * Allocate memory for an object.
079       *
080       * @param bytes The number of bytes required for the object.
081       * @param align Required alignment for the object.
082       * @param offset Offset associated with the alignment.
083       * @param allocator The allocator associated with this request.
084       * @param site Allocation site
085       * @return The low address of the allocated memory.
086       */
087      @Inline
088      public final Address alloc(int bytes, int align, int offset, int allocator, int site) {
089        if (allocator == GenImmix.ALLOC_MATURE) {
090          if (VM.VERIFY_ASSERTIONS) VM.assertions._assert(false); // no pretenuring yet
091          return mature.alloc(bytes, align, offset);
092        }
093        return super.alloc(bytes, align, offset, allocator, site);
094      }
095    
096      /**
097       * Perform post-allocation actions.  For many allocators none are
098       * required.
099       *
100       * @param ref The newly allocated object
101       * @param typeRef the type reference for the instance being created
102       * @param bytes The size of the space to be allocated (in bytes)
103       * @param allocator The allocator number to be used for this allocation
104       */
105      @Inline
106      public final void postAlloc(ObjectReference ref, ObjectReference typeRef,
107          int bytes, int allocator) {
108        if (allocator == GenImmix.ALLOC_MATURE) {
109          if (VM.VERIFY_ASSERTIONS) VM.assertions._assert(false); // no pretenuring yet
110        } else {
111          super.postAlloc(ref, typeRef, bytes, allocator);
112        }
113      }
114    
115      /**
116       * Return the allocator instance associated with a space
117       * <code>space</code>, for this plan instance.
118       *
119       * @param space The space for which the allocator instance is desired.
120       * @return The allocator instance associated with this plan instance
121       * which is allocating into <code>space</code>, or <code>null</code>
122       * if no appropriate allocator can be established.
123       */
124      public Allocator getAllocatorFromSpace(Space space) {
125        if (space == GenImmix.immixSpace) return mature;
126        return super.getAllocatorFromSpace(space);
127      }
128    
129      /*****************************************************************************
130       *
131       * Collection
132       */
133    
134      /**
135       * Perform a per-mutator collection phase.
136       *
137       * @param phaseId Collection phase to perform
138       * @param primary Is this thread to do the one-off thread-local tasks
139       */
140      @NoInline
141      public void collectionPhase(short phaseId, boolean primary) {
142        if (global().traceFullHeap()) {
143          if (phaseId == GenImmix.PREPARE) {
144            super.collectionPhase(phaseId, primary);
145            if (global().gcFullHeap) mature.prepare();
146            return;
147          }
148    
149          if (phaseId == GenImmix.RELEASE) {
150            if (global().gcFullHeap) mature.release();
151            super.collectionPhase(phaseId, primary);
152            return;
153          }
154        }
155    
156        super.collectionPhase(phaseId, primary);
157      }
158    
159      /****************************************************************************
160       *
161       * Miscellaneous
162       */
163    
164      /** @return The active global plan as a <code>GenImmix</code> instance. */
165      @Inline
166      private static GenImmix global() {
167        return (GenImmix) VM.activePlan.global();
168      }
169    }