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" |
11 #include "src/assert-scope.h" | 11 #include "src/assert-scope.h" |
12 #include "src/counters.h" | 12 #include "src/counters.h" |
| 13 #include "src/gc-tracer.h" |
13 #include "src/globals.h" | 14 #include "src/globals.h" |
14 #include "src/incremental-marking.h" | 15 #include "src/incremental-marking.h" |
15 #include "src/list.h" | 16 #include "src/list.h" |
16 #include "src/mark-compact.h" | 17 #include "src/mark-compact.h" |
17 #include "src/objects-visiting.h" | 18 #include "src/objects-visiting.h" |
18 #include "src/spaces.h" | 19 #include "src/spaces.h" |
19 #include "src/splay-tree-inl.h" | 20 #include "src/splay-tree-inl.h" |
20 #include "src/store-buffer.h" | 21 #include "src/store-buffer.h" |
21 | 22 |
22 namespace v8 { | 23 namespace v8 { |
(...skipping 517 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
540 | 541 |
541 DISALLOW_COPY_AND_ASSIGN(ExternalStringTable); | 542 DISALLOW_COPY_AND_ASSIGN(ExternalStringTable); |
542 }; | 543 }; |
543 | 544 |
544 | 545 |
545 enum ArrayStorageAllocationMode { | 546 enum ArrayStorageAllocationMode { |
546 DONT_INITIALIZE_ARRAY_ELEMENTS, | 547 DONT_INITIALIZE_ARRAY_ELEMENTS, |
547 INITIALIZE_ARRAY_ELEMENTS_WITH_HOLE | 548 INITIALIZE_ARRAY_ELEMENTS_WITH_HOLE |
548 }; | 549 }; |
549 | 550 |
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_ && | |
565 index_ == rhs.index_; | |
566 } | |
567 | |
568 bool operator!=(const const_iterator& rhs) const { | |
569 return elements_ != rhs.elements_ || | |
570 index_ != rhs.index_; | |
571 } | |
572 | |
573 operator const T*() const { | |
574 return elements_ + index_; | |
575 } | |
576 | |
577 const T* operator->() const { | |
578 return elements_ + index_; | |
579 } | |
580 | |
581 const T& operator*() const { | |
582 return elements_[index_]; | |
583 } | |
584 | |
585 const_iterator& operator++() { | |
586 index_ = (index_ + 1) % (MAX_SIZE + 1); | |
587 return *this; | |
588 } | |
589 | |
590 const_iterator& operator--() { | |
591 index_ = (index_ + MAX_SIZE) % (MAX_SIZE + 1); | |
592 return *this; | |
593 } | |
594 | |
595 private: | |
596 size_t index_; | |
597 const T* elements_; | |
598 }; | |
599 | |
600 RingBuffer() : begin_(0), end_(0) {} | |
601 | |
602 bool empty() const { return begin_ == end_; } | |
603 size_t size() const { | |
604 return (end_ - begin_ + MAX_SIZE + 1) % (MAX_SIZE + 1); | |
605 } | |
606 const_iterator begin() const { return const_iterator(begin_, elements_); } | |
607 const_iterator end() const { return const_iterator(end_, elements_); } | |
608 const_iterator back() const { return --end(); } | |
609 void push_back(const T& element) { | |
610 elements_[end_] = element; | |
611 end_ = (end_ + 1) % (MAX_SIZE + 1); | |
612 if (end_ == begin_) | |
613 begin_ = (begin_ + 1) % (MAX_SIZE + 1); | |
614 } | |
615 void push_front(const T& element) { | |
616 begin_ = (begin_ + MAX_SIZE) % (MAX_SIZE + 1); | |
617 if (begin_ == end_) | |
618 end_ = (end_ + MAX_SIZE) % (MAX_SIZE + 1); | |
619 elements_[begin_] = element; | |
620 } | |
621 | |
622 private: | |
623 T elements_[MAX_SIZE + 1]; | |
624 size_t begin_; | |
625 size_t end_; | |
626 | |
627 DISALLOW_COPY_AND_ASSIGN(RingBuffer); | |
628 }; | |
629 | |
630 | |
631 // GCTracer collects and prints ONE line after each garbage collector | |
632 // invocation IFF --trace_gc is used. | |
633 | |
634 // TODO(ernstm): Unit tests. Move to separate file. | |
635 class GCTracer BASE_EMBEDDED { | |
636 public: | |
637 class Scope BASE_EMBEDDED { | |
638 public: | |
639 enum ScopeId { | |
640 EXTERNAL, | |
641 MC_MARK, | |
642 MC_SWEEP, | |
643 MC_SWEEP_NEWSPACE, | |
644 MC_SWEEP_OLDSPACE, | |
645 MC_SWEEP_CODE, | |
646 MC_SWEEP_CELL, | |
647 MC_SWEEP_MAP, | |
648 MC_EVACUATE_PAGES, | |
649 MC_UPDATE_NEW_TO_NEW_POINTERS, | |
650 MC_UPDATE_ROOT_TO_NEW_POINTERS, | |
651 MC_UPDATE_OLD_TO_NEW_POINTERS, | |
652 MC_UPDATE_POINTERS_TO_EVACUATED, | |
653 MC_UPDATE_POINTERS_BETWEEN_EVACUATED, | |
654 MC_UPDATE_MISC_POINTERS, | |
655 MC_WEAKCOLLECTION_PROCESS, | |
656 MC_WEAKCOLLECTION_CLEAR, | |
657 MC_FLUSH_CODE, | |
658 NUMBER_OF_SCOPES | |
659 }; | |
660 | |
661 Scope(GCTracer* tracer, ScopeId scope) | |
662 : tracer_(tracer), | |
663 scope_(scope) { | |
664 start_time_ = base::OS::TimeCurrentMillis(); | |
665 } | |
666 | |
667 ~Scope() { | |
668 ASSERT(scope_ < NUMBER_OF_SCOPES); // scope_ is unsigned. | |
669 tracer_->current_.scopes[scope_] += | |
670 base::OS::TimeCurrentMillis() - start_time_; | |
671 } | |
672 | |
673 private: | |
674 GCTracer* tracer_; | |
675 ScopeId scope_; | |
676 double start_time_; | |
677 | |
678 DISALLOW_COPY_AND_ASSIGN(Scope); | |
679 }; | |
680 | |
681 | |
682 class Event { | |
683 public: | |
684 enum Type { | |
685 SCAVENGER = 0, | |
686 MARK_COMPACTOR = 1, | |
687 START = 2 | |
688 }; | |
689 | |
690 // Default constructor leaves the event uninitialized. | |
691 Event() {} | |
692 | |
693 Event(Type type, | |
694 const char* gc_reason, | |
695 const char* collector_reason); | |
696 | |
697 // Returns a string describing the event type. | |
698 const char* TypeName(bool short_name) const; | |
699 | |
700 // Type of event | |
701 Type type; | |
702 | |
703 const char* gc_reason; | |
704 const char* collector_reason; | |
705 | |
706 // Timestamp set in the constructor. | |
707 double start_time; | |
708 | |
709 // Timestamp set in the destructor. | |
710 double end_time; | |
711 | |
712 // Size of objects in heap set in constructor. | |
713 intptr_t start_object_size; | |
714 | |
715 // Size of objects in heap set in destructor. | |
716 intptr_t end_object_size; | |
717 | |
718 // Size of memory allocated from OS set in constructor. | |
719 intptr_t start_memory_size; | |
720 | |
721 // Size of memory allocated from OS set in destructor. | |
722 intptr_t end_memory_size; | |
723 | |
724 // Total amount of space either wasted or contained in one of free lists | |
725 // before the current GC. | |
726 intptr_t start_holes_size; | |
727 | |
728 // Total amount of space either wasted or contained in one of free lists | |
729 // after the current GC. | |
730 intptr_t end_holes_size; | |
731 | |
732 // Number of incremental marking steps since creation of tracer. | |
733 // (value at start of event) | |
734 int incremental_marking_steps; | |
735 | |
736 // Cumulative duration of incremental marking steps since creation of | |
737 // tracer. (value at start of event) | |
738 double incremental_marking_duration; | |
739 | |
740 // Longest incremental marking step since start of marking. | |
741 // (value at start of event) | |
742 double longest_incremental_marking_step; | |
743 | |
744 // Amounts of time spent in different scopes during GC. | |
745 double scopes[Scope::NUMBER_OF_SCOPES]; | |
746 }; | |
747 | |
748 static const int kRingBufferMaxSize = 10; | |
749 | |
750 typedef RingBuffer<Event, kRingBufferMaxSize> EventBuffer; | |
751 | |
752 explicit GCTracer(Heap* heap); | |
753 | |
754 // Start collecting data. | |
755 void Start(GarbageCollector collector, | |
756 const char* gc_reason, | |
757 const char* collector_reason); | |
758 | |
759 // Stop collecting data and print results. | |
760 void Stop(); | |
761 | |
762 // Log an incremental marking step. | |
763 void AddIncrementalMarkingStep(double duration); | |
764 | |
765 private: | |
766 // Print one detailed trace line in name=value format. | |
767 // TODO(ernstm): Move to Heap. | |
768 void PrintNVP() const; | |
769 | |
770 // Print one trace line. | |
771 // TODO(ernstm): Move to Heap. | |
772 void Print() const; | |
773 | |
774 // Pointer to the heap that owns this tracer. | |
775 Heap* heap_; | |
776 | |
777 // Current tracer event. Populated during Start/Stop cycle. Valid after Stop() | |
778 // has returned. | |
779 Event current_; | |
780 | |
781 // Previous tracer event. | |
782 Event previous_; | |
783 | |
784 // Previous MARK_COMPACTOR event. | |
785 Event previous_mark_compactor_event_; | |
786 | |
787 // RingBuffers for SCAVENGER events. | |
788 EventBuffer scavenger_events_; | |
789 | |
790 // RingBuffers for MARK_COMPACTOR events. | |
791 EventBuffer mark_compactor_events_; | |
792 | |
793 // Cumulative number of incremental marking steps since creation of tracer. | |
794 int incremental_marking_steps_; | |
795 | |
796 // Cumulative duration of incremental marking steps since creation of tracer. | |
797 double incremental_marking_duration_; | |
798 | |
799 // Longest incremental marking step since start of marking. | |
800 double longest_incremental_marking_step_; | |
801 | |
802 DISALLOW_COPY_AND_ASSIGN(GCTracer); | |
803 }; | |
804 | |
805 | 551 |
806 class Heap { | 552 class Heap { |
807 public: | 553 public: |
808 // Configure heap size in MB before setup. Return false if the heap has been | 554 // Configure heap size in MB before setup. Return false if the heap has been |
809 // set up already. | 555 // set up already. |
810 bool ConfigureHeap(int max_semi_space_size, | 556 bool ConfigureHeap(int max_semi_space_size, |
811 int max_old_space_size, | 557 int max_old_space_size, |
812 int max_executable_size, | 558 int max_executable_size, |
813 size_t code_range_size); | 559 size_t code_range_size); |
814 bool ConfigureHeapDefault(); | 560 bool ConfigureHeapDefault(); |
(...skipping 2097 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2912 DisallowHeapAllocation no_allocation; // i.e. no gc allowed. | 2658 DisallowHeapAllocation no_allocation; // i.e. no gc allowed. |
2913 | 2659 |
2914 private: | 2660 private: |
2915 DISALLOW_IMPLICIT_CONSTRUCTORS(PathTracer); | 2661 DISALLOW_IMPLICIT_CONSTRUCTORS(PathTracer); |
2916 }; | 2662 }; |
2917 #endif // DEBUG | 2663 #endif // DEBUG |
2918 | 2664 |
2919 } } // namespace v8::internal | 2665 } } // namespace v8::internal |
2920 | 2666 |
2921 #endif // V8_HEAP_H_ | 2667 #endif // V8_HEAP_H_ |
OLD | NEW |