Changeset 43619 in webkit for trunk/JavaScriptCore/bytecode/SamplingTool.h
- Timestamp:
- May 13, 2009, 2:10:02 AM (16 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/JavaScriptCore/bytecode/SamplingTool.h
r43553 r43619 273 273 }; 274 274 275 // AbstractSamplingCounter: 276 // 277 // Implements a named set of counters, printed on exit if ENABLE(SAMPLING_COUNTERS). 278 // See subclasses below, SamplingCounter, GlobalSamplingCounter and DeletableSamplingCounter. 279 class AbstractSamplingCounter { 280 friend class JIT; 281 friend class DeletableSamplingCounter; 282 public: 283 void count(uint32_t count = 1) 284 { 285 m_counter += count; 286 } 287 288 static void dump(); 289 290 protected: 291 // Effectively the contructor, however called lazily in the case of GlobalSamplingCounter. 292 void init(const char* name) 293 { 294 m_counter = 0; 295 m_name = name; 296 297 // Set m_next to point to the head of the chain, and inform whatever is 298 // currently at the head that this node will now hold the pointer to it. 299 m_next = s_abstractSamplingCounterChain; 300 s_abstractSamplingCounterChain->m_referer = &m_next; 301 // Add this node to the head of the list. 302 s_abstractSamplingCounterChain = this; 303 m_referer = &s_abstractSamplingCounterChain; 304 } 305 306 int64_t m_counter; 307 const char* m_name; 308 AbstractSamplingCounter* m_next; 309 // This is a pointer to the pointer to this node in the chain; used to 310 // allow fast linked list deletion. 311 AbstractSamplingCounter** m_referer; 312 // Null object used to detect end of static chain. 313 static AbstractSamplingCounter s_abstractSamplingCounterChainEnd; 314 static AbstractSamplingCounter* s_abstractSamplingCounterChain; 315 static bool s_completed; 316 }; 317 318 #if ENABLE(SAMPLING_COUNTERS) 319 // SamplingCounter: 320 // 321 // This class is suitable and (hopefully!) convenient for cases where a counter is 322 // required within the scope of a single function. It can be instantiated as a 323 // static variable since it contains a constructor but not a destructor (static 324 // variables in WebKit cannot have destructors). 325 // 326 // For example: 327 // 328 // void someFunction() 329 // { 330 // static SamplingCounter countMe("This is my counter. There are many like it, but this one is mine."); 331 // countMe.count(); 332 // // ... 333 // } 334 // 335 class SamplingCounter : public AbstractSamplingCounter { 336 public: 337 SamplingCounter(const char* name) { init(name); } 338 }; 339 340 // GlobalSamplingCounter: 341 // 342 // This class is suitable for use where a counter is to be declared globally, 343 // since it contains neither a constructor nor destructor. Instead, ensure 344 // that 'name()' is called to provide the counter with a name (and also to 345 // allow it to be printed out on exit). 346 // 347 // GlobalSamplingCounter globalCounter; 348 // 349 // void firstFunction() 350 // { 351 // // Put this within a function that is definitely called! 352 // // (Or alternatively alongside all calls to 'count()'). 353 // globalCounter.name("I Name You Destroyer."); 354 // globalCounter.count(); 355 // // ... 356 // } 357 // 358 // void secondFunction() 359 // { 360 // globalCounter.count(); 361 // // ... 362 // } 363 // 364 class GlobalSamplingCounter : public AbstractSamplingCounter { 365 public: 366 void name(const char* name) 367 { 368 // Global objects should be mapped in zero filled memory, so this should 369 // be a safe (albeit not necessarily threadsafe) check for 'first call'. 370 if (!m_next) 371 init(name); 372 } 373 }; 374 375 // DeletableSamplingCounter: 376 // 377 // The above classes (SamplingCounter, GlobalSamplingCounter), are intended for 378 // use within a global or static scope, and as such cannot have a destructor. 379 // This means there is no convenient way for them to remove themselves from the 380 // static list of counters, and should an instance of either class be freed 381 // before 'dump()' has walked over the list it will potentially walk over an 382 // invalid pointer. 383 // 384 // This class is intended for use where the counter may possibly be deleted before 385 // the program exits. Should this occur, the counter will print it's value to 386 // stderr, and remove itself from the static list. Example: 387 // 388 // DeletableSamplingCounter* counter = new DeletableSamplingCounter("The Counter With No Name"); 389 // counter->count(); 390 // delete counter; 391 // 392 class DeletableSamplingCounter : public AbstractSamplingCounter { 393 public: 394 DeletableSamplingCounter(const char* name) { init(name); } 395 396 ~DeletableSamplingCounter() 397 { 398 if (!s_completed) 399 fprintf(stderr, "DeletableSamplingCounter \"%s\" deleted early (with count %lld)\n", m_name, m_counter); 400 // Our m_referer pointer should know where the pointer to this node is, 401 // and m_next should know that this node is the previous node in the list. 402 ASSERT(*m_referer == this); 403 ASSERT(m_next->m_referer == &m_next); 404 // Remove this node from the list, and inform m_next that we have done so. 405 m_next->m_referer = m_referer; 406 *m_referer = m_next; 407 } 408 }; 409 #endif 410 275 411 } // namespace JSC 276 412
Note:
See TracChangeset
for help on using the changeset viewer.