/* * 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); } }