| OLD | NEW |
| 1 // Copyright 2007-2008 the V8 project authors. All rights reserved. | 1 // Copyright 2007-2008 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 60 } | 60 } |
| 61 | 61 |
| 62 private: | 62 private: |
| 63 static CounterLookupCallback lookup_function_; | 63 static CounterLookupCallback lookup_function_; |
| 64 }; | 64 }; |
| 65 | 65 |
| 66 // StatsCounters are dynamically created values which can be tracked in | 66 // StatsCounters are dynamically created values which can be tracked in |
| 67 // the StatsTable. They are designed to be lightweight to create and | 67 // the StatsTable. They are designed to be lightweight to create and |
| 68 // easy to use. | 68 // easy to use. |
| 69 // | 69 // |
| 70 // The implementation of the StatsTable is external to this module. | |
| 71 // | |
| 72 // Example usage: | |
| 73 // { | |
| 74 // StatsCounter request_count("RequestCount"); | |
| 75 // request_count.Increment(); | |
| 76 // } | |
| 77 // | |
| 78 // Internally, a counter represents a value in a row of a StatsTable. | 70 // Internally, a counter represents a value in a row of a StatsTable. |
| 79 // The row has a 32bit value for each process/thread in the table and also | 71 // The row has a 32bit value for each process/thread in the table and also |
| 80 // a name (stored in the table metadata). Since the storage location can be | 72 // a name (stored in the table metadata). Since the storage location can be |
| 81 // thread-specific, this class cannot be shared across threads. | 73 // thread-specific, this class cannot be shared across threads. |
| 82 // | 74 // |
| 83 | 75 // This class is designed to be POD initialized. It will be registered with |
| 84 // StatsCounter represents a counter in the StatsTable class. | 76 // the counter system on first use. For example: |
| 85 class StatsCounter BASE_EMBEDDED { | 77 // StatsCounter c = { L"c:myctr", NULL, false }; |
| 86 public: | 78 struct StatsCounter { |
| 87 // Create a StatsCounter object. | 79 const wchar_t* name_; |
| 88 explicit StatsCounter(const wchar_t* name, int id) : | 80 int* ptr_; |
| 89 lookup_done_(false), | 81 bool lookup_done_; |
| 90 ptr_(NULL), | |
| 91 id_(id) { | |
| 92 int len = wcslen(name); | |
| 93 // we prepend the name with 'c:' to indicate that it is a counter. | |
| 94 name_ = Vector<wchar_t>::New(len+3); | |
| 95 OS::WcsCpy(name_, L"c:"); | |
| 96 OS::WcsCpy(name_ + 2, name); | |
| 97 }; | |
| 98 | |
| 99 ~StatsCounter() { | |
| 100 name_.Dispose(); | |
| 101 } | |
| 102 | 82 |
| 103 // Sets the counter to a specific value. | 83 // Sets the counter to a specific value. |
| 104 void Set(int value) { | 84 void Set(int value) { |
| 105 int* loc = GetPtr(); | 85 int* loc = GetPtr(); |
| 106 if (loc) *loc = value; | 86 if (loc) *loc = value; |
| 107 } | 87 } |
| 108 | 88 |
| 109 // Increments the counter. | 89 // Increments the counter. |
| 110 void Increment() { | 90 void Increment() { |
| 111 int* loc = GetPtr(); | 91 int* loc = GetPtr(); |
| (...skipping 25 matching lines...) Expand all Loading... |
| 137 | 117 |
| 138 // Get the internal pointer to the counter. This is used | 118 // Get the internal pointer to the counter. This is used |
| 139 // by the code generator to emit code that manipulates a | 119 // by the code generator to emit code that manipulates a |
| 140 // given counter without calling the runtime system. | 120 // given counter without calling the runtime system. |
| 141 int* GetInternalPointer() { | 121 int* GetInternalPointer() { |
| 142 int* loc = GetPtr(); | 122 int* loc = GetPtr(); |
| 143 ASSERT(loc != NULL); | 123 ASSERT(loc != NULL); |
| 144 return loc; | 124 return loc; |
| 145 } | 125 } |
| 146 | 126 |
| 147 int Id() { | |
| 148 return id_; | |
| 149 } | |
| 150 | |
| 151 protected: | 127 protected: |
| 152 StatsCounter() : | |
| 153 lookup_done_(false), | |
| 154 ptr_(NULL) { | |
| 155 } | |
| 156 | |
| 157 // Returns the cached address of this counter location. | 128 // Returns the cached address of this counter location. |
| 158 int* GetPtr() { | 129 int* GetPtr() { |
| 159 if (lookup_done_) | 130 if (lookup_done_) |
| 160 return ptr_; | 131 return ptr_; |
| 161 lookup_done_ = true; | 132 lookup_done_ = true; |
| 162 ptr_ = StatsTable::FindLocation(name_.start()); | 133 ptr_ = StatsTable::FindLocation(name_.start()); |
| 163 return ptr_; | 134 return ptr_; |
| 164 } | 135 } |
| 165 | |
| 166 Vector<wchar_t> name_; | |
| 167 bool lookup_done_; | |
| 168 int* ptr_; | |
| 169 int id_; | |
| 170 }; | 136 }; |
| 171 | 137 |
| 172 // A StatsCounterTimer is a StatsCounter which keeps a timer during | 138 // StatsCounterTimer t = { { L"t:foo", NULL, false }, 0, 0 }; |
| 173 // the scope of the StatsCounterTimer. On destruction, it will record | 139 struct StatsCounterTimer { |
| 174 // its time measurement. | 140 StatsCounter counter_; |
| 175 class StatsCounterTimer : StatsCounter { | 141 |
| 176 public: | 142 int64_t start_time_; |
| 177 // Constructs and starts the timer. | 143 int64_t stop_time_; |
| 178 explicit StatsCounterTimer(const wchar_t* name); | |
| 179 | 144 |
| 180 // Start the timer. | 145 // Start the timer. |
| 181 void Start(); | 146 void Start(); |
| 182 | 147 |
| 183 // Stop the timer and record the results. | 148 // Stop the timer and record the results. |
| 184 void Stop(); | 149 void Stop(); |
| 185 | 150 |
| 186 // Returns true if the timer is running. | 151 // Returns true if the timer is running. |
| 187 bool Running() { | 152 bool Running() { |
| 188 return Enabled() && start_time_ != 0 && stop_time_ == 0; | 153 return counter_.Enabled() && start_time_ != 0 && stop_time_ == 0; |
| 189 } | 154 } |
| 190 | |
| 191 private: | |
| 192 // Compute the delta between start and stop, in milliseconds. | |
| 193 void Record() { | |
| 194 int milliseconds = static_cast<int>(stop_time_ - start_time_) / 1000; | |
| 195 Increment(milliseconds); | |
| 196 } | |
| 197 | |
| 198 int64_t start_time_; | |
| 199 int64_t stop_time_; | |
| 200 }; | 155 }; |
| 201 | 156 |
| 202 | |
| 203 // A StatsRate is a combination of both a timer and a counter so that | 157 // A StatsRate is a combination of both a timer and a counter so that |
| 204 // several statistics can be produced: | 158 // several statistics can be produced: |
| 205 // min, max, avg, count, total | 159 // min, max, avg, count, total |
| 206 class StatsRate BASE_EMBEDDED { | 160 // |
| 207 public: | 161 // For example: |
| 208 // Constructs and starts the timer. | 162 // StatsCounter c = { { { L"t:myrate", NULL, false }, 0, 0 }, |
| 209 explicit StatsRate(const wchar_t* name, int id) : | 163 // { L"c:myrate", NULL, false } }; |
| 210 timer_(name), | 164 struct StatsRate { |
| 211 counter_(name, id) { | 165 StatsCounterTimer timer_; |
| 212 } | 166 StatsCounter counter_; |
| 213 | 167 |
| 214 // Starts the rate timer. | 168 // Starts the rate timer. |
| 215 void Start() { | 169 void Start() { |
| 216 timer_.Start(); | 170 timer_.Start(); |
| 217 } | 171 } |
| 218 | 172 |
| 219 // Stops the rate and records the time. | 173 // Stops the rate and records the time. |
| 220 void Stop() { | 174 void Stop() { |
| 221 if (timer_.Running()) { | 175 if (timer_.Running()) { |
| 222 timer_.Stop(); | 176 timer_.Stop(); |
| 223 counter_.Increment(); | 177 counter_.Increment(); |
| 224 } | 178 } |
| 225 } | 179 } |
| 226 | |
| 227 // Access to the timer. | |
| 228 StatsCounterTimer& timer() { return timer_; } | |
| 229 | |
| 230 private: | |
| 231 StatsCounterTimer timer_; | |
| 232 StatsCounter counter_; | |
| 233 }; | 180 }; |
| 234 | 181 |
| 235 | 182 |
| 236 // Helper class for scoping a timer. | |
| 237 class StatsTimerScope BASE_EMBEDDED { | |
| 238 public: | |
| 239 explicit StatsTimerScope(StatsCounterTimer* timer) : | |
| 240 timer_(timer) { | |
| 241 timer_->Start(); | |
| 242 } | |
| 243 ~StatsTimerScope() { | |
| 244 timer_->Stop(); | |
| 245 } | |
| 246 private: | |
| 247 StatsCounterTimer* timer_; | |
| 248 }; | |
| 249 | |
| 250 // Helper class for scoping a rate. | 183 // Helper class for scoping a rate. |
| 251 class StatsRateScope BASE_EMBEDDED { | 184 class StatsRateScope BASE_EMBEDDED { |
| 252 public: | 185 public: |
| 253 explicit StatsRateScope(StatsRate* rate) : | 186 explicit StatsRateScope(StatsRate* rate) : |
| 254 rate_(rate) { | 187 rate_(rate) { |
| 255 rate_->Start(); | 188 rate_->Start(); |
| 256 } | 189 } |
| 257 ~StatsRateScope() { | 190 ~StatsRateScope() { |
| 258 rate_->Stop(); | 191 rate_->Stop(); |
| 259 } | 192 } |
| 260 private: | 193 private: |
| 261 StatsRate* rate_; | 194 StatsRate* rate_; |
| 262 }; | 195 }; |
| 263 | 196 |
| 264 | 197 |
| 265 } } // namespace v8::internal | 198 } } // namespace v8::internal |
| 266 | 199 |
| 267 #endif // V8_COUNTERS_H_ | 200 #endif // V8_COUNTERS_H_ |
| OLD | NEW |