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): comments and unit test. Move into GCTracer? | |
551 template<typename T, size_t MAX_SIZE> | |
552 class RingBuffer { | |
553 public: | |
554 class const_iterator { | |
555 public: | |
556 const_iterator() : ring_buffer_(NULL) {} | |
557 const_iterator(size_t index, const RingBuffer* ring_buffer) : | |
558 index_(index), ring_buffer_(ring_buffer) {} | |
559 operator bool() const { return ring_buffer_ != NULL; } | |
560 const T* operator->() const { return ring_buffer_->elements_ + index_; } | |
561 const T& operator*() const { return ring_buffer_->elements_[index_]; } | |
562 const_iterator& operator++() { | |
563 index_ = (index_ + 1) % MAX_SIZE; | |
564 if (index_ == ring_buffer_->end_) | |
565 *this = const_iterator(); | |
566 | |
567 return *this; | |
568 } | |
569 const_iterator& operator--() { | |
570 if (index_ == ring_buffer_->begin_) | |
571 *this = const_iterator(); | |
572 else | |
573 index_ = (index_ + MAX_SIZE - 1) % MAX_SIZE; | |
574 | |
575 return *this; | |
576 } | |
577 | |
578 private: | |
579 size_t index_; | |
580 const RingBuffer* ring_buffer_; | |
581 }; | |
582 | |
583 RingBuffer() : begin_(0), end_(0) {} | |
584 | |
585 const_iterator begin() const { return const_iterator(begin_, this); } | |
586 const_iterator end() const { return const_iterator(end_, this); } | |
587 const_iterator back() const { return --end(); } | |
588 void push_back(const T& element) { | |
589 elements_[end_] = element; | |
590 end_ = (end_ + 1) % MAX_SIZE; | |
591 if (end_ == begin_) | |
592 ++begin_; | |
593 } | |
594 | |
595 private: | |
596 T elements_[MAX_SIZE]; | |
597 size_t begin_; | |
598 size_t end_; | |
599 }; | |
600 | |
550 | 601 |
551 // GCTracer collects and prints ONE line after each garbage collector | 602 // GCTracer collects and prints ONE line after each garbage collector |
552 // invocation IFF --trace_gc is used. | 603 // invocation IFF --trace_gc is used. |
553 | 604 |
605 // TODO(ernstm): unit tests. move to separate file. | |
554 class GCTracer BASE_EMBEDDED { | 606 class GCTracer BASE_EMBEDDED { |
555 public: | 607 public: |
556 class Scope BASE_EMBEDDED { | 608 class Scope BASE_EMBEDDED { |
557 public: | 609 public: |
558 enum ScopeId { | 610 enum ScopeId { |
559 EXTERNAL, | 611 EXTERNAL, |
560 MC_MARK, | 612 MC_MARK, |
561 MC_SWEEP, | 613 MC_SWEEP, |
562 MC_SWEEP_NEWSPACE, | 614 MC_SWEEP_NEWSPACE, |
563 MC_SWEEP_OLDSPACE, | 615 MC_SWEEP_OLDSPACE, |
(...skipping 14 matching lines...) Expand all Loading... | |
578 }; | 630 }; |
579 | 631 |
580 Scope(GCTracer* tracer, ScopeId scope) | 632 Scope(GCTracer* tracer, ScopeId scope) |
581 : tracer_(tracer), | 633 : tracer_(tracer), |
582 scope_(scope) { | 634 scope_(scope) { |
583 start_time_ = base::OS::TimeCurrentMillis(); | 635 start_time_ = base::OS::TimeCurrentMillis(); |
584 } | 636 } |
585 | 637 |
586 ~Scope() { | 638 ~Scope() { |
587 ASSERT(scope_ < NUMBER_OF_SCOPES); // scope_ is unsigned. | 639 ASSERT(scope_ < NUMBER_OF_SCOPES); // scope_ is unsigned. |
588 tracer_->scopes_[scope_] += base::OS::TimeCurrentMillis() - start_time_; | 640 tracer_->pending_.scopes[scope_] += |
641 base::OS::TimeCurrentMillis() - start_time_; | |
589 } | 642 } |
590 | 643 |
591 private: | 644 private: |
592 GCTracer* tracer_; | 645 GCTracer* tracer_; |
593 ScopeId scope_; | 646 ScopeId scope_; |
594 double start_time_; | 647 double start_time_; |
595 | 648 |
596 DISALLOW_COPY_AND_ASSIGN(Scope); | 649 DISALLOW_COPY_AND_ASSIGN(Scope); |
597 }; | 650 }; |
598 | 651 |
652 | |
653 struct Event { | |
Hannes Payer (out of office)
2014/07/22 09:10:17
C++ style guide: Use a struct only for passive obj
ernstm
2014/07/22 14:09:29
Done.
| |
654 Event(); | |
655 | |
656 Event(GarbageCollector collector, | |
657 const char* gc_reason, | |
658 const char* collector_reason); | |
659 | |
660 // Type of collector. | |
661 GarbageCollector collector; | |
662 | |
663 const char* gc_reason; | |
664 const char* collector_reason; | |
665 | |
666 // Timestamp set in the constructor. | |
667 double start_time; | |
668 | |
669 // Timestamp set in the destructor. | |
670 double end_time; | |
671 | |
672 // Size of objects in heap set in constructor. | |
673 intptr_t start_object_size; | |
674 | |
675 // Size of objects in heap set in destructor. | |
676 intptr_t end_object_size; | |
677 | |
678 // Size of memory allocated from OS set in constructor. | |
679 intptr_t start_memory_size; | |
680 | |
681 // Size of memory allocated from OS set in destructor. | |
682 intptr_t end_memory_size; | |
683 | |
684 // Total amount of space either wasted or contained in one of free lists | |
685 // before the current GC. | |
686 intptr_t start_holes_size; | |
687 | |
688 // Total amount of space either wasted or contained in one of free lists | |
689 // after the current GC. | |
690 intptr_t end_holes_size; | |
691 | |
692 // Number of incremental marking steps since creation of tracer. | |
693 // (value at start of event) | |
694 int incremental_marking_steps; | |
695 | |
696 // Cumulative duration of incremental marking steps since creation of | |
697 // tracer. (value at start of event) | |
698 double incremental_marking_duration; | |
699 | |
700 // Longest incremental marking step since start of marking. | |
701 // (value at start of event) | |
702 double longest_incremental_marking_step; | |
703 | |
704 // Amounts of time spent in different scopes during GC. | |
705 double scopes[Scope::NUMBER_OF_SCOPES]; | |
706 }; | |
707 | |
708 typedef RingBuffer<Event, 10> EventBuffer; | |
709 | |
599 explicit GCTracer(Heap* heap); | 710 explicit GCTracer(Heap* heap); |
600 | 711 |
601 // Start collecting data. | 712 // Start collecting data. |
602 void start(GarbageCollector collector, | 713 void Start(GarbageCollector collector, |
603 const char* gc_reason, | 714 const char* gc_reason, |
604 const char* collector_reason); | 715 const char* collector_reason); |
605 | 716 |
606 // Stop collecting data and print results. | 717 // Stop collecting data and print results. |
607 void stop(); | 718 void Stop(); |
719 | |
720 // The event with the most recent end_time (selected from all event buffer) | |
721 EventBuffer::const_iterator Current() const; | |
722 | |
723 // The event before the current event (selected from all event buffers). | |
724 EventBuffer::const_iterator Previous() const; | |
725 | |
726 // Log an incremental marking step. | |
727 void AddIncrementalMarkingStep(double duration); | |
608 | 728 |
609 private: | 729 private: |
610 // Returns a string matching the collector. | 730 // Returns a string matching the collector. |
611 const char* CollectorString() const; | 731 const char* CollectorString(GarbageCollector collector, |
732 bool short_name) const; | |
612 | 733 |
613 // Print one detailed trace line in name=value format. | 734 // Print one detailed trace line in name=value format. |
735 // TODO(ernstm): move to Heap. | |
614 void PrintNVP() const; | 736 void PrintNVP() const; |
615 | 737 |
616 // Print one trace line. | 738 // Print one trace line. |
739 // TODO(ernstm): move to Heap. | |
617 void Print() const; | 740 void Print() const; |
618 | 741 |
619 // Timestamp set in the constructor. | 742 // Pointer to the heap that owns this tracer. |
620 double start_time_; | |
621 | |
622 // Timestamp set in the destructor. | |
623 double end_time_; | |
624 | |
625 // Size of objects in heap set in constructor. | |
626 intptr_t start_object_size_; | |
627 | |
628 // Size of objects in heap set in destructor. | |
629 intptr_t end_object_size_; | |
630 | |
631 // Size of memory allocated from OS set in constructor. | |
632 intptr_t start_memory_size_; | |
633 | |
634 // Size of memory allocated from OS set in destructor. | |
635 intptr_t end_memory_size_; | |
636 | |
637 // Type of collector. | |
638 GarbageCollector collector_; | |
639 | |
640 // Amounts of time spent in different scopes during GC. | |
641 double scopes_[Scope::NUMBER_OF_SCOPES]; | |
642 | |
643 // Total amount of space either wasted or contained in one of free lists | |
644 // before the current GC. | |
645 intptr_t in_free_list_or_wasted_before_gc_; | |
646 | |
647 // Difference between space used in the heap at the beginning of the current | |
648 // collection and the end of the previous collection. | |
649 intptr_t allocated_since_last_gc_; | |
650 | |
651 // Amount of time spent in mutator that is time elapsed between end of the | |
652 // previous collection and the beginning of the current one. | |
653 double spent_in_mutator_; | |
654 | |
655 // Incremental marking steps counters. | |
656 int steps_count_; | |
657 double steps_took_; | |
658 double longest_step_; | |
659 int steps_count_since_last_gc_; | |
660 double steps_took_since_last_gc_; | |
661 | |
662 Heap* heap_; | 743 Heap* heap_; |
663 | 744 |
664 const char* gc_reason_; | 745 // Pending tracer event that is filled during one Start/Stop cycle. |
665 const char* collector_reason_; | 746 Event pending_; |
747 | |
748 // Two RingBuffers of events. One each for SCAVENGER and MARK_COMPACTOR. | |
749 EventBuffer event_buffers_[2]; | |
Hannes Payer (out of office)
2014/07/22 09:10:17
Ah, now I see why you have to initialize the enum.
ernstm
2014/07/22 14:09:28
I've chosen the array, because the Previous() meth
ernstm
2014/07/22 14:10:26
Update: The latest version uses two separate membe
| |
750 | |
751 // Cumulative number of incremental marking steps since creation of tracer. | |
752 int incremental_marking_steps_; | |
753 | |
754 // Cumulative duration of incremental marking steps since creation of tracer. | |
755 double incremental_marking_duration_; | |
756 | |
757 // Longest incremental marking step since start of marking. | |
758 double longest_incremental_marking_step_; | |
666 | 759 |
667 DISALLOW_COPY_AND_ASSIGN(GCTracer); | 760 DISALLOW_COPY_AND_ASSIGN(GCTracer); |
668 }; | 761 }; |
669 | 762 |
670 | 763 |
671 class Heap { | 764 class Heap { |
672 public: | 765 public: |
673 // Configure heap size in MB before setup. Return false if the heap has been | 766 // Configure heap size in MB before setup. Return false if the heap has been |
674 // set up already. | 767 // set up already. |
675 bool ConfigureHeap(int max_semi_space_size, | 768 bool ConfigureHeap(int max_semi_space_size, |
(...skipping 685 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1361 | 1454 |
1362 void IncrementCodeGeneratedBytes(bool is_crankshafted, int size) { | 1455 void IncrementCodeGeneratedBytes(bool is_crankshafted, int size) { |
1363 if (is_crankshafted) { | 1456 if (is_crankshafted) { |
1364 crankshaft_codegen_bytes_generated_ += size; | 1457 crankshaft_codegen_bytes_generated_ += size; |
1365 } else { | 1458 } else { |
1366 full_codegen_bytes_generated_ += size; | 1459 full_codegen_bytes_generated_ += size; |
1367 } | 1460 } |
1368 } | 1461 } |
1369 | 1462 |
1370 // Update GC statistics that are tracked on the Heap. | 1463 // Update GC statistics that are tracked on the Heap. |
1371 void UpdateGCStatistics(double start_time, | 1464 void UpdateCumulativeGCStatistics(double duration, |
1372 double end_time, | 1465 double spent_in_mutator, |
1373 double spent_in_mutator, | 1466 double marking_time); |
1374 double marking_time); | |
1375 | 1467 |
1376 // Returns maximum GC pause. | 1468 // Returns maximum GC pause. |
1377 double get_max_gc_pause() { return max_gc_pause_; } | 1469 double get_max_gc_pause() { return max_gc_pause_; } |
1378 | 1470 |
1379 // Returns maximum size of objects alive after GC. | 1471 // Returns maximum size of objects alive after GC. |
1380 intptr_t get_max_alive_after_gc() { return max_alive_after_gc_; } | 1472 intptr_t get_max_alive_after_gc() { return max_alive_after_gc_; } |
1381 | 1473 |
1382 // Returns minimal interval between two subsequent collections. | 1474 // Returns minimal interval between two subsequent collections. |
1383 double get_min_in_mutator() { return min_in_mutator_; } | 1475 double get_min_in_mutator() { return min_in_mutator_; } |
1384 | 1476 |
(...skipping 849 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2234 | 2326 |
2235 // Total time spent in GC. | 2327 // Total time spent in GC. |
2236 double total_gc_time_ms_; | 2328 double total_gc_time_ms_; |
2237 | 2329 |
2238 // Maximum size of objects alive after GC. | 2330 // Maximum size of objects alive after GC. |
2239 intptr_t max_alive_after_gc_; | 2331 intptr_t max_alive_after_gc_; |
2240 | 2332 |
2241 // Minimal interval between two subsequent collections. | 2333 // Minimal interval between two subsequent collections. |
2242 double min_in_mutator_; | 2334 double min_in_mutator_; |
2243 | 2335 |
2244 // Size of objects alive after last GC. | |
2245 intptr_t alive_after_last_gc_; | |
2246 | |
2247 double last_gc_end_timestamp_; | |
2248 | |
2249 // Cumulative GC time spent in marking | 2336 // Cumulative GC time spent in marking |
2250 double marking_time_; | 2337 double marking_time_; |
2251 | 2338 |
2252 // Cumulative GC time spent in sweeping | 2339 // Cumulative GC time spent in sweeping |
2253 double sweeping_time_; | 2340 double sweeping_time_; |
2254 | 2341 |
2255 MarkCompactCollector mark_compact_collector_; | 2342 MarkCompactCollector mark_compact_collector_; |
2256 | 2343 |
2257 StoreBuffer store_buffer_; | 2344 StoreBuffer store_buffer_; |
2258 | 2345 |
(...skipping 524 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2783 DisallowHeapAllocation no_allocation; // i.e. no gc allowed. | 2870 DisallowHeapAllocation no_allocation; // i.e. no gc allowed. |
2784 | 2871 |
2785 private: | 2872 private: |
2786 DISALLOW_IMPLICIT_CONSTRUCTORS(PathTracer); | 2873 DISALLOW_IMPLICIT_CONSTRUCTORS(PathTracer); |
2787 }; | 2874 }; |
2788 #endif // DEBUG | 2875 #endif // DEBUG |
2789 | 2876 |
2790 } } // namespace v8::internal | 2877 } } // namespace v8::internal |
2791 | 2878 |
2792 #endif // V8_HEAP_H_ | 2879 #endif // V8_HEAP_H_ |
OLD | NEW |