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
055 /**
056 *
057 */
058 private final GenImmixMatureTraceLocal matureTrace = new GenImmixMatureTraceLocal(global().matureTrace, this);
059 private final GenImmixMatureDefragTraceLocal defragTrace = new GenImmixMatureDefragTraceLocal(global().matureTrace, this);
060
061 private final org.mmtk.policy.immix.CollectorLocal immix = new org.mmtk.policy.immix.CollectorLocal(GenImmix.immixSpace);
062
063 private final ImmixAllocator copy = new ImmixAllocator(GenImmix.immixSpace, true, false);
064 private final ImmixAllocator defragCopy = new ImmixAllocator(GenImmix.immixSpace, true, true);
065
066 /****************************************************************************
067 *
068 * Collection-time allocation
069 */
070
071 /**
072 * {@inheritDoc}
073 */
074 @Override
075 @Inline
076 public final Address allocCopy(ObjectReference original, int bytes,
077 int align, int offset, int allocator) {
078
079 if (Stats.GATHER_MARK_CONS_STATS) {
080 if (Space.isInSpace(GenImmix.NURSERY, original)) GenImmix.nurseryMark.inc(bytes);
081 }
082 if (allocator == Plan.ALLOC_LOS) {
083 if (VM.VERIFY_ASSERTIONS) VM.assertions._assert(Allocator.getMaximumAlignedSize(bytes, align) > Plan.MAX_NON_LOS_COPY_BYTES);
084 return los.alloc(bytes, align, offset);
085 } else {
086 if (VM.VERIFY_ASSERTIONS) {
087 VM.assertions._assert(bytes <= Plan.MAX_NON_LOS_COPY_BYTES);
088 if (GenImmix.immixSpace.inImmixCollection())
089 VM.assertions._assert(allocator == GenImmix.ALLOC_MATURE_MAJORGC);
090 else
091 VM.assertions._assert(allocator == GenImmix.ALLOC_MATURE_MINORGC);
092 }
093 if (GenImmix.immixSpace.inImmixDefragCollection()) {
094 return defragCopy.alloc(bytes, align, offset);
095 } else
096 return copy.alloc(bytes, align, offset);
097 }
098 }
099
100 @Override
101 @Inline
102 public final void postCopy(ObjectReference object, ObjectReference typeRef,
103 int bytes, int allocator) {
104 if (allocator == Plan.ALLOC_LOS)
105 Plan.loSpace.initializeHeader(object, false);
106 else {
107 if (VM.VERIFY_ASSERTIONS) {
108 VM.assertions._assert((!GenImmix.immixSpace.inImmixCollection() && allocator == GenImmix.ALLOC_MATURE_MINORGC) ||
109 (GenImmix.immixSpace.inImmixCollection() && allocator == GenImmix.ALLOC_MATURE_MAJORGC));
110 }
111 GenImmix.immixSpace.postCopy(object, bytes, allocator == GenImmix.ALLOC_MATURE_MAJORGC);
112 }
113 if (Gen.USE_OBJECT_BARRIER)
114 HeaderByte.markAsUnlogged(object);
115 }
116
117 /*****************************************************************************
118 *
119 * Collection
120 */
121
122 /**
123 * {@inheritDoc}
124 */
125 @Override
126 @Inline
127 public void collectionPhase(short phaseId, boolean primary) {
128 TraceLocal trace = GenImmix.immixSpace.inImmixDefragCollection() ? defragTrace : matureTrace;
129
130 if (global().traceFullHeap()) {
131 if (phaseId == GenImmix.PREPARE) {
132 super.collectionPhase(phaseId, primary);
133 trace.prepare();
134 copy.reset();
135 if (global().gcFullHeap) {
136 immix.prepare(true);
137 defragCopy.reset();
138 }
139 return;
140 }
141
142 if (phaseId == GenImmix.CLOSURE) {
143 trace.completeTrace();
144 return;
145 }
146
147 if (phaseId == GenImmix.RELEASE) {
148 trace.release();
149 if (global().gcFullHeap) {
150 immix.release(true);
151 copy.reset();
152 }
153 super.collectionPhase(phaseId, primary);
154 return;
155 }
156 }
157
158 super.collectionPhase(phaseId, primary);
159 }
160
161 @Override
162 @Inline
163 public final TraceLocal getFullHeapTrace() {
164 return GenImmix.immixSpace.inImmixDefragCollection() ? defragTrace : matureTrace;
165 }
166
167 /****************************************************************************
168 *
169 * Miscellaneous
170 */
171
172 /** @return The active global plan as a <code>GenImmix</code> instance. */
173 @Inline
174 private static GenImmix global() {
175 return (GenImmix) VM.activePlan.global();
176 }
177 }