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.copying;
014
015 import org.mmtk.policy.CopySpace;
016 import org.mmtk.policy.Space;
017 import org.mmtk.plan.generational.*;
018 import org.mmtk.plan.Trace;
019 import org.mmtk.plan.TransitiveClosure;
020 import org.mmtk.utility.heap.VMRequest;
021 import org.mmtk.vm.VM;
022
023 import org.vmmagic.pragma.*;
024
025 /**
026 * This class implements the functionality of a standard
027 * two-generation copying collector. Nursery collections occur when
028 * either the heap is full or the nursery is full. The nursery size
029 * is determined by an optional command line argument. If undefined,
030 * the nursery size is "infinite", so nursery collections only occur
031 * when the heap is full (this is known as a flexible-sized nursery
032 * collector). Thus both fixed and flexible nursery sizes are
033 * supported. Full heap collections occur when the nursery size has
034 * dropped to a statically defined threshold,
035 * <code>NURSERY_THRESHOLD</code><p>
036 *
037 * See the Jones & Lins GC book, chapter 7 for a detailed discussion
038 * of generational collection and section 7.3 for an overview of the
039 * flexible nursery behavior ("The Standard ML of New Jersey
040 * collector"), or go to Appel's paper "Simple generational garbage
041 * collection and fast allocation." SP&E 19(2):171--183, 1989.<p>
042 *
043 * All plans make a clear distinction between <i>global</i> and
044 * <i>thread-local</i> activities. Global activities must be
045 * synchronized, whereas no synchronization is required for
046 * thread-local activities. Instances of Plan map 1:1 to "kernel
047 * threads" (aka CPUs). Thus instance
048 * methods allow fast, unsychronized access to Plan utilities such as
049 * allocation and collection. Each instance rests on static resources
050 * (such as memory and virtual memory resources) which are "global"
051 * and therefore "static" members of Plan. This mapping of threads to
052 * instances is crucial to understanding the correctness and
053 * performance properties of this plan.
054 */
055 @Uninterruptible public class GenCopy extends Gen {
056
057 /****************************************************************************
058 *
059 * Class variables
060 */
061
062 // GC state
063
064 /**
065 * <code>true</code> if copying to "higher" semispace
066 */
067 static boolean hi = false;
068
069 /**
070 * The low half of the copying mature space. We allocate into this space
071 * when <code>hi</code> is <code>false</code>.
072 */
073 static CopySpace matureSpace0 = new CopySpace("ss0", false, VMRequest.create());
074 static final int MS0 = matureSpace0.getDescriptor();
075
076 /**
077 * The high half of the copying mature space. We allocate into this space
078 * when <code>hi</code> is <code>true</code>.
079 */
080 static CopySpace matureSpace1 = new CopySpace("ss1", true, VMRequest.create());
081 static final int MS1 = matureSpace1.getDescriptor();
082
083
084 /****************************************************************************
085 *
086 * Instance fields
087 */
088
089 /**
090 *
091 */
092 final Trace matureTrace;
093
094 /**
095 * Constructor
096 */
097 public GenCopy() {
098 super();
099 if (VM.VERIFY_ASSERTIONS) VM.assertions._assert(!IGNORE_REMSETS); // Not supported for GenCopy
100 matureTrace = new Trace(metaDataSpace);
101 }
102
103 @Override
104 protected boolean copyMature() {
105 return true;
106 }
107
108 /**
109 * @return The semispace we are currently allocating into
110 */
111 static CopySpace toSpace() {
112 return hi ? matureSpace1 : matureSpace0;
113 }
114
115 /**
116 * @return Space descriptor for to-space.
117 */
118 static int toSpaceDesc() { return hi ? MS1 : MS0; }
119
120 /**
121 * @return The semispace we are currently copying from
122 * (or copied from at last major GC)
123 */
124 static CopySpace fromSpace() {
125 return hi ? matureSpace0 : matureSpace1;
126 }
127
128 /**
129 * @return Space descriptor for from-space
130 */
131 static int fromSpaceDesc() { return hi ? MS0 : MS1; }
132
133 /****************************************************************************
134 *
135 * Collection
136 */
137
138 /**
139 * {@inheritDoc}
140 */
141 @Override
142 @Inline
143 public void collectionPhase(short phaseId) {
144 if (traceFullHeap()) {
145 if (phaseId == PREPARE) {
146 super.collectionPhase(phaseId);
147 hi = !hi; // flip the semi-spaces
148 matureSpace0.prepare(hi);
149 matureSpace1.prepare(!hi);
150 matureTrace.prepare();
151 return;
152 }
153 if (phaseId == CLOSURE) {
154 matureTrace.prepare();
155 return;
156 }
157 if (phaseId == RELEASE) {
158 matureTrace.release();
159 fromSpace().release();
160 super.collectionPhase(phaseId);
161 return;
162 }
163 }
164 super.collectionPhase(phaseId);
165 }
166
167 /*****************************************************************************
168 *
169 * Accounting
170 */
171
172 /**
173 * Return the number of pages reserved for use given the pending
174 * allocation.
175 */
176 @Override
177 @Inline
178 public int getPagesUsed() {
179 return toSpace().reservedPages() + super.getPagesUsed();
180 }
181
182 /**
183 * Return the number of pages reserved for copying.
184 *
185 * @return the number of pages reserved for copying.
186 */
187 @Override
188 public final int getCollectionReserve() {
189 // we must account for the number of pages required for copying,
190 // which equals the number of semi-space pages reserved
191 return toSpace().reservedPages() + super.getCollectionReserve();
192 }
193
194 @Override
195 public int getMaturePhysicalPagesAvail() {
196 return toSpace().availablePhysicalPages() >> 1;
197 }
198
199 /**************************************************************************
200 * Miscellaneous methods
201 */
202
203 /**
204 * @return The mature space we are currently allocating into
205 */
206 @Override
207 @Inline
208 public Space activeMatureSpace() {
209 return toSpace();
210 }
211
212 @Override
213 @Interruptible
214 protected void registerSpecializedMethods() {
215 TransitiveClosure.registerSpecializedScan(SCAN_MATURE, GenCopyMatureTraceLocal.class);
216 super.registerSpecializedMethods();
217 }
218 }