001 /* 002 * This file is part of the Jikes RVM project (http://jikesrvm.org). 003 * 004 * This file is licensed to You under the Eclipse Public License (EPL); 005 * You may not use this file except in compliance with the License. You 006 * may obtain a copy of the License at 007 * 008 * http://www.opensource.org/licenses/eclipse-1.0.php 009 * 010 * See the COPYRIGHT.txt file distributed with this work for information 011 * regarding copyright ownership. 012 */ 013 package org.mmtk.utility.statistics; 014 015 import org.mmtk.utility.Log; 016 017 import org.mmtk.vm.VM; 018 019 import org.vmmagic.pragma.*; 020 021 /** 022 * This class implements a simple boolean counter (counting number of 023 * phases where some boolean event is true). 024 */ 025 @Uninterruptible 026 public class BooleanCounter extends Counter { 027 028 /**************************************************************************** 029 * 030 * Instance variables 031 */ 032 033 /** 034 * 035 */ 036 private final boolean[] state; 037 038 protected int total = 0; 039 private boolean running = false; 040 041 /**************************************************************************** 042 * 043 * Initialization 044 */ 045 046 /** 047 * Constructor 048 * 049 * @param name The name to be associated with this counter 050 */ 051 public BooleanCounter(String name) { 052 this(name, true, false); 053 } 054 055 /** 056 * Constructor 057 * 058 * @param name The name to be associated with this counter 059 * @param start {@code true} if this counter is to be implicitly started 060 * when <code>startAll()</code> is called (otherwise the counter 061 * must be explicitly started). 062 */ 063 public BooleanCounter(String name, boolean start) { 064 this(name, start, false); 065 } 066 067 /** 068 * Constructor 069 * 070 * @param name The name to be associated with this counter 071 * @param start True if this counter is to be implicitly started 072 * when <code>startAll()</code> is called (otherwise the counter 073 * must be explicitly started). 074 * @param mergephases True if this counter does not separately 075 * report GC and Mutator phases. 076 */ 077 public BooleanCounter(String name, boolean start, boolean mergephases) { 078 super(name, start, mergephases); 079 state = new boolean[Stats.MAX_PHASES]; 080 } 081 082 /**************************************************************************** 083 * 084 * Counter-specific methods 085 */ 086 087 /** 088 * Set the boolean to {@code true} for this phase, increment the total. 089 */ 090 public void set() { 091 if (VM.VERIFY_ASSERTIONS) VM.assertions._assert(Stats.phase == Stats.MAX_PHASES -1 || !state[Stats.phase]); 092 state[Stats.phase] = true; 093 total++; 094 } 095 096 /**************************************************************************** 097 * 098 * Generic counter control methods: start, stop, print etc 099 */ 100 101 /** 102 * {@inheritDoc} 103 */ 104 @Override 105 protected void start() { 106 if (!Stats.gatheringStats) return; 107 if (VM.VERIFY_ASSERTIONS) VM.assertions._assert(!running); 108 running = true; 109 } 110 111 @Override 112 protected void stop() { 113 if (!Stats.gatheringStats) return; 114 if (VM.VERIFY_ASSERTIONS) VM.assertions._assert(running); 115 running = false; 116 } 117 118 /** 119 * The phase has changed (from GC to mutator or mutator to GC). 120 * Take action with respect to the last phase if necessary. 121 * <b>Do nothing in this case.</b> 122 * 123 * @param oldPhase The last phase 124 */ 125 @Override 126 void phaseChange(int oldPhase) {} 127 128 /** 129 * {@inheritDoc} 130 * Print '0' for {@code false}, '1' for {@code true}. 131 * 132 * @param phase The phase to be printed 133 */ 134 @Override 135 protected final void printCount(int phase) { 136 if (VM.VERIFY_ASSERTIONS && mergePhases()) 137 if (VM.VERIFY_ASSERTIONS) VM.assertions._assert((phase | 1) == (phase + 1)); 138 if (mergePhases()) 139 printValue((state[phase] || state[phase + 1]) ? 1 : 0); 140 else 141 printValue((state[phase]) ? 1 : 0); 142 } 143 144 /** 145 * Print the current total number of {@code true} phases for this counter 146 */ 147 @Override 148 protected final void printTotal() { 149 int total = 0; 150 for (int p = 0; p <= Stats.phase; p++) { 151 total += (state[p]) ? 1 : 0; 152 } 153 printValue(total); 154 } 155 156 @Override 157 protected final void printTotal(boolean mutator) { 158 int total = 0; 159 for (int p = (mutator) ? 0 : 1; p <= Stats.phase; p += 2) { 160 total += (state[p]) ? 1 : 0; 161 } 162 printValue(total); 163 } 164 165 /** 166 * {@inheritDoc} 167 * <b>Do nothing in this case.</b> 168 */ 169 @Override 170 protected final void printMin(boolean mutator) {} 171 172 /** 173 * {@inheritDoc} 174 * <b>Do nothing in this case.</b> 175 */ 176 @Override 177 protected final void printMax(boolean mutator) {} 178 179 /** 180 * Print the given value 181 * 182 * @param value The value to be printed 183 */ 184 void printValue(int value) { 185 Log.write(value); 186 } 187 188 @Override 189 public void printLast() { 190 if (Stats.phase > 0) printCount(Stats.phase - 1); 191 } 192 }