/* * 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 abstract class implements a simple counter (counting some * integer (long) value for each phase). */ @Uninterruptible public abstract class LongCounter extends Counter { /**************************************************************************** * * Instance variables */ private final long[] count; private long startValue = 0; protected long totalCount = 0; private boolean running = false; /**************************************************************************** * * Initialization */ /** * Constructor * * @param name The name to be associated with this counter */ LongCounter(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). */ LongCounter(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. */ LongCounter(String name, boolean start, boolean mergephases) { super(name, start, mergephases); count = new long[Stats.MAX_PHASES]; } /**************************************************************************** * * Counter-specific methods */ protected abstract long getCurrentValue(); /**************************************************************************** * * Generic counter control methods: start, stop, print etc */ /** * Start this counter */ public void start() { if (!Stats.gatheringStats) return; if (VM.VERIFY_ASSERTIONS) VM.assertions._assert(!running); running = true; startValue = getCurrentValue(); } /** * Stop this counter */ public void stop() { if (!Stats.gatheringStats) return; if (VM.VERIFY_ASSERTIONS) VM.assertions._assert(running); running = false; long delta = getCurrentValue() - startValue; count[Stats.phase] += delta; totalCount += delta; } /** * 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 */ protected void phaseChange(int oldPhase) { if (running) { long now = getCurrentValue(); long delta = now - startValue; count[oldPhase] += delta; totalCount += delta; startValue = now; } } /** * 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(count[phase] + count[phase + 1]); else printValue(count[phase]); } /** * Print the current total for this counter */ public final void printTotal() { printValue(totalCount); } /** * Get the total as at the lasts phase * * @return The total as at the last phase */ long getLastTotal() { return totalCount; } /** * Print the current total 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) { long total = 0; for (int p = (mutator) ? 0 : 1; p <= Stats.phase; p += 2) { total += count[p]; } printValue(total); } /** * Print the current minimum value for either the mutator or GC * phase. * * @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) { int p = (mutator) ? 0 : 1; long min = count[p]; for (; p < Stats.phase; p += 2) { if (count[p] < min) min = count[p]; } printValue(min); } /** * Print the current maximum value for either the mutator or GC * phase. * * @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) { int p = (mutator) ? 0 : 1; long max = count[p]; for (; p < Stats.phase; p += 2) { if (count[p] > max) max = count[p]; } printValue(max); } /** * Print the given value * * @param value The value to be printed */ void printValue(long value) { Log.write(value); } }