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       * {@inheritDoc}
079       */
080      @Override
081      @Inline
082      public final Address alloc(int bytes, int align, int offset, int allocator, int site) {
083        if (allocator == GenImmix.ALLOC_MATURE) {
084          if (VM.VERIFY_ASSERTIONS) VM.assertions._assert(false); // no pretenuring yet
085          return mature.alloc(bytes, align, offset);
086        }
087        return super.alloc(bytes, align, offset, allocator, site);
088      }
089    
090      @Override
091      @Inline
092      public final void postAlloc(ObjectReference ref, ObjectReference typeRef,
093          int bytes, int allocator) {
094        if (allocator == GenImmix.ALLOC_MATURE) {
095          if (VM.VERIFY_ASSERTIONS) VM.assertions._assert(false); // no pretenuring yet
096        } else {
097          super.postAlloc(ref, typeRef, bytes, allocator);
098        }
099      }
100    
101      @Override
102      public Allocator getAllocatorFromSpace(Space space) {
103        if (space == GenImmix.immixSpace) return mature;
104        return super.getAllocatorFromSpace(space);
105      }
106    
107      /*****************************************************************************
108       *
109       * Collection
110       */
111    
112      /**
113       * {@inheritDoc}
114       */
115      @Override
116      @NoInline
117      public void collectionPhase(short phaseId, boolean primary) {
118        if (global().traceFullHeap()) {
119          if (phaseId == GenImmix.PREPARE) {
120            super.collectionPhase(phaseId, primary);
121            if (global().gcFullHeap) mature.prepare();
122            return;
123          }
124    
125          if (phaseId == GenImmix.RELEASE) {
126            if (global().gcFullHeap) mature.release();
127            super.collectionPhase(phaseId, primary);
128            return;
129          }
130        }
131    
132        super.collectionPhase(phaseId, primary);
133      }
134    
135      /****************************************************************************
136       *
137       * Miscellaneous
138       */
139    
140      /** @return The active global plan as a <code>GenImmix</code> instance. */
141      @Inline
142      private static GenImmix global() {
143        return (GenImmix) VM.activePlan.global();
144      }
145    }