OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project 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 V8_HEAP_H_ | 5 #ifndef V8_HEAP_H_ |
6 #define V8_HEAP_H_ | 6 #define V8_HEAP_H_ |
7 | 7 |
8 #include <cmath> | 8 #include <cmath> |
9 | 9 |
10 #include "src/allocation.h" | 10 #include "src/allocation.h" |
(...skipping 529 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
540 | 540 |
541 DISALLOW_COPY_AND_ASSIGN(ExternalStringTable); | 541 DISALLOW_COPY_AND_ASSIGN(ExternalStringTable); |
542 }; | 542 }; |
543 | 543 |
544 | 544 |
545 enum ArrayStorageAllocationMode { | 545 enum ArrayStorageAllocationMode { |
546 DONT_INITIALIZE_ARRAY_ELEMENTS, | 546 DONT_INITIALIZE_ARRAY_ELEMENTS, |
547 INITIALIZE_ARRAY_ELEMENTS_WITH_HOLE | 547 INITIALIZE_ARRAY_ELEMENTS_WITH_HOLE |
548 }; | 548 }; |
549 | 549 |
| 550 // TODO(ernstm): Move into GCTracer. |
| 551 // A simple ring buffer class with maximum size known at compile time. |
| 552 // The class only implements the functionality required in GCTracer. |
| 553 template <typename T, size_t MAX_SIZE> |
| 554 class RingBuffer { |
| 555 public: |
| 556 class const_iterator { |
| 557 public: |
| 558 const_iterator() : index_(0), elements_(NULL) {} |
| 559 |
| 560 const_iterator(size_t index, const T* elements) |
| 561 : index_(index), elements_(elements) {} |
| 562 |
| 563 bool operator==(const const_iterator& rhs) const { |
| 564 return elements_ == rhs.elements_ && index_ == rhs.index_; |
| 565 } |
| 566 |
| 567 bool operator!=(const const_iterator& rhs) const { |
| 568 return elements_ != rhs.elements_ || index_ != rhs.index_; |
| 569 } |
| 570 |
| 571 operator const T*() const { return elements_ + index_; } |
| 572 |
| 573 const T* operator->() const { return elements_ + index_; } |
| 574 |
| 575 const T& operator*() const { return elements_[index_]; } |
| 576 |
| 577 const_iterator& operator++() { |
| 578 index_ = (index_ + 1) % (MAX_SIZE + 1); |
| 579 return *this; |
| 580 } |
| 581 |
| 582 const_iterator& operator--() { |
| 583 index_ = (index_ + MAX_SIZE) % (MAX_SIZE + 1); |
| 584 return *this; |
| 585 } |
| 586 |
| 587 private: |
| 588 size_t index_; |
| 589 const T* elements_; |
| 590 }; |
| 591 |
| 592 RingBuffer() : begin_(0), end_(0) {} |
| 593 |
| 594 bool empty() const { return begin_ == end_; } |
| 595 size_t size() const { |
| 596 return (end_ - begin_ + MAX_SIZE + 1) % (MAX_SIZE + 1); |
| 597 } |
| 598 const_iterator begin() const { return const_iterator(begin_, elements_); } |
| 599 const_iterator end() const { return const_iterator(end_, elements_); } |
| 600 const_iterator back() const { return --end(); } |
| 601 void push_back(const T& element) { |
| 602 elements_[end_] = element; |
| 603 end_ = (end_ + 1) % (MAX_SIZE + 1); |
| 604 if (end_ == begin_) begin_ = (begin_ + 1) % (MAX_SIZE + 1); |
| 605 } |
| 606 void push_front(const T& element) { |
| 607 begin_ = (begin_ + MAX_SIZE) % (MAX_SIZE + 1); |
| 608 if (begin_ == end_) end_ = (end_ + MAX_SIZE) % (MAX_SIZE + 1); |
| 609 elements_[begin_] = element; |
| 610 } |
| 611 |
| 612 private: |
| 613 T elements_[MAX_SIZE + 1]; |
| 614 size_t begin_; |
| 615 size_t end_; |
| 616 |
| 617 DISALLOW_COPY_AND_ASSIGN(RingBuffer); |
| 618 }; |
| 619 |
550 | 620 |
551 // GCTracer collects and prints ONE line after each garbage collector | 621 // GCTracer collects and prints ONE line after each garbage collector |
552 // invocation IFF --trace_gc is used. | 622 // invocation IFF --trace_gc is used. |
553 | 623 |
| 624 // TODO(ernstm): Unit tests. Move to separate file. |
554 class GCTracer BASE_EMBEDDED { | 625 class GCTracer BASE_EMBEDDED { |
555 public: | 626 public: |
556 class Scope BASE_EMBEDDED { | 627 class Scope BASE_EMBEDDED { |
557 public: | 628 public: |
558 enum ScopeId { | 629 enum ScopeId { |
559 EXTERNAL, | 630 EXTERNAL, |
560 MC_MARK, | 631 MC_MARK, |
561 MC_SWEEP, | 632 MC_SWEEP, |
562 MC_SWEEP_NEWSPACE, | 633 MC_SWEEP_NEWSPACE, |
563 MC_SWEEP_OLDSPACE, | 634 MC_SWEEP_OLDSPACE, |
(...skipping 14 matching lines...) Expand all Loading... |
578 }; | 649 }; |
579 | 650 |
580 Scope(GCTracer* tracer, ScopeId scope) | 651 Scope(GCTracer* tracer, ScopeId scope) |
581 : tracer_(tracer), | 652 : tracer_(tracer), |
582 scope_(scope) { | 653 scope_(scope) { |
583 start_time_ = base::OS::TimeCurrentMillis(); | 654 start_time_ = base::OS::TimeCurrentMillis(); |
584 } | 655 } |
585 | 656 |
586 ~Scope() { | 657 ~Scope() { |
587 ASSERT(scope_ < NUMBER_OF_SCOPES); // scope_ is unsigned. | 658 ASSERT(scope_ < NUMBER_OF_SCOPES); // scope_ is unsigned. |
588 tracer_->scopes_[scope_] += base::OS::TimeCurrentMillis() - start_time_; | 659 tracer_->current_.scopes[scope_] += |
| 660 base::OS::TimeCurrentMillis() - start_time_; |
589 } | 661 } |
590 | 662 |
591 private: | 663 private: |
592 GCTracer* tracer_; | 664 GCTracer* tracer_; |
593 ScopeId scope_; | 665 ScopeId scope_; |
594 double start_time_; | 666 double start_time_; |
595 | 667 |
596 DISALLOW_COPY_AND_ASSIGN(Scope); | 668 DISALLOW_COPY_AND_ASSIGN(Scope); |
597 }; | 669 }; |
598 | 670 |
| 671 |
| 672 class Event { |
| 673 public: |
| 674 enum Type { SCAVENGER = 0, MARK_COMPACTOR = 1, START = 2 }; |
| 675 |
| 676 // Default constructor leaves the event uninitialized. |
| 677 Event() {} |
| 678 |
| 679 Event(Type type, const char* gc_reason, const char* collector_reason); |
| 680 |
| 681 // Returns a string describing the event type. |
| 682 const char* TypeName(bool short_name) const; |
| 683 |
| 684 // Type of event |
| 685 Type type; |
| 686 |
| 687 const char* gc_reason; |
| 688 const char* collector_reason; |
| 689 |
| 690 // Timestamp set in the constructor. |
| 691 double start_time; |
| 692 |
| 693 // Timestamp set in the destructor. |
| 694 double end_time; |
| 695 |
| 696 // Size of objects in heap set in constructor. |
| 697 intptr_t start_object_size; |
| 698 |
| 699 // Size of objects in heap set in destructor. |
| 700 intptr_t end_object_size; |
| 701 |
| 702 // Size of memory allocated from OS set in constructor. |
| 703 intptr_t start_memory_size; |
| 704 |
| 705 // Size of memory allocated from OS set in destructor. |
| 706 intptr_t end_memory_size; |
| 707 |
| 708 // Total amount of space either wasted or contained in one of free lists |
| 709 // before the current GC. |
| 710 intptr_t start_holes_size; |
| 711 |
| 712 // Total amount of space either wasted or contained in one of free lists |
| 713 // after the current GC. |
| 714 intptr_t end_holes_size; |
| 715 |
| 716 // Number of incremental marking steps since creation of tracer. |
| 717 // (value at start of event) |
| 718 int incremental_marking_steps; |
| 719 |
| 720 // Cumulative duration of incremental marking steps since creation of |
| 721 // tracer. (value at start of event) |
| 722 double incremental_marking_duration; |
| 723 |
| 724 // Longest incremental marking step since start of marking. |
| 725 // (value at start of event) |
| 726 double longest_incremental_marking_step; |
| 727 |
| 728 // Amounts of time spent in different scopes during GC. |
| 729 double scopes[Scope::NUMBER_OF_SCOPES]; |
| 730 }; |
| 731 |
| 732 static const int kRingBufferMaxSize = 10; |
| 733 |
| 734 typedef RingBuffer<Event, kRingBufferMaxSize> EventBuffer; |
| 735 |
599 explicit GCTracer(Heap* heap); | 736 explicit GCTracer(Heap* heap); |
600 | 737 |
601 // Start collecting data. | 738 // Start collecting data. |
602 void start(GarbageCollector collector, const char* gc_reason, | 739 void Start(GarbageCollector collector, const char* gc_reason, |
603 const char* collector_reason); | 740 const char* collector_reason); |
604 | 741 |
605 // Stop collecting data and print results. | 742 // Stop collecting data and print results. |
606 void stop(); | 743 void Stop(); |
| 744 |
| 745 // Log an incremental marking step. |
| 746 void AddIncrementalMarkingStep(double duration); |
607 | 747 |
608 private: | 748 private: |
609 // Returns a string matching the collector. | |
610 const char* CollectorString() const; | |
611 | |
612 // Print one detailed trace line in name=value format. | 749 // Print one detailed trace line in name=value format. |
| 750 // TODO(ernstm): Move to Heap. |
613 void PrintNVP() const; | 751 void PrintNVP() const; |
614 | 752 |
615 // Print one trace line. | 753 // Print one trace line. |
| 754 // TODO(ernstm): Move to Heap. |
616 void Print() const; | 755 void Print() const; |
617 | 756 |
618 // Timestamp set in the constructor. | 757 // Pointer to the heap that owns this tracer. |
619 double start_time_; | |
620 | |
621 // Timestamp set in the destructor. | |
622 double end_time_; | |
623 | |
624 // Size of objects in heap set in constructor. | |
625 intptr_t start_object_size_; | |
626 | |
627 // Size of objects in heap set in destructor. | |
628 intptr_t end_object_size_; | |
629 | |
630 // Size of memory allocated from OS set in constructor. | |
631 intptr_t start_memory_size_; | |
632 | |
633 // Size of memory allocated from OS set in destructor. | |
634 intptr_t end_memory_size_; | |
635 | |
636 // Type of collector. | |
637 GarbageCollector collector_; | |
638 | |
639 // Amounts of time spent in different scopes during GC. | |
640 double scopes_[Scope::NUMBER_OF_SCOPES]; | |
641 | |
642 // Total amount of space either wasted or contained in one of free lists | |
643 // before the current GC. | |
644 intptr_t in_free_list_or_wasted_before_gc_; | |
645 | |
646 // Difference between space used in the heap at the beginning of the current | |
647 // collection and the end of the previous collection. | |
648 intptr_t allocated_since_last_gc_; | |
649 | |
650 // Amount of time spent in mutator that is time elapsed between end of the | |
651 // previous collection and the beginning of the current one. | |
652 double spent_in_mutator_; | |
653 | |
654 // Incremental marking steps counters. | |
655 int steps_count_; | |
656 double steps_took_; | |
657 double longest_step_; | |
658 int steps_count_since_last_gc_; | |
659 double steps_took_since_last_gc_; | |
660 | |
661 Heap* heap_; | 758 Heap* heap_; |
662 | 759 |
663 const char* gc_reason_; | 760 // Current tracer event. Populated during Start/Stop cycle. Valid after Stop() |
664 const char* collector_reason_; | 761 // has returned. |
| 762 Event current_; |
| 763 |
| 764 // Previous tracer event. |
| 765 Event previous_; |
| 766 |
| 767 // Previous MARK_COMPACTOR event. |
| 768 Event previous_mark_compactor_event_; |
| 769 |
| 770 // RingBuffers for SCAVENGER events. |
| 771 EventBuffer scavenger_events_; |
| 772 |
| 773 // RingBuffers for MARK_COMPACTOR events. |
| 774 EventBuffer mark_compactor_events_; |
| 775 |
| 776 // Cumulative number of incremental marking steps since creation of tracer. |
| 777 int incremental_marking_steps_; |
| 778 |
| 779 // Cumulative duration of incremental marking steps since creation of tracer. |
| 780 double incremental_marking_duration_; |
| 781 |
| 782 // Longest incremental marking step since start of marking. |
| 783 double longest_incremental_marking_step_; |
665 | 784 |
666 DISALLOW_COPY_AND_ASSIGN(GCTracer); | 785 DISALLOW_COPY_AND_ASSIGN(GCTracer); |
667 }; | 786 }; |
668 | 787 |
669 | 788 |
670 class Heap { | 789 class Heap { |
671 public: | 790 public: |
672 // Configure heap size in MB before setup. Return false if the heap has been | 791 // Configure heap size in MB before setup. Return false if the heap has been |
673 // set up already. | 792 // set up already. |
674 bool ConfigureHeap(int max_semi_space_size, | 793 bool ConfigureHeap(int max_semi_space_size, |
(...skipping 685 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1360 | 1479 |
1361 void IncrementCodeGeneratedBytes(bool is_crankshafted, int size) { | 1480 void IncrementCodeGeneratedBytes(bool is_crankshafted, int size) { |
1362 if (is_crankshafted) { | 1481 if (is_crankshafted) { |
1363 crankshaft_codegen_bytes_generated_ += size; | 1482 crankshaft_codegen_bytes_generated_ += size; |
1364 } else { | 1483 } else { |
1365 full_codegen_bytes_generated_ += size; | 1484 full_codegen_bytes_generated_ += size; |
1366 } | 1485 } |
1367 } | 1486 } |
1368 | 1487 |
1369 // Update GC statistics that are tracked on the Heap. | 1488 // Update GC statistics that are tracked on the Heap. |
1370 void UpdateGCStatistics(double start_time, double end_time, | 1489 void UpdateCumulativeGCStatistics(double duration, double spent_in_mutator, |
1371 double spent_in_mutator, double marking_time); | 1490 double marking_time); |
1372 | 1491 |
1373 // Returns maximum GC pause. | 1492 // Returns maximum GC pause. |
1374 double get_max_gc_pause() { return max_gc_pause_; } | 1493 double get_max_gc_pause() { return max_gc_pause_; } |
1375 | 1494 |
1376 // Returns maximum size of objects alive after GC. | 1495 // Returns maximum size of objects alive after GC. |
1377 intptr_t get_max_alive_after_gc() { return max_alive_after_gc_; } | 1496 intptr_t get_max_alive_after_gc() { return max_alive_after_gc_; } |
1378 | 1497 |
1379 // Returns minimal interval between two subsequent collections. | 1498 // Returns minimal interval between two subsequent collections. |
1380 double get_min_in_mutator() { return min_in_mutator_; } | 1499 double get_min_in_mutator() { return min_in_mutator_; } |
1381 | 1500 |
(...skipping 849 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2231 | 2350 |
2232 // Total time spent in GC. | 2351 // Total time spent in GC. |
2233 double total_gc_time_ms_; | 2352 double total_gc_time_ms_; |
2234 | 2353 |
2235 // Maximum size of objects alive after GC. | 2354 // Maximum size of objects alive after GC. |
2236 intptr_t max_alive_after_gc_; | 2355 intptr_t max_alive_after_gc_; |
2237 | 2356 |
2238 // Minimal interval between two subsequent collections. | 2357 // Minimal interval between two subsequent collections. |
2239 double min_in_mutator_; | 2358 double min_in_mutator_; |
2240 | 2359 |
2241 // Size of objects alive after last GC. | |
2242 intptr_t alive_after_last_gc_; | |
2243 | |
2244 double last_gc_end_timestamp_; | |
2245 | |
2246 // Cumulative GC time spent in marking | 2360 // Cumulative GC time spent in marking |
2247 double marking_time_; | 2361 double marking_time_; |
2248 | 2362 |
2249 // Cumulative GC time spent in sweeping | 2363 // Cumulative GC time spent in sweeping |
2250 double sweeping_time_; | 2364 double sweeping_time_; |
2251 | 2365 |
2252 MarkCompactCollector mark_compact_collector_; | 2366 MarkCompactCollector mark_compact_collector_; |
2253 | 2367 |
2254 StoreBuffer store_buffer_; | 2368 StoreBuffer store_buffer_; |
2255 | 2369 |
(...skipping 524 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2780 DisallowHeapAllocation no_allocation; // i.e. no gc allowed. | 2894 DisallowHeapAllocation no_allocation; // i.e. no gc allowed. |
2781 | 2895 |
2782 private: | 2896 private: |
2783 DISALLOW_IMPLICIT_CONSTRUCTORS(PathTracer); | 2897 DISALLOW_IMPLICIT_CONSTRUCTORS(PathTracer); |
2784 }; | 2898 }; |
2785 #endif // DEBUG | 2899 #endif // DEBUG |
2786 | 2900 |
2787 } } // namespace v8::internal | 2901 } } // namespace v8::internal |
2788 | 2902 |
2789 #endif // V8_HEAP_H_ | 2903 #endif // V8_HEAP_H_ |
OLD | NEW |