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.immix;
014
015import org.mmtk.plan.*;
016import org.mmtk.policy.Space;
017import org.mmtk.policy.immix.MutatorLocal;
018
019import org.mmtk.utility.alloc.Allocator;
020
021import org.vmmagic.pragma.*;
022import org.vmmagic.unboxed.*;
023
024/**
025 * This class implements <i>per-mutator thread</i> behavior
026 * and state for the <i>Immix</i> plan, which implements a full-heap
027 * immix collector.<p>
028 *
029 * Specifically, this class defines <i>Immix</i> mutator-time allocation
030 * and per-mutator thread collection semantics (flushing and restoring
031 * per-mutator allocator state).
032 *
033 * @see Immix
034 * @see org.mmtk.policy.immix.CollectorLocal
035 * @see StopTheWorldMutator
036 * @see MutatorContext
037 */
038@Uninterruptible
039public class ImmixMutator extends StopTheWorldMutator {
040
041  /****************************************************************************
042   * Instance fields
043   */
044  protected final MutatorLocal immix;
045
046  /****************************************************************************
047   *
048   * Initialization
049   */
050
051  /**
052   * Constructor
053   */
054  public ImmixMutator() {
055    immix = new org.mmtk.policy.immix.MutatorLocal(Immix.immixSpace, false);
056  }
057
058  /****************************************************************************
059   *
060   * MutatorLocal-time allocation
061   */
062
063  /**
064   * {@inheritDoc}<p>
065   *
066   * This class handles the default allocator from the mark sweep space,
067   * and delegates everything else to the superclass.
068   */
069  @Override
070  @Inline
071  public Address alloc(int bytes, int align, int offset, int allocator, int site) {
072    if (allocator == Immix.ALLOC_DEFAULT)
073      return immix.alloc(bytes, align, offset);
074    return super.alloc(bytes, align, offset, allocator, site);
075  }
076
077  /**
078   * {@inheritDoc}
079   *
080   * Initialize the object header for objects in the mark-sweep space,
081   * and delegate to the superclass for other objects.
082   */
083  @Override
084  @Inline
085  public void postAlloc(ObjectReference ref, ObjectReference typeRef,
086      int bytes, int allocator) {
087    if (allocator == Immix.ALLOC_DEFAULT)
088      Immix.immixSpace.postAlloc(ref, bytes);
089    else
090      super.postAlloc(ref, typeRef, bytes, allocator);
091  }
092
093  @Override
094  public Allocator getAllocatorFromSpace(Space space) {
095    if (space == Immix.immixSpace) return immix;  // FIXME is it not a problem that we have a 2:1 mapping?
096    return super.getAllocatorFromSpace(space);
097  }
098
099  /****************************************************************************
100   *
101   * Collection
102   */
103
104  /**
105   * {@inheritDoc}
106   */
107  @Override
108  @Inline
109  public void collectionPhase(short phaseId, boolean primary) {
110
111    if (phaseId == Immix.PREPARE) {
112      super.collectionPhase(phaseId, primary);
113      immix.prepare();
114      return;
115    }
116
117    if (phaseId == Immix.RELEASE) {
118      immix.release();
119      super.collectionPhase(phaseId, primary);
120      return;
121    }
122
123    super.collectionPhase(phaseId, primary);
124  }
125}