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" |
11 #include "src/base/bits.h" | 11 #include "src/base/bits.h" |
12 #include "src/base/platform/mutex.h" | 12 #include "src/base/platform/mutex.h" |
13 #include "src/flags.h" | 13 #include "src/flags.h" |
14 #include "src/hashmap.h" | 14 #include "src/hashmap.h" |
15 #include "src/list.h" | 15 #include "src/list.h" |
16 #include "src/objects.h" | 16 #include "src/objects.h" |
17 #include "src/utils.h" | 17 #include "src/utils.h" |
18 | 18 |
19 namespace v8 { | 19 namespace v8 { |
20 namespace internal { | 20 namespace internal { |
21 | 21 |
22 class AllocationInfo; | 22 class AllocationInfo; |
23 class AllocationObserver; | |
23 class CompactionSpace; | 24 class CompactionSpace; |
24 class CompactionSpaceCollection; | 25 class CompactionSpaceCollection; |
25 class FreeList; | 26 class FreeList; |
26 class InlineAllocationObserver; | |
27 class Isolate; | 27 class Isolate; |
28 class MemoryAllocator; | 28 class MemoryAllocator; |
29 class MemoryChunk; | 29 class MemoryChunk; |
30 class PagedSpace; | 30 class PagedSpace; |
31 class SemiSpace; | 31 class SemiSpace; |
32 class SkipList; | 32 class SkipList; |
33 class SlotsBuffer; | 33 class SlotsBuffer; |
34 class Space; | 34 class Space; |
35 | 35 |
36 // ----------------------------------------------------------------------------- | 36 // ----------------------------------------------------------------------------- |
(...skipping 903 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
940 | 940 |
941 friend class MemoryAllocator; | 941 friend class MemoryAllocator; |
942 }; | 942 }; |
943 | 943 |
944 | 944 |
945 // ---------------------------------------------------------------------------- | 945 // ---------------------------------------------------------------------------- |
946 // Space is the abstract superclass for all allocation spaces. | 946 // Space is the abstract superclass for all allocation spaces. |
947 class Space : public Malloced { | 947 class Space : public Malloced { |
948 public: | 948 public: |
949 Space(Heap* heap, AllocationSpace id, Executability executable) | 949 Space(Heap* heap, AllocationSpace id, Executability executable) |
950 : heap_(heap), | 950 : allocation_observers_paused_(false), |
951 heap_(heap), | |
951 id_(id), | 952 id_(id), |
952 executable_(executable), | 953 executable_(executable), |
953 committed_(0), | 954 committed_(0), |
954 max_committed_(0) {} | 955 max_committed_(0) { |
956 allocation_observers_ = new List<AllocationObserver*>(); | |
ofrobots
2016/02/11 05:51:46
Never freed? Use SmartPointer to manage this.
mattloring
2016/02/11 14:54:14
Done.
| |
957 } | |
955 | 958 |
956 virtual ~Space() {} | 959 virtual ~Space() {} |
957 | 960 |
958 Heap* heap() const { return heap_; } | 961 Heap* heap() const { return heap_; } |
959 | 962 |
960 // Does the space need executable memory? | 963 // Does the space need executable memory? |
961 Executability executable() { return executable_; } | 964 Executability executable() { return executable_; } |
962 | 965 |
963 // Identity used in error reporting. | 966 // Identity used in error reporting. |
964 AllocationSpace identity() { return id_; } | 967 AllocationSpace identity() { return id_; } |
965 | 968 |
969 virtual void AddAllocationObserver(AllocationObserver* observer) { | |
970 allocation_observers_->Add(observer); | |
971 } | |
972 | |
973 virtual void RemoveAllocationObserver(AllocationObserver* observer) { | |
974 bool removed = allocation_observers_->RemoveElement(observer); | |
975 USE(removed); | |
976 DCHECK(removed); | |
977 } | |
978 | |
979 virtual void PauseAllocationObservers() { | |
980 allocation_observers_paused_ = true; | |
981 } | |
982 | |
983 virtual void ResumeAllocationObservers() { | |
984 allocation_observers_paused_ = false; | |
985 } | |
986 | |
987 void AllocationStep(Address soon_object, int size); | |
988 | |
966 // Return the total amount committed memory for this space, i.e., allocatable | 989 // Return the total amount committed memory for this space, i.e., allocatable |
967 // memory and page headers. | 990 // memory and page headers. |
968 virtual intptr_t CommittedMemory() { return committed_; } | 991 virtual intptr_t CommittedMemory() { return committed_; } |
969 | 992 |
970 virtual intptr_t MaximumCommittedMemory() { return max_committed_; } | 993 virtual intptr_t MaximumCommittedMemory() { return max_committed_; } |
971 | 994 |
972 // Returns allocated size. | 995 // Returns allocated size. |
973 virtual intptr_t Size() = 0; | 996 virtual intptr_t Size() = 0; |
974 | 997 |
975 // Returns size of objects. Can differ from the allocated size | 998 // Returns size of objects. Can differ from the allocated size |
(...skipping 26 matching lines...) Expand all Loading... | |
1002 max_committed_ = committed_; | 1025 max_committed_ = committed_; |
1003 } | 1026 } |
1004 } | 1027 } |
1005 | 1028 |
1006 void AccountUncommitted(intptr_t bytes) { | 1029 void AccountUncommitted(intptr_t bytes) { |
1007 DCHECK_GE(bytes, 0); | 1030 DCHECK_GE(bytes, 0); |
1008 committed_ -= bytes; | 1031 committed_ -= bytes; |
1009 DCHECK_GE(committed_, 0); | 1032 DCHECK_GE(committed_, 0); |
1010 } | 1033 } |
1011 | 1034 |
1035 // When inline allocation stepping is active, either because of incremental | |
1036 // marking, idle scavenge, or allocation statistics gathering, we 'interrupt' | |
1037 // inline allocation every once in a while. This is done by setting | |
1038 // allocation_info_.limit to be lower than the actual limit and and increasing | |
1039 // it in steps to guarantee that the observers are notified periodically. | |
1040 List<AllocationObserver*>* allocation_observers_; | |
ofrobots
2016/02/11 05:51:46
The comment about inline allocation stepping seems
mattloring
2016/02/11 14:54:14
I'm guessing you meant that it doesn't. I've moved
| |
1041 bool allocation_observers_paused_; | |
1042 | |
1012 private: | 1043 private: |
1013 Heap* heap_; | 1044 Heap* heap_; |
1014 AllocationSpace id_; | 1045 AllocationSpace id_; |
1015 Executability executable_; | 1046 Executability executable_; |
1016 | 1047 |
1017 // Keeps track of committed memory in a space. | 1048 // Keeps track of committed memory in a space. |
1018 intptr_t committed_; | 1049 intptr_t committed_; |
1019 intptr_t max_committed_; | 1050 intptr_t max_committed_; |
1020 }; | 1051 }; |
1021 | 1052 |
(...skipping 1528 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2550 // forwards most functions to the appropriate semispace. | 2581 // forwards most functions to the appropriate semispace. |
2551 | 2582 |
2552 class NewSpace : public Space { | 2583 class NewSpace : public Space { |
2553 public: | 2584 public: |
2554 // Constructor. | 2585 // Constructor. |
2555 explicit NewSpace(Heap* heap) | 2586 explicit NewSpace(Heap* heap) |
2556 : Space(heap, NEW_SPACE, NOT_EXECUTABLE), | 2587 : Space(heap, NEW_SPACE, NOT_EXECUTABLE), |
2557 to_space_(heap, kToSpace), | 2588 to_space_(heap, kToSpace), |
2558 from_space_(heap, kFromSpace), | 2589 from_space_(heap, kFromSpace), |
2559 reservation_(), | 2590 reservation_(), |
2560 top_on_previous_step_(0), | 2591 top_on_previous_step_(0) {} |
2561 inline_allocation_observers_paused_(false) {} | |
2562 | 2592 |
2563 // Sets up the new space using the given chunk. | 2593 // Sets up the new space using the given chunk. |
2564 bool SetUp(int reserved_semispace_size_, int max_semi_space_size); | 2594 bool SetUp(int reserved_semispace_size_, int max_semi_space_size); |
2565 | 2595 |
2566 // Tears down the space. Heap memory was not allocated by the space, so it | 2596 // Tears down the space. Heap memory was not allocated by the space, so it |
2567 // is not deallocated here. | 2597 // is not deallocated here. |
2568 void TearDown(); | 2598 void TearDown(); |
2569 | 2599 |
2570 // True if the space has been set up but not torn down. | 2600 // True if the space has been set up but not torn down. |
2571 bool HasBeenSetUp() { | 2601 bool HasBeenSetUp() { |
(...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2723 int size_in_bytes, AllocationAlignment alignment)); | 2753 int size_in_bytes, AllocationAlignment alignment)); |
2724 | 2754 |
2725 MUST_USE_RESULT inline AllocationResult AllocateRawSynchronized( | 2755 MUST_USE_RESULT inline AllocationResult AllocateRawSynchronized( |
2726 int size_in_bytes, AllocationAlignment alignment); | 2756 int size_in_bytes, AllocationAlignment alignment); |
2727 | 2757 |
2728 // Reset the allocation pointer to the beginning of the active semispace. | 2758 // Reset the allocation pointer to the beginning of the active semispace. |
2729 void ResetAllocationInfo(); | 2759 void ResetAllocationInfo(); |
2730 | 2760 |
2731 void UpdateInlineAllocationLimit(int size_in_bytes); | 2761 void UpdateInlineAllocationLimit(int size_in_bytes); |
2732 | 2762 |
2733 // Allows observation of inline allocation. The observer->Step() method gets | |
2734 // called after every step_size bytes have been allocated (approximately). | |
2735 // This works by adjusting the allocation limit to a lower value and adjusting | |
2736 // it after each step. | |
2737 void AddInlineAllocationObserver(InlineAllocationObserver* observer); | |
2738 | |
2739 // Removes a previously installed observer. | |
2740 void RemoveInlineAllocationObserver(InlineAllocationObserver* observer); | |
2741 | |
2742 void DisableInlineAllocationSteps() { | 2763 void DisableInlineAllocationSteps() { |
2743 top_on_previous_step_ = 0; | 2764 top_on_previous_step_ = 0; |
2744 UpdateInlineAllocationLimit(0); | 2765 UpdateInlineAllocationLimit(0); |
2745 } | 2766 } |
2746 | 2767 |
2768 // Allows observation of inline allocation. The observer->Step() method gets | |
2769 // called after every step_size bytes have been allocated (approximately). | |
2770 // This works by adjusting the allocation limit to a lower value and adjusting | |
2771 // it after each step. | |
2772 void AddAllocationObserver(AllocationObserver* observer) override; | |
2773 | |
2774 void RemoveAllocationObserver(AllocationObserver* observer) override; | |
2775 | |
2747 // Get the extent of the inactive semispace (for use as a marking stack, | 2776 // Get the extent of the inactive semispace (for use as a marking stack, |
2748 // or to zap it). Notice: space-addresses are not necessarily on the | 2777 // or to zap it). Notice: space-addresses are not necessarily on the |
2749 // same page, so FromSpaceStart() might be above FromSpaceEnd(). | 2778 // same page, so FromSpaceStart() might be above FromSpaceEnd(). |
2750 Address FromSpacePageLow() { return from_space_.page_low(); } | 2779 Address FromSpacePageLow() { return from_space_.page_low(); } |
2751 Address FromSpacePageHigh() { return from_space_.page_high(); } | 2780 Address FromSpacePageHigh() { return from_space_.page_high(); } |
2752 Address FromSpaceStart() { return from_space_.space_start(); } | 2781 Address FromSpaceStart() { return from_space_.space_start(); } |
2753 Address FromSpaceEnd() { return from_space_.space_end(); } | 2782 Address FromSpaceEnd() { return from_space_.space_end(); } |
2754 | 2783 |
2755 // Get the extent of the active semispace's pages' memory. | 2784 // Get the extent of the active semispace's pages' memory. |
2756 Address ToSpaceStart() { return to_space_.space_start(); } | 2785 Address ToSpaceStart() { return to_space_.space_start(); } |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2807 | 2836 |
2808 bool UncommitFromSpace() { | 2837 bool UncommitFromSpace() { |
2809 if (!from_space_.is_committed()) return true; | 2838 if (!from_space_.is_committed()) return true; |
2810 return from_space_.Uncommit(); | 2839 return from_space_.Uncommit(); |
2811 } | 2840 } |
2812 | 2841 |
2813 bool IsFromSpaceCommitted() { return from_space_.is_committed(); } | 2842 bool IsFromSpaceCommitted() { return from_space_.is_committed(); } |
2814 | 2843 |
2815 SemiSpace* active_space() { return &to_space_; } | 2844 SemiSpace* active_space() { return &to_space_; } |
2816 | 2845 |
2846 void PauseAllocationObservers() override; | |
2847 void ResumeAllocationObservers() override; | |
2848 | |
2817 private: | 2849 private: |
2818 // Update allocation info to match the current to-space page. | 2850 // Update allocation info to match the current to-space page. |
2819 void UpdateAllocationInfo(); | 2851 void UpdateAllocationInfo(); |
2820 | 2852 |
2821 base::Mutex mutex_; | 2853 base::Mutex mutex_; |
2822 | 2854 |
2823 Address chunk_base_; | 2855 Address chunk_base_; |
2824 uintptr_t chunk_size_; | 2856 uintptr_t chunk_size_; |
2825 | 2857 |
2826 // The semispaces. | 2858 // The semispaces. |
2827 SemiSpace to_space_; | 2859 SemiSpace to_space_; |
2828 SemiSpace from_space_; | 2860 SemiSpace from_space_; |
2829 base::VirtualMemory reservation_; | 2861 base::VirtualMemory reservation_; |
2830 int pages_used_; | 2862 int pages_used_; |
2831 | 2863 |
2832 // Start address and bit mask for containment testing. | 2864 // Start address and bit mask for containment testing. |
2833 Address start_; | 2865 Address start_; |
2834 uintptr_t address_mask_; | 2866 uintptr_t address_mask_; |
2835 uintptr_t object_mask_; | 2867 uintptr_t object_mask_; |
2836 uintptr_t object_expected_; | 2868 uintptr_t object_expected_; |
2837 | 2869 |
2838 // Allocation pointer and limit for normal allocation and allocation during | 2870 // Allocation pointer and limit for normal allocation and allocation during |
2839 // mark-compact collection. | 2871 // mark-compact collection. |
2840 AllocationInfo allocation_info_; | 2872 AllocationInfo allocation_info_; |
2841 | 2873 |
2842 // When inline allocation stepping is active, either because of incremental | |
2843 // marking or because of idle scavenge, we 'interrupt' inline allocation every | |
2844 // once in a while. This is done by setting allocation_info_.limit to be lower | |
2845 // than the actual limit and and increasing it in steps to guarantee that the | |
2846 // observers are notified periodically. | |
2847 List<InlineAllocationObserver*> inline_allocation_observers_; | |
2848 Address top_on_previous_step_; | 2874 Address top_on_previous_step_; |
2849 bool inline_allocation_observers_paused_; | |
2850 | 2875 |
2851 HistogramInfo* allocated_histogram_; | 2876 HistogramInfo* allocated_histogram_; |
2852 HistogramInfo* promoted_histogram_; | 2877 HistogramInfo* promoted_histogram_; |
2853 | 2878 |
2854 bool EnsureAllocation(int size_in_bytes, AllocationAlignment alignment); | 2879 bool EnsureAllocation(int size_in_bytes, AllocationAlignment alignment); |
2855 | 2880 |
2856 // If we are doing inline allocation in steps, this method performs the 'step' | 2881 // If we are doing inline allocation in steps, this method performs the 'step' |
2857 // operation. top is the memory address of the bump pointer at the last | 2882 // operation. top is the memory address of the bump pointer at the last |
2858 // inline allocation (i.e. it determines the numbers of bytes actually | 2883 // inline allocation (i.e. it determines the numbers of bytes actually |
2859 // allocated since the last step.) new_top is the address of the bump pointer | 2884 // allocated since the last step.) new_top is the address of the bump pointer |
2860 // where the next byte is going to be allocated from. top and new_top may be | 2885 // where the next byte is going to be allocated from. top and new_top may be |
2861 // different when we cross a page boundary or reset the space. | 2886 // different when we cross a page boundary or reset the space. |
2862 void InlineAllocationStep(Address top, Address new_top, Address soon_object, | 2887 void InlineAllocationStep(Address top, Address new_top, Address soon_object, |
2863 size_t size); | 2888 size_t size); |
2864 intptr_t GetNextInlineAllocationStepSize(); | 2889 intptr_t GetNextInlineAllocationStepSize(); |
2865 void StartNextInlineAllocationStep(); | 2890 void StartNextInlineAllocationStep(); |
2866 void PauseInlineAllocationObservers(); | |
2867 void ResumeInlineAllocationObservers(); | |
2868 | 2891 |
2869 friend class PauseInlineAllocationObserversScope; | |
2870 friend class SemiSpaceIterator; | 2892 friend class SemiSpaceIterator; |
2871 }; | 2893 }; |
2872 | 2894 |
2873 class PauseInlineAllocationObserversScope { | 2895 class PauseAllocationObserversScope { |
2874 public: | 2896 public: |
2875 explicit PauseInlineAllocationObserversScope(NewSpace* new_space) | 2897 explicit PauseAllocationObserversScope(Heap* heap); |
2876 : new_space_(new_space) { | 2898 ~PauseAllocationObserversScope(); |
2877 new_space_->PauseInlineAllocationObservers(); | |
2878 } | |
2879 ~PauseInlineAllocationObserversScope() { | |
2880 new_space_->ResumeInlineAllocationObservers(); | |
2881 } | |
2882 | 2899 |
2883 private: | 2900 private: |
2884 NewSpace* new_space_; | 2901 Heap* heap_; |
2885 DISALLOW_COPY_AND_ASSIGN(PauseInlineAllocationObserversScope); | 2902 DISALLOW_COPY_AND_ASSIGN(PauseAllocationObserversScope); |
2886 }; | 2903 }; |
2887 | 2904 |
2888 // ----------------------------------------------------------------------------- | 2905 // ----------------------------------------------------------------------------- |
2889 // Compaction space that is used temporarily during compaction. | 2906 // Compaction space that is used temporarily during compaction. |
2890 | 2907 |
2891 class CompactionSpace : public PagedSpace { | 2908 class CompactionSpace : public PagedSpace { |
2892 public: | 2909 public: |
2893 CompactionSpace(Heap* heap, AllocationSpace id, Executability executable) | 2910 CompactionSpace(Heap* heap, AllocationSpace id, Executability executable) |
2894 : PagedSpace(heap, id, executable) {} | 2911 : PagedSpace(heap, id, executable) {} |
2895 | 2912 |
(...skipping 232 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3128 count = 0; | 3145 count = 0; |
3129 } | 3146 } |
3130 // Must be small, since an iteration is used for lookup. | 3147 // Must be small, since an iteration is used for lookup. |
3131 static const int kMaxComments = 64; | 3148 static const int kMaxComments = 64; |
3132 }; | 3149 }; |
3133 #endif | 3150 #endif |
3134 } // namespace internal | 3151 } // namespace internal |
3135 } // namespace v8 | 3152 } // namespace v8 |
3136 | 3153 |
3137 #endif // V8_HEAP_SPACES_H_ | 3154 #endif // V8_HEAP_SPACES_H_ |
OLD | NEW |