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.immix;
014
015 import org.mmtk.plan.*;
016 import org.mmtk.policy.Space;
017 import org.mmtk.policy.immix.MutatorLocal;
018
019 import org.mmtk.utility.alloc.Allocator;
020
021 import org.vmmagic.pragma.*;
022 import 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).<p>
032 *
033 * @see Immix
034 * @see org.mmtk.policy.immix.CollectorLocal
035 * @see StopTheWorldMutator
036 * @see MutatorContext
037 */
038 @Uninterruptible
039 public 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 }