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.immix;
014
015 import org.mmtk.plan.Plan;
016 import org.mmtk.plan.TraceLocal;
017 import org.mmtk.plan.generational.*;
018 import org.mmtk.policy.Space;
019 import org.mmtk.utility.HeaderByte;
020 import org.mmtk.utility.alloc.Allocator;
021 import org.mmtk.utility.alloc.ImmixAllocator;
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>GenImmix</code> two-generational copying collector.<p>
032 *
033 * Specifically, this class defines semantics specific to the collection of
034 * the copy generation (<code>GenCollector</code> defines nursery semantics).
035 * In particular the copy space allocator is defined (for collection-time
036 * allocation into the copy space), and the copy space per-collector thread
037 * collection time semantics are defined.<p>
038 *
039 * @see GenImmix for a description of the <code>GenImmix</code> algorithm.
040 *
041 * @see GenImmix
042 * @see GenImmixMutator
043 * @see GenCollector
044 * @see org.mmtk.plan.StopTheWorldCollector
045 * @see org.mmtk.plan.CollectorContext
046 */
047 @Uninterruptible
048 public class GenImmixCollector extends GenCollector {
049
050 /*****************************************************************************
051 *
052 * Instance fields
053 */
054 private final GenImmixMatureTraceLocal matureTrace = new GenImmixMatureTraceLocal(global().matureTrace, this);
055 private final GenImmixMatureDefragTraceLocal defragTrace = new GenImmixMatureDefragTraceLocal(global().matureTrace, this);
056
057 private final org.mmtk.policy.immix.CollectorLocal immix = new org.mmtk.policy.immix.CollectorLocal(GenImmix.immixSpace);
058
059 private final ImmixAllocator copy = new ImmixAllocator(GenImmix.immixSpace, true, false);
060 private final ImmixAllocator defragCopy = new ImmixAllocator(GenImmix.immixSpace, true, true);
061
062 /****************************************************************************
063 *
064 * Collection-time allocation
065 */
066
067 /**
068 * Allocate space for copying an object (this method <i>does not</i>
069 * copy the object, it only allocates space)
070 *
071 * @param original A reference to the original object
072 * @param bytes The size of the space to be allocated (in bytes)
073 * @param align The requested alignment.
074 * @param offset The alignment offset.
075 * @param allocator The allocator to use.
076 * @return The address of the first byte of the allocated region
077 */
078 @Inline
079 public final Address allocCopy(ObjectReference original, int bytes,
080 int align, int offset, int allocator) {
081
082 if (Stats.GATHER_MARK_CONS_STATS) {
083 if (Space.isInSpace(GenImmix.NURSERY, original)) GenImmix.nurseryMark.inc(bytes);
084 }
085 if (allocator == Plan.ALLOC_LOS) {
086 if (VM.VERIFY_ASSERTIONS) VM.assertions._assert(Allocator.getMaximumAlignedSize(bytes, align) > Plan.MAX_NON_LOS_COPY_BYTES);
087 return los.alloc(bytes, align, offset);
088 } else {
089 if (VM.VERIFY_ASSERTIONS) {
090 VM.assertions._assert(bytes <= Plan.MAX_NON_LOS_COPY_BYTES);
091 if (GenImmix.immixSpace.inImmixCollection())
092 VM.assertions._assert(allocator == GenImmix.ALLOC_MATURE_MAJORGC);
093 else
094 VM.assertions._assert(allocator == GenImmix.ALLOC_MATURE_MINORGC);
095 }
096 if (GenImmix.immixSpace.inImmixDefragCollection()) {
097 return defragCopy.alloc(bytes, align, offset);
098 } else
099 return copy.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 public final void postCopy(ObjectReference object, ObjectReference typeRef,
112 int bytes, int allocator) {
113 if (allocator == Plan.ALLOC_LOS)
114 Plan.loSpace.initializeHeader(object, false);
115 else {
116 if (VM.VERIFY_ASSERTIONS) {
117 VM.assertions._assert((!GenImmix.immixSpace.inImmixCollection() && allocator == GenImmix.ALLOC_MATURE_MINORGC) ||
118 (GenImmix.immixSpace.inImmixCollection() && allocator == GenImmix.ALLOC_MATURE_MAJORGC));
119 }
120 GenImmix.immixSpace.postCopy(object, bytes, allocator == GenImmix.ALLOC_MATURE_MAJORGC);
121 }
122 if (Gen.USE_OBJECT_BARRIER)
123 HeaderByte.markAsUnlogged(object);
124 }
125
126 /*****************************************************************************
127 *
128 * Collection
129 */
130
131 /**
132 * Perform a (local) collection phase.
133 *
134 * @param phaseId Collection phase to perform
135 * @param primary Is this thread to do the one-off thread-local tasks
136 */
137 @NoInline
138 public void collectionPhase(short phaseId, boolean primary) {
139 TraceLocal trace = GenImmix.immixSpace.inImmixDefragCollection() ? defragTrace : matureTrace;
140
141 if (global().traceFullHeap()) {
142 if (phaseId == GenImmix.PREPARE) {
143 super.collectionPhase(phaseId, primary);
144 trace.prepare();
145 copy.reset();
146 if (global().gcFullHeap) {
147 immix.prepare(true);
148 defragCopy.reset();
149 }
150 return;
151 }
152
153 if (phaseId == GenImmix.CLOSURE) {
154 trace.completeTrace();
155 return;
156 }
157
158 if (phaseId == GenImmix.RELEASE) {
159 trace.release();
160 if (global().gcFullHeap) {
161 immix.release(true);
162 copy.reset();
163 }
164 super.collectionPhase(phaseId, primary);
165 return;
166 }
167 }
168
169 super.collectionPhase(phaseId, primary);
170 }
171
172 @Inline
173 public final TraceLocal getFullHeapTrace() {
174 return GenImmix.immixSpace.inImmixDefragCollection() ? defragTrace : matureTrace;
175 }
176
177 /****************************************************************************
178 *
179 * Miscellaneous
180 */
181
182 /** @return The active global plan as a <code>GenImmix</code> instance. */
183 @Inline
184 private static GenImmix global() {
185 return (GenImmix) VM.activePlan.global();
186 }
187 }