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 * {@inheritDoc}
073 */
074 @Inline
075 @Override
076 public final Address allocCopy(ObjectReference original, int bytes,
077 int align, int offset, int allocator) {
078 if (Stats.GATHER_MARK_CONS_STATS) {
079 if (Space.isInSpace(GenMS.NURSERY, original)) GenMS.nurseryMark.inc(bytes);
080 }
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 VM.assertions._assert(allocator == GenMS.ALLOC_MATURE_MINORGC ||
089 allocator == GenMS.ALLOC_MATURE_MAJORGC);
090 }
091 return mature.alloc(bytes, align, offset);
092 }
093 }
094
095 @Inline
096 @Override
097 public final void postCopy(ObjectReference object, ObjectReference typeRef,
098 int bytes, int allocator) {
099 if (allocator == Plan.ALLOC_LOS)
100 Plan.loSpace.initializeHeader(object, false);
101 else
102 GenMS.msSpace.postCopy(object, allocator == GenMS.ALLOC_MATURE_MAJORGC);
103 if (Gen.USE_OBJECT_BARRIER)
104 HeaderByte.markAsUnlogged(object);
105 }
106
107 /*****************************************************************************
108 *
109 * Collection
110 */
111
112 /**
113 * {@inheritDoc}
114 */
115 @Override
116 @NoInline
117 public void collectionPhase(short phaseId, boolean primary) {
118 if (global().traceFullHeap()) {
119 if (phaseId == GenMS.PREPARE) {
120 super.collectionPhase(phaseId, primary);
121 matureTrace.prepare();
122 if (global().gcFullHeap) mature.prepare();
123 return;
124 }
125
126 if (phaseId == GenMS.CLOSURE) {
127 matureTrace.completeTrace();
128 return;
129 }
130
131 if (phaseId == GenMS.RELEASE) {
132 matureTrace.release();
133 if (global().gcFullHeap) {
134 mature.release();
135 }
136 super.collectionPhase(phaseId, primary);
137 return;
138 }
139 }
140
141 super.collectionPhase(phaseId, primary);
142 }
143
144 @Override
145 @Inline
146 public final TraceLocal getFullHeapTrace() {
147 return matureTrace;
148 }
149
150 /****************************************************************************
151 *
152 * Miscellaneous
153 */
154
155 /** @return The active global plan as a <code>GenMS</code> instance. */
156 @Inline
157 private static GenMS global() {
158 return (GenMS) VM.activePlan.global();
159 }
160 }