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 protected ImmixTraceLocal fastTrace;
056 protected ImmixDefragTraceLocal defragTrace;
057 protected CollectorLocal immix;
058 protected final ImmixAllocator copy;
059 protected final BumpPointer immortal;
060 protected TraceLocal currentTrace;
061
062 /****************************************************************************
063 * Initialization
064 */
065
066 /**
067 * Constructor
068 */
069 public ImmixCollector() {
070 fastTrace = new ImmixTraceLocal(global().immixTrace, null);
071 defragTrace = new ImmixDefragTraceLocal(global().immixTrace, null);
072 immix = new CollectorLocal(Immix.immixSpace);
073 copy = new ImmixAllocator(Immix.immixSpace, true, true);
074 immortal = new ImmortalLocal(Plan.immortalSpace);
075 }
076
077 /****************************************************************************
078 *
079 * Collection-time allocation
080 */
081
082 /**
083 * Allocate space for copying an object (this method <i>does not</i>
084 * copy the object, it only allocates space)
085 *
086 * @param original A reference to the original object
087 * @param bytes The size of the space to be allocated (in bytes)
088 * @param align The requested alignment.
089 * @param offset The alignment offset.
090 * @return The address of the first byte of the allocated region
091 */
092 @Inline
093 public Address allocCopy(ObjectReference original, int bytes,
094 int align, int offset, int allocator) {
095 if (VM.VERIFY_ASSERTIONS) {
096 VM.assertions._assert(bytes <= Plan.MAX_NON_LOS_COPY_BYTES);
097 VM.assertions._assert(allocator == Immix.ALLOC_DEFAULT);
098 }
099 return copy.alloc(bytes, align, offset);
100 }
101
102 /**
103 * Perform any post-copy actions.
104 *
105 * @param object The newly allocated object
106 * @param typeRef the type reference for the instance being created
107 * @param bytes The size of the space to be allocated (in bytes)
108 */
109 @Inline
110 public void postCopy(ObjectReference object, ObjectReference typeRef,
111 int bytes, int allocator) {
112 if (VM.VERIFY_ASSERTIONS) VM.assertions._assert(allocator == Immix.ALLOC_DEFAULT);
113 Immix.immixSpace.postCopy(object, bytes, true);
114
115 if (VM.VERIFY_ASSERTIONS) {
116 VM.assertions._assert(getCurrentTrace().isLive(object));
117 VM.assertions._assert(getCurrentTrace().willNotMoveInCurrentCollection(object));
118 }
119 }
120
121 /****************************************************************************
122 *
123 * Collection
124 */
125
126 /**
127 * Perform a per-collector collection phase.
128 *
129 * @param phaseId The collection phase to perform
130 * @param primary Perform any single-threaded activities using this thread.
131 */
132 @Inline
133 public void collectionPhase(short phaseId, boolean primary) {
134
135 if (phaseId == Immix.PREPARE) {
136 super.collectionPhase(phaseId, primary);
137 currentTrace = Immix.immixSpace.inImmixDefragCollection() ? defragTrace : fastTrace;
138 immix.prepare(true);
139 currentTrace.prepare();
140 copy.reset();
141 return;
142 }
143
144 if (phaseId == Immix.CLOSURE) {
145 currentTrace.completeTrace();
146 return;
147 }
148
149 if (phaseId == Immix.RELEASE) {
150 currentTrace.release();
151 immix.release(true);
152 super.collectionPhase(phaseId, primary);
153 return;
154 }
155
156 super.collectionPhase(phaseId, primary);
157 }
158
159 /****************************************************************************
160 *
161 * Miscellaneous
162 */
163
164 /** @return The active global plan as an <code>Immix</code> instance. */
165 @Inline
166 private static Immix global() {
167 return (Immix) VM.activePlan.global();
168 }
169
170 /** @return The current fastTrace instance. */
171 @Inline
172 public final TraceLocal getCurrentTrace() {
173 return currentTrace;
174 }
175 }