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.semispace;
014
015 import org.mmtk.plan.*;
016 import org.mmtk.policy.CopyLocal;
017 import org.mmtk.policy.LargeObjectLocal;
018 import org.mmtk.policy.Space;
019 import org.mmtk.utility.ForwardingWord;
020 import org.mmtk.vm.VM;
021
022 import org.vmmagic.unboxed.*;
023 import org.vmmagic.pragma.*;
024
025 /**
026 * This class implements <i>per-collector thread</i> behavior
027 * and state for the <i>SS</i> plan, which implements a full-heap
028 * semi-space collector.<p>
029 *
030 * Specifically, this class defines <i>SS</i> collection behavior
031 * (through <code>trace</code> and the <code>collectionPhase</code>
032 * method), and collection-time allocation (copying of objects).<p>
033 *
034 * See {@link SS} for an overview of the semi-space algorithm.<p>
035 *
036 * @see SS
037 * @see SSMutator
038 * @see StopTheWorldCollector
039 * @see CollectorContext
040 */
041 @Uninterruptible
042 public class SSCollector extends StopTheWorldCollector {
043
044 /****************************************************************************
045 * Instance fields
046 */
047
048 /**
049 *
050 */
051 protected final SSTraceLocal trace;
052 protected final CopyLocal ss;
053 protected final LargeObjectLocal los;
054
055 /****************************************************************************
056 *
057 * Initialization
058 */
059
060 /**
061 * Constructor
062 */
063 public SSCollector() {
064 this(new SSTraceLocal(global().ssTrace));
065 }
066
067 /**
068 * Constructor
069 * @param tr The trace to use
070 */
071 protected SSCollector(SSTraceLocal tr) {
072 ss = new CopyLocal();
073 los = new LargeObjectLocal(Plan.loSpace);
074 trace = tr;
075 }
076
077 /****************************************************************************
078 *
079 * Collection-time allocation
080 */
081
082 /**
083 * {@inheritDoc}
084 */
085 @Override
086 @Inline
087 public Address allocCopy(ObjectReference original, int bytes,
088 int align, int offset, int allocator) {
089 if (allocator == Plan.ALLOC_LOS) {
090 if (VM.VERIFY_ASSERTIONS) VM.assertions._assert(bytes > Plan.MAX_NON_LOS_COPY_BYTES);
091 return los.alloc(bytes, align, offset);
092 } else {
093 if (VM.VERIFY_ASSERTIONS) {
094 VM.assertions._assert(bytes <= Plan.MAX_NON_LOS_COPY_BYTES);
095 VM.assertions._assert(allocator == SS.ALLOC_SS);
096 }
097 return ss.alloc(bytes, align, offset);
098 }
099 }
100
101 @Override
102 @Inline
103 public void postCopy(ObjectReference object, ObjectReference typeRef,
104 int bytes, int allocator) {
105 ForwardingWord.clearForwardingBits(object);
106 if (allocator == Plan.ALLOC_LOS)
107 Plan.loSpace.initializeHeader(object, false);
108 }
109
110 /****************************************************************************
111 *
112 * Collection
113 */
114
115 /**
116 * {@inheritDoc}
117 */
118 @Override
119 @Inline
120 public void collectionPhase(short phaseId, boolean primary) {
121 if (phaseId == SS.PREPARE) {
122 // rebind the copy bump pointer to the appropriate semispace.
123 ss.rebind(SS.toSpace());
124 los.prepare(true);
125 super.collectionPhase(phaseId, primary);
126 return;
127 }
128
129 if (phaseId == SS.CLOSURE) {
130 trace.completeTrace();
131 return;
132 }
133
134 if (phaseId == SS.RELEASE) {
135 trace.release();
136 los.release(true);
137 super.collectionPhase(phaseId, primary);
138 return;
139 }
140
141 super.collectionPhase(phaseId, primary);
142 }
143
144
145 /****************************************************************************
146 *
147 * Object processing and tracing
148 */
149
150 /**
151 * Return {@code true} if the given reference is to an object that is within
152 * one of the semi-spaces.
153 *
154 * @param object The object in question
155 * @return {@code true} if the given reference is to an object that is within
156 * one of the semi-spaces.
157 */
158 public static boolean isSemiSpaceObject(ObjectReference object) {
159 return Space.isInSpace(SS.SS0, object) || Space.isInSpace(SS.SS1, object);
160 }
161
162 /****************************************************************************
163 *
164 * Miscellaneous
165 */
166
167 /** @return The active global plan as an <code>SS</code> instance. */
168 @Inline
169 private static SS global() {
170 return (SS) VM.activePlan.global();
171 }
172
173 @Override
174 public TraceLocal getCurrentTrace() {
175 return trace;
176 }
177 }