/*
* This file is part of the Jikes RVM project (http://jikesrvm.org).
*
* This file is licensed to You under the Common Public License (CPL);
* 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/cpl1.0.php
*
* See the COPYRIGHT.txt file distributed with this work for information
* regarding copyright ownership.
*/
package org.mmtk.plan.refcount.cd;
import org.mmtk.plan.refcount.RCBase;
import org.mmtk.utility.options.CycleFilterThreshold;
import org.mmtk.utility.options.CycleMetaDataLimit;
import org.mmtk.utility.options.CycleTriggerThreshold;
import org.mmtk.utility.options.Options;
import org.mmtk.utility.statistics.Stats;
import org.mmtk.vm.VM;
import org.vmmagic.pragma.*;
import org.vmmagic.unboxed.*;
/**
* This class implements <i>global</i> behavior
* and state for a cycle detector.
*/
@Uninterruptible public abstract class CD {
/****************************************************************************
* Constants
*/
/****************************************************************************
* Class variables
*/
/****************************************************************************
* Instance variables
*/
/**
* Constructor.
*/
public CD() {
Options.cycleFilterThreshold = new CycleFilterThreshold();
Options.cycleTriggerThreshold = new CycleTriggerThreshold();
Options.cycleMetaDataLimit = new CycleMetaDataLimit();
}
/*****************************************************************************
*
* Collection
*/
/**
* Decide whether cycle collection should be invoked. This uses
* a probabalisitic heuristic based on heap fullness.
*
* @return True if cycle collection should be invoked
*/
protected final boolean shouldCollectCycles() {
return shouldAct(Options.cycleTriggerThreshold.getPages());
}
/**
* Decide whether the purple buffer should be filtered. This will
* happen if the heap is close to full or if the number of purple
* objects enqued has reached a user-defined threashold.
*
* @return True if the unfiltered purple buffer should be filtered
*/
protected final boolean shouldFilterPurple() {
return shouldAct(Options.cycleFilterThreshold.getPages());
}
/**
* Decide whether to act on cycle collection or purple filtering.
* This uses a probabalisitic heuristic based on heap fullness.
*
* @return True if we should act
*/
private boolean shouldAct(int thresholdPages) {
if (RCBase.FORCE_FULL_CD) return true;
final int LOG_WRIGGLE = 2;
int slack = log2(VM.activePlan.global().getPagesAvail() / thresholdPages);
int mask = (1 << slack) - 1;
boolean rtn = (slack <= LOG_WRIGGLE) && ((Stats.gcCount() & mask) == mask);
return rtn;
}
private int log2(int value) {
int rtn = 0;
while (value > 1<<rtn) rtn++;
return rtn;
}
/**
* Perform a (global) collection phase.
*
* @param phaseId Collection phase to execute.
*/
@Inline
public boolean collectionPhase(int phaseId) {
return false;
}
/**
* Update the CD section of the RC word when an increment is performed
*
* @param rcWord The refcount word after the increment.
* @return The updated status after CD modification
*/
public abstract int notifyIncRC(int rcWord);
/**
* If the reported decrement succeeds, should we buffer the object?
*
* @param rcWord The refcount work post decrement.
* @return True if DEC_BUFFER should be returned
*/
public abstract boolean shouldBufferOnDecRC(int rcWord);
/**
* Allow a free of this object, or is it in a CD data structure
*
* @param object The object to check
* @return True if free is safe
*/
public abstract boolean allowFree(ObjectReference object);
/**
* Update the header on a buffered dec to non-zero RC
*
* @param rcWord The refcount work post decrement.
* @return The updated status after CD modification
*/
public abstract int updateHeaderOnBufferedDec(int rcWord);
/**
* Update the header on a non-buffered dec to non-zero RC
*
* @param rcWord The refcount work post decrement.
* @return The updated status after CD modification
*/
public abstract int updateHeaderOnUnbufferedDec(int rcWord);
/**
* Perform any cycle detector header initialization.
*
* @param typeRef Type information for the object.
* @param rcWord The refcount work post decrement.
* @return The updated status after CD modification
*/
public abstract int initializeHeader(ObjectReference typeRef, int rcWord);
/****************************************************************************
*
* Miscellaneous
*/
/** @return The active cycle detector global instance */
@Inline
public static CD current() {
return ((RCBase)VM.activePlan.global()).cycleDetector();
}
}