| 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_ && 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 | |
| 620 | |
| 621 // GCTracer collects and prints ONE line after each garbage collector | |
| 622 // invocation IFF --trace_gc is used. | |
| 623 | |
| 624 // TODO(ernstm): Unit tests. Move to separate file. | |
| 625 class GCTracer BASE_EMBEDDED { | |
| 626 public: | |
| 627 class Scope BASE_EMBEDDED { | |
| 628 public: | |
| 629 enum ScopeId { | |
| 630 EXTERNAL, | |
| 631 MC_MARK, | |
| 632 MC_SWEEP, | |
| 633 MC_SWEEP_NEWSPACE, | |
| 634 MC_SWEEP_OLDSPACE, | |
| 635 MC_SWEEP_CODE, | |
| 636 MC_SWEEP_CELL, | |
| 637 MC_SWEEP_MAP, | |
| 638 MC_EVACUATE_PAGES, | |
| 639 MC_UPDATE_NEW_TO_NEW_POINTERS, | |
| 640 MC_UPDATE_ROOT_TO_NEW_POINTERS, | |
| 641 MC_UPDATE_OLD_TO_NEW_POINTERS, | |
| 642 MC_UPDATE_POINTERS_TO_EVACUATED, | |
| 643 MC_UPDATE_POINTERS_BETWEEN_EVACUATED, | |
| 644 MC_UPDATE_MISC_POINTERS, | |
| 645 MC_WEAKCOLLECTION_PROCESS, | |
| 646 MC_WEAKCOLLECTION_CLEAR, | |
| 647 MC_FLUSH_CODE, | |
| 648 NUMBER_OF_SCOPES | |
| 649 }; | |
| 650 | |
| 651 Scope(GCTracer* tracer, ScopeId scope) | |
| 652 : tracer_(tracer), | |
| 653 scope_(scope) { | |
| 654 start_time_ = base::OS::TimeCurrentMillis(); | |
| 655 } | |
| 656 | |
| 657 ~Scope() { | |
| 658 ASSERT(scope_ < NUMBER_OF_SCOPES); // scope_ is unsigned. | |
| 659 tracer_->current_.scopes[scope_] += | |
| 660 base::OS::TimeCurrentMillis() - start_time_; | |
| 661 } | |
| 662 | |
| 663 private: | |
| 664 GCTracer* tracer_; | |
| 665 ScopeId scope_; | |
| 666 double start_time_; | |
| 667 | |
| 668 DISALLOW_COPY_AND_ASSIGN(Scope); | |
| 669 }; | |
| 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 | |
| 736 explicit GCTracer(Heap* heap); | |
| 737 | |
| 738 // Start collecting data. | |
| 739 void Start(GarbageCollector collector, const char* gc_reason, | |
| 740 const char* collector_reason); | |
| 741 | |
| 742 // Stop collecting data and print results. | |
| 743 void Stop(); | |
| 744 | |
| 745 // Log an incremental marking step. | |
| 746 void AddIncrementalMarkingStep(double duration); | |
| 747 | |
| 748 private: | |
| 749 // Print one detailed trace line in name=value format. | |
| 750 // TODO(ernstm): Move to Heap. | |
| 751 void PrintNVP() const; | |
| 752 | |
| 753 // Print one trace line. | |
| 754 // TODO(ernstm): Move to Heap. | |
| 755 void Print() const; | |
| 756 | |
| 757 // Pointer to the heap that owns this tracer. | |
| 758 Heap* heap_; | |
| 759 | |
| 760 // Current tracer event. Populated during Start/Stop cycle. Valid after Stop() | |
| 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_; | |
| 784 | |
| 785 DISALLOW_COPY_AND_ASSIGN(GCTracer); | |
| 786 }; | |
| 787 | |
| 788 | 551 |
| 789 class Heap { | 552 class Heap { |
| 790 public: | 553 public: |
| 791 // 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 |
| 792 // set up already. | 555 // set up already. |
| 793 bool ConfigureHeap(int max_semi_space_size, | 556 bool ConfigureHeap(int max_semi_space_size, |
| 794 int max_old_space_size, | 557 int max_old_space_size, |
| 795 int max_executable_size, | 558 int max_executable_size, |
| 796 size_t code_range_size); | 559 size_t code_range_size); |
| 797 bool ConfigureHeapDefault(); | 560 bool ConfigureHeapDefault(); |
| (...skipping 2096 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2894 DisallowHeapAllocation no_allocation; // i.e. no gc allowed. | 2657 DisallowHeapAllocation no_allocation; // i.e. no gc allowed. |
| 2895 | 2658 |
| 2896 private: | 2659 private: |
| 2897 DISALLOW_IMPLICIT_CONSTRUCTORS(PathTracer); | 2660 DISALLOW_IMPLICIT_CONSTRUCTORS(PathTracer); |
| 2898 }; | 2661 }; |
| 2899 #endif // DEBUG | 2662 #endif // DEBUG |
| 2900 | 2663 |
| 2901 } } // namespace v8::internal | 2664 } } // namespace v8::internal |
| 2902 | 2665 |
| 2903 #endif // V8_HEAP_H_ | 2666 #endif // V8_HEAP_H_ |
| OLD | NEW |