blob: 881063e38afe83d37c7b2ee2821b0c2d4fdc2271 [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.utility.statistics;
import org.mmtk.utility.Log;
import org.mmtk.vm.VM;
import org.vmmagic.pragma.*;
/**
* This class implements a simple boolean counter (counting number of
* phases where some boolean event is true).
*/
@Uninterruptible public class BooleanCounter extends Counter {
/****************************************************************************
*
* Instance variables
*/
private final boolean[] state;
protected int total = 0;
private boolean running = false;
/****************************************************************************
*
* Initialization
*/
/**
* Constructor
*
* @param name The name to be associated with this counter
*/
public BooleanCounter(String name) {
this(name, true, false);
}
/**
* Constructor
*
* @param name The name to be associated with this counter
* @param start True if this counter is to be implicitly started
* when <code>startAll()</code> is called (otherwise the counter
* must be explicitly started).
*/
public BooleanCounter(String name, boolean start) {
this(name, start, false);
}
/**
* Constructor
*
* @param name The name to be associated with this counter
* @param start True if this counter is to be implicitly started
* when <code>startAll()</code> is called (otherwise the counter
* must be explicitly started).
* @param mergephases True if this counter does not separately
* report GC and Mutator phases.
*/
public BooleanCounter(String name, boolean start, boolean mergephases) {
super(name, start, mergephases);
state = new boolean[Stats.MAX_PHASES];
for (int i = 0; i < Stats.MAX_PHASES; i++)
state[i] = false;
}
/****************************************************************************
*
* Counter-specific methods
*/
/**
* Set the boolean to true for this phase, increment the total.
*/
public void set() {
if (VM.VERIFY_ASSERTIONS) VM.assertions._assert(Stats.phase == Stats.MAX_PHASES -1 || !state[Stats.phase]);
state[Stats.phase] = true;
total++;
}
/****************************************************************************
*
* Generic counter control methods: start, stop, print etc
*/
/**
* Start this counter
*/
protected void start() {
if (!Stats.gatheringStats) return;
if (VM.VERIFY_ASSERTIONS) VM.assertions._assert(!running);
running = true;
}
/**
* Stop this counter
*/
protected void stop() {
if (!Stats.gatheringStats) return;
if (VM.VERIFY_ASSERTIONS) VM.assertions._assert(running);
running = false;
}
/**
* The phase has changed (from GC to mutator or mutator to GC).
* Take action with respect to the last phase if necessary.
* <b>Do nothing in this case.</b>
*
* @param oldPhase The last phase
*/
void phaseChange(int oldPhase) {}
/**
* Print the value of this counter for the given phase. Print '0'
* for false, '1' for true.
*
* @param phase The phase to be printed
*/
protected final void printCount(int phase) {
if (VM.VERIFY_ASSERTIONS && mergePhases())
if (VM.VERIFY_ASSERTIONS) VM.assertions._assert((phase | 1) == (phase + 1));
if (mergePhases())
printValue((state[phase] || state[phase + 1]) ? 1 : 0);
else
printValue((state[phase]) ? 1 : 0);
}
/**
* Print the current total number of 'true' phases for this counter
*/
protected final void printTotal() {
int total = 0;
for (int p = 0; p <= Stats.phase; p++) {
total += (state[p]) ? 1 : 0;
}
printValue(total);
}
/**
* Print the current total number of 'true' phases for either the
* mutator or GC phase
*
* @param mutator True if the total for the mutator phases is to be
* printed (otherwise the total for the GC phases will be printed).
*/
protected final void printTotal(boolean mutator) {
int total = 0;
for (int p = (mutator) ? 0 : 1; p <= Stats.phase; p += 2) {
total += (state[p]) ? 1 : 0;
}
printValue(total);
}
/**
* Print the current minimum value for either the mutator or GC
* phase. <b>Do nothing in this case.</b>
*
* @param mutator True if the minimum for the mutator phase is to be
* printed (otherwise the minimum for the GC phase will be printed).
*/
protected final void printMin(boolean mutator) {}
/**
* Print the current maximum value for either the mutator or GC
* phase. <b>Do nothing in this case.</b>
*
* @param mutator True if the maximum for the mutator phase is to be
* printed (otherwise the maximum for the GC phase will be printed).
*/
protected final void printMax(boolean mutator) {}
/**
* Print the given value
*
* @param value The value to be printed
*/
void printValue(int value) {
Log.write(value);
}
/**
* Print statistics for the most recent phase
*/
public void printLast() {
if (Stats.phase > 0) printCount(Stats.phase - 1);
}
}