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 530 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
541 static const int kAllocatableMemory = kPageSize - kObjectStartOffset; | 541 static const int kAllocatableMemory = kPageSize - kObjectStartOffset; |
542 | 542 |
543 static inline void IncrementLiveBytesFromMutator(HeapObject* object, int by); | 543 static inline void IncrementLiveBytesFromMutator(HeapObject* object, int by); |
544 static inline void IncrementLiveBytesFromGC(HeapObject* object, int by); | 544 static inline void IncrementLiveBytesFromGC(HeapObject* object, int by); |
545 | 545 |
546 // Only works if the pointer is in the first kPageSize of the MemoryChunk. | 546 // Only works if the pointer is in the first kPageSize of the MemoryChunk. |
547 static MemoryChunk* FromAddress(Address a) { | 547 static MemoryChunk* FromAddress(Address a) { |
548 return reinterpret_cast<MemoryChunk*>(OffsetFrom(a) & ~kAlignmentMask); | 548 return reinterpret_cast<MemoryChunk*>(OffsetFrom(a) & ~kAlignmentMask); |
549 } | 549 } |
550 | 550 |
551 static intptr_t OffsetInPage(Address a) { | |
552 return reinterpret_cast<intptr_t>(a) & kPageAlignmentMask; | |
553 } | |
554 | |
555 static inline MemoryChunk* FromAnyPointerAddress(Heap* heap, Address addr); | 551 static inline MemoryChunk* FromAnyPointerAddress(Heap* heap, Address addr); |
556 | 552 |
557 static inline void UpdateHighWaterMark(Address mark) { | 553 static inline void UpdateHighWaterMark(Address mark) { |
558 if (mark == nullptr) return; | 554 if (mark == nullptr) return; |
559 // Need to subtract one from the mark because when a chunk is full the | 555 // Need to subtract one from the mark because when a chunk is full the |
560 // top points to the next address after the chunk, which effectively belongs | 556 // top points to the next address after the chunk, which effectively belongs |
561 // to another chunk. See the comment to Page::FromTopOrLimit. | 557 // to another chunk. See the comment to Page::FromTopOrLimit. |
562 MemoryChunk* chunk = MemoryChunk::FromAddress(mark - 1); | 558 MemoryChunk* chunk = MemoryChunk::FromAddress(mark - 1); |
563 intptr_t new_mark = static_cast<intptr_t>(mark - chunk->address()); | 559 intptr_t new_mark = static_cast<intptr_t>(mark - chunk->address()); |
564 intptr_t old_mark = 0; | 560 intptr_t old_mark = 0; |
(...skipping 1957 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2522 // forwards most functions to the appropriate semispace. | 2518 // forwards most functions to the appropriate semispace. |
2523 | 2519 |
2524 class NewSpace : public Space { | 2520 class NewSpace : public Space { |
2525 public: | 2521 public: |
2526 explicit NewSpace(Heap* heap) | 2522 explicit NewSpace(Heap* heap) |
2527 : Space(heap, NEW_SPACE, NOT_EXECUTABLE), | 2523 : Space(heap, NEW_SPACE, NOT_EXECUTABLE), |
2528 to_space_(heap, kToSpace), | 2524 to_space_(heap, kToSpace), |
2529 from_space_(heap, kFromSpace), | 2525 from_space_(heap, kFromSpace), |
2530 reservation_(), | 2526 reservation_(), |
2531 pages_used_(0), | 2527 pages_used_(0), |
2532 allocated_since_last_gc_(0), | |
2533 top_on_previous_step_(0), | 2528 top_on_previous_step_(0), |
2534 allocated_histogram_(nullptr), | 2529 allocated_histogram_(nullptr), |
2535 promoted_histogram_(nullptr) {} | 2530 promoted_histogram_(nullptr) {} |
2536 | 2531 |
2537 inline bool Contains(HeapObject* o); | 2532 inline bool Contains(HeapObject* o); |
2538 inline bool ContainsSlow(Address a); | 2533 inline bool ContainsSlow(Address a); |
2539 inline bool Contains(Object* o); | 2534 inline bool Contains(Object* o); |
2540 | 2535 |
2541 bool SetUp(int initial_semispace_capacity, int max_semispace_capacity); | 2536 bool SetUp(int initial_semispace_capacity, int max_semispace_capacity); |
2542 | 2537 |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2594 return from_space_.MaximumCommittedMemory() + | 2589 return from_space_.MaximumCommittedMemory() + |
2595 to_space_.MaximumCommittedMemory(); | 2590 to_space_.MaximumCommittedMemory(); |
2596 } | 2591 } |
2597 | 2592 |
2598 // Approximate amount of physical memory committed for this space. | 2593 // Approximate amount of physical memory committed for this space. |
2599 size_t CommittedPhysicalMemory() override; | 2594 size_t CommittedPhysicalMemory() override; |
2600 | 2595 |
2601 // Return the available bytes without growing. | 2596 // Return the available bytes without growing. |
2602 intptr_t Available() override { return Capacity() - Size(); } | 2597 intptr_t Available() override { return Capacity() - Size(); } |
2603 | 2598 |
2604 V8_INLINE size_t AllocatedSinceLastGC(); | 2599 size_t AllocatedSinceLastGC() { |
| 2600 bool seen_age_mark = false; |
| 2601 Address age_mark = to_space_.age_mark(); |
| 2602 Page* current_page = to_space_.first_page(); |
| 2603 Page* age_mark_page = Page::FromAddress(age_mark); |
| 2604 Page* last_page = Page::FromAddress(top() - kPointerSize); |
| 2605 if (age_mark_page == last_page) { |
| 2606 if (top() - age_mark >= 0) { |
| 2607 return top() - age_mark; |
| 2608 } |
| 2609 // Top was reset at some point, invalidating this metric. |
| 2610 return 0; |
| 2611 } |
| 2612 while (current_page != last_page) { |
| 2613 if (current_page == age_mark_page) { |
| 2614 seen_age_mark = true; |
| 2615 break; |
| 2616 } |
| 2617 current_page = current_page->next_page(); |
| 2618 } |
| 2619 if (!seen_age_mark) { |
| 2620 // Top was reset at some point, invalidating this metric. |
| 2621 return 0; |
| 2622 } |
| 2623 intptr_t allocated = age_mark_page->area_end() - age_mark; |
| 2624 DCHECK_EQ(current_page, age_mark_page); |
| 2625 current_page = age_mark_page->next_page(); |
| 2626 while (current_page != last_page) { |
| 2627 allocated += Page::kAllocatableMemory; |
| 2628 current_page = current_page->next_page(); |
| 2629 } |
| 2630 allocated += top() - current_page->area_start(); |
| 2631 DCHECK_LE(0, allocated); |
| 2632 DCHECK_LE(allocated, Size()); |
| 2633 return static_cast<size_t>(allocated); |
| 2634 } |
2605 | 2635 |
2606 bool ReplaceWithEmptyPage(Page* page) { | 2636 bool ReplaceWithEmptyPage(Page* page) { |
2607 // This method is called after flipping the semispace. | 2637 // This method is called after flipping the semispace. |
2608 DCHECK(page->InFromSpace()); | 2638 DCHECK(page->InFromSpace()); |
2609 return from_space_.ReplaceWithEmptyPage(page); | 2639 return from_space_.ReplaceWithEmptyPage(page); |
2610 } | 2640 } |
2611 | 2641 |
2612 // Return the maximum capacity of a semispace. | 2642 // Return the maximum capacity of a semispace. |
2613 int MaximumCapacity() { | 2643 int MaximumCapacity() { |
2614 DCHECK(to_space_.maximum_capacity() == from_space_.maximum_capacity()); | 2644 DCHECK(to_space_.maximum_capacity() == from_space_.maximum_capacity()); |
(...skipping 19 matching lines...) Expand all Loading... |
2634 DCHECK(to_space_.current_page()->ContainsLimit(allocation_info_.limit())); | 2664 DCHECK(to_space_.current_page()->ContainsLimit(allocation_info_.limit())); |
2635 return allocation_info_.limit(); | 2665 return allocation_info_.limit(); |
2636 } | 2666 } |
2637 | 2667 |
2638 // Return the address of the first object in the active semispace. | 2668 // Return the address of the first object in the active semispace. |
2639 Address bottom() { return to_space_.space_start(); } | 2669 Address bottom() { return to_space_.space_start(); } |
2640 | 2670 |
2641 // Get the age mark of the inactive semispace. | 2671 // Get the age mark of the inactive semispace. |
2642 Address age_mark() { return from_space_.age_mark(); } | 2672 Address age_mark() { return from_space_.age_mark(); } |
2643 // Set the age mark in the active semispace. | 2673 // Set the age mark in the active semispace. |
2644 void set_age_mark(Address mark) { | 2674 void set_age_mark(Address mark) { to_space_.set_age_mark(mark); } |
2645 to_space_.set_age_mark(mark); | |
2646 allocated_since_last_gc_ = 0; | |
2647 } | |
2648 | 2675 |
2649 // The allocation top and limit address. | 2676 // The allocation top and limit address. |
2650 Address* allocation_top_address() { return allocation_info_.top_address(); } | 2677 Address* allocation_top_address() { return allocation_info_.top_address(); } |
2651 | 2678 |
2652 // The allocation limit address. | 2679 // The allocation limit address. |
2653 Address* allocation_limit_address() { | 2680 Address* allocation_limit_address() { |
2654 return allocation_info_.limit_address(); | 2681 return allocation_info_.limit_address(); |
2655 } | 2682 } |
2656 | 2683 |
2657 MUST_USE_RESULT INLINE(AllocationResult AllocateRawAligned( | 2684 MUST_USE_RESULT INLINE(AllocationResult AllocateRawAligned( |
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2758 // Update allocation info to match the current to-space page. | 2785 // Update allocation info to match the current to-space page. |
2759 void UpdateAllocationInfo(); | 2786 void UpdateAllocationInfo(); |
2760 | 2787 |
2761 base::Mutex mutex_; | 2788 base::Mutex mutex_; |
2762 | 2789 |
2763 // The semispaces. | 2790 // The semispaces. |
2764 SemiSpace to_space_; | 2791 SemiSpace to_space_; |
2765 SemiSpace from_space_; | 2792 SemiSpace from_space_; |
2766 base::VirtualMemory reservation_; | 2793 base::VirtualMemory reservation_; |
2767 int pages_used_; | 2794 int pages_used_; |
2768 intptr_t allocated_since_last_gc_; | |
2769 | 2795 |
2770 // Allocation pointer and limit for normal allocation and allocation during | 2796 // Allocation pointer and limit for normal allocation and allocation during |
2771 // mark-compact collection. | 2797 // mark-compact collection. |
2772 AllocationInfo allocation_info_; | 2798 AllocationInfo allocation_info_; |
2773 | 2799 |
2774 Address top_on_previous_step_; | 2800 Address top_on_previous_step_; |
2775 | 2801 |
2776 HistogramInfo* allocated_histogram_; | 2802 HistogramInfo* allocated_histogram_; |
2777 HistogramInfo* promoted_histogram_; | 2803 HistogramInfo* promoted_histogram_; |
2778 | 2804 |
(...skipping 259 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3038 count = 0; | 3064 count = 0; |
3039 } | 3065 } |
3040 // Must be small, since an iteration is used for lookup. | 3066 // Must be small, since an iteration is used for lookup. |
3041 static const int kMaxComments = 64; | 3067 static const int kMaxComments = 64; |
3042 }; | 3068 }; |
3043 #endif | 3069 #endif |
3044 } // namespace internal | 3070 } // namespace internal |
3045 } // namespace v8 | 3071 } // namespace v8 |
3046 | 3072 |
3047 #endif // V8_HEAP_SPACES_H_ | 3073 #endif // V8_HEAP_SPACES_H_ |
OLD | NEW |