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.markcompact;
014
015 import org.mmtk.plan.*;
016 import org.mmtk.policy.MarkCompactCollector;
017
018 import org.mmtk.vm.VM;
019
020 import org.vmmagic.pragma.*;
021 import org.vmmagic.unboxed.*;
022
023 /**
024 * This class implements <i>per-collector thread</i> behavior
025 * and state for the <i>MC</i> plan, which implements a full-heap
026 * mark-compact collector.<p>
027 *
028 * Specifically, this class defines <i>MC</i> collection behavior
029 * (through <code>trace</code> and the <code>collectionPhase</code>
030 * method), and collection-time allocation.<p>
031 *
032 * @see MC for an overview of the mark-compact algorithm.<p>
033 * @see MCMutator
034 * @see StopTheWorldCollector
035 * @see CollectorContext
036 */
037 @Uninterruptible public class MCCollector extends StopTheWorldCollector {
038
039 private static final boolean TRACE_MARK = false;
040 private static final boolean TRACE_FORWARD = true;
041
042 /****************************************************************************
043 * Instance fields
044 */
045
046 private final MCMarkTraceLocal markTrace;
047 private final MCForwardTraceLocal forwardTrace;
048 private final MarkCompactCollector mc;
049 private boolean currentTrace;
050
051 /****************************************************************************
052 *
053 * Initialization
054 */
055
056 /**
057 * Constructor
058 */
059 public MCCollector() {
060 markTrace = new MCMarkTraceLocal(global().markTrace);
061 forwardTrace = new MCForwardTraceLocal(global().forwardTrace);
062 mc = new MarkCompactCollector(MC.mcSpace);
063 }
064
065
066 /****************************************************************************
067 *
068 * Collection-time allocation
069 */
070
071 /**
072 * Allocate space for copying an object (this method <i>does not</i>
073 * copy the object, it only allocates space)
074 *
075 * @param original A reference to the original object
076 * @param bytes The size of the space to be allocated (in bytes)
077 * @param align The requested alignment.
078 * @param offset The alignment offset.
079 * @return The address of the first byte of the allocated region
080 */
081 @Override
082 @Inline
083 public Address allocCopy(ObjectReference original, int bytes,
084 int align, int offset, int allocator) {
085 if (VM.VERIFY_ASSERTIONS) VM.assertions._assert(allocator == MC.ALLOC_IMMORTAL);
086
087 return immortal.alloc(bytes, align, offset);
088 }
089
090 /**
091 * Perform any post-copy actions.
092 *
093 * @param object The newly allocated object
094 * @param typeRef the type reference for the instance being created
095 * @param bytes The size of the space to be allocated (in bytes)
096 */
097 @Override
098 @Inline
099 public void postCopy(ObjectReference object, ObjectReference typeRef,
100 int bytes, int allocator) {
101 MC.immortalSpace.initializeHeader(object);
102 }
103
104 /****************************************************************************
105 *
106 * Collection
107 */
108
109 /**
110 * Perform a per-collector collection phase.
111 *
112 * @param phaseId The collection phase to perform
113 * @param primary Perform any single-threaded activities using this thread.
114 */
115 @Override
116 @Inline
117 public final void collectionPhase(short phaseId, boolean primary) {
118 if (phaseId == MC.PREPARE) {
119 currentTrace = TRACE_MARK;
120 super.collectionPhase(phaseId, primary);
121 markTrace.prepare();
122 return;
123 }
124
125 if (phaseId == MC.CLOSURE) {
126 markTrace.completeTrace();
127 return;
128 }
129
130 if (phaseId == MC.CALCULATE_FP) {
131 mc.calculateForwardingPointers();
132 return;
133 }
134
135 if (phaseId == MC.COMPACT) {
136 mc.compact();
137 return;
138 }
139
140 if (phaseId == MC.RELEASE) {
141 markTrace.release();
142 super.collectionPhase(phaseId, primary);
143 return;
144 }
145
146 if (phaseId == MC.PREPARE_FORWARD) {
147 currentTrace = TRACE_FORWARD;
148 super.collectionPhase(MC.PREPARE, primary);
149 forwardTrace.prepare();
150 return;
151 }
152
153 if (phaseId == MC.FORWARD_CLOSURE) {
154 forwardTrace.completeTrace();
155 return;
156 }
157
158 if (phaseId == MC.RELEASE_FORWARD) {
159 forwardTrace.release();
160 super.collectionPhase(MC.RELEASE, primary);
161 return;
162 }
163
164 super.collectionPhase(phaseId, primary);
165 }
166
167 /****************************************************************************
168 *
169 * Miscellaneous
170 */
171
172 /** @return The current trace instance. */
173 @Override
174 public final TraceLocal getCurrentTrace() {
175 if (currentTrace == TRACE_MARK) {
176 return markTrace;
177 }
178 return forwardTrace;
179 }
180
181 /** @return The active global plan as an <code>MC</code> instance. */
182 @Inline
183 private static MC global() {
184 return (MC) VM.activePlan.global();
185 }
186 }