| 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 |