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 */
013package org.mmtk.plan.generational.marksweep;
014
015import org.mmtk.plan.generational.*;
016import org.mmtk.policy.MarkSweepLocal;
017import org.mmtk.policy.Space;
018import org.mmtk.utility.alloc.Allocator;
019
020import org.mmtk.vm.VM;
021
022import org.vmmagic.pragma.*;
023import 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
045public 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}