blob: 6498a0242f9246a1d638bcd55f620971bf135740 [file] [log] [blame]
ager@chromium.org9258b6b2008-09-11 09:11:10 +00001// Copyright 2007-2008 the V8 project authors. All rights reserved.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002// Redistribution and use in source and binary forms, with or without
3// modification, are permitted provided that the following conditions are
4// met:
5//
6// * Redistributions of source code must retain the above copyright
7// notice, this list of conditions and the following disclaimer.
8// * Redistributions in binary form must reproduce the above
9// copyright notice, this list of conditions and the following
10// disclaimer in the documentation and/or other materials provided
11// with the distribution.
12// * Neither the name of Google Inc. nor the names of its
13// contributors may be used to endorse or promote products derived
14// from this software without specific prior written permission.
15//
16// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
28#ifndef V8_COUNTERS_H_
29#define V8_COUNTERS_H_
30
whesse@chromium.org023421e2010-12-21 12:19:12 +000031#include "../include/v8.h"
32#include "allocation.h"
33
kasperl@chromium.org71affb52009-05-26 05:44:31 +000034namespace v8 {
35namespace internal {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000036
37// StatsCounters is an interface for plugging into external
38// counters for monitoring. Counters can be looked up and
39// manipulated by name.
40
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +000041class StatsTable {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000042 public:
43 // Register an application-defined function where
44 // counters can be looked up.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +000045 void SetCounterFunction(CounterLookupCallback f) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000046 lookup_function_ = f;
47 }
48
ager@chromium.orgbb29dc92009-03-24 13:25:23 +000049 // Register an application-defined function to create
50 // a histogram for passing to the AddHistogramSample function
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +000051 void SetCreateHistogramFunction(CreateHistogramCallback f) {
ager@chromium.orgbb29dc92009-03-24 13:25:23 +000052 create_histogram_function_ = f;
53 }
54
55 // Register an application-defined function to add a sample
56 // to a histogram created with CreateHistogram function
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +000057 void SetAddHistogramSampleFunction(AddHistogramSampleCallback f) {
ager@chromium.orgbb29dc92009-03-24 13:25:23 +000058 add_histogram_sample_function_ = f;
59 }
60
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +000061 bool HasCounterFunction() const {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000062 return lookup_function_ != NULL;
63 }
64
65 // Lookup the location of a counter by name. If the lookup
66 // is successful, returns a non-NULL pointer for writing the
67 // value of the counter. Each thread calling this function
68 // may receive a different location to store it's counter.
69 // The return value must not be cached and re-used across
70 // threads, although a single thread is free to cache it.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +000071 int* FindLocation(const char* name) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000072 if (!lookup_function_) return NULL;
73 return lookup_function_(name);
74 }
75
ager@chromium.orgbb29dc92009-03-24 13:25:23 +000076 // Create a histogram by name. If the create is successful,
77 // returns a non-NULL pointer for use with AddHistogramSample
78 // function. min and max define the expected minimum and maximum
79 // sample values. buckets is the maximum number of buckets
80 // that the samples will be grouped into.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +000081 void* CreateHistogram(const char* name,
82 int min,
83 int max,
84 size_t buckets) {
ager@chromium.orgbb29dc92009-03-24 13:25:23 +000085 if (!create_histogram_function_) return NULL;
86 return create_histogram_function_(name, min, max, buckets);
87 }
88
89 // Add a sample to a histogram created with the CreateHistogram
90 // function.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +000091 void AddHistogramSample(void* histogram, int sample) {
ager@chromium.orgbb29dc92009-03-24 13:25:23 +000092 if (!add_histogram_sample_function_) return;
93 return add_histogram_sample_function_(histogram, sample);
94 }
95
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000096 private:
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +000097 StatsTable();
98
99 CounterLookupCallback lookup_function_;
100 CreateHistogramCallback create_histogram_function_;
101 AddHistogramSampleCallback add_histogram_sample_function_;
102
103 friend class Isolate;
104
105 DISALLOW_COPY_AND_ASSIGN(StatsTable);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000106};
107
108// StatsCounters are dynamically created values which can be tracked in
109// the StatsTable. They are designed to be lightweight to create and
110// easy to use.
111//
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000112// Internally, a counter represents a value in a row of a StatsTable.
113// The row has a 32bit value for each process/thread in the table and also
114// a name (stored in the table metadata). Since the storage location can be
115// thread-specific, this class cannot be shared across threads.
116//
kasperl@chromium.orgb9123622008-09-17 14:05:56 +0000117// This class is designed to be POD initialized. It will be registered with
118// the counter system on first use. For example:
ager@chromium.orga74f0da2008-12-03 16:05:52 +0000119// StatsCounter c = { "c:myctr", NULL, false };
kasperl@chromium.orgb9123622008-09-17 14:05:56 +0000120struct StatsCounter {
ager@chromium.orga74f0da2008-12-03 16:05:52 +0000121 const char* name_;
kasperl@chromium.orgb9123622008-09-17 14:05:56 +0000122 int* ptr_;
123 bool lookup_done_;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000124
125 // Sets the counter to a specific value.
126 void Set(int value) {
127 int* loc = GetPtr();
128 if (loc) *loc = value;
129 }
130
131 // Increments the counter.
132 void Increment() {
133 int* loc = GetPtr();
134 if (loc) (*loc)++;
135 }
136
137 void Increment(int value) {
138 int* loc = GetPtr();
139 if (loc)
140 (*loc) += value;
141 }
142
143 // Decrements the counter.
144 void Decrement() {
145 int* loc = GetPtr();
146 if (loc) (*loc)--;
147 }
148
149 void Decrement(int value) {
150 int* loc = GetPtr();
151 if (loc) (*loc) -= value;
152 }
153
154 // Is this counter enabled?
155 // Returns false if table is full.
156 bool Enabled() {
157 return GetPtr() != NULL;
158 }
159
160 // Get the internal pointer to the counter. This is used
161 // by the code generator to emit code that manipulates a
162 // given counter without calling the runtime system.
163 int* GetInternalPointer() {
164 int* loc = GetPtr();
165 ASSERT(loc != NULL);
166 return loc;
167 }
168
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000169 protected:
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000170 // Returns the cached address of this counter location.
171 int* GetPtr() {
172 if (lookup_done_)
173 return ptr_;
174 lookup_done_ = true;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000175 ptr_ = FindLocationInStatsTable();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000176 return ptr_;
177 }
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000178
179 private:
180 int* FindLocationInStatsTable() const;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000181};
182
kasperl@chromium.orgb9123622008-09-17 14:05:56 +0000183// StatsCounterTimer t = { { L"t:foo", NULL, false }, 0, 0 };
184struct StatsCounterTimer {
185 StatsCounter counter_;
186
187 int64_t start_time_;
188 int64_t stop_time_;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000189
190 // Start the timer.
191 void Start();
192
193 // Stop the timer and record the results.
194 void Stop();
195
196 // Returns true if the timer is running.
197 bool Running() {
kasperl@chromium.orgb9123622008-09-17 14:05:56 +0000198 return counter_.Enabled() && start_time_ != 0 && stop_time_ == 0;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000199 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000200};
201
ager@chromium.orgbb29dc92009-03-24 13:25:23 +0000202// A HistogramTimer allows distributions of results to be created
203// HistogramTimer t = { L"foo", NULL, false, 0, 0 };
204struct HistogramTimer {
205 const char* name_;
206 void* histogram_;
207 bool lookup_done_;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000208
ager@chromium.orgbb29dc92009-03-24 13:25:23 +0000209 int64_t start_time_;
210 int64_t stop_time_;
211
212 // Start the timer.
213 void Start();
214
215 // Stop the timer and record the results.
216 void Stop();
217
218 // Returns true if the timer is running.
219 bool Running() {
220 return (histogram_ != NULL) && (start_time_ != 0) && (stop_time_ == 0);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000221 }
222
ager@chromium.orgbb29dc92009-03-24 13:25:23 +0000223 protected:
224 // Returns the handle to the histogram.
225 void* GetHistogram() {
226 if (!lookup_done_) {
227 lookup_done_ = true;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000228 histogram_ = CreateHistogram();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000229 }
ager@chromium.orgbb29dc92009-03-24 13:25:23 +0000230 return histogram_;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000231 }
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000232
233 private:
234 void* CreateHistogram() const;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000235};
236
ager@chromium.orgbb29dc92009-03-24 13:25:23 +0000237// Helper class for scoping a HistogramTimer.
238class HistogramTimerScope BASE_EMBEDDED {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000239 public:
ager@chromium.orgbb29dc92009-03-24 13:25:23 +0000240 explicit HistogramTimerScope(HistogramTimer* timer) :
241 timer_(timer) {
242 timer_->Start();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000243 }
ager@chromium.orgbb29dc92009-03-24 13:25:23 +0000244 ~HistogramTimerScope() {
245 timer_->Stop();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000246 }
247 private:
ager@chromium.orgbb29dc92009-03-24 13:25:23 +0000248 HistogramTimer* timer_;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000249};
250
251
252} } // namespace v8::internal
253
254#endif // V8_COUNTERS_H_