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