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.generational.marksweep;
014
015 import org.mmtk.plan.Plan;
016 import org.mmtk.plan.TraceLocal;
017 import org.mmtk.plan.generational.*;
018 import org.mmtk.policy.MarkSweepLocal;
019 import org.mmtk.policy.Space;
020 import org.mmtk.utility.HeaderByte;
021 import org.mmtk.utility.alloc.Allocator;
022 import org.mmtk.utility.statistics.Stats;
023
024 import org.mmtk.vm.VM;
025
026 import org.vmmagic.pragma.*;
027 import org.vmmagic.unboxed.*;
028
029 /**
030 * This class implements <i>per-collector thread</i> behavior and state for
031 * the <code>GenMS</code> two-generational copying collector.<p>
032 *
033 * Specifically, this class defines semantics specific to the collection of
034 * the mature generation (<code>GenCollector</code> defines nursery semantics).
035 * In particular the mature space allocator is defined (for collection-time
036 * allocation into the mature space), and the mature space per-collector thread
037 * collection time semantics are defined.<p>
038 *
039 * @see GenMS for a description of the <code>GenMS</code> algorithm.
040 *
041 * @see GenMS
042 * @see GenMSMutator
043 * @see GenCollector
044 * @see org.mmtk.plan.StopTheWorldCollector
045 * @see org.mmtk.plan.CollectorContext
046 */
047 @Uninterruptible
048 public class GenMSCollector extends GenCollector {
049
050 /*****************************************************************************
051 *
052 * Instance fields
053 */
054
055 /** The allocator for the mature space */
056 private final MarkSweepLocal mature;
057 private final GenMSMatureTraceLocal matureTrace;
058
059 /**
060 * Constructor
061 */
062 public GenMSCollector() {
063 mature = new MarkSweepLocal(GenMS.msSpace);
064 matureTrace = new GenMSMatureTraceLocal(global().matureTrace, this);
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 * @param allocator The allocator to use.
080 * @return The address of the first byte of the allocated region
081 */
082 @Inline
083 @Override
084 public final Address allocCopy(ObjectReference original, int bytes,
085 int align, int offset, int allocator) {
086 if (Stats.GATHER_MARK_CONS_STATS) {
087 if (Space.isInSpace(GenMS.NURSERY, original)) GenMS.nurseryMark.inc(bytes);
088 }
089
090 if (allocator == Plan.ALLOC_LOS) {
091 if (VM.VERIFY_ASSERTIONS) VM.assertions._assert(Allocator.getMaximumAlignedSize(bytes, align) > Plan.MAX_NON_LOS_COPY_BYTES);
092 return los.alloc(bytes, align, offset);
093 } else {
094 if (VM.VERIFY_ASSERTIONS) {
095 VM.assertions._assert(bytes <= Plan.MAX_NON_LOS_COPY_BYTES);
096 VM.assertions._assert(allocator == GenMS.ALLOC_MATURE_MINORGC ||
097 allocator == GenMS.ALLOC_MATURE_MAJORGC);
098 }
099 return mature.alloc(bytes, align, offset);
100 }
101 }
102
103 /**
104 * Perform any post-copy actions.
105 *
106 * @param object The newly allocated object
107 * @param typeRef the type reference for the instance being created
108 * @param bytes The size of the space to be allocated (in bytes)
109 */
110 @Inline
111 @Override
112 public final void postCopy(ObjectReference object, ObjectReference typeRef,
113 int bytes, int allocator) {
114 if (allocator == Plan.ALLOC_LOS)
115 Plan.loSpace.initializeHeader(object, false);
116 else
117 GenMS.msSpace.postCopy(object, allocator == GenMS.ALLOC_MATURE_MAJORGC);
118 if (Gen.USE_OBJECT_BARRIER)
119 HeaderByte.markAsUnlogged(object);
120 }
121
122 /*****************************************************************************
123 *
124 * Collection
125 */
126
127 /**
128 * Perform a (local) collection phase.
129 *
130 * @param phaseId Collection phase to perform
131 * @param primary Is this thread to do the one-off thread-local tasks
132 */
133 @NoInline
134 public void collectionPhase(short phaseId, boolean primary) {
135 if (global().traceFullHeap()) {
136 if (phaseId == GenMS.PREPARE) {
137 super.collectionPhase(phaseId, primary);
138 matureTrace.prepare();
139 if (global().gcFullHeap) mature.prepare();
140 return;
141 }
142
143 if (phaseId == GenMS.CLOSURE) {
144 matureTrace.completeTrace();
145 return;
146 }
147
148 if (phaseId == GenMS.RELEASE) {
149 matureTrace.release();
150 if (global().gcFullHeap) {
151 mature.release();
152 }
153 super.collectionPhase(phaseId, primary);
154 return;
155 }
156 }
157
158 super.collectionPhase(phaseId, primary);
159 }
160
161 @Inline
162 public final TraceLocal getFullHeapTrace() {
163 return matureTrace;
164 }
165
166 /****************************************************************************
167 *
168 * Miscellaneous
169 */
170
171 /** @return The active global plan as a <code>GenMS</code> instance. */
172 @Inline
173 private static GenMS global() {
174 return (GenMS) VM.activePlan.global();
175 }
176 }