Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(189)

Side by Side Diff: src/profile-generator.h

Issue 2722005: The new JS Heap Profiler: the main part. (Closed)
Patch Set: Comments addressed Created 10 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | src/profile-generator.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 13 matching lines...) Expand all
24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 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. 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 27
28 #ifndef V8_PROFILE_GENERATOR_H_ 28 #ifndef V8_PROFILE_GENERATOR_H_
29 #define V8_PROFILE_GENERATOR_H_ 29 #define V8_PROFILE_GENERATOR_H_
30 30
31 #ifdef ENABLE_LOGGING_AND_PROFILING 31 #ifdef ENABLE_LOGGING_AND_PROFILING
32 32
33 #include "hashmap.h" 33 #include "hashmap.h"
34 #include "../include/v8-profiler.h"
34 35
35 namespace v8 { 36 namespace v8 {
36 namespace internal { 37 namespace internal {
37 38
38 class TokenEnumerator { 39 class TokenEnumerator {
39 public: 40 public:
40 TokenEnumerator(); 41 TokenEnumerator();
41 ~TokenEnumerator(); 42 ~TokenEnumerator();
42 int GetTokenId(Object* token); 43 int GetTokenId(Object* token);
43 44
44 static const int kNoSecurityToken = -1; 45 static const int kNoSecurityToken = -1;
45 static const int kInheritsSecurityToken = -2; 46 static const int kInheritsSecurityToken = -2;
46 47
47 private: 48 private:
48 static void TokenRemovedCallback(v8::Persistent<v8::Value> handle, 49 static void TokenRemovedCallback(v8::Persistent<v8::Value> handle,
49 void* parameter); 50 void* parameter);
50 void TokenRemoved(Object** token_location); 51 void TokenRemoved(Object** token_location);
51 52
52 List<Object**> token_locations_; 53 List<Object**> token_locations_;
53 List<bool> token_removed_; 54 List<bool> token_removed_;
54 55
55 friend class TokenEnumeratorTester; 56 friend class TokenEnumeratorTester;
57
58 DISALLOW_COPY_AND_ASSIGN(TokenEnumerator);
56 }; 59 };
57 60
58 61
59 // Provides a storage of strings allocated in C++ heap, to hold them 62 // Provides a storage of strings allocated in C++ heap, to hold them
60 // forever, even if they disappear from JS heap or external storage. 63 // forever, even if they disappear from JS heap or external storage.
61 class StringsStorage { 64 class StringsStorage {
62 public: 65 public:
63 StringsStorage(); 66 StringsStorage();
64 ~StringsStorage(); 67 ~StringsStorage();
65 68
(...skipping 284 matching lines...) Expand 10 before | Expand all | Expand 10 after
350 // order should provide enough precision while keeping away from a 353 // order should provide enough precision while keeping away from a
351 // potential overflow. 354 // potential overflow.
352 static const int kResultScale = 100000; 355 static const int kResultScale = 100000;
353 356
354 AtomicWord result_; 357 AtomicWord result_;
355 // All other fields are accessed only from the sampler thread. 358 // All other fields are accessed only from the sampler thread.
356 double ticks_per_ms_; 359 double ticks_per_ms_;
357 unsigned measurements_count_; 360 unsigned measurements_count_;
358 unsigned wall_time_query_countdown_; 361 unsigned wall_time_query_countdown_;
359 double last_wall_time_; 362 double last_wall_time_;
363
364 DISALLOW_COPY_AND_ASSIGN(SampleRateCalculator);
360 }; 365 };
361 366
362 367
363 class ProfileGenerator { 368 class ProfileGenerator {
364 public: 369 public:
365 explicit ProfileGenerator(CpuProfilesCollection* profiles); 370 explicit ProfileGenerator(CpuProfilesCollection* profiles);
366 371
367 INLINE(CodeEntry* NewCodeEntry(Logger::LogEventsAndTags tag, 372 INLINE(CodeEntry* NewCodeEntry(Logger::LogEventsAndTags tag,
368 String* name, 373 String* name,
369 String* resource_name, 374 String* resource_name,
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
409 414
410 CpuProfilesCollection* profiles_; 415 CpuProfilesCollection* profiles_;
411 CodeMap code_map_; 416 CodeMap code_map_;
412 CodeEntry* program_entry_; 417 CodeEntry* program_entry_;
413 CodeEntry* gc_entry_; 418 CodeEntry* gc_entry_;
414 SampleRateCalculator sample_rate_calc_; 419 SampleRateCalculator sample_rate_calc_;
415 420
416 DISALLOW_COPY_AND_ASSIGN(ProfileGenerator); 421 DISALLOW_COPY_AND_ASSIGN(ProfileGenerator);
417 }; 422 };
418 423
424
425 class HeapSnapshot;
426 class HeapEntry;
427
428
429 class HeapGraphEdge {
430 public:
431 enum Type {
432 CONTEXT_VARIABLE,
433 ELEMENT,
434 PROPERTY
435 };
436
437 HeapGraphEdge(Type type, const char* name, HeapEntry* from, HeapEntry* to);
438 HeapGraphEdge(int index, HeapEntry* from, HeapEntry* to);
439
440 Type type() const { return type_; }
441 int index() const {
442 ASSERT(type_ == ELEMENT);
443 return index_;
444 }
445 const char* name() const {
446 ASSERT(type_ == CONTEXT_VARIABLE || type_ == PROPERTY);
447 return name_;
448 }
449 HeapEntry* from() const { return from_; }
450 HeapEntry* to() const { return to_; }
451
452 private:
453 Type type_;
454 union {
455 int index_;
456 const char* name_;
457 };
458 HeapEntry* from_;
459 HeapEntry* to_;
460
461 DISALLOW_COPY_AND_ASSIGN(HeapGraphEdge);
462 };
463
464
465 class HeapGraphPath;
466 class CachedHeapGraphPath;
467
468 class HeapEntry {
469 public:
470 enum Type {
471 INTERNAL,
472 ARRAY,
473 STRING,
474 JS_OBJECT,
475 CODE,
476 CLOSURE
477 };
478
479 explicit HeapEntry(HeapSnapshot* snapshot)
480 : snapshot_(snapshot),
481 visited_(false),
482 type_(INTERNAL),
483 name_(""),
484 next_auto_index_(0),
485 self_size_(0),
486 security_token_id_(TokenEnumerator::kNoSecurityToken),
487 children_(1),
488 retainers_(0),
489 retaining_paths_(0),
490 total_size_(kUnknownSize),
491 non_shared_total_size_(kUnknownSize),
492 painted_(kUnpainted) { }
493 HeapEntry(HeapSnapshot* snapshot,
494 Type type,
495 const char* name,
496 int self_size,
497 int security_token_id)
498 : snapshot_(snapshot),
499 visited_(false),
500 type_(type),
501 name_(name),
502 next_auto_index_(1),
503 self_size_(self_size),
504 security_token_id_(security_token_id),
505 children_(4),
506 retainers_(4),
507 retaining_paths_(4),
508 total_size_(kUnknownSize),
509 non_shared_total_size_(kUnknownSize),
510 painted_(kUnpainted) { }
511 ~HeapEntry();
512
513 bool visited() const { return visited_; }
514 Type type() const { return type_; }
515 const char* name() const { return name_; }
516 int self_size() const { return self_size_; }
517 int security_token_id() const { return security_token_id_; }
518 bool painted_reachable() { return painted_ == kPaintReachable; }
519 bool not_painted_reachable_from_others() {
520 return painted_ != kPaintReachableFromOthers;
521 }
522 const List<HeapGraphEdge*>* children() const { return &children_; }
523 const List<HeapGraphEdge*>* retainers() const { return &retainers_; }
524 const List<HeapGraphPath*>* GetRetainingPaths();
525
526 void ClearPaint() { painted_ = kUnpainted; }
527 void CutEdges();
528 void MarkAsVisited() { visited_ = true; }
529 void PaintReachable() {
530 ASSERT(painted_ == kUnpainted);
531 painted_ = kPaintReachable;
532 }
533 void PaintReachableFromOthers() { painted_ = kPaintReachableFromOthers; }
534 void SetClosureReference(const char* name, HeapEntry* entry);
535 void SetElementReference(int index, HeapEntry* entry);
536 void SetPropertyReference(const char* name, HeapEntry* entry);
537 void SetAutoIndexReference(HeapEntry* entry);
538
539 int TotalSize();
540 int NonSharedTotalSize();
541
542 void Print(int max_depth, int indent);
543
544 private:
545 int CalculateTotalSize();
546 int CalculateNonSharedTotalSize();
547 void FindRetainingPaths(HeapEntry* node, CachedHeapGraphPath* prev_path);
548 void RemoveChild(HeapGraphEdge* edge);
549 void RemoveRetainer(HeapGraphEdge* edge);
550
551 const char* TypeAsString();
552
553 HeapSnapshot* snapshot_;
554 bool visited_;
555 Type type_;
556 const char* name_;
557 int next_auto_index_;
558 int self_size_;
559 int security_token_id_;
560 List<HeapGraphEdge*> children_;
561 List<HeapGraphEdge*> retainers_;
562 List<HeapGraphPath*> retaining_paths_;
563 int total_size_;
564 int non_shared_total_size_;
565 int painted_;
566
567 static const int kUnknownSize = -1;
568 static const int kUnpainted = 0;
569 static const int kPaintReachable = 1;
570 static const int kPaintReachableFromOthers = 2;
571
572 DISALLOW_IMPLICIT_CONSTRUCTORS(HeapEntry);
573 };
574
575
576 class HeapGraphPath {
577 public:
578 HeapGraphPath()
579 : path_(8) { }
580 explicit HeapGraphPath(const List<HeapGraphEdge*>& path);
581
582 void Add(HeapGraphEdge* edge) { path_.Add(edge); }
583 void Set(int index, HeapGraphEdge* edge) { path_[index] = edge; }
584 const List<HeapGraphEdge*>* path() const { return &path_; }
585
586 void Print();
587
588 private:
589 List<HeapGraphEdge*> path_;
590
591 DISALLOW_COPY_AND_ASSIGN(HeapGraphPath);
592 };
593
594
595 class HeapEntriesMap {
596 public:
597 HeapEntriesMap();
598 ~HeapEntriesMap();
599
600 void Alias(HeapObject* object, HeapEntry* entry);
601 void Apply(void (HeapEntry::*Func)(void));
602 template<class Visitor>
603 void Apply(Visitor* visitor);
604 HeapEntry* Map(HeapObject* object);
605 void Pair(HeapObject* object, HeapEntry* entry);
606
607 private:
608 INLINE(uint32_t Hash(HeapObject* object)) {
609 return static_cast<uint32_t>(reinterpret_cast<intptr_t>(object));
610 }
611 INLINE(static bool HeapObjectsMatch(void* key1, void* key2)) {
612 return key1 == key2;
613 }
614 INLINE(bool IsAlias(void* ptr)) {
615 return reinterpret_cast<intptr_t>(ptr) & kAliasTag;
616 }
617
618 static const intptr_t kAliasTag = 1;
619
620 HashMap entries_;
621
622 DISALLOW_COPY_AND_ASSIGN(HeapEntriesMap);
623 };
624
625
626 class HeapSnapshotsCollection;
627
628 // HeapSnapshot represents a single heap snapshot. It is stored in
629 // HeapSnapshotsCollection, which is also a factory for
630 // HeapSnapshots. All HeapSnapshots share strings copied from JS heap
631 // to be able to return them even if they were collected.
632 // HeapSnapshotGenerator fills in a HeapSnapshot.
633 class HeapSnapshot {
634 public:
635 HeapSnapshot(HeapSnapshotsCollection* collection,
636 const char* title,
637 unsigned uid);
638 void ClearPaint();
639 void CutObjectsFromForeignSecurityContexts();
640 HeapEntry* GetEntry(Object* object);
641 void SetClosureReference(
642 HeapEntry* parent, String* reference_name, Object* child);
643 void SetElementReference(HeapEntry* parent, int index, Object* child);
644 void SetPropertyReference(
645 HeapEntry* parent, String* reference_name, Object* child);
646
647 INLINE(const char* title() const) { return title_; }
648 INLINE(unsigned uid() const) { return uid_; }
649 const HeapEntry* const_root() const { return &root_; }
650 HeapEntry* root() { return &root_; }
651 template<class Visitor>
652 void IterateEntries(Visitor* visitor) { entries_.Apply(visitor); }
653
654 void Print(int max_depth);
655
656 private:
657 HeapEntry* AddEntry(HeapObject* object, HeapEntry::Type type) {
658 return AddEntry(object, type, "");
659 }
660 HeapEntry* AddEntry(
661 HeapObject* object, HeapEntry::Type type, const char* name);
662 void AddEntryAlias(HeapObject* object, HeapEntry* entry) {
663 entries_.Alias(object, entry);
664 }
665 HeapEntry* FindEntry(HeapObject* object) {
666 return entries_.Map(object);
667 }
668 int GetGlobalSecurityToken();
669 int GetObjectSecurityToken(HeapObject* obj);
670 static int GetObjectSize(HeapObject* obj);
671 static int CalculateNetworkSize(JSObject* obj);
672
673 HeapSnapshotsCollection* collection_;
674 const char* title_;
675 unsigned uid_;
676 HeapEntry root_;
677 // HeapObject* -> HeapEntry*
678 HeapEntriesMap entries_;
679
680 DISALLOW_COPY_AND_ASSIGN(HeapSnapshot);
681 };
682
683
684 class HeapSnapshotsCollection {
685 public:
686 HeapSnapshotsCollection();
687 ~HeapSnapshotsCollection();
688
689 HeapSnapshot* NewSnapshot(const char* name, unsigned uid);
690 List<HeapSnapshot*>* snapshots() { return &snapshots_; }
691 HeapSnapshot* GetSnapshot(unsigned uid);
692
693 const char* GetName(String* name) { return names_.GetName(name); }
694
695 TokenEnumerator* token_enumerator() { return token_enumerator_; }
696
697 private:
698 INLINE(static bool HeapSnapshotsMatch(void* key1, void* key2)) {
699 return key1 == key2;
700 }
701
702 List<HeapSnapshot*> snapshots_;
703 // uid -> HeapSnapshot*
704 HashMap snapshots_uids_;
705 StringsStorage names_;
706 TokenEnumerator* token_enumerator_;
707
708 DISALLOW_COPY_AND_ASSIGN(HeapSnapshotsCollection);
709 };
710
711
712 class HeapSnapshotGenerator {
713 public:
714 explicit HeapSnapshotGenerator(HeapSnapshot* snapshot);
715 void GenerateSnapshot();
716
717 private:
718 void ExtractReferences(HeapObject* obj);
719 void ExtractClosureReferences(JSObject* js_obj, HeapEntry* entry);
720 void ExtractPropertyReferences(JSObject* js_obj, HeapEntry* entry);
721 void ExtractElementReferences(JSObject* js_obj, HeapEntry* entry);
722
723 HeapSnapshot* snapshot_;
724
725 DISALLOW_COPY_AND_ASSIGN(HeapSnapshotGenerator);
726 };
727
419 } } // namespace v8::internal 728 } } // namespace v8::internal
420 729
421 #endif // ENABLE_LOGGING_AND_PROFILING 730 #endif // ENABLE_LOGGING_AND_PROFILING
422 731
423 #endif // V8_PROFILE_GENERATOR_H_ 732 #endif // V8_PROFILE_GENERATOR_H_
OLDNEW
« no previous file with comments | « no previous file | src/profile-generator.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698