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 */
013package org.mmtk.plan.generational.copying;
014
015import org.mmtk.policy.CopySpace;
016import org.mmtk.policy.Space;
017import org.mmtk.plan.generational.*;
018import org.mmtk.plan.Trace;
019import org.mmtk.plan.TransitiveClosure;
020import org.mmtk.utility.heap.VMRequest;
021import org.mmtk.vm.VM;
022
023import 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 &amp; 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&amp;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.discontiguous());
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.discontiguous());
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() {
119    return hi ? MS1 : MS0;
120  }
121
122  /**
123   * @return The semispace we are currently copying from
124   * (or copied from at last major GC)
125   */
126  static CopySpace fromSpace() {
127    return hi ? matureSpace0 : matureSpace1;
128  }
129
130  /**
131   * @return Space descriptor for from-space
132   */
133  static int fromSpaceDesc() {
134    return hi ? MS0 : MS1;
135  }
136
137  /****************************************************************************
138   *
139   * Collection
140   */
141
142  /**
143   * {@inheritDoc}
144   */
145  @Override
146  @Inline
147  public void collectionPhase(short phaseId) {
148    if (traceFullHeap()) {
149      if (phaseId == PREPARE) {
150        super.collectionPhase(phaseId);
151        hi = !hi; // flip the semi-spaces
152        matureSpace0.prepare(hi);
153        matureSpace1.prepare(!hi);
154        matureTrace.prepare();
155        return;
156      }
157      if (phaseId == CLOSURE) {
158        matureTrace.prepare();
159        return;
160      }
161      if (phaseId == RELEASE) {
162        matureTrace.release();
163        fromSpace().release();
164        super.collectionPhase(phaseId);
165        return;
166      }
167    }
168    super.collectionPhase(phaseId);
169  }
170
171  /*****************************************************************************
172   *
173   * Accounting
174   */
175
176  /**
177   * Return the number of pages reserved for use given the pending
178   * allocation.
179   */
180  @Override
181  @Inline
182  public int getPagesUsed() {
183    return toSpace().reservedPages() + super.getPagesUsed();
184  }
185
186  /**
187   * Return the number of pages reserved for copying.
188   *
189   * @return the number of pages reserved for copying.
190   */
191  @Override
192  public final int getCollectionReserve() {
193    // we must account for the number of pages required for copying,
194    // which equals the number of semi-space pages reserved
195    return toSpace().reservedPages() + super.getCollectionReserve();
196  }
197
198  @Override
199  public int getMaturePhysicalPagesAvail() {
200    return toSpace().availablePhysicalPages() >> 1;
201  }
202
203  /**************************************************************************
204   * Miscellaneous methods
205   */
206
207  /**
208   * @return The mature space we are currently allocating into
209   */
210  @Override
211  @Inline
212  public Space activeMatureSpace() {
213    return toSpace();
214  }
215
216  @Override
217  @Interruptible
218  protected void registerSpecializedMethods() {
219    TransitiveClosure.registerSpecializedScan(SCAN_MATURE, GenCopyMatureTraceLocal.class);
220    super.registerSpecializedMethods();
221  }
222}