/* * 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.utility.sanitychecker.SanityCheckerLocal; import org.mmtk.vm.VM; import org.vmmagic.pragma.*; /** * This class (and its sub-classes) implement <i>per-collector thread</i> * behavior and state.<p> * * 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. * * @see CollectorContext */ @Uninterruptible public abstract class SimpleCollector extends ParallelCollector { /**************************************************************************** * Instance fields */ /** Used for sanity checking. */ protected final SanityCheckerLocal sanityLocal = new SanityCheckerLocal(); /**************************************************************************** * * Collection */ /** * {@inheritDoc} */ @Override @Inline public void collectionPhase(short phaseId, boolean primary) { if (phaseId == Simple.PREPARE) { // Nothing to do 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()) { if (!Plan.isEmergencyCollection()) { VM.softReferences.scan(getCurrentTrace(),global().isCurrentGCNursery(),true); } } } return; } if (phaseId == Simple.WEAK_REFS) { if (primary) { if (Options.noReferenceTypes.getValue()) { VM.softReferences.clear(); VM.weakReferences.clear(); } else { VM.softReferences.scan(getCurrentTrace(),global().isCurrentGCNursery(), false); VM.weakReferences.scan(getCurrentTrace(),global().isCurrentGCNursery(), false); } } 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(),false); } 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(); } }