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 }