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.ImmortalLocal;
017 import org.mmtk.policy.immix.CollectorLocal;
018 import org.mmtk.utility.alloc.BumpPointer;
019 import org.mmtk.utility.alloc.ImmixAllocator;
020 import org.mmtk.vm.VM;
021
022 import org.vmmagic.pragma.*;
023 import org.vmmagic.unboxed.Address;
024 import org.vmmagic.unboxed.ObjectReference;
025
026 /**
027 * This class implements <i>per-collector thread</i> behavior
028 * and state for the <i>Immix</i> plan, which implements a full-heap
029 * immix collector.<p>
030 *
031 * Specifically, this class defines <i>Immix</i> collection behavior
032 * (through <code>fastTrace</code> and the <code>collectionPhase</code>
033 * method).<p>
034 *
035 * @see Immix for an overview of the immix algorithm.<p>
036 *
037 * FIXME The SegregatedFreeList class (and its decendents such as
038 * MarkSweepLocal) does not properly separate mutator and collector
039 * behaviors, so the immix field below should really not exist in
040 * this class as there is no collection-time allocation in this
041 * collector.
042 *
043 * @see Immix
044 * @see org.mmtk.policy.immix.MutatorLocal
045 * @see StopTheWorldCollector
046 * @see CollectorContext
047 * @see Phase
048 */
049 @Uninterruptible
050 public class ImmixCollector extends StopTheWorldCollector {
051
052 /****************************************************************************
053 * Instance fields
054 */
055
056 /**
057 *
058 */
059 protected ImmixTraceLocal fastTrace;
060 protected ImmixDefragTraceLocal defragTrace;
061 protected CollectorLocal immix;
062 protected final ImmixAllocator copy;
063 protected final BumpPointer immortal;
064 protected TraceLocal currentTrace;
065
066 /****************************************************************************
067 * Initialization
068 */
069
070 /**
071 * Constructor
072 */
073 public ImmixCollector() {
074 fastTrace = new ImmixTraceLocal(global().immixTrace, null);
075 defragTrace = new ImmixDefragTraceLocal(global().immixTrace, null);
076 immix = new CollectorLocal(Immix.immixSpace);
077 copy = new ImmixAllocator(Immix.immixSpace, true, true);
078 immortal = new ImmortalLocal(Plan.immortalSpace);
079 }
080
081 /****************************************************************************
082 *
083 * Collection-time allocation
084 */
085
086 /**
087 * {@inheritDoc}
088 */
089 @Override
090 @Inline
091 public Address allocCopy(ObjectReference original, int bytes,
092 int align, int offset, int allocator) {
093 if (VM.VERIFY_ASSERTIONS) {
094 VM.assertions._assert(bytes <= Plan.MAX_NON_LOS_COPY_BYTES);
095 VM.assertions._assert(allocator == Immix.ALLOC_DEFAULT);
096 }
097 return copy.alloc(bytes, align, offset);
098 }
099
100 @Override
101 @Inline
102 public void postCopy(ObjectReference object, ObjectReference typeRef,
103 int bytes, int allocator) {
104 if (VM.VERIFY_ASSERTIONS) VM.assertions._assert(allocator == Immix.ALLOC_DEFAULT);
105 Immix.immixSpace.postCopy(object, bytes, true);
106
107 if (VM.VERIFY_ASSERTIONS) {
108 VM.assertions._assert(getCurrentTrace().isLive(object));
109 VM.assertions._assert(getCurrentTrace().willNotMoveInCurrentCollection(object));
110 }
111 }
112
113 /****************************************************************************
114 *
115 * Collection
116 */
117
118 /**
119 * {@inheritDoc}
120 */
121 @Override
122 @Inline
123 public void collectionPhase(short phaseId, boolean primary) {
124
125 if (phaseId == Immix.PREPARE) {
126 super.collectionPhase(phaseId, primary);
127 currentTrace = Immix.immixSpace.inImmixDefragCollection() ? defragTrace : fastTrace;
128 immix.prepare(true);
129 currentTrace.prepare();
130 copy.reset();
131 return;
132 }
133
134 if (phaseId == Immix.CLOSURE) {
135 currentTrace.completeTrace();
136 return;
137 }
138
139 if (phaseId == Immix.RELEASE) {
140 currentTrace.release();
141 immix.release(true);
142 super.collectionPhase(phaseId, primary);
143 return;
144 }
145
146 super.collectionPhase(phaseId, primary);
147 }
148
149 /****************************************************************************
150 *
151 * Miscellaneous
152 */
153
154 /** @return The active global plan as an <code>Immix</code> instance. */
155 @Inline
156 private static Immix global() {
157 return (Immix) VM.activePlan.global();
158 }
159
160 /** @return The current fastTrace instance. */
161 @Override
162 @Inline
163 public final TraceLocal getCurrentTrace() {
164 return currentTrace;
165 }
166 }