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 AllocationObserver; | |
22 class CompactionSpaceCollection; | 23 class CompactionSpaceCollection; |
23 class InlineAllocationObserver; | |
24 class Isolate; | 24 class Isolate; |
25 | 25 |
26 // ----------------------------------------------------------------------------- | 26 // ----------------------------------------------------------------------------- |
27 // Heap structures: | 27 // Heap structures: |
28 // | 28 // |
29 // A JS heap consists of a young generation, an old generation, and a large | 29 // A JS heap consists of a young generation, an old generation, and a large |
30 // object space. The young generation is divided into two semispaces. A | 30 // object space. The young generation is divided into two semispaces. A |
31 // scavenger implements Cheney's copying algorithm. The old generation is | 31 // scavenger implements Cheney's copying algorithm. The old generation is |
32 // separated into a map space and an old object space. The map space contains | 32 // separated into a map space and an old object space. The map space contains |
33 // all (and only) map objects, the rest of old objects go into the old space. | 33 // all (and only) map objects, the rest of old objects go into the old space. |
(...skipping 916 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
950 | 950 |
951 friend class MemoryAllocator; | 951 friend class MemoryAllocator; |
952 }; | 952 }; |
953 | 953 |
954 | 954 |
955 // ---------------------------------------------------------------------------- | 955 // ---------------------------------------------------------------------------- |
956 // Space is the abstract superclass for all allocation spaces. | 956 // Space is the abstract superclass for all allocation spaces. |
957 class Space : public Malloced { | 957 class Space : public Malloced { |
958 public: | 958 public: |
959 Space(Heap* heap, AllocationSpace id, Executability executable) | 959 Space(Heap* heap, AllocationSpace id, Executability executable) |
960 : heap_(heap), | 960 : allocation_observers_paused_(false), |
ofrobots
2016/01/26 00:38:25
As per suggestion above, it might make sense for H
mattloring
2016/01/30 00:38:03
This is currently enforced by the PauseAllocationO
| |
961 heap_(heap), | |
961 id_(id), | 962 id_(id), |
962 executable_(executable), | 963 executable_(executable), |
963 committed_(0), | 964 committed_(0), |
964 max_committed_(0) {} | 965 max_committed_(0) {} |
965 | 966 |
966 virtual ~Space() {} | 967 virtual ~Space() {} |
967 | 968 |
968 Heap* heap() const { return heap_; } | 969 Heap* heap() const { return heap_; } |
969 | 970 |
970 // Does the space need executable memory? | 971 // Does the space need executable memory? |
971 Executability executable() { return executable_; } | 972 Executability executable() { return executable_; } |
972 | 973 |
973 // Identity used in error reporting. | 974 // Identity used in error reporting. |
974 AllocationSpace identity() { return id_; } | 975 AllocationSpace identity() { return id_; } |
975 | 976 |
977 virtual void AddAllocationObserver(AllocationObserver* observer) { | |
978 allocation_observers_->Add(observer); | |
979 } | |
980 | |
981 virtual void RemoveAllocationObserver(AllocationObserver* observer) { | |
982 bool removed = allocation_observers_->RemoveElement(observer); | |
983 static_cast<void>(removed); | |
984 DCHECK(removed); | |
985 } | |
986 | |
987 virtual void PauseAllocationObservers() { | |
988 allocation_observers_paused_ = true; | |
989 } | |
990 | |
991 virtual void ResumeAllocationObservers() { | |
992 allocation_observers_paused_ = false; | |
993 } | |
994 | |
995 void AllocationStep(Address soon_object, int size); | |
996 | |
976 // Return the total amount committed memory for this space, i.e., allocatable | 997 // Return the total amount committed memory for this space, i.e., allocatable |
977 // memory and page headers. | 998 // memory and page headers. |
978 virtual intptr_t CommittedMemory() { return committed_; } | 999 virtual intptr_t CommittedMemory() { return committed_; } |
979 | 1000 |
980 virtual intptr_t MaximumCommittedMemory() { return max_committed_; } | 1001 virtual intptr_t MaximumCommittedMemory() { return max_committed_; } |
981 | 1002 |
982 // Returns allocated size. | 1003 // Returns allocated size. |
983 virtual intptr_t Size() = 0; | 1004 virtual intptr_t Size() = 0; |
984 | 1005 |
985 // Returns size of objects. Can differ from the allocated size | 1006 // Returns size of objects. Can differ from the allocated size |
(...skipping 26 matching lines...) Expand all Loading... | |
1012 max_committed_ = committed_; | 1033 max_committed_ = committed_; |
1013 } | 1034 } |
1014 } | 1035 } |
1015 | 1036 |
1016 void AccountUncommitted(intptr_t bytes) { | 1037 void AccountUncommitted(intptr_t bytes) { |
1017 DCHECK_GE(bytes, 0); | 1038 DCHECK_GE(bytes, 0); |
1018 committed_ -= bytes; | 1039 committed_ -= bytes; |
1019 DCHECK_GE(committed_, 0); | 1040 DCHECK_GE(committed_, 0); |
1020 } | 1041 } |
1021 | 1042 |
1043 List<AllocationObserver*>* allocation_observers_ = | |
1044 new List<AllocationObserver*>(); | |
1045 bool allocation_observers_paused_; | |
1046 | |
1022 private: | 1047 private: |
1023 Heap* heap_; | 1048 Heap* heap_; |
1024 AllocationSpace id_; | 1049 AllocationSpace id_; |
1025 Executability executable_; | 1050 Executability executable_; |
1026 | 1051 |
1027 // Keeps track of committed memory in a space. | 1052 // Keeps track of committed memory in a space. |
1028 intptr_t committed_; | 1053 intptr_t committed_; |
1029 intptr_t max_committed_; | 1054 intptr_t max_committed_; |
1030 }; | 1055 }; |
1031 | 1056 |
(...skipping 1535 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2567 // forwards most functions to the appropriate semispace. | 2592 // forwards most functions to the appropriate semispace. |
2568 | 2593 |
2569 class NewSpace : public Space { | 2594 class NewSpace : public Space { |
2570 public: | 2595 public: |
2571 // Constructor. | 2596 // Constructor. |
2572 explicit NewSpace(Heap* heap) | 2597 explicit NewSpace(Heap* heap) |
2573 : Space(heap, NEW_SPACE, NOT_EXECUTABLE), | 2598 : Space(heap, NEW_SPACE, NOT_EXECUTABLE), |
2574 to_space_(heap, kToSpace), | 2599 to_space_(heap, kToSpace), |
2575 from_space_(heap, kFromSpace), | 2600 from_space_(heap, kFromSpace), |
2576 reservation_(), | 2601 reservation_(), |
2577 top_on_previous_step_(0), | 2602 top_on_previous_step_(0) {} |
2578 inline_allocation_observers_paused_(false) {} | |
2579 | 2603 |
2580 // Sets up the new space using the given chunk. | 2604 // Sets up the new space using the given chunk. |
2581 bool SetUp(int reserved_semispace_size_, int max_semi_space_size); | 2605 bool SetUp(int reserved_semispace_size_, int max_semi_space_size); |
2582 | 2606 |
2583 // Tears down the space. Heap memory was not allocated by the space, so it | 2607 // Tears down the space. Heap memory was not allocated by the space, so it |
2584 // is not deallocated here. | 2608 // is not deallocated here. |
2585 void TearDown(); | 2609 void TearDown(); |
2586 | 2610 |
2587 // True if the space has been set up but not torn down. | 2611 // True if the space has been set up but not torn down. |
2588 bool HasBeenSetUp() { | 2612 bool HasBeenSetUp() { |
(...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2745 int size_in_bytes, AllocationAlignment alignment)); | 2769 int size_in_bytes, AllocationAlignment alignment)); |
2746 | 2770 |
2747 MUST_USE_RESULT inline AllocationResult AllocateRawSynchronized( | 2771 MUST_USE_RESULT inline AllocationResult AllocateRawSynchronized( |
2748 int size_in_bytes, AllocationAlignment alignment); | 2772 int size_in_bytes, AllocationAlignment alignment); |
2749 | 2773 |
2750 // Reset the allocation pointer to the beginning of the active semispace. | 2774 // Reset the allocation pointer to the beginning of the active semispace. |
2751 void ResetAllocationInfo(); | 2775 void ResetAllocationInfo(); |
2752 | 2776 |
2753 void UpdateInlineAllocationLimit(int size_in_bytes); | 2777 void UpdateInlineAllocationLimit(int size_in_bytes); |
2754 | 2778 |
2755 // Allows observation of inline allocation. The observer->Step() method gets | |
2756 // called after every step_size bytes have been allocated (approximately). | |
2757 // This works by adjusting the allocation limit to a lower value and adjusting | |
2758 // it after each step. | |
2759 void AddInlineAllocationObserver(InlineAllocationObserver* observer); | |
2760 | |
2761 // Removes a previously installed observer. | |
2762 void RemoveInlineAllocationObserver(InlineAllocationObserver* observer); | |
2763 | |
2764 void DisableInlineAllocationSteps() { | 2779 void DisableInlineAllocationSteps() { |
2765 top_on_previous_step_ = 0; | 2780 top_on_previous_step_ = 0; |
2766 UpdateInlineAllocationLimit(0); | 2781 UpdateInlineAllocationLimit(0); |
2767 } | 2782 } |
2768 | 2783 |
2784 void AddAllocationObserver(AllocationObserver* observer) override; | |
2785 | |
2786 void RemoveAllocationObserver(AllocationObserver* observer) override; | |
2787 | |
2769 // Get the extent of the inactive semispace (for use as a marking stack, | 2788 // Get the extent of the inactive semispace (for use as a marking stack, |
2770 // or to zap it). Notice: space-addresses are not necessarily on the | 2789 // or to zap it). Notice: space-addresses are not necessarily on the |
2771 // same page, so FromSpaceStart() might be above FromSpaceEnd(). | 2790 // same page, so FromSpaceStart() might be above FromSpaceEnd(). |
2772 Address FromSpacePageLow() { return from_space_.page_low(); } | 2791 Address FromSpacePageLow() { return from_space_.page_low(); } |
2773 Address FromSpacePageHigh() { return from_space_.page_high(); } | 2792 Address FromSpacePageHigh() { return from_space_.page_high(); } |
2774 Address FromSpaceStart() { return from_space_.space_start(); } | 2793 Address FromSpaceStart() { return from_space_.space_start(); } |
2775 Address FromSpaceEnd() { return from_space_.space_end(); } | 2794 Address FromSpaceEnd() { return from_space_.space_end(); } |
2776 | 2795 |
2777 // Get the extent of the active semispace's pages' memory. | 2796 // Get the extent of the active semispace's pages' memory. |
2778 Address ToSpaceStart() { return to_space_.space_start(); } | 2797 Address ToSpaceStart() { return to_space_.space_start(); } |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2854 // Start address and bit mask for containment testing. | 2873 // Start address and bit mask for containment testing. |
2855 Address start_; | 2874 Address start_; |
2856 uintptr_t address_mask_; | 2875 uintptr_t address_mask_; |
2857 uintptr_t object_mask_; | 2876 uintptr_t object_mask_; |
2858 uintptr_t object_expected_; | 2877 uintptr_t object_expected_; |
2859 | 2878 |
2860 // Allocation pointer and limit for normal allocation and allocation during | 2879 // Allocation pointer and limit for normal allocation and allocation during |
2861 // mark-compact collection. | 2880 // mark-compact collection. |
2862 AllocationInfo allocation_info_; | 2881 AllocationInfo allocation_info_; |
2863 | 2882 |
2864 // When inline allocation stepping is active, either because of incremental | |
2865 // marking or because of idle scavenge, we 'interrupt' inline allocation every | |
2866 // once in a while. This is done by setting allocation_info_.limit to be lower | |
2867 // than the actual limit and and increasing it in steps to guarantee that the | |
2868 // observers are notified periodically. | |
2869 List<InlineAllocationObserver*> inline_allocation_observers_; | |
2870 Address top_on_previous_step_; | 2883 Address top_on_previous_step_; |
2871 bool inline_allocation_observers_paused_; | |
2872 | 2884 |
2873 HistogramInfo* allocated_histogram_; | 2885 HistogramInfo* allocated_histogram_; |
2874 HistogramInfo* promoted_histogram_; | 2886 HistogramInfo* promoted_histogram_; |
2875 | 2887 |
2876 bool EnsureAllocation(int size_in_bytes, AllocationAlignment alignment); | 2888 bool EnsureAllocation(int size_in_bytes, AllocationAlignment alignment); |
2877 | 2889 |
2878 // If we are doing inline allocation in steps, this method performs the 'step' | 2890 // If we are doing inline allocation in steps, this method performs the 'step' |
2879 // operation. top is the memory address of the bump pointer at the last | 2891 // operation. top is the memory address of the bump pointer at the last |
2880 // inline allocation (i.e. it determines the numbers of bytes actually | 2892 // inline allocation (i.e. it determines the numbers of bytes actually |
2881 // allocated since the last step.) new_top is the address of the bump pointer | 2893 // allocated since the last step.) new_top is the address of the bump pointer |
2882 // where the next byte is going to be allocated from. top and new_top may be | 2894 // where the next byte is going to be allocated from. top and new_top may be |
2883 // different when we cross a page boundary or reset the space. | 2895 // different when we cross a page boundary or reset the space. |
2884 void InlineAllocationStep(Address top, Address new_top, Address soon_object, | 2896 void InlineAllocationStep(Address top, Address new_top, Address soon_object, |
2885 size_t size); | 2897 size_t size); |
2886 intptr_t GetNextInlineAllocationStepSize(); | 2898 intptr_t GetNextInlineAllocationStepSize(); |
2887 void StartNextInlineAllocationStep(); | 2899 void StartNextInlineAllocationStep(); |
2888 void PauseInlineAllocationObservers(); | 2900 void PauseAllocationObservers() override; |
2889 void ResumeInlineAllocationObservers(); | 2901 void ResumeAllocationObservers() override; |
2890 | 2902 |
2891 friend class PauseInlineAllocationObserversScope; | 2903 friend class PauseInlineAllocationObserversScope; |
2892 friend class SemiSpaceIterator; | 2904 friend class SemiSpaceIterator; |
2893 }; | 2905 }; |
2894 | 2906 |
2895 class PauseInlineAllocationObserversScope { | 2907 class PauseAllocationObserversScope { |
2896 public: | 2908 public: |
2897 explicit PauseInlineAllocationObserversScope(NewSpace* new_space) | 2909 explicit PauseAllocationObserversScope(Space* space) : space_(space) { |
2898 : new_space_(new_space) { | 2910 space_->PauseAllocationObservers(); |
2899 new_space_->PauseInlineAllocationObservers(); | |
2900 } | 2911 } |
2901 ~PauseInlineAllocationObserversScope() { | 2912 ~PauseAllocationObserversScope() { space_->ResumeAllocationObservers(); } |
2902 new_space_->ResumeInlineAllocationObservers(); | |
2903 } | |
2904 | 2913 |
2905 private: | 2914 private: |
2906 NewSpace* new_space_; | 2915 Space* space_; |
2907 DISALLOW_COPY_AND_ASSIGN(PauseInlineAllocationObserversScope); | 2916 DISALLOW_COPY_AND_ASSIGN(PauseAllocationObserversScope); |
2908 }; | 2917 }; |
2909 | 2918 |
2910 // ----------------------------------------------------------------------------- | 2919 // ----------------------------------------------------------------------------- |
2911 // Compaction space that is used temporarily during compaction. | 2920 // Compaction space that is used temporarily during compaction. |
2912 | 2921 |
2913 class CompactionSpace : public PagedSpace { | 2922 class CompactionSpace : public PagedSpace { |
2914 public: | 2923 public: |
2915 CompactionSpace(Heap* heap, AllocationSpace id, Executability executable) | 2924 CompactionSpace(Heap* heap, AllocationSpace id, Executability executable) |
2916 : PagedSpace(heap, id, executable) {} | 2925 : PagedSpace(heap, id, executable) {} |
2917 | 2926 |
(...skipping 246 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3164 count = 0; | 3173 count = 0; |
3165 } | 3174 } |
3166 // Must be small, since an iteration is used for lookup. | 3175 // Must be small, since an iteration is used for lookup. |
3167 static const int kMaxComments = 64; | 3176 static const int kMaxComments = 64; |
3168 }; | 3177 }; |
3169 #endif | 3178 #endif |
3170 } // namespace internal | 3179 } // namespace internal |
3171 } // namespace v8 | 3180 } // namespace v8 |
3172 | 3181 |
3173 #endif // V8_HEAP_SPACES_H_ | 3182 #endif // V8_HEAP_SPACES_H_ |
OLD | NEW |