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<p>
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", false, VMRequest.create());
062
063 public static final int IMMIX = immixSpace.getDescriptor();
064
065 /** Specialized scanning method identifier */
066 public static final int SCAN_IMMIX = 1;
067
068 /****************************************************************************
069 *
070 * Instance fields
071 */
072
073 /** The trace class for a full-heap collection */
074 public final Trace matureTrace = new Trace(metaDataSpace);
075 private boolean lastGCWasDefrag = false;
076
077 /*****************************************************************************
078 *
079 * Collection
080 */
081
082 /**
083 * {@inheritDoc}
084 */
085 @Inline
086 @Override
087 public final void collectionPhase(short phaseId) {
088 if (phaseId == SET_COLLECTION_KIND) {
089 super.collectionPhase(phaseId);
090 if (gcFullHeap) {
091 immixSpace.decideWhetherToDefrag(emergencyCollection, true, collectionAttempt, userTriggeredCollection);
092 }
093 return;
094 }
095
096 if (traceFullHeap()) {
097 if (phaseId == PREPARE) {
098 super.collectionPhase(phaseId);
099 matureTrace.prepare();
100 immixSpace.prepare(true);
101 return;
102 }
103
104 if (phaseId == CLOSURE) {
105 matureTrace.prepare();
106 return;
107 }
108
109 if (phaseId == RELEASE) {
110 matureTrace.release();
111 lastGCWasDefrag = immixSpace.release(true);
112 super.collectionPhase(phaseId);
113 return;
114 }
115 } else
116 lastGCWasDefrag = false;
117
118 super.collectionPhase(phaseId);
119 }
120
121 @Override
122 public boolean lastCollectionWasExhaustive() {
123 return lastGCWasDefrag;
124 }
125
126 /*****************************************************************************
127 *
128 * Accounting
129 */
130
131 /**
132 * Return the number of pages reserved for use given the pending
133 * allocation.
134 */
135 @Inline
136 @Override
137 public int getPagesUsed() {
138 return immixSpace.reservedPages() + super.getPagesUsed();
139 }
140
141 @Override
142 public int getMaturePhysicalPagesAvail() {
143 return immixSpace.availablePhysicalPages();
144 }
145
146 @Override
147 public int getCollectionReserve() {
148 return super.getCollectionReserve() + immixSpace.defragHeadroomPages();
149 }
150
151 /*****************************************************************************
152 *
153 * Miscellaneous
154 */
155
156 /**
157 * @return The active mature space
158 */
159 @Override
160 @Inline
161 protected final Space activeMatureSpace() {
162 return immixSpace;
163 }
164
165 @Override
166 public boolean willNeverMove(ObjectReference object) {
167 if (Space.isInSpace(IMMIX, object)) {
168 ObjectHeader.pinObject(object);
169 return true;
170 } else
171 return super.willNeverMove(object);
172 }
173
174 @Override
175 @Interruptible
176 protected void registerSpecializedMethods() {
177 TransitiveClosure.registerSpecializedScan(SCAN_IMMIX, GenImmixMatureTraceLocal.class);
178 // TransitiveClosure.registerSpecializedScan(SCAN_DEFRAG, GenImmixMatureDefragTraceLocal.class);
179 super.registerSpecializedMethods();
180 }
181 }