Chromium Code Reviews| 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_ && | |
| 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 const T* operator->() const { | |
| 574 return elements_ + index_; | |
| 575 } | |
| 576 | |
| 577 const T& operator*() const { | |
| 578 return elements_[index_]; | |
| 579 } | |
| 580 | |
| 581 const_iterator& operator++() { | |
| 582 index_ = (index_ + 1) % (MAX_SIZE + 1); | |
| 583 return *this; | |
| 584 } | |
| 585 | |
| 586 const_iterator& operator--() { | |
| 587 index_ = (index_ + MAX_SIZE) % (MAX_SIZE + 1); | |
| 588 return *this; | |
| 589 } | |
| 590 | |
| 591 private: | |
| 592 size_t index_; | |
| 593 const T* elements_; | |
| 594 }; | |
| 595 | |
| 596 RingBuffer() : begin_(0), end_(0) {} | |
| 597 | |
| 598 bool empty() const { return begin_ == end_; } | |
| 599 size_t size() const { | |
| 600 return (end_ - begin_ + MAX_SIZE + 1) % (MAX_SIZE + 1); | |
| 601 } | |
| 602 const_iterator begin() const { return const_iterator(begin_, elements_); } | |
| 603 const_iterator end() const { return const_iterator(end_, elements_); } | |
| 604 const_iterator back() const { return --end(); } | |
| 605 void push_back(const T& element) { | |
| 606 elements_[end_] = element; | |
| 607 end_ = (end_ + 1) % (MAX_SIZE + 1); | |
|
Hannes Payer (out of office)
2014/07/22 15:21:31
Hmm, MAX_SIZE+1 makes the code really complicated.
ernstm
2014/07/22 15:57:25
That is unrelated to anchor elements. The extra el
Hannes Payer (out of office)
2014/07/22 16:29:12
Ahm, yes. I guess we could also use a counter. But
ernstm
2014/07/23 10:32:26
The counter could be used to distinguish empty fro
| |
| 608 if (end_ == begin_) | |
| 609 begin_ = (begin_ + 1) % (MAX_SIZE + 1); | |
| 610 } | |
| 611 | |
| 612 private: | |
| 613 T elements_[MAX_SIZE + 1]; | |
| 614 size_t begin_; | |
| 615 size_t end_; | |
|
Hannes Payer (out of office)
2014/07/22 15:21:31
DISALLOW_COPY_AND_ASSIGN
ernstm
2014/07/22 15:57:24
Done.
| |
| 616 }; | |
| 617 | |
| 550 | 618 |
| 551 // GCTracer collects and prints ONE line after each garbage collector | 619 // GCTracer collects and prints ONE line after each garbage collector |
| 552 // invocation IFF --trace_gc is used. | 620 // invocation IFF --trace_gc is used. |
| 553 | 621 |
| 622 // TODO(ernstm): unit tests. move to separate file. | |
| 554 class GCTracer BASE_EMBEDDED { | 623 class GCTracer BASE_EMBEDDED { |
| 555 public: | 624 public: |
| 556 class Scope BASE_EMBEDDED { | 625 class Scope BASE_EMBEDDED { |
| 557 public: | 626 public: |
| 558 enum ScopeId { | 627 enum ScopeId { |
| 559 EXTERNAL, | 628 EXTERNAL, |
| 560 MC_MARK, | 629 MC_MARK, |
| 561 MC_SWEEP, | 630 MC_SWEEP, |
| 562 MC_SWEEP_NEWSPACE, | 631 MC_SWEEP_NEWSPACE, |
| 563 MC_SWEEP_OLDSPACE, | 632 MC_SWEEP_OLDSPACE, |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 578 }; | 647 }; |
| 579 | 648 |
| 580 Scope(GCTracer* tracer, ScopeId scope) | 649 Scope(GCTracer* tracer, ScopeId scope) |
| 581 : tracer_(tracer), | 650 : tracer_(tracer), |
| 582 scope_(scope) { | 651 scope_(scope) { |
| 583 start_time_ = base::OS::TimeCurrentMillis(); | 652 start_time_ = base::OS::TimeCurrentMillis(); |
| 584 } | 653 } |
| 585 | 654 |
| 586 ~Scope() { | 655 ~Scope() { |
| 587 ASSERT(scope_ < NUMBER_OF_SCOPES); // scope_ is unsigned. | 656 ASSERT(scope_ < NUMBER_OF_SCOPES); // scope_ is unsigned. |
| 588 tracer_->scopes_[scope_] += base::OS::TimeCurrentMillis() - start_time_; | 657 tracer_->pending_.scopes[scope_] += |
| 658 base::OS::TimeCurrentMillis() - start_time_; | |
| 589 } | 659 } |
| 590 | 660 |
| 591 private: | 661 private: |
| 592 GCTracer* tracer_; | 662 GCTracer* tracer_; |
| 593 ScopeId scope_; | 663 ScopeId scope_; |
| 594 double start_time_; | 664 double start_time_; |
| 595 | 665 |
| 596 DISALLOW_COPY_AND_ASSIGN(Scope); | 666 DISALLOW_COPY_AND_ASSIGN(Scope); |
| 597 }; | 667 }; |
| 598 | 668 |
| 669 | |
| 670 class Event { | |
| 671 public: | |
| 672 enum Type { | |
| 673 SCAVENGER = 0, | |
| 674 MARK_COMPACTOR = 1, | |
| 675 ANCHOR = 2, | |
| 676 INVALID = 3 | |
|
Hannes Payer (out of office)
2014/07/22 15:21:30
what is the purpose of invalid?
ernstm
2014/07/22 15:57:25
Not really required. See commend on default constr
| |
| 677 }; | |
| 678 | |
| 679 Event(); | |
| 680 | |
| 681 Event(Type type, | |
| 682 const char* gc_reason, | |
| 683 const char* collector_reason); | |
| 684 | |
| 685 // Returns a string describing the event type. | |
| 686 const char* TypeName(bool short_name) const; | |
| 687 | |
| 688 // Type of event | |
| 689 Type type; | |
| 690 | |
| 691 const char* gc_reason; | |
| 692 const char* collector_reason; | |
| 693 | |
| 694 // Timestamp set in the constructor. | |
| 695 double start_time; | |
| 696 | |
| 697 // Timestamp set in the destructor. | |
| 698 double end_time; | |
| 699 | |
| 700 // Size of objects in heap set in constructor. | |
| 701 intptr_t start_object_size; | |
| 702 | |
| 703 // Size of objects in heap set in destructor. | |
| 704 intptr_t end_object_size; | |
| 705 | |
| 706 // Size of memory allocated from OS set in constructor. | |
| 707 intptr_t start_memory_size; | |
| 708 | |
| 709 // Size of memory allocated from OS set in destructor. | |
| 710 intptr_t end_memory_size; | |
| 711 | |
| 712 // Total amount of space either wasted or contained in one of free lists | |
| 713 // before the current GC. | |
| 714 intptr_t start_holes_size; | |
| 715 | |
| 716 // Total amount of space either wasted or contained in one of free lists | |
| 717 // after the current GC. | |
| 718 intptr_t end_holes_size; | |
| 719 | |
| 720 // Number of incremental marking steps since creation of tracer. | |
| 721 // (value at start of event) | |
| 722 int incremental_marking_steps; | |
| 723 | |
| 724 // Cumulative duration of incremental marking steps since creation of | |
| 725 // tracer. (value at start of event) | |
| 726 double incremental_marking_duration; | |
| 727 | |
| 728 // Longest incremental marking step since start of marking. | |
| 729 // (value at start of event) | |
| 730 double longest_incremental_marking_step; | |
| 731 | |
| 732 // Amounts of time spent in different scopes during GC. | |
| 733 double scopes[Scope::NUMBER_OF_SCOPES]; | |
| 734 }; | |
| 735 | |
| 736 typedef RingBuffer<Event, 10> EventBuffer; | |
| 737 | |
| 599 explicit GCTracer(Heap* heap); | 738 explicit GCTracer(Heap* heap); |
| 600 | 739 |
| 601 // Start collecting data. | 740 // Start collecting data. |
| 602 void start(GarbageCollector collector, | 741 void Start(GarbageCollector collector, |
| 603 const char* gc_reason, | 742 const char* gc_reason, |
| 604 const char* collector_reason); | 743 const char* collector_reason); |
| 605 | 744 |
| 606 // Stop collecting data and print results. | 745 // Stop collecting data and print results. |
| 607 void stop(); | 746 void Stop(); |
| 747 | |
| 748 // The event with the most recent end_time (selected from all event buffer) | |
| 749 EventBuffer::const_iterator Current() const; | |
| 750 | |
| 751 // The event before the current event (selected from all event buffers). | |
| 752 EventBuffer::const_iterator Previous() const; | |
| 753 | |
| 754 // Log an incremental marking step. | |
| 755 void AddIncrementalMarkingStep(double duration); | |
| 608 | 756 |
| 609 private: | 757 private: |
| 610 // Returns a string matching the collector. | |
| 611 const char* CollectorString() const; | |
| 612 | |
| 613 // Print one detailed trace line in name=value format. | 758 // Print one detailed trace line in name=value format. |
| 759 // TODO(ernstm): move to Heap. | |
| 614 void PrintNVP() const; | 760 void PrintNVP() const; |
| 615 | 761 |
| 616 // Print one trace line. | 762 // Print one trace line. |
| 763 // TODO(ernstm): move to Heap. | |
| 617 void Print() const; | 764 void Print() const; |
| 618 | 765 |
| 619 // Timestamp set in the constructor. | 766 // 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_; | 767 Heap* heap_; |
| 663 | 768 |
| 664 const char* gc_reason_; | 769 // Pending tracer event that is filled during one Start/Stop cycle. |
| 665 const char* collector_reason_; | 770 Event pending_; |
| 771 | |
| 772 // RingBuffers for SCAVENGER events. | |
| 773 EventBuffer scavenger_events_; | |
| 774 | |
| 775 // RingBuffers for MARK_COMPACTOR events. | |
| 776 EventBuffer mark_compactor_events_; | |
| 777 | |
| 778 // Cumulative number of incremental marking steps since creation of tracer. | |
| 779 int incremental_marking_steps_; | |
| 780 | |
| 781 // Cumulative duration of incremental marking steps since creation of tracer. | |
| 782 double incremental_marking_duration_; | |
| 783 | |
| 784 // Longest incremental marking step since start of marking. | |
| 785 double longest_incremental_marking_step_; | |
| 666 | 786 |
| 667 DISALLOW_COPY_AND_ASSIGN(GCTracer); | 787 DISALLOW_COPY_AND_ASSIGN(GCTracer); |
| 668 }; | 788 }; |
| 669 | 789 |
| 670 | 790 |
| 671 class Heap { | 791 class Heap { |
| 672 public: | 792 public: |
| 673 // Configure heap size in MB before setup. Return false if the heap has been | 793 // Configure heap size in MB before setup. Return false if the heap has been |
| 674 // set up already. | 794 // set up already. |
| 675 bool ConfigureHeap(int max_semi_space_size, | 795 bool ConfigureHeap(int max_semi_space_size, |
| (...skipping 685 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1361 | 1481 |
| 1362 void IncrementCodeGeneratedBytes(bool is_crankshafted, int size) { | 1482 void IncrementCodeGeneratedBytes(bool is_crankshafted, int size) { |
| 1363 if (is_crankshafted) { | 1483 if (is_crankshafted) { |
| 1364 crankshaft_codegen_bytes_generated_ += size; | 1484 crankshaft_codegen_bytes_generated_ += size; |
| 1365 } else { | 1485 } else { |
| 1366 full_codegen_bytes_generated_ += size; | 1486 full_codegen_bytes_generated_ += size; |
| 1367 } | 1487 } |
| 1368 } | 1488 } |
| 1369 | 1489 |
| 1370 // Update GC statistics that are tracked on the Heap. | 1490 // Update GC statistics that are tracked on the Heap. |
| 1371 void UpdateGCStatistics(double start_time, | 1491 void UpdateCumulativeGCStatistics(double duration, |
| 1372 double end_time, | 1492 double spent_in_mutator, |
| 1373 double spent_in_mutator, | 1493 double marking_time); |
| 1374 double marking_time); | |
| 1375 | 1494 |
| 1376 // Returns maximum GC pause. | 1495 // Returns maximum GC pause. |
| 1377 double get_max_gc_pause() { return max_gc_pause_; } | 1496 double get_max_gc_pause() { return max_gc_pause_; } |
| 1378 | 1497 |
| 1379 // Returns maximum size of objects alive after GC. | 1498 // Returns maximum size of objects alive after GC. |
| 1380 intptr_t get_max_alive_after_gc() { return max_alive_after_gc_; } | 1499 intptr_t get_max_alive_after_gc() { return max_alive_after_gc_; } |
| 1381 | 1500 |
| 1382 // Returns minimal interval between two subsequent collections. | 1501 // Returns minimal interval between two subsequent collections. |
| 1383 double get_min_in_mutator() { return min_in_mutator_; } | 1502 double get_min_in_mutator() { return min_in_mutator_; } |
| 1384 | 1503 |
| (...skipping 849 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2234 | 2353 |
| 2235 // Total time spent in GC. | 2354 // Total time spent in GC. |
| 2236 double total_gc_time_ms_; | 2355 double total_gc_time_ms_; |
| 2237 | 2356 |
| 2238 // Maximum size of objects alive after GC. | 2357 // Maximum size of objects alive after GC. |
| 2239 intptr_t max_alive_after_gc_; | 2358 intptr_t max_alive_after_gc_; |
| 2240 | 2359 |
| 2241 // Minimal interval between two subsequent collections. | 2360 // Minimal interval between two subsequent collections. |
| 2242 double min_in_mutator_; | 2361 double min_in_mutator_; |
| 2243 | 2362 |
| 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 | 2363 // Cumulative GC time spent in marking |
| 2250 double marking_time_; | 2364 double marking_time_; |
| 2251 | 2365 |
| 2252 // Cumulative GC time spent in sweeping | 2366 // Cumulative GC time spent in sweeping |
| 2253 double sweeping_time_; | 2367 double sweeping_time_; |
| 2254 | 2368 |
| 2255 MarkCompactCollector mark_compact_collector_; | 2369 MarkCompactCollector mark_compact_collector_; |
| 2256 | 2370 |
| 2257 StoreBuffer store_buffer_; | 2371 StoreBuffer store_buffer_; |
| 2258 | 2372 |
| (...skipping 524 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2783 DisallowHeapAllocation no_allocation; // i.e. no gc allowed. | 2897 DisallowHeapAllocation no_allocation; // i.e. no gc allowed. |
| 2784 | 2898 |
| 2785 private: | 2899 private: |
| 2786 DISALLOW_IMPLICIT_CONSTRUCTORS(PathTracer); | 2900 DISALLOW_IMPLICIT_CONSTRUCTORS(PathTracer); |
| 2787 }; | 2901 }; |
| 2788 #endif // DEBUG | 2902 #endif // DEBUG |
| 2789 | 2903 |
| 2790 } } // namespace v8::internal | 2904 } } // namespace v8::internal |
| 2791 | 2905 |
| 2792 #endif // V8_HEAP_H_ | 2906 #endif // V8_HEAP_H_ |
| OLD | NEW |