blob: 2348df292a938bd762c2471982201925e8f41a4e [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;
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();
}
}