blob: d963383a486ee776aedb3dbeddead2ade738e589 [file] [log] [blame]
/*
* This file is part of the Jikes RVM project (http://jikesrvm.org).
*
* This file is licensed to You under the Eclipse Public License (EPL);
* You may not use this file except in compliance with the License. You
* may obtain a copy of the License at
*
* http://www.opensource.org/licenses/eclipse-1.0.php
*
* See the COPYRIGHT.txt file distributed with this work for information
* regarding copyright ownership.
*/
package org.mmtk.plan.generational.copying;
import org.mmtk.policy.CopySpace;
import org.mmtk.policy.Space;
import org.mmtk.plan.generational.*;
import org.mmtk.plan.Trace;
import org.mmtk.plan.TransitiveClosure;
import org.mmtk.utility.heap.VMRequest;
import org.mmtk.vm.VM;
import org.vmmagic.pragma.*;
/**
* This class implements the functionality of a standard
* two-generation copying collector. Nursery collections occur when
* either the heap is full or the nursery is full. The nursery size
* is determined by an optional command line argument. If undefined,
* the nursery size is "infinite", so nursery collections only occur
* when the heap is full (this is known as a flexible-sized nursery
* collector). Thus both fixed and flexible nursery sizes are
* supported. Full heap collections occur when the nursery size has
* dropped to a statically defined threshold,
* <code>NURSERY_THRESHOLD</code><p>
*
* See the Jones & Lins GC book, chapter 7 for a detailed discussion
* of generational collection and section 7.3 for an overview of the
* flexible nursery behavior ("The Standard ML of New Jersey
* collector"), or go to Appel's paper "Simple generational garbage
* collection and fast allocation." SP&E 19(2):171--183, 1989.<p>
*
* All plans make a clear distinction between <i>global</i> and
* <i>thread-local</i> activities. Global activities must be
* synchronized, whereas no synchronization is required for
* thread-local activities. Instances of Plan map 1:1 to "kernel
* threads" (aka CPUs). Thus instance
* methods allow fast, unsychronized access to Plan utilities such as
* allocation and collection. Each instance rests on static resources
* (such as memory and virtual memory resources) which are "global"
* and therefore "static" members of Plan. This mapping of threads to
* instances is crucial to understanding the correctness and
* performance proprties of this plan.
*/
@Uninterruptible public class GenCopy extends Gen {
/****************************************************************************
*
* Class variables
*/
// GC state
static boolean hi = false; // True if copying to "higher" semispace
/**
* The low half of the copying mature space. We allocate into this space
* when <code>hi</code> is <code>false</code>.
*/
static CopySpace matureSpace0 = new CopySpace("ss0", DEFAULT_POLL_FREQUENCY, false, VMRequest.create());
static final int MS0 = matureSpace0.getDescriptor();
/**
* The high half of the copying mature space. We allocate into this space
* when <code>hi</code> is <code>true</code>.
*/
static CopySpace matureSpace1 = new CopySpace("ss1", DEFAULT_POLL_FREQUENCY, true, VMRequest.create());
static final int MS1 = matureSpace1.getDescriptor();
/****************************************************************************
*
* Instance fields
*/
final Trace matureTrace;
/**
* Constructor
*/
public GenCopy() {
super();
if (VM.VERIFY_ASSERTIONS) VM.assertions._assert(!IGNORE_REMSETS); // Not supported for GenCopy
matureTrace = new Trace(metaDataSpace);
}
/**
* @return Does the mature space do copying ?
*/
protected boolean copyMature() {
return true;
}
/**
* @return The semispace we are currently allocating into
*/
static CopySpace toSpace() {
return hi ? matureSpace1 : matureSpace0;
}
/**
* @return Space descriptor for to-space.
*/
static int toSpaceDesc() { return hi ? MS1 : MS0; }
/**
* @return The semispace we are currently copying from
* (or copied from at last major GC)
*/
static CopySpace fromSpace() {
return hi ? matureSpace0 : matureSpace1;
}
/**
* @return Space descriptor for from-space
*/
static int fromSpaceDesc() { return hi ? MS0 : MS1; }
/****************************************************************************
*
* Collection
*/
/**
* Perform a phase of the currently active collection.
*
* @param phaseId Collection phase to process
*/
@Inline
public void collectionPhase(short phaseId) {
if (traceFullHeap()) {
if (phaseId == PREPARE) {
super.collectionPhase(phaseId);
hi = !hi; // flip the semi-spaces
matureSpace0.prepare(hi);
matureSpace1.prepare(!hi);
matureTrace.prepare();
return;
}
if (phaseId == CLOSURE) {
matureTrace.prepare();
return;
}
if (phaseId == RELEASE) {
matureTrace.release();
fromSpace().release();
super.collectionPhase(phaseId);
return;
}
}
super.collectionPhase(phaseId);
}
/*****************************************************************************
*
* Accounting
*/
/**
* Return the number of pages reserved for use given the pending
* allocation.
*
* @return The number of pages reserved given the pending
* allocation, excluding space reserved for copying.
*/
@Inline
public int getPagesUsed() {
return toSpace().reservedPages() + super.getPagesUsed();
}
/**
* Return the number of pages reserved for copying.
*
* @return the number of pages reserved for copying.
*/
public final int getCollectionReserve() {
// we must account for the number of pages required for copying,
// which equals the number of semi-space pages reserved
return toSpace().reservedPages() + super.getCollectionReserve();
}
/**
* Calculate the number of pages a collection is required to free to satisfy
* outstanding allocation requests.
*
* @return the number of pages a collection is required to free to satisfy
* outstanding allocation requests.
*/
public int getPagesRequired() {
return super.getPagesRequired() + (toSpace().requiredPages() << 1);
}
/**
* Return the number of pages available for allocation into the mature
* space.
*
* @return The number of pages available for allocation into the mature
* space.
*/
public int getMaturePhysicalPagesAvail() {
return toSpace().availablePhysicalPages() >> 1;
}
/**************************************************************************
* Miscellaneous methods
*/
/**
* @return The mature space we are currently allocating into
*/
@Inline
public Space activeMatureSpace() {
return toSpace();
}
/**
* Register specialized methods.
*/
@Interruptible
protected void registerSpecializedMethods() {
TransitiveClosure.registerSpecializedScan(SCAN_MATURE, GenCopyMatureTraceLocal.class);
super.registerSpecializedMethods();
}
}