/* * 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.semispace; import org.mmtk.policy.CopySpace; import org.mmtk.policy.Space; import org.mmtk.plan.*; import org.mmtk.utility.heap.VMRequest; import org.vmmagic.pragma.*; import org.vmmagic.unboxed.*; /** * This class implements a simple semi-space collector. See the Jones * & Lins GC book, section 2.2 for an overview of the basic * algorithm. This implementation also includes a large object space * (LOS), and an uncollected "immortal" space.<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 properties of this plan. */ @Uninterruptible public class SS extends StopTheWorld { /**************************************************************************** * * Class variables */ /** {@code true} if allocating into the "higher" semispace */ public static boolean hi = false; /** One of the two semi spaces that alternate roles at each collection */ public static final CopySpace copySpace0 = new CopySpace("ss0", false, VMRequest.discontiguous()); public static final int SS0 = copySpace0.getDescriptor(); /** One of the two semi spaces that alternate roles at each collection */ public static final CopySpace copySpace1 = new CopySpace("ss1", true, VMRequest.discontiguous()); public static final int SS1 = copySpace1.getDescriptor(); public final Trace ssTrace; /**************************************************************************** * * Initialization */ /** * Class variables */ /** * */ public static final int ALLOC_SS = Plan.ALLOC_DEFAULT; public static final int SCAN_SS = 0; /** * Constructor */ public SS() { ssTrace = new Trace(metaDataSpace); } /** * @return The to space for the current collection. */ @Inline public static CopySpace toSpace() { return hi ? copySpace1 : copySpace0; } /** * @return The from space for the current collection. */ @Inline public static CopySpace fromSpace() { return hi ? copySpace0 : copySpace1; } /**************************************************************************** * * Collection */ /** * {@inheritDoc} */ @Override @Inline public void collectionPhase(short phaseId) { if (phaseId == SS.PREPARE) { hi = !hi; // flip the semi-spaces // prepare each of the collected regions copySpace0.prepare(hi); copySpace1.prepare(!hi); ssTrace.prepare(); super.collectionPhase(phaseId); return; } if (phaseId == CLOSURE) { ssTrace.prepare(); return; } if (phaseId == SS.RELEASE) { // release the collected region fromSpace().release(); super.collectionPhase(phaseId); return; } super.collectionPhase(phaseId); } /**************************************************************************** * * Accounting */ /** * Return the number of pages reserved for copying. */ @Override 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(); } /** * Return the number of pages reserved for use given the pending * allocation. This is <i>exclusive of</i> space reserved for * copying. */ @Override public int getPagesUsed() { return super.getPagesUsed() + toSpace().reservedPages(); } /** * Return the number of pages available for allocation, <i>assuming * all future allocation is to the semi-space</i>. * * @return The number of pages available for allocation, <i>assuming * all future allocation is to the semi-space</i>. */ @Override public final int getPagesAvail() { return(super.getPagesAvail()) >> 1; } @Override public boolean willNeverMove(ObjectReference object) { if (Space.isInSpace(SS0, object) || Space.isInSpace(SS1, object)) return false; return super.willNeverMove(object); } @Override @Interruptible protected void registerSpecializedMethods() { TransitiveClosure.registerSpecializedScan(SCAN_SS, SSTraceLocal.class); super.registerSpecializedMethods(); } }