| OLD | NEW |
| 1 // Copyright 2010 the V8 project authors. All rights reserved. | 1 // Copyright 2010 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 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 67 ~StringsStorage(); | 67 ~StringsStorage(); |
| 68 | 68 |
| 69 const char* GetName(String* name); | 69 const char* GetName(String* name); |
| 70 | 70 |
| 71 private: | 71 private: |
| 72 INLINE(static bool StringsMatch(void* key1, void* key2)) { | 72 INLINE(static bool StringsMatch(void* key1, void* key2)) { |
| 73 return strcmp(reinterpret_cast<char*>(key1), | 73 return strcmp(reinterpret_cast<char*>(key1), |
| 74 reinterpret_cast<char*>(key2)) == 0; | 74 reinterpret_cast<char*>(key2)) == 0; |
| 75 } | 75 } |
| 76 | 76 |
| 77 // String::Hash -> const char* | 77 // Mapping of strings by String::Hash to const char* strings. |
| 78 HashMap names_; | 78 HashMap names_; |
| 79 | 79 |
| 80 DISALLOW_COPY_AND_ASSIGN(StringsStorage); | 80 DISALLOW_COPY_AND_ASSIGN(StringsStorage); |
| 81 }; | 81 }; |
| 82 | 82 |
| 83 | 83 |
| 84 class CodeEntry { | 84 class CodeEntry { |
| 85 public: | 85 public: |
| 86 explicit INLINE(CodeEntry(int security_token_id)); | 86 explicit INLINE(CodeEntry(int security_token_id)); |
| 87 // CodeEntry doesn't own name strings, just references them. | 87 // CodeEntry doesn't own name strings, just references them. |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 149 } | 149 } |
| 150 | 150 |
| 151 INLINE(static uint32_t CodeEntryHash(CodeEntry* entry)) { | 151 INLINE(static uint32_t CodeEntryHash(CodeEntry* entry)) { |
| 152 return static_cast<int32_t>(reinterpret_cast<intptr_t>(entry)); | 152 return static_cast<int32_t>(reinterpret_cast<intptr_t>(entry)); |
| 153 } | 153 } |
| 154 | 154 |
| 155 ProfileTree* tree_; | 155 ProfileTree* tree_; |
| 156 CodeEntry* entry_; | 156 CodeEntry* entry_; |
| 157 unsigned total_ticks_; | 157 unsigned total_ticks_; |
| 158 unsigned self_ticks_; | 158 unsigned self_ticks_; |
| 159 // CodeEntry* -> ProfileNode* | 159 // Mapping from CodeEntry* to ProfileNode* |
| 160 HashMap children_; | 160 HashMap children_; |
| 161 List<ProfileNode*> children_list_; | 161 List<ProfileNode*> children_list_; |
| 162 | 162 |
| 163 DISALLOW_COPY_AND_ASSIGN(ProfileNode); | 163 DISALLOW_COPY_AND_ASSIGN(ProfileNode); |
| 164 }; | 164 }; |
| 165 | 165 |
| 166 | 166 |
| 167 class ProfileTree { | 167 class ProfileTree { |
| 168 public: | 168 public: |
| 169 ProfileTree(); | 169 ProfileTree(); |
| (...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 305 INLINE(const char* GetFunctionName(const char* name)); | 305 INLINE(const char* GetFunctionName(const char* name)); |
| 306 const char* GetName(int args_count); | 306 const char* GetName(int args_count); |
| 307 List<CpuProfile*>* GetProfilesList(int security_token_id); | 307 List<CpuProfile*>* GetProfilesList(int security_token_id); |
| 308 int TokenToIndex(int security_token_id); | 308 int TokenToIndex(int security_token_id); |
| 309 | 309 |
| 310 INLINE(static bool UidsMatch(void* key1, void* key2)) { | 310 INLINE(static bool UidsMatch(void* key1, void* key2)) { |
| 311 return key1 == key2; | 311 return key1 == key2; |
| 312 } | 312 } |
| 313 | 313 |
| 314 StringsStorage function_and_resource_names_; | 314 StringsStorage function_and_resource_names_; |
| 315 // args_count -> char* | 315 // Mapping from args_count (int) to char* strings. |
| 316 List<char*> args_count_names_; | 316 List<char*> args_count_names_; |
| 317 List<CodeEntry*> code_entries_; | 317 List<CodeEntry*> code_entries_; |
| 318 List<List<CpuProfile*>* > profiles_by_token_; | 318 List<List<CpuProfile*>* > profiles_by_token_; |
| 319 // uid -> index | 319 // Mapping from profiles' uids to indexes in the second nested list |
| 320 // of profiles_by_token_. |
| 320 HashMap profiles_uids_; | 321 HashMap profiles_uids_; |
| 321 | 322 |
| 322 // Accessed by VM thread and profile generator thread. | 323 // Accessed by VM thread and profile generator thread. |
| 323 List<CpuProfile*> current_profiles_; | 324 List<CpuProfile*> current_profiles_; |
| 324 Semaphore* current_profiles_semaphore_; | 325 Semaphore* current_profiles_semaphore_; |
| 325 | 326 |
| 326 DISALLOW_COPY_AND_ASSIGN(CpuProfilesCollection); | 327 DISALLOW_COPY_AND_ASSIGN(CpuProfilesCollection); |
| 327 }; | 328 }; |
| 328 | 329 |
| 329 | 330 |
| (...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 475 OBJECT = v8::HeapGraphNode::OBJECT, | 476 OBJECT = v8::HeapGraphNode::OBJECT, |
| 476 CODE = v8::HeapGraphNode::CODE, | 477 CODE = v8::HeapGraphNode::CODE, |
| 477 CLOSURE = v8::HeapGraphNode::CLOSURE | 478 CLOSURE = v8::HeapGraphNode::CLOSURE |
| 478 }; | 479 }; |
| 479 | 480 |
| 480 explicit HeapEntry(HeapSnapshot* snapshot) | 481 explicit HeapEntry(HeapSnapshot* snapshot) |
| 481 : snapshot_(snapshot), | 482 : snapshot_(snapshot), |
| 482 visited_(false), | 483 visited_(false), |
| 483 type_(INTERNAL), | 484 type_(INTERNAL), |
| 484 name_(""), | 485 name_(""), |
| 486 id_(0), |
| 485 next_auto_index_(0), | 487 next_auto_index_(0), |
| 486 self_size_(0), | 488 self_size_(0), |
| 487 security_token_id_(TokenEnumerator::kNoSecurityToken), | 489 security_token_id_(TokenEnumerator::kNoSecurityToken), |
| 488 children_(1), | 490 children_(1), |
| 489 retainers_(0), | 491 retainers_(0), |
| 490 retaining_paths_(0), | 492 retaining_paths_(0), |
| 491 total_size_(kUnknownSize), | 493 total_size_(kUnknownSize), |
| 492 non_shared_total_size_(kUnknownSize), | 494 non_shared_total_size_(kUnknownSize), |
| 493 painted_(kUnpainted) { } | 495 painted_(kUnpainted) { } |
| 494 HeapEntry(HeapSnapshot* snapshot, | 496 HeapEntry(HeapSnapshot* snapshot, |
| 495 Type type, | 497 Type type, |
| 496 const char* name, | 498 const char* name, |
| 499 int id, |
| 497 int self_size, | 500 int self_size, |
| 498 int security_token_id) | 501 int security_token_id) |
| 499 : snapshot_(snapshot), | 502 : snapshot_(snapshot), |
| 500 visited_(false), | 503 visited_(false), |
| 501 type_(type), | 504 type_(type), |
| 502 name_(name), | 505 name_(name), |
| 506 id_(id), |
| 503 next_auto_index_(1), | 507 next_auto_index_(1), |
| 504 self_size_(self_size), | 508 self_size_(self_size), |
| 505 security_token_id_(security_token_id), | 509 security_token_id_(security_token_id), |
| 506 children_(4), | 510 children_(4), |
| 507 retainers_(4), | 511 retainers_(4), |
| 508 retaining_paths_(4), | 512 retaining_paths_(4), |
| 509 total_size_(kUnknownSize), | 513 total_size_(kUnknownSize), |
| 510 non_shared_total_size_(kUnknownSize), | 514 non_shared_total_size_(kUnknownSize), |
| 511 painted_(kUnpainted) { } | 515 painted_(kUnpainted) { } |
| 512 ~HeapEntry(); | 516 ~HeapEntry(); |
| 513 | 517 |
| 514 bool visited() const { return visited_; } | 518 bool visited() const { return visited_; } |
| 515 Type type() const { return type_; } | 519 Type type() const { return type_; } |
| 516 const char* name() const { return name_; } | 520 const char* name() const { return name_; } |
| 521 uint64_t id() const { return id_; } |
| 517 int self_size() const { return self_size_; } | 522 int self_size() const { return self_size_; } |
| 518 int security_token_id() const { return security_token_id_; } | 523 int security_token_id() const { return security_token_id_; } |
| 519 bool painted_reachable() { return painted_ == kPaintReachable; } | 524 bool painted_reachable() { return painted_ == kPaintReachable; } |
| 520 bool not_painted_reachable_from_others() { | 525 bool not_painted_reachable_from_others() { |
| 521 return painted_ != kPaintReachableFromOthers; | 526 return painted_ != kPaintReachableFromOthers; |
| 522 } | 527 } |
| 523 const List<HeapGraphEdge*>* children() const { return &children_; } | 528 const List<HeapGraphEdge*>* children() const { return &children_; } |
| 524 const List<HeapGraphEdge*>* retainers() const { return &retainers_; } | 529 const List<HeapGraphEdge*>* retainers() const { return &retainers_; } |
| 525 const List<HeapGraphPath*>* GetRetainingPaths(); | 530 const List<HeapGraphPath*>* GetRetainingPaths(); |
| 526 | 531 |
| 532 template<class Visitor> |
| 533 void ApplyAndPaintAllReachable(Visitor* visitor); |
| 534 |
| 527 void ClearPaint() { painted_ = kUnpainted; } | 535 void ClearPaint() { painted_ = kUnpainted; } |
| 528 void CutEdges(); | 536 void CutEdges(); |
| 529 void MarkAsVisited() { visited_ = true; } | 537 void MarkAsVisited() { visited_ = true; } |
| 538 void PaintAllReachable(); |
| 530 void PaintReachable() { | 539 void PaintReachable() { |
| 531 ASSERT(painted_ == kUnpainted); | 540 ASSERT(painted_ == kUnpainted); |
| 532 painted_ = kPaintReachable; | 541 painted_ = kPaintReachable; |
| 533 } | 542 } |
| 534 void PaintReachableFromOthers() { painted_ = kPaintReachableFromOthers; } | 543 void PaintReachableFromOthers() { painted_ = kPaintReachableFromOthers; } |
| 535 void SetClosureReference(const char* name, HeapEntry* entry); | 544 void SetClosureReference(const char* name, HeapEntry* entry); |
| 536 void SetElementReference(int index, HeapEntry* entry); | 545 void SetElementReference(int index, HeapEntry* entry); |
| 537 void SetInternalReference(const char* name, HeapEntry* entry); | 546 void SetInternalReference(const char* name, HeapEntry* entry); |
| 538 void SetPropertyReference(const char* name, HeapEntry* entry); | 547 void SetPropertyReference(const char* name, HeapEntry* entry); |
| 539 void SetAutoIndexReference(HeapEntry* entry); | 548 void SetAutoIndexReference(HeapEntry* entry); |
| 549 void SetUnidirAutoIndexReference(HeapEntry* entry); |
| 540 | 550 |
| 541 int TotalSize(); | 551 int TotalSize(); |
| 542 int NonSharedTotalSize(); | 552 int NonSharedTotalSize(); |
| 543 | 553 |
| 544 void Print(int max_depth, int indent); | 554 void Print(int max_depth, int indent); |
| 545 | 555 |
| 546 private: | 556 private: |
| 547 void AddEdge(HeapGraphEdge* edge); | 557 void AddEdge(HeapGraphEdge* edge); |
| 548 int CalculateTotalSize(); | 558 int CalculateTotalSize(); |
| 549 int CalculateNonSharedTotalSize(); | 559 int CalculateNonSharedTotalSize(); |
| 550 void FindRetainingPaths(HeapEntry* node, CachedHeapGraphPath* prev_path); | 560 void FindRetainingPaths(HeapEntry* node, CachedHeapGraphPath* prev_path); |
| 551 void RemoveChild(HeapGraphEdge* edge); | 561 void RemoveChild(HeapGraphEdge* edge); |
| 552 void RemoveRetainer(HeapGraphEdge* edge); | 562 void RemoveRetainer(HeapGraphEdge* edge); |
| 553 | 563 |
| 554 const char* TypeAsString(); | 564 const char* TypeAsString(); |
| 555 | 565 |
| 556 HeapSnapshot* snapshot_; | 566 HeapSnapshot* snapshot_; |
| 557 bool visited_; | 567 bool visited_; |
| 558 Type type_; | 568 Type type_; |
| 559 const char* name_; | 569 const char* name_; |
| 570 uint64_t id_; |
| 560 int next_auto_index_; | 571 int next_auto_index_; |
| 561 int self_size_; | 572 int self_size_; |
| 562 int security_token_id_; | 573 int security_token_id_; |
| 563 List<HeapGraphEdge*> children_; | 574 List<HeapGraphEdge*> children_; |
| 564 List<HeapGraphEdge*> retainers_; | 575 List<HeapGraphEdge*> retainers_; |
| 565 List<HeapGraphPath*> retaining_paths_; | 576 List<HeapGraphPath*> retaining_paths_; |
| 566 int total_size_; | 577 int total_size_; |
| 567 int non_shared_total_size_; | 578 int non_shared_total_size_; |
| 568 int painted_; | 579 int painted_; |
| 569 | 580 |
| (...skipping 30 matching lines...) Expand all Loading... |
| 600 HeapEntriesMap(); | 611 HeapEntriesMap(); |
| 601 ~HeapEntriesMap(); | 612 ~HeapEntriesMap(); |
| 602 | 613 |
| 603 void Alias(HeapObject* object, HeapEntry* entry); | 614 void Alias(HeapObject* object, HeapEntry* entry); |
| 604 void Apply(void (HeapEntry::*Func)(void)); | 615 void Apply(void (HeapEntry::*Func)(void)); |
| 605 template<class Visitor> | 616 template<class Visitor> |
| 606 void Apply(Visitor* visitor); | 617 void Apply(Visitor* visitor); |
| 607 HeapEntry* Map(HeapObject* object); | 618 HeapEntry* Map(HeapObject* object); |
| 608 void Pair(HeapObject* object, HeapEntry* entry); | 619 void Pair(HeapObject* object, HeapEntry* entry); |
| 609 | 620 |
| 621 uint32_t capacity() { return entries_.capacity(); } |
| 622 |
| 610 private: | 623 private: |
| 611 INLINE(uint32_t Hash(HeapObject* object)) { | 624 INLINE(uint32_t Hash(HeapObject* object)) { |
| 612 return static_cast<uint32_t>(reinterpret_cast<intptr_t>(object)); | 625 return static_cast<uint32_t>(reinterpret_cast<intptr_t>(object)); |
| 613 } | 626 } |
| 614 INLINE(static bool HeapObjectsMatch(void* key1, void* key2)) { | 627 INLINE(static bool HeapObjectsMatch(void* key1, void* key2)) { |
| 615 return key1 == key2; | 628 return key1 == key2; |
| 616 } | 629 } |
| 617 INLINE(bool IsAlias(void* ptr)) { | 630 INLINE(bool IsAlias(void* ptr)) { |
| 618 return reinterpret_cast<intptr_t>(ptr) & kAliasTag; | 631 return reinterpret_cast<intptr_t>(ptr) & kAliasTag; |
| 619 } | 632 } |
| 620 | 633 |
| 621 static const intptr_t kAliasTag = 1; | 634 static const intptr_t kAliasTag = 1; |
| 622 | 635 |
| 623 HashMap entries_; | 636 HashMap entries_; |
| 624 | 637 |
| 625 DISALLOW_COPY_AND_ASSIGN(HeapEntriesMap); | 638 DISALLOW_COPY_AND_ASSIGN(HeapEntriesMap); |
| 626 }; | 639 }; |
| 627 | 640 |
| 628 | 641 |
| 629 class HeapSnapshotsCollection; | 642 class HeapSnapshotsCollection; |
| 643 class HeapSnapshotsDiff; |
| 630 | 644 |
| 631 // HeapSnapshot represents a single heap snapshot. It is stored in | 645 // HeapSnapshot represents a single heap snapshot. It is stored in |
| 632 // HeapSnapshotsCollection, which is also a factory for | 646 // HeapSnapshotsCollection, which is also a factory for |
| 633 // HeapSnapshots. All HeapSnapshots share strings copied from JS heap | 647 // HeapSnapshots. All HeapSnapshots share strings copied from JS heap |
| 634 // to be able to return them even if they were collected. | 648 // to be able to return them even if they were collected. |
| 635 // HeapSnapshotGenerator fills in a HeapSnapshot. | 649 // HeapSnapshotGenerator fills in a HeapSnapshot. |
| 636 class HeapSnapshot { | 650 class HeapSnapshot { |
| 637 public: | 651 public: |
| 638 HeapSnapshot(HeapSnapshotsCollection* collection, | 652 HeapSnapshot(HeapSnapshotsCollection* collection, |
| 639 const char* title, | 653 const char* title, |
| 640 unsigned uid); | 654 unsigned uid); |
| 655 ~HeapSnapshot(); |
| 641 void ClearPaint(); | 656 void ClearPaint(); |
| 642 void CutObjectsFromForeignSecurityContexts(); | 657 void CutObjectsFromForeignSecurityContexts(); |
| 643 HeapEntry* GetEntry(Object* object); | 658 HeapEntry* GetEntry(Object* object); |
| 644 void SetClosureReference( | 659 void SetClosureReference( |
| 645 HeapEntry* parent, String* reference_name, Object* child); | 660 HeapEntry* parent, String* reference_name, Object* child); |
| 646 void SetElementReference(HeapEntry* parent, int index, Object* child); | 661 void SetElementReference(HeapEntry* parent, int index, Object* child); |
| 647 void SetInternalReference( | 662 void SetInternalReference( |
| 648 HeapEntry* parent, const char* reference_name, Object* child); | 663 HeapEntry* parent, const char* reference_name, Object* child); |
| 649 void SetPropertyReference( | 664 void SetPropertyReference( |
| 650 HeapEntry* parent, String* reference_name, Object* child); | 665 HeapEntry* parent, String* reference_name, Object* child); |
| 651 | 666 |
| 652 INLINE(const char* title() const) { return title_; } | 667 INLINE(const char* title() const) { return title_; } |
| 653 INLINE(unsigned uid() const) { return uid_; } | 668 INLINE(unsigned uid() const) { return uid_; } |
| 654 const HeapEntry* const_root() const { return &root_; } | 669 const HeapEntry* const_root() const { return &root_; } |
| 655 HeapEntry* root() { return &root_; } | 670 HeapEntry* root() { return &root_; } |
| 656 template<class Visitor> | 671 template<class Visitor> |
| 657 void IterateEntries(Visitor* visitor) { entries_.Apply(visitor); } | 672 void IterateEntries(Visitor* visitor) { entries_.Apply(visitor); } |
| 673 List<HeapEntry*>* GetSortedEntriesList(); |
| 674 HeapSnapshotsDiff* CompareWith(HeapSnapshot* snapshot); |
| 658 | 675 |
| 659 void Print(int max_depth); | 676 void Print(int max_depth); |
| 660 | 677 |
| 661 private: | 678 private: |
| 662 HeapEntry* AddEntry(HeapObject* object, HeapEntry::Type type) { | 679 HeapEntry* AddEntry(HeapObject* object, HeapEntry::Type type) { |
| 663 return AddEntry(object, type, ""); | 680 return AddEntry(object, type, ""); |
| 664 } | 681 } |
| 665 HeapEntry* AddEntry( | 682 HeapEntry* AddEntry( |
| 666 HeapObject* object, HeapEntry::Type type, const char* name); | 683 HeapObject* object, HeapEntry::Type type, const char* name); |
| 667 void AddEntryAlias(HeapObject* object, HeapEntry* entry) { | 684 void AddEntryAlias(HeapObject* object, HeapEntry* entry) { |
| 668 entries_.Alias(object, entry); | 685 entries_.Alias(object, entry); |
| 669 } | 686 } |
| 670 HeapEntry* FindEntry(HeapObject* object) { | 687 HeapEntry* FindEntry(HeapObject* object) { |
| 671 return entries_.Map(object); | 688 return entries_.Map(object); |
| 672 } | 689 } |
| 673 int GetGlobalSecurityToken(); | 690 int GetGlobalSecurityToken(); |
| 674 int GetObjectSecurityToken(HeapObject* obj); | 691 int GetObjectSecurityToken(HeapObject* obj); |
| 675 static int GetObjectSize(HeapObject* obj); | 692 static int GetObjectSize(HeapObject* obj); |
| 676 static int CalculateNetworkSize(JSObject* obj); | 693 static int CalculateNetworkSize(JSObject* obj); |
| 677 | 694 |
| 678 HeapSnapshotsCollection* collection_; | 695 HeapSnapshotsCollection* collection_; |
| 679 const char* title_; | 696 const char* title_; |
| 680 unsigned uid_; | 697 unsigned uid_; |
| 681 HeapEntry root_; | 698 HeapEntry root_; |
| 682 // HeapObject* -> HeapEntry* | 699 // Mapping from HeapObject* pointers to HeapEntry* pointers. |
| 683 HeapEntriesMap entries_; | 700 HeapEntriesMap entries_; |
| 701 // Entries sorted by id. |
| 702 List<HeapEntry*>* sorted_entries_; |
| 684 | 703 |
| 685 DISALLOW_COPY_AND_ASSIGN(HeapSnapshot); | 704 DISALLOW_COPY_AND_ASSIGN(HeapSnapshot); |
| 686 }; | 705 }; |
| 687 | 706 |
| 688 | 707 |
| 708 class HeapObjectsMap { |
| 709 public: |
| 710 HeapObjectsMap(); |
| 711 ~HeapObjectsMap(); |
| 712 |
| 713 void SnapshotGenerationFinished(); |
| 714 uint64_t FindObject(Address addr); |
| 715 void MoveObject(Address from, Address to); |
| 716 |
| 717 private: |
| 718 struct EntryInfo { |
| 719 explicit EntryInfo(uint64_t id) : id(id), accessed(true) { } |
| 720 EntryInfo(uint64_t id, bool accessed) : id(id), accessed(accessed) { } |
| 721 uint64_t id; |
| 722 bool accessed; |
| 723 }; |
| 724 |
| 725 void AddEntry(Address addr, uint64_t id); |
| 726 uint64_t FindEntry(Address addr); |
| 727 void RemoveDeadEntries(); |
| 728 |
| 729 static bool AddressesMatch(void* key1, void* key2) { |
| 730 return key1 == key2; |
| 731 } |
| 732 |
| 733 static uint32_t AddressHash(Address addr) { |
| 734 return static_cast<int32_t>(reinterpret_cast<intptr_t>(addr)); |
| 735 } |
| 736 |
| 737 bool initial_fill_mode_; |
| 738 uint64_t next_id_; |
| 739 HashMap entries_map_; |
| 740 List<EntryInfo>* entries_; |
| 741 |
| 742 DISALLOW_COPY_AND_ASSIGN(HeapObjectsMap); |
| 743 }; |
| 744 |
| 745 |
| 746 class HeapSnapshotsDiff { |
| 747 public: |
| 748 HeapSnapshotsDiff(HeapSnapshot* snapshot1, HeapSnapshot* snapshot2) |
| 749 : snapshot1_(snapshot1), |
| 750 snapshot2_(snapshot2), |
| 751 additions_root_(new HeapEntry(snapshot2)), |
| 752 deletions_root_(new HeapEntry(snapshot1)) { } |
| 753 |
| 754 ~HeapSnapshotsDiff() { |
| 755 delete deletions_root_; |
| 756 delete additions_root_; |
| 757 } |
| 758 |
| 759 void AddAddedEntry(HeapEntry* entry) { |
| 760 additions_root_->SetUnidirAutoIndexReference(entry); |
| 761 } |
| 762 |
| 763 void AddDeletedEntry(HeapEntry* entry) { |
| 764 deletions_root_->SetUnidirAutoIndexReference(entry); |
| 765 } |
| 766 |
| 767 const HeapEntry* additions_root() const { return additions_root_; } |
| 768 const HeapEntry* deletions_root() const { return deletions_root_; } |
| 769 |
| 770 private: |
| 771 HeapSnapshot* snapshot1_; |
| 772 HeapSnapshot* snapshot2_; |
| 773 HeapEntry* additions_root_; |
| 774 HeapEntry* deletions_root_; |
| 775 |
| 776 DISALLOW_COPY_AND_ASSIGN(HeapSnapshotsDiff); |
| 777 }; |
| 778 |
| 779 |
| 780 class HeapSnapshotsComparator { |
| 781 public: |
| 782 HeapSnapshotsComparator() { } |
| 783 ~HeapSnapshotsComparator(); |
| 784 HeapSnapshotsDiff* Compare(HeapSnapshot* snapshot1, HeapSnapshot* snapshot2); |
| 785 private: |
| 786 List<HeapSnapshotsDiff*> diffs_; |
| 787 |
| 788 DISALLOW_COPY_AND_ASSIGN(HeapSnapshotsComparator); |
| 789 }; |
| 790 |
| 791 |
| 689 class HeapSnapshotsCollection { | 792 class HeapSnapshotsCollection { |
| 690 public: | 793 public: |
| 691 HeapSnapshotsCollection(); | 794 HeapSnapshotsCollection(); |
| 692 ~HeapSnapshotsCollection(); | 795 ~HeapSnapshotsCollection(); |
| 693 | 796 |
| 797 bool is_tracking_objects() { return is_tracking_objects_; } |
| 798 |
| 694 HeapSnapshot* NewSnapshot(const char* name, unsigned uid); | 799 HeapSnapshot* NewSnapshot(const char* name, unsigned uid); |
| 800 void SnapshotGenerationFinished() { ids_.SnapshotGenerationFinished(); } |
| 695 List<HeapSnapshot*>* snapshots() { return &snapshots_; } | 801 List<HeapSnapshot*>* snapshots() { return &snapshots_; } |
| 696 HeapSnapshot* GetSnapshot(unsigned uid); | 802 HeapSnapshot* GetSnapshot(unsigned uid); |
| 697 | 803 |
| 698 const char* GetName(String* name) { return names_.GetName(name); } | 804 const char* GetName(String* name) { return names_.GetName(name); } |
| 699 | 805 |
| 700 TokenEnumerator* token_enumerator() { return token_enumerator_; } | 806 TokenEnumerator* token_enumerator() { return token_enumerator_; } |
| 701 | 807 |
| 808 uint64_t GetObjectId(Address addr) { return ids_.FindObject(addr); } |
| 809 void ObjectMoveEvent(Address from, Address to) { ids_.MoveObject(from, to); } |
| 810 |
| 811 HeapSnapshotsDiff* CompareSnapshots(HeapSnapshot* snapshot1, |
| 812 HeapSnapshot* snapshot2); |
| 813 |
| 702 private: | 814 private: |
| 703 INLINE(static bool HeapSnapshotsMatch(void* key1, void* key2)) { | 815 INLINE(static bool HeapSnapshotsMatch(void* key1, void* key2)) { |
| 704 return key1 == key2; | 816 return key1 == key2; |
| 705 } | 817 } |
| 706 | 818 |
| 819 bool is_tracking_objects_; // Whether tracking object moves is needed. |
| 707 List<HeapSnapshot*> snapshots_; | 820 List<HeapSnapshot*> snapshots_; |
| 708 // uid -> HeapSnapshot* | 821 // Mapping from snapshots' uids to HeapSnapshot* pointers. |
| 709 HashMap snapshots_uids_; | 822 HashMap snapshots_uids_; |
| 710 StringsStorage names_; | 823 StringsStorage names_; |
| 711 TokenEnumerator* token_enumerator_; | 824 TokenEnumerator* token_enumerator_; |
| 825 // Mapping from HeapObject addresses to objects' uids. |
| 826 HeapObjectsMap ids_; |
| 827 HeapSnapshotsComparator comparator_; |
| 712 | 828 |
| 713 DISALLOW_COPY_AND_ASSIGN(HeapSnapshotsCollection); | 829 DISALLOW_COPY_AND_ASSIGN(HeapSnapshotsCollection); |
| 714 }; | 830 }; |
| 715 | 831 |
| 716 | 832 |
| 717 class HeapSnapshotGenerator { | 833 class HeapSnapshotGenerator { |
| 718 public: | 834 public: |
| 719 explicit HeapSnapshotGenerator(HeapSnapshot* snapshot); | 835 explicit HeapSnapshotGenerator(HeapSnapshot* snapshot); |
| 720 void GenerateSnapshot(); | 836 void GenerateSnapshot(); |
| 721 | 837 |
| 722 private: | 838 private: |
| 723 void ExtractReferences(HeapObject* obj); | 839 void ExtractReferences(HeapObject* obj); |
| 724 void ExtractClosureReferences(JSObject* js_obj, HeapEntry* entry); | 840 void ExtractClosureReferences(JSObject* js_obj, HeapEntry* entry); |
| 725 void ExtractPropertyReferences(JSObject* js_obj, HeapEntry* entry); | 841 void ExtractPropertyReferences(JSObject* js_obj, HeapEntry* entry); |
| 726 void ExtractElementReferences(JSObject* js_obj, HeapEntry* entry); | 842 void ExtractElementReferences(JSObject* js_obj, HeapEntry* entry); |
| 727 | 843 |
| 728 HeapSnapshot* snapshot_; | 844 HeapSnapshot* snapshot_; |
| 729 | 845 |
| 730 DISALLOW_COPY_AND_ASSIGN(HeapSnapshotGenerator); | 846 DISALLOW_COPY_AND_ASSIGN(HeapSnapshotGenerator); |
| 731 }; | 847 }; |
| 732 | 848 |
| 733 } } // namespace v8::internal | 849 } } // namespace v8::internal |
| 734 | 850 |
| 735 #endif // ENABLE_LOGGING_AND_PROFILING | 851 #endif // ENABLE_LOGGING_AND_PROFILING |
| 736 | 852 |
| 737 #endif // V8_PROFILE_GENERATOR_H_ | 853 #endif // V8_PROFILE_GENERATOR_H_ |
| OLD | NEW |