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.generational.Gen;
016 import org.mmtk.plan.Trace;
017 import org.mmtk.plan.TransitiveClosure;
018 import org.mmtk.policy.immix.ImmixSpace;
019 import org.mmtk.policy.immix.ObjectHeader;
020 import org.mmtk.policy.Space;
021 import org.mmtk.utility.heap.VMRequest;
022
023 import org.vmmagic.pragma.*;
024 import org.vmmagic.unboxed.*;
025
026 /**
027 * This class implements the functionality of a two-generation copying
028 * collector where <b>the higher generation is an immix space</b>.
029 *
030 * Nursery collections occur when either the heap is full or the nursery
031 * is full. The nursery size is determined by an optional command line
032 * argument. If undefined, the nursery size is "infinite", so nursery
033 * collections only occur when the heap is full (this is known as a
034 * flexible-sized nursery collector). Thus both fixed and flexible
035 * nursery sizes are supported. Full heap collections occur when the
036 * nursery size has dropped to a statically defined threshold,
037 * <code>NURSERY_THRESHOLD</code><p>
038 *
039 * See the PLDI'08 paper by Blackburn and McKinley for a description
040 * of the algorithm: http://doi.acm.org/10.1145/1375581.1375586
041 *
042 * See the Jones & Lins GC book, chapter 7 for a detailed discussion
043 * of generational collection and section 7.3 for an overview of the
044 * flexible nursery behavior ("The Standard ML of New Jersey
045 * collector"), or go to Appel's paper "Simple generational garbage
046 * collection and fast allocation." SP&E 19(2):171--183, 1989.<p>
047 *
048 *
049 * For general comments about the global/local distinction among classes refer
050 * to Plan.java and PlanLocal.java.
051 */
052 @Uninterruptible
053 public class GenImmix extends Gen {
054
055 /*****************************************************************************
056 *
057 * Class fields
058 */
059
060 /** The mature space, which for GenImmix uses a mark sweep collection policy. */
061 public static final ImmixSpace immixSpace = new ImmixSpace("immix", DEFAULT_POLL_FREQUENCY, VMRequest.create());
062
063 public static final int IMMIX = immixSpace.getDescriptor();
064
065 public static final int SCAN_IMMIX = 1;
066 public static final int SCAN_DEFRAG = 2;
067
068 /****************************************************************************
069 *
070 * Instance fields
071 */
072 /* The trace class for a full-heap collection */
073 public final Trace matureTrace = new Trace(metaDataSpace);
074 private boolean lastGCWasDefrag = false;
075
076 /*****************************************************************************
077 *
078 * Collection
079 */
080
081 /**
082 * Perform a (global) collection phase.
083 */
084 @Inline
085 @Override
086 public final void collectionPhase(short phaseId) {
087 if (phaseId == SET_COLLECTION_KIND) {
088 super.collectionPhase(phaseId);
089 if (gcFullHeap)
090 immixSpace.decideWhetherToDefrag(emergencyCollection, true, collectionAttempt, collectionTrigger);
091 return;
092 }
093
094 if (traceFullHeap()) {
095 if (phaseId == PREPARE) {
096 super.collectionPhase(phaseId);
097 matureTrace.prepare();
098 immixSpace.prepare(true);
099 return;
100 }
101
102 if (phaseId == CLOSURE) {
103 matureTrace.prepare();
104 return;
105 }
106
107 if (phaseId == RELEASE) {
108 matureTrace.release();
109 lastGCWasDefrag = immixSpace.release(true);
110 super.collectionPhase(phaseId);
111 return;
112 }
113 } else
114 lastGCWasDefrag = false;
115
116 super.collectionPhase(phaseId);
117 }
118
119 /**
120 * @return Whether last GC was an exhaustive attempt to collect the heap. For many collectors this is the same as asking whether the last GC was a full heap collection.
121 */
122 @Override
123 public boolean lastCollectionWasExhaustive() {
124 return lastGCWasDefrag;
125 }
126
127 /*****************************************************************************
128 *
129 * Accounting
130 */
131
132 /**
133 * Return the number of pages reserved for use given the pending
134 * allocation.
135 *
136 * @return The number of pages reserved given the pending
137 * allocation, excluding space reserved for copying.
138 */
139 @Inline
140 @Override
141 public int getPagesUsed() {
142 return immixSpace.reservedPages() + super.getPagesUsed();
143 }
144
145 /**
146 * Return the number of pages available for allocation into the mature
147 * space.
148 *
149 * @return The number of pages available for allocation into the mature
150 * space.
151 */
152 public int getMaturePhysicalPagesAvail() {
153 return immixSpace.availablePhysicalPages();
154 }
155
156 /*****************************************************************************
157 *
158 * Miscellaneous
159 */
160
161 /**
162 * Accessor method to allow the generic generational code in Gen.java
163 * to access the mature space.
164 *
165 * @return The active mature space
166 */
167 @Inline
168 protected final Space activeMatureSpace() {
169 return immixSpace;
170 }
171
172 /**
173 * @see org.mmtk.plan.Plan#willNeverMove
174 *
175 * @param object Object in question
176 * @return true if the object will never move
177 */
178 @Override
179 public boolean willNeverMove(ObjectReference object) {
180 if (Space.isInSpace(IMMIX, object)) {
181 ObjectHeader.pinObject(object);
182 return true;
183 } else
184 return super.willNeverMove(object);
185 }
186
187 /**
188 * Register specialized methods.
189 */
190 @Interruptible
191 protected void registerSpecializedMethods() {
192 TransitiveClosure.registerSpecializedScan(SCAN_IMMIX, GenImmixMatureTraceLocal.class);
193 TransitiveClosure.registerSpecializedScan(SCAN_DEFRAG, GenImmixMatureDefragTraceLocal.class);
194 super.registerSpecializedMethods();
195 }
196 }