blob: 93911d721615dfd81e3198cd70074927a4cfa01f [file] [log] [blame]
jkummerow@chromium.org28583c92012-07-16 11:31:55 +00001// Copyright 2012 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.
danno@chromium.orgca29dd82013-04-26 11:59:48 +0000116class StatsCounter {
117 public:
118 StatsCounter() { }
mstarzinger@chromium.orge9000182013-09-03 11:25:39 +0000119 explicit StatsCounter(Isolate* isolate, const char* name)
120 : isolate_(isolate), name_(name), ptr_(NULL), lookup_done_(false) { }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000121
122 // Sets the counter to a specific value.
123 void Set(int value) {
124 int* loc = GetPtr();
125 if (loc) *loc = value;
126 }
127
128 // Increments the counter.
129 void Increment() {
130 int* loc = GetPtr();
131 if (loc) (*loc)++;
132 }
133
134 void Increment(int value) {
135 int* loc = GetPtr();
136 if (loc)
137 (*loc) += value;
138 }
139
140 // Decrements the counter.
141 void Decrement() {
142 int* loc = GetPtr();
143 if (loc) (*loc)--;
144 }
145
146 void Decrement(int value) {
147 int* loc = GetPtr();
148 if (loc) (*loc) -= value;
149 }
150
151 // Is this counter enabled?
152 // Returns false if table is full.
153 bool Enabled() {
154 return GetPtr() != NULL;
155 }
156
157 // Get the internal pointer to the counter. This is used
158 // by the code generator to emit code that manipulates a
159 // given counter without calling the runtime system.
160 int* GetInternalPointer() {
161 int* loc = GetPtr();
162 ASSERT(loc != NULL);
163 return loc;
164 }
165
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000166 protected:
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000167 // Returns the cached address of this counter location.
168 int* GetPtr() {
jkummerow@chromium.org28583c92012-07-16 11:31:55 +0000169 if (lookup_done_) return ptr_;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000170 lookup_done_ = true;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000171 ptr_ = FindLocationInStatsTable();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000172 return ptr_;
173 }
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000174
175 private:
176 int* FindLocationInStatsTable() const;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000177
mstarzinger@chromium.orge9000182013-09-03 11:25:39 +0000178 Isolate* isolate_;
danno@chromium.orgca29dd82013-04-26 11:59:48 +0000179 const char* name_;
180 int* ptr_;
181 bool lookup_done_;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000182};
183
jkummerow@chromium.org28583c92012-07-16 11:31:55 +0000184// A Histogram represents a dynamically created histogram in the StatsTable.
danno@chromium.orgca29dd82013-04-26 11:59:48 +0000185// It will be registered with the histogram system on first use.
186class Histogram {
187 public:
188 Histogram() { }
189 Histogram(const char* name,
190 int min,
191 int max,
192 int num_buckets,
193 Isolate* isolate)
194 : name_(name),
195 min_(min),
196 max_(max),
197 num_buckets_(num_buckets),
198 histogram_(NULL),
199 lookup_done_(false),
200 isolate_(isolate) { }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000201
jkummerow@chromium.org28583c92012-07-16 11:31:55 +0000202 // Add a single sample to this histogram.
203 void AddSample(int sample);
ager@chromium.orgbb29dc92009-03-24 13:25:23 +0000204
jkummerow@chromium.org28583c92012-07-16 11:31:55 +0000205 // Returns true if this histogram is enabled.
206 bool Enabled() {
207 return GetHistogram() != NULL;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000208 }
209
mstarzinger@chromium.org471f2f12012-08-10 14:46:33 +0000210 // Reset the cached internal pointer.
211 void Reset() {
212 lookup_done_ = false;
213 }
214
ager@chromium.orgbb29dc92009-03-24 13:25:23 +0000215 protected:
216 // Returns the handle to the histogram.
217 void* GetHistogram() {
218 if (!lookup_done_) {
219 lookup_done_ = true;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000220 histogram_ = CreateHistogram();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000221 }
ager@chromium.orgbb29dc92009-03-24 13:25:23 +0000222 return histogram_;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000223 }
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000224
danno@chromium.orgca29dd82013-04-26 11:59:48 +0000225 const char* name() { return name_; }
226 Isolate* isolate() const { return isolate_; }
227
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000228 private:
229 void* CreateHistogram() const;
danno@chromium.orgca29dd82013-04-26 11:59:48 +0000230
231 const char* name_;
232 int min_;
233 int max_;
234 int num_buckets_;
235 void* histogram_;
236 bool lookup_done_;
237 Isolate* isolate_;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000238};
239
danno@chromium.orgca29dd82013-04-26 11:59:48 +0000240// A HistogramTimer allows distributions of results to be created.
241class HistogramTimer : public Histogram {
242 public:
243 HistogramTimer() { }
244 HistogramTimer(const char* name,
245 int min,
246 int max,
247 int num_buckets,
248 Isolate* isolate)
jkummerow@chromium.orgdc94e192013-08-30 11:35:42 +0000249 : Histogram(name, min, max, num_buckets, isolate) {}
jkummerow@chromium.org28583c92012-07-16 11:31:55 +0000250
251 // Start the timer.
252 void Start();
253
254 // Stop the timer and record the results.
255 void Stop();
256
257 // Returns true if the timer is running.
258 bool Running() {
jkummerow@chromium.orgdc94e192013-08-30 11:35:42 +0000259 return Enabled() && timer_.IsStarted();
jkummerow@chromium.org28583c92012-07-16 11:31:55 +0000260 }
mstarzinger@chromium.org471f2f12012-08-10 14:46:33 +0000261
danno@chromium.orgca29dd82013-04-26 11:59:48 +0000262 private:
jkummerow@chromium.orgdc94e192013-08-30 11:35:42 +0000263 ElapsedTimer timer_;
jkummerow@chromium.org28583c92012-07-16 11:31:55 +0000264};
265
ager@chromium.orgbb29dc92009-03-24 13:25:23 +0000266// Helper class for scoping a HistogramTimer.
267class HistogramTimerScope BASE_EMBEDDED {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000268 public:
ager@chromium.orgbb29dc92009-03-24 13:25:23 +0000269 explicit HistogramTimerScope(HistogramTimer* timer) :
270 timer_(timer) {
271 timer_->Start();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000272 }
ager@chromium.orgbb29dc92009-03-24 13:25:23 +0000273 ~HistogramTimerScope() {
274 timer_->Stop();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000275 }
276 private:
ager@chromium.orgbb29dc92009-03-24 13:25:23 +0000277 HistogramTimer* timer_;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000278};
279
280
281} } // namespace v8::internal
282
283#endif // V8_COUNTERS_H_