OLD | NEW |
1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 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_SPACES_H_ | 5 #ifndef V8_HEAP_SPACES_H_ |
6 #define V8_HEAP_SPACES_H_ | 6 #define V8_HEAP_SPACES_H_ |
7 | 7 |
8 #include "src/allocation.h" | 8 #include "src/allocation.h" |
9 #include "src/atomic-utils.h" | 9 #include "src/atomic-utils.h" |
10 #include "src/base/atomicops.h" | 10 #include "src/base/atomicops.h" |
(...skipping 524 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
535 static const int kAllocatableMemory = kPageSize - kObjectStartOffset; | 535 static const int kAllocatableMemory = kPageSize - kObjectStartOffset; |
536 | 536 |
537 static inline void IncrementLiveBytesFromMutator(HeapObject* object, int by); | 537 static inline void IncrementLiveBytesFromMutator(HeapObject* object, int by); |
538 static inline void IncrementLiveBytesFromGC(HeapObject* object, int by); | 538 static inline void IncrementLiveBytesFromGC(HeapObject* object, int by); |
539 | 539 |
540 // Only works if the pointer is in the first kPageSize of the MemoryChunk. | 540 // Only works if the pointer is in the first kPageSize of the MemoryChunk. |
541 static MemoryChunk* FromAddress(Address a) { | 541 static MemoryChunk* FromAddress(Address a) { |
542 return reinterpret_cast<MemoryChunk*>(OffsetFrom(a) & ~kAlignmentMask); | 542 return reinterpret_cast<MemoryChunk*>(OffsetFrom(a) & ~kAlignmentMask); |
543 } | 543 } |
544 | 544 |
| 545 static intptr_t OffsetInPage(Address a) { |
| 546 return reinterpret_cast<intptr_t>(a) & kPageAlignmentMask; |
| 547 } |
| 548 |
545 static inline MemoryChunk* FromAnyPointerAddress(Heap* heap, Address addr); | 549 static inline MemoryChunk* FromAnyPointerAddress(Heap* heap, Address addr); |
546 | 550 |
547 static inline void UpdateHighWaterMark(Address mark) { | 551 static inline void UpdateHighWaterMark(Address mark) { |
548 if (mark == nullptr) return; | 552 if (mark == nullptr) return; |
549 // Need to subtract one from the mark because when a chunk is full the | 553 // Need to subtract one from the mark because when a chunk is full the |
550 // top points to the next address after the chunk, which effectively belongs | 554 // top points to the next address after the chunk, which effectively belongs |
551 // to another chunk. See the comment to Page::FromAllocationTop. | 555 // to another chunk. See the comment to Page::FromAllocationTop. |
552 MemoryChunk* chunk = MemoryChunk::FromAddress(mark - 1); | 556 MemoryChunk* chunk = MemoryChunk::FromAddress(mark - 1); |
553 intptr_t new_mark = static_cast<intptr_t>(mark - chunk->address()); | 557 intptr_t new_mark = static_cast<intptr_t>(mark - chunk->address()); |
554 intptr_t old_mark = 0; | 558 intptr_t old_mark = 0; |
(...skipping 2020 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2575 // forwards most functions to the appropriate semispace. | 2579 // forwards most functions to the appropriate semispace. |
2576 | 2580 |
2577 class NewSpace : public Space { | 2581 class NewSpace : public Space { |
2578 public: | 2582 public: |
2579 explicit NewSpace(Heap* heap) | 2583 explicit NewSpace(Heap* heap) |
2580 : Space(heap, NEW_SPACE, NOT_EXECUTABLE), | 2584 : Space(heap, NEW_SPACE, NOT_EXECUTABLE), |
2581 to_space_(heap, kToSpace), | 2585 to_space_(heap, kToSpace), |
2582 from_space_(heap, kFromSpace), | 2586 from_space_(heap, kFromSpace), |
2583 reservation_(), | 2587 reservation_(), |
2584 pages_used_(0), | 2588 pages_used_(0), |
| 2589 allocated_since_last_gc_(0), |
2585 top_on_previous_step_(0), | 2590 top_on_previous_step_(0), |
2586 allocated_histogram_(nullptr), | 2591 allocated_histogram_(nullptr), |
2587 promoted_histogram_(nullptr) {} | 2592 promoted_histogram_(nullptr) {} |
2588 | 2593 |
2589 inline bool Contains(HeapObject* o); | 2594 inline bool Contains(HeapObject* o); |
2590 inline bool ContainsSlow(Address a); | 2595 inline bool ContainsSlow(Address a); |
2591 inline bool Contains(Object* o); | 2596 inline bool Contains(Object* o); |
2592 | 2597 |
2593 bool SetUp(int initial_semispace_capacity, int max_semispace_capacity); | 2598 bool SetUp(int initial_semispace_capacity, int max_semispace_capacity); |
2594 | 2599 |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2646 return from_space_.MaximumCommittedMemory() + | 2651 return from_space_.MaximumCommittedMemory() + |
2647 to_space_.MaximumCommittedMemory(); | 2652 to_space_.MaximumCommittedMemory(); |
2648 } | 2653 } |
2649 | 2654 |
2650 // Approximate amount of physical memory committed for this space. | 2655 // Approximate amount of physical memory committed for this space. |
2651 size_t CommittedPhysicalMemory() override; | 2656 size_t CommittedPhysicalMemory() override; |
2652 | 2657 |
2653 // Return the available bytes without growing. | 2658 // Return the available bytes without growing. |
2654 intptr_t Available() override { return Capacity() - Size(); } | 2659 intptr_t Available() override { return Capacity() - Size(); } |
2655 | 2660 |
2656 size_t AllocatedSinceLastGC() { | 2661 inline size_t AllocatedSinceLastGC(); |
2657 bool seen_age_mark = false; | |
2658 Address age_mark = to_space_.age_mark(); | |
2659 NewSpacePage* current_page = to_space_.first_page(); | |
2660 NewSpacePage* age_mark_page = NewSpacePage::FromAddress(age_mark); | |
2661 NewSpacePage* last_page = NewSpacePage::FromAddress(top() - kPointerSize); | |
2662 if (age_mark_page == last_page) { | |
2663 if (top() - age_mark >= 0) { | |
2664 return top() - age_mark; | |
2665 } | |
2666 // Top was reset at some point, invalidating this metric. | |
2667 return 0; | |
2668 } | |
2669 while (current_page != last_page) { | |
2670 if (current_page == age_mark_page) { | |
2671 seen_age_mark = true; | |
2672 break; | |
2673 } | |
2674 current_page = current_page->next_page(); | |
2675 } | |
2676 if (!seen_age_mark) { | |
2677 // Top was reset at some point, invalidating this metric. | |
2678 return 0; | |
2679 } | |
2680 intptr_t allocated = age_mark_page->area_end() - age_mark; | |
2681 DCHECK_EQ(current_page, age_mark_page); | |
2682 current_page = age_mark_page->next_page(); | |
2683 while (current_page != last_page) { | |
2684 allocated += NewSpacePage::kAllocatableMemory; | |
2685 current_page = current_page->next_page(); | |
2686 } | |
2687 allocated += top() - current_page->area_start(); | |
2688 DCHECK_LE(0, allocated); | |
2689 DCHECK_LE(allocated, Size()); | |
2690 return static_cast<size_t>(allocated); | |
2691 } | |
2692 | 2662 |
2693 // Return the maximum capacity of a semispace. | 2663 // Return the maximum capacity of a semispace. |
2694 int MaximumCapacity() { | 2664 int MaximumCapacity() { |
2695 DCHECK(to_space_.maximum_capacity() == from_space_.maximum_capacity()); | 2665 DCHECK(to_space_.maximum_capacity() == from_space_.maximum_capacity()); |
2696 return to_space_.maximum_capacity(); | 2666 return to_space_.maximum_capacity(); |
2697 } | 2667 } |
2698 | 2668 |
2699 bool IsAtMaximumCapacity() { return TotalCapacity() == MaximumCapacity(); } | 2669 bool IsAtMaximumCapacity() { return TotalCapacity() == MaximumCapacity(); } |
2700 | 2670 |
2701 // Returns the initial capacity of a semispace. | 2671 // Returns the initial capacity of a semispace. |
(...skipping 13 matching lines...) Expand all Loading... |
2715 DCHECK(to_space_.current_page()->ContainsLimit(allocation_info_.limit())); | 2685 DCHECK(to_space_.current_page()->ContainsLimit(allocation_info_.limit())); |
2716 return allocation_info_.limit(); | 2686 return allocation_info_.limit(); |
2717 } | 2687 } |
2718 | 2688 |
2719 // Return the address of the first object in the active semispace. | 2689 // Return the address of the first object in the active semispace. |
2720 Address bottom() { return to_space_.space_start(); } | 2690 Address bottom() { return to_space_.space_start(); } |
2721 | 2691 |
2722 // Get the age mark of the inactive semispace. | 2692 // Get the age mark of the inactive semispace. |
2723 Address age_mark() { return from_space_.age_mark(); } | 2693 Address age_mark() { return from_space_.age_mark(); } |
2724 // Set the age mark in the active semispace. | 2694 // Set the age mark in the active semispace. |
2725 void set_age_mark(Address mark) { to_space_.set_age_mark(mark); } | 2695 void set_age_mark(Address mark) { |
| 2696 to_space_.set_age_mark(mark); |
| 2697 allocated_since_last_gc_ = 0; |
| 2698 } |
2726 | 2699 |
2727 // The allocation top and limit address. | 2700 // The allocation top and limit address. |
2728 Address* allocation_top_address() { return allocation_info_.top_address(); } | 2701 Address* allocation_top_address() { return allocation_info_.top_address(); } |
2729 | 2702 |
2730 // The allocation limit address. | 2703 // The allocation limit address. |
2731 Address* allocation_limit_address() { | 2704 Address* allocation_limit_address() { |
2732 return allocation_info_.limit_address(); | 2705 return allocation_info_.limit_address(); |
2733 } | 2706 } |
2734 | 2707 |
2735 MUST_USE_RESULT INLINE(AllocationResult AllocateRawAligned( | 2708 MUST_USE_RESULT INLINE(AllocationResult AllocateRawAligned( |
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2836 // Update allocation info to match the current to-space page. | 2809 // Update allocation info to match the current to-space page. |
2837 void UpdateAllocationInfo(); | 2810 void UpdateAllocationInfo(); |
2838 | 2811 |
2839 base::Mutex mutex_; | 2812 base::Mutex mutex_; |
2840 | 2813 |
2841 // The semispaces. | 2814 // The semispaces. |
2842 SemiSpace to_space_; | 2815 SemiSpace to_space_; |
2843 SemiSpace from_space_; | 2816 SemiSpace from_space_; |
2844 base::VirtualMemory reservation_; | 2817 base::VirtualMemory reservation_; |
2845 int pages_used_; | 2818 int pages_used_; |
| 2819 intptr_t allocated_since_last_gc_; |
2846 | 2820 |
2847 // Allocation pointer and limit for normal allocation and allocation during | 2821 // Allocation pointer and limit for normal allocation and allocation during |
2848 // mark-compact collection. | 2822 // mark-compact collection. |
2849 AllocationInfo allocation_info_; | 2823 AllocationInfo allocation_info_; |
2850 | 2824 |
2851 Address top_on_previous_step_; | 2825 Address top_on_previous_step_; |
2852 | 2826 |
2853 HistogramInfo* allocated_histogram_; | 2827 HistogramInfo* allocated_histogram_; |
2854 HistogramInfo* promoted_histogram_; | 2828 HistogramInfo* promoted_histogram_; |
2855 | 2829 |
(...skipping 259 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3115 count = 0; | 3089 count = 0; |
3116 } | 3090 } |
3117 // Must be small, since an iteration is used for lookup. | 3091 // Must be small, since an iteration is used for lookup. |
3118 static const int kMaxComments = 64; | 3092 static const int kMaxComments = 64; |
3119 }; | 3093 }; |
3120 #endif | 3094 #endif |
3121 } // namespace internal | 3095 } // namespace internal |
3122 } // namespace v8 | 3096 } // namespace v8 |
3123 | 3097 |
3124 #endif // V8_HEAP_SPACES_H_ | 3098 #endif // V8_HEAP_SPACES_H_ |
OLD | NEW |