OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #ifndef BASE_TRACKED_OBJECTS_H_ | 5 #ifndef BASE_TRACKED_OBJECTS_H_ |
6 #define BASE_TRACKED_OBJECTS_H_ | 6 #define BASE_TRACKED_OBJECTS_H_ |
7 #pragma once | 7 #pragma once |
8 | 8 |
9 #include <map> | 9 #include <map> |
10 #include <stack> | 10 #include <stack> |
(...skipping 322 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
333 return death_data_.run_duration_max(); | 333 return death_data_.run_duration_max(); |
334 } | 334 } |
335 DurationInt queue_duration() const { return death_data_.queue_duration(); } | 335 DurationInt queue_duration() const { return death_data_.queue_duration(); } |
336 DurationInt AverageMsQueueDuration() const { | 336 DurationInt AverageMsQueueDuration() const { |
337 return death_data_.AverageMsQueueDuration(); | 337 return death_data_.AverageMsQueueDuration(); |
338 } | 338 } |
339 DurationInt queue_duration_max() const { | 339 DurationInt queue_duration_max() const { |
340 return death_data_.queue_duration_max(); | 340 return death_data_.queue_duration_max(); |
341 } | 341 } |
342 | 342 |
343 // Emit contents for use in a line of HTML | |
344 void WriteHTML(std::string* output) const; | |
345 | |
346 // Construct a DictionaryValue instance containing all our data recursively. | 343 // Construct a DictionaryValue instance containing all our data recursively. |
347 // The caller assumes ownership of the memory in the returned instance. | 344 // The caller assumes ownership of the memory in the returned instance. |
348 base::DictionaryValue* ToValue() const; | 345 base::DictionaryValue* ToValue() const; |
349 | 346 |
350 private: | 347 private: |
351 const BirthOnThread* birth_; // Includes Location and birth_thread. | 348 const BirthOnThread* birth_; // Includes Location and birth_thread. |
352 const ThreadData* death_thread_; | 349 const ThreadData* death_thread_; |
353 DeathData death_data_; | 350 DeathData death_data_; |
354 }; | 351 }; |
355 | 352 |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
394 | 391 |
395 // The total number of births recorded at each location for which we have not | 392 // The total number of births recorded at each location for which we have not |
396 // seen a death count. This map changes as we do Append() calls, and is later | 393 // seen a death count. This map changes as we do Append() calls, and is later |
397 // used by AddListOfLivingObjects() to gather up unaccounted for births. | 394 // used by AddListOfLivingObjects() to gather up unaccounted for births. |
398 BirthCount global_birth_count_; | 395 BirthCount global_birth_count_; |
399 | 396 |
400 DISALLOW_COPY_AND_ASSIGN(DataCollector); | 397 DISALLOW_COPY_AND_ASSIGN(DataCollector); |
401 }; | 398 }; |
402 | 399 |
403 //------------------------------------------------------------------------------ | 400 //------------------------------------------------------------------------------ |
404 // Aggregation contains summaries (totals and subtotals) of groups of Snapshot | |
405 // instances to provide printing of these collections on a single line. | |
406 // We generally provide an aggregate total for the entire list, as well as | |
407 // aggregate subtotals for groups of stats (example: group of all lives that | |
408 // died on the specific thread). | |
409 | |
410 class BASE_EXPORT Aggregation: public DeathData { | |
411 public: | |
412 Aggregation(); | |
413 ~Aggregation(); | |
414 | |
415 void AddDeathSnapshot(const Snapshot& snapshot); | |
416 void AddBirths(const Births& births); | |
417 void AddBirth(const BirthOnThread& birth); | |
418 void AddBirthPlace(const Location& location); | |
419 void WriteHTML(std::string* output) const; | |
420 void Clear(); | |
421 | |
422 private: | |
423 int birth_count_; | |
424 std::map<std::string, int> birth_files_; | |
425 std::map<Location, int> locations_; | |
426 std::map<const ThreadData*, int> birth_threads_; | |
427 DeathData death_data_; | |
428 std::map<const ThreadData*, int> death_threads_; | |
429 | |
430 DISALLOW_COPY_AND_ASSIGN(Aggregation); | |
431 }; | |
432 | |
433 //------------------------------------------------------------------------------ | |
434 // Comparator is a class that supports the comparison of Snapshot instances. | |
435 // An instance is actually a list of chained Comparitors, that can provide for | |
436 // arbitrary ordering. The path portion of an about:profiler URL is translated | |
437 // into such a chain, which is then used to order Snapshot instances in a | |
438 // vector. It orders them into groups (for aggregation), and can also order | |
439 // instances within the groups (for detailed rendering of the instances in an | |
440 // aggregation). | |
441 | |
442 class BASE_EXPORT Comparator { | |
443 public: | |
444 // Selector enum is the token identifier for each parsed keyword, most of | |
445 // which specify a sort order. | |
446 // Since it is not meaningful to sort more than once on a specific key, we | |
447 // use bitfields to accumulate what we have sorted on so far. | |
448 enum Selector { | |
449 // Sort orders. | |
450 NIL = 0, | |
451 BIRTH_THREAD = 1, | |
452 DEATH_THREAD = 2, | |
453 BIRTH_FILE = 4, | |
454 BIRTH_FUNCTION = 8, | |
455 BIRTH_LINE = 16, | |
456 COUNT = 32, | |
457 AVERAGE_RUN_DURATION = 64, | |
458 TOTAL_RUN_DURATION = 128, | |
459 AVERAGE_QUEUE_DURATION = 256, | |
460 TOTAL_QUEUE_DURATION = 512, | |
461 MAX_RUN_DURATION = 1024, | |
462 MAX_QUEUE_DURATION = 2048, | |
463 | |
464 // Imediate action keywords. | |
465 RESET_ALL_DATA = -1, | |
466 UNKNOWN_KEYWORD = -2, | |
467 }; | |
468 | |
469 explicit Comparator(); | |
470 | |
471 // Reset the comparator to a NIL selector. Clear() and recursively delete any | |
472 // tiebreaker_ entries. NOTE: We can't use a standard destructor, because | |
473 // the sort algorithm makes copies of this object, and then deletes them, | |
474 // which would cause problems (either we'd make expensive deep copies, or we'd | |
475 // do more thna one delete on a tiebreaker_. | |
476 void Clear(); | |
477 | |
478 // The less() operator for sorting the array via std::sort(). | |
479 bool operator()(const Snapshot& left, const Snapshot& right) const; | |
480 | |
481 void Sort(DataCollector::Collection* collection) const; | |
482 | |
483 // Check to see if the items are sort equivalents (should be aggregated). | |
484 bool Equivalent(const Snapshot& left, const Snapshot& right) const; | |
485 | |
486 // Check to see if all required fields are present in the given sample. | |
487 bool Acceptable(const Snapshot& sample) const; | |
488 | |
489 // A comparator can be refined by specifying what to do if the selected basis | |
490 // for comparison is insufficient to establish an ordering. This call adds | |
491 // the indicated attribute as the new "least significant" basis of comparison. | |
492 void SetTiebreaker(Selector selector, const std::string& required); | |
493 | |
494 // Indicate if this instance is set up to sort by the given Selector, thereby | |
495 // putting that information in the SortGrouping, so it is not needed in each | |
496 // printed line. | |
497 bool IsGroupedBy(Selector selector) const; | |
498 | |
499 // Using the tiebreakers as set above, we mostly get an ordering, with some | |
500 // equivalent groups. If those groups are displayed (rather than just being | |
501 // aggregated, then the following is used to order them (within the group). | |
502 void SetSubgroupTiebreaker(Selector selector); | |
503 | |
504 // Translate a keyword and restriction in URL path to a selector for sorting. | |
505 void ParseKeyphrase(const std::string& key_phrase); | |
506 | |
507 // Parse a query to decide on sort ordering. | |
508 bool ParseQuery(const std::string& query); | |
509 | |
510 // Output a header line that can be used to indicated what items will be | |
511 // collected in the group. It lists all (potentially) tested attributes and | |
512 // their values (in the sample item). | |
513 bool WriteSortGrouping(const Snapshot& sample, std::string* output) const; | |
514 | |
515 // Output a sample, with SortGroup details not displayed. | |
516 void WriteSnapshotHTML(const Snapshot& sample, std::string* output) const; | |
517 | |
518 private: | |
519 // The selector directs this instance to compare based on the specified | |
520 // members of the tested elements. | |
521 enum Selector selector_; | |
522 | |
523 // Translate a path keyword into a selector. This is a slow implementation, | |
524 // but this is rarely done, and only for HTML presentations. | |
525 static Selector FindSelector(const std::string& keyword); | |
526 | |
527 // For filtering into acceptable and unacceptable snapshot instance, the | |
528 // following is required to be a substring of the selector_ field. | |
529 std::string required_; | |
530 | |
531 // If this instance can't decide on an ordering, we can consult a tie-breaker | |
532 // which may have a different basis of comparison. | |
533 Comparator* tiebreaker_; | |
534 | |
535 // We or together all the selectors we sort on (not counting sub-group | |
536 // selectors), so that we can tell if we've decided to group on any given | |
537 // criteria. | |
538 int combined_selectors_; | |
539 | |
540 // Some tiebreakrs are for subgroup ordering, and not for basic ordering (in | |
541 // preparation for aggregation). The subgroup tiebreakers are not consulted | |
542 // when deciding if two items are in equivalent groups. This flag tells us | |
543 // to ignore the tiebreaker when doing Equivalent() testing. | |
544 bool use_tiebreaker_for_sort_only_; | |
545 }; | |
546 | |
547 //------------------------------------------------------------------------------ | |
548 // For each thread, we have a ThreadData that stores all tracking info generated | 401 // For each thread, we have a ThreadData that stores all tracking info generated |
549 // on this thread. This prevents the need for locking as data accumulates. | 402 // on this thread. This prevents the need for locking as data accumulates. |
550 // We use ThreadLocalStorage to quickly identfy the current ThreadData context. | 403 // We use ThreadLocalStorage to quickly identfy the current ThreadData context. |
551 // We also have a linked list of ThreadData instances, and that list is used to | 404 // We also have a linked list of ThreadData instances, and that list is used to |
552 // harvest data from all existing instances. | 405 // harvest data from all existing instances. |
553 | 406 |
554 class BASE_EXPORT ThreadData { | 407 class BASE_EXPORT ThreadData { |
555 public: | 408 public: |
556 // Current allowable states of the tracking system. The states can vary | 409 // Current allowable states of the tracking system. The states can vary |
557 // between ACTIVE and DEACTIVATED, but can never go back to UNINITIALIZED. | 410 // between ACTIVE and DEACTIVATED, but can never go back to UNINITIALIZED. |
(...skipping 11 matching lines...) Expand all Loading... |
569 // set *before* any births on the threads have taken place. It is generally | 422 // set *before* any births on the threads have taken place. It is generally |
570 // only used by the message loop, which has a well defined thread name. | 423 // only used by the message loop, which has a well defined thread name. |
571 static void InitializeThreadContext(const std::string& suggested_name); | 424 static void InitializeThreadContext(const std::string& suggested_name); |
572 | 425 |
573 // Using Thread Local Store, find the current instance for collecting data. | 426 // Using Thread Local Store, find the current instance for collecting data. |
574 // If an instance does not exist, construct one (and remember it for use on | 427 // If an instance does not exist, construct one (and remember it for use on |
575 // this thread. | 428 // this thread. |
576 // This may return NULL if the system is disabled for any reason. | 429 // This may return NULL if the system is disabled for any reason. |
577 static ThreadData* Get(); | 430 static ThreadData* Get(); |
578 | 431 |
579 // For a given (unescaped) about:profiler query, develop resulting HTML, and | |
580 // append to output. | |
581 static void WriteHTML(const std::string& query, std::string* output); | |
582 | |
583 // For a given accumulated array of results, use the comparator to sort and | |
584 // subtotal, writing the results to the output. | |
585 static void WriteHTMLTotalAndSubtotals( | |
586 const DataCollector::Collection& match_array, | |
587 const Comparator& comparator, std::string* output); | |
588 | |
589 // Constructs a DictionaryValue instance containing all recursive results in | 432 // Constructs a DictionaryValue instance containing all recursive results in |
590 // our process. The caller assumes ownership of the memory in the returned | 433 // our process. The caller assumes ownership of the memory in the returned |
591 // instance. | 434 // instance. |
592 static base::DictionaryValue* ToValue(); | 435 static base::DictionaryValue* ToValue(); |
593 | 436 |
594 // Finds (or creates) a place to count births from the given location in this | 437 // Finds (or creates) a place to count births from the given location in this |
595 // thread, and increment that tally. | 438 // thread, and increment that tally. |
596 // TallyABirthIfActive will returns NULL if the birth cannot be tallied. | 439 // TallyABirthIfActive will returns NULL if the birth cannot be tallied. |
597 static Births* TallyABirthIfActive(const Location& location); | 440 static Births* TallyABirthIfActive(const Location& location); |
598 | 441 |
(...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
818 } | 661 } |
819 | 662 |
820 private: | 663 private: |
821 | 664 |
822 DISALLOW_COPY_AND_ASSIGN(AutoTracking); | 665 DISALLOW_COPY_AND_ASSIGN(AutoTracking); |
823 }; | 666 }; |
824 | 667 |
825 } // namespace tracked_objects | 668 } // namespace tracked_objects |
826 | 669 |
827 #endif // BASE_TRACKED_OBJECTS_H_ | 670 #endif // BASE_TRACKED_OBJECTS_H_ |
OLD | NEW |