The data contained in this repository can be downloaded to your computer using one of several clients.
Please see the documentation of your version control software client for more information.

Please select the desired protocol below to get the URL.

This URL has Read-Only access.

Statistics
| Branch: | Revision:

main_repo / deps / v8 / src / counters.h @ f230a1cf

History | View | Annotate | Download (8.86 KB)

1
// Copyright 2012 the V8 project authors. All rights reserved.
2
// 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

    
31
#include "../include/v8.h"
32
#include "allocation.h"
33

    
34
namespace v8 {
35
namespace internal {
36

    
37
// StatsCounters is an interface for plugging into external
38
// counters for monitoring.  Counters can be looked up and
39
// manipulated by name.
40

    
41
class StatsTable {
42
 public:
43
  // Register an application-defined function where
44
  // counters can be looked up.
45
  void SetCounterFunction(CounterLookupCallback f) {
46
    lookup_function_ = f;
47
  }
48

    
49
  // Register an application-defined function to create
50
  // a histogram for passing to the AddHistogramSample function
51
  void SetCreateHistogramFunction(CreateHistogramCallback f) {
52
    create_histogram_function_ = f;
53
  }
54

    
55
  // Register an application-defined function to add a sample
56
  // to a histogram created with CreateHistogram function
57
  void SetAddHistogramSampleFunction(AddHistogramSampleCallback f) {
58
    add_histogram_sample_function_ = f;
59
  }
60

    
61
  bool HasCounterFunction() const {
62
    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.
71
  int* FindLocation(const char* name) {
72
    if (!lookup_function_) return NULL;
73
    return lookup_function_(name);
74
  }
75

    
76
  // 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.
81
  void* CreateHistogram(const char* name,
82
                        int min,
83
                        int max,
84
                        size_t buckets) {
85
    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.
91
  void AddHistogramSample(void* histogram, int sample) {
92
    if (!add_histogram_sample_function_) return;
93
    return add_histogram_sample_function_(histogram, sample);
94
  }
95

    
96
 private:
97
  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);
106
};
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
//
112
// 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
class StatsCounter {
117
 public:
118
  StatsCounter() { }
119
  explicit StatsCounter(Isolate* isolate, const char* name)
120
      : isolate_(isolate), name_(name), ptr_(NULL), lookup_done_(false) { }
121

    
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

    
166
 protected:
167
  // Returns the cached address of this counter location.
168
  int* GetPtr() {
169
    if (lookup_done_) return ptr_;
170
    lookup_done_ = true;
171
    ptr_ = FindLocationInStatsTable();
172
    return ptr_;
173
  }
174

    
175
 private:
176
  int* FindLocationInStatsTable() const;
177

    
178
  Isolate* isolate_;
179
  const char* name_;
180
  int* ptr_;
181
  bool lookup_done_;
182
};
183

    
184
// A Histogram represents a dynamically created histogram in the StatsTable.
185
// It will be registered with the histogram system on first use.
186
class 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) { }
201

    
202
  // Add a single sample to this histogram.
203
  void AddSample(int sample);
204

    
205
  // Returns true if this histogram is enabled.
206
  bool Enabled() {
207
    return GetHistogram() != NULL;
208
  }
209

    
210
  // Reset the cached internal pointer.
211
  void Reset() {
212
    lookup_done_ = false;
213
  }
214

    
215
 protected:
216
  // Returns the handle to the histogram.
217
  void* GetHistogram() {
218
    if (!lookup_done_) {
219
      lookup_done_ = true;
220
      histogram_ = CreateHistogram();
221
    }
222
    return histogram_;
223
  }
224

    
225
  const char* name() { return name_; }
226
  Isolate* isolate() const { return isolate_; }
227

    
228
 private:
229
  void* CreateHistogram() const;
230

    
231
  const char* name_;
232
  int min_;
233
  int max_;
234
  int num_buckets_;
235
  void* histogram_;
236
  bool lookup_done_;
237
  Isolate* isolate_;
238
};
239

    
240
// A HistogramTimer allows distributions of results to be created.
241
class 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)
249
      : Histogram(name, min, max, num_buckets, isolate) {}
250

    
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() {
259
    return Enabled() && timer_.IsStarted();
260
  }
261

    
262
  // TODO(bmeurer): Remove this when HistogramTimerScope is fixed.
263
#ifdef DEBUG
264
  ElapsedTimer* timer() { return &timer_; }
265
#endif
266

    
267
 private:
268
  ElapsedTimer timer_;
269
};
270

    
271
// Helper class for scoping a HistogramTimer.
272
// TODO(bmeurer): The ifdeffery is an ugly hack around the fact that the
273
// Parser is currently reentrant (when it throws an error, we call back
274
// into JavaScript and all bets are off), but ElapsedTimer is not
275
// reentry-safe. Fix this properly and remove |allow_nesting|.
276
class HistogramTimerScope BASE_EMBEDDED {
277
 public:
278
  explicit HistogramTimerScope(HistogramTimer* timer,
279
                               bool allow_nesting = false)
280
#ifdef DEBUG
281
      : timer_(timer),
282
        skipped_timer_start_(false) {
283
    if (timer_->timer()->IsStarted() && allow_nesting) {
284
      skipped_timer_start_ = true;
285
    } else {
286
      timer_->Start();
287
    }
288
#else
289
      : timer_(timer) {
290
    timer_->Start();
291
#endif
292
  }
293
  ~HistogramTimerScope() {
294
#ifdef DEBUG
295
    if (!skipped_timer_start_) {
296
      timer_->Stop();
297
    }
298
#else
299
    timer_->Stop();
300
#endif
301
  }
302
 private:
303
  HistogramTimer* timer_;
304
#ifdef DEBUG
305
  bool skipped_timer_start_;
306
#endif
307
};
308

    
309

    
310
} }  // namespace v8::internal
311

    
312
#endif  // V8_COUNTERS_H_