/* * 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; import org.mmtk.utility.Log; import org.mmtk.utility.options.Options; import org.mmtk.vm.VM; import org.vmmagic.pragma.*; /** * This class (and its sub-classes) implement <i>per-collector thread</i> * behavior and state. * * MMTk assumes that the VM instantiates instances of CollectorContext * in thread local storage (TLS) for each thread participating in * collection. Accesses to this state are therefore assumed to be * low-cost during mutator time.<p> * * @see CollectorContext */ @Uninterruptible public abstract class SimpleCollector extends CollectorContext { /**************************************************************************** * Instance fields */ /**************************************************************************** * * Collection */ /** * Perform a per-collector collection phase. * * @param phaseId The unique phase identifier * @param primary Should this thread be used to execute any single-threaded * local operations? */ @Inline public void collectionPhase(short phaseId, boolean primary) { if (phaseId == Simple.PREPARE_STACKS) { if (!Plan.stacksPrepared()) { VM.collection.prepareCollector(this); } return; } if (phaseId == Simple.PREPARE) { // Nothing to do return; } if (phaseId == Simple.PRECOPY) { if (VM.activePlan.constraints().movesObjects()) { VM.scanning.preCopyGCInstances(getCurrentTrace()); } return; } if (phaseId == Simple.STACK_ROOTS) { VM.scanning.computeThreadRoots(getCurrentTrace()); return; } if (phaseId == Simple.ROOTS) { VM.scanning.computeGlobalRoots(getCurrentTrace()); VM.scanning.computeStaticRoots(getCurrentTrace()); if (Plan.SCAN_BOOT_IMAGE) { VM.scanning.computeBootImageRoots(getCurrentTrace()); } return; } if (phaseId == Simple.SOFT_REFS) { if (primary) { if (Options.noReferenceTypes.getValue()) VM.softReferences.clear(); else VM.softReferences.scan(getCurrentTrace(),global().isCurrentGCNursery()); } return; } if (phaseId == Simple.WEAK_REFS) { if (primary) { if (Options.noReferenceTypes.getValue()) VM.weakReferences.clear(); else VM.weakReferences.scan(getCurrentTrace(),global().isCurrentGCNursery()); } return; } if (phaseId == Simple.FINALIZABLE) { if (primary) { if (Options.noFinalizer.getValue()) VM.finalizableProcessor.clear(); else VM.finalizableProcessor.scan(getCurrentTrace(),global().isCurrentGCNursery()); } return; } if (phaseId == Simple.PHANTOM_REFS) { if (primary) { if (Options.noReferenceTypes.getValue()) VM.phantomReferences.clear(); else VM.phantomReferences.scan(getCurrentTrace(),global().isCurrentGCNursery()); } return; } if (phaseId == Simple.FORWARD_REFS) { if (primary && !Options.noReferenceTypes.getValue() && VM.activePlan.constraints().needsForwardAfterLiveness()) { VM.softReferences.forward(getCurrentTrace(),global().isCurrentGCNursery()); VM.weakReferences.forward(getCurrentTrace(),global().isCurrentGCNursery()); VM.phantomReferences.forward(getCurrentTrace(),global().isCurrentGCNursery()); } return; } if (phaseId == Simple.FORWARD_FINALIZABLE) { if (primary && !Options.noFinalizer.getValue() && VM.activePlan.constraints().needsForwardAfterLiveness()) { VM.finalizableProcessor.forward(getCurrentTrace(),global().isCurrentGCNursery()); } return; } if (phaseId == Simple.COMPLETE) { // Nothing to do return; } if (phaseId == Simple.RELEASE) { // Nothing to do return; } if (Options.sanityCheck.getValue() && sanityLocal.collectionPhase(phaseId, primary)) { return; } Log.write("Per-collector phase "); Log.write(Phase.getName(phaseId)); Log.writeln(" not handled."); VM.assertions.fail("Per-collector phase not handled!"); } /**************************************************************************** * * Miscellaneous. */ /** @return The active global plan as a <code>Simple</code> instance. */ @Inline private static Simple global() { return (Simple) VM.activePlan.global(); } }