Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(3)

Side by Side Diff: src/heap/spaces.h

Issue 1625753002: Allocation sampling for paged/lo spaces (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: "Rebase" Created 4 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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) {}
955 956
956 virtual ~Space() {} 957 virtual ~Space() {}
957 958
958 Heap* heap() const { return heap_; } 959 Heap* heap() const { return heap_; }
959 960
960 // Does the space need executable memory? 961 // Does the space need executable memory?
961 Executability executable() { return executable_; } 962 Executability executable() { return executable_; }
962 963
963 // Identity used in error reporting. 964 // Identity used in error reporting.
964 AllocationSpace identity() { return id_; } 965 AllocationSpace identity() { return id_; }
965 966
967 virtual void AddAllocationObserver(AllocationObserver* observer) {
968 allocation_observers_->Add(observer);
969 }
970
971 virtual void RemoveAllocationObserver(AllocationObserver* observer) {
972 bool removed = allocation_observers_->RemoveElement(observer);
973 static_cast<void>(removed);
Hannes Payer (out of office) 2016/02/08 10:13:48 USE(removed);
mattloring 2016/02/09 20:20:05 Done.
974 DCHECK(removed);
975 }
976
977 virtual void PauseAllocationObservers() {
978 allocation_observers_paused_ = true;
979 }
980
981 virtual void ResumeAllocationObservers() {
982 allocation_observers_paused_ = false;
983 }
984
985 void AllocationStep(Address soon_object, int size);
986
966 // Return the total amount committed memory for this space, i.e., allocatable 987 // Return the total amount committed memory for this space, i.e., allocatable
967 // memory and page headers. 988 // memory and page headers.
968 virtual intptr_t CommittedMemory() { return committed_; } 989 virtual intptr_t CommittedMemory() { return committed_; }
969 990
970 virtual intptr_t MaximumCommittedMemory() { return max_committed_; } 991 virtual intptr_t MaximumCommittedMemory() { return max_committed_; }
971 992
972 // Returns allocated size. 993 // Returns allocated size.
973 virtual intptr_t Size() = 0; 994 virtual intptr_t Size() = 0;
974 995
975 // Returns size of objects. Can differ from the allocated size 996 // Returns size of objects. Can differ from the allocated size
(...skipping 26 matching lines...) Expand all
1002 max_committed_ = committed_; 1023 max_committed_ = committed_;
1003 } 1024 }
1004 } 1025 }
1005 1026
1006 void AccountUncommitted(intptr_t bytes) { 1027 void AccountUncommitted(intptr_t bytes) {
1007 DCHECK_GE(bytes, 0); 1028 DCHECK_GE(bytes, 0);
1008 committed_ -= bytes; 1029 committed_ -= bytes;
1009 DCHECK_GE(committed_, 0); 1030 DCHECK_GE(committed_, 0);
1010 } 1031 }
1011 1032
1033 // When inline allocation stepping is active, either because of incremental
1034 // marking or because of idle scavenge, we 'interrupt' inline allocation every
Hannes Payer (out of office) 2016/02/08 10:13:48 This list is not complete: allocation statistics g
mattloring 2016/02/09 20:20:05 Done.
1035 // once in a while. This is done by setting allocation_info_.limit to be lower
1036 // than the actual limit and and increasing it in steps to guarantee that the
1037 // observers are notified periodically.
1038 List<AllocationObserver*>* allocation_observers_ =
Hannes Payer (out of office) 2016/02/08 10:13:48 allocate the allocation_observers in the construct
mattloring 2016/02/09 20:20:05 What is the best strategy for deallocating a list
ofrobots 2016/02/10 08:15:38 Does allocation_observers_ need to be dynamically
mattloring 2016/02/10 13:19:23 If I do not dynamically allocate it, it causes the
Hannes Payer (out of office) 2016/02/11 11:50:08 I am not sure if I understand your question. When
mattloring 2016/02/11 14:54:14 Sorry for the confusion. This should be handled no
1039 new List<AllocationObserver*>();
1040 bool allocation_observers_paused_;
1041
1012 private: 1042 private:
1013 Heap* heap_; 1043 Heap* heap_;
1014 AllocationSpace id_; 1044 AllocationSpace id_;
1015 Executability executable_; 1045 Executability executable_;
1016 1046
1017 // Keeps track of committed memory in a space. 1047 // Keeps track of committed memory in a space.
1018 intptr_t committed_; 1048 intptr_t committed_;
1019 intptr_t max_committed_; 1049 intptr_t max_committed_;
1020 }; 1050 };
1021 1051
(...skipping 1528 matching lines...) Expand 10 before | Expand all | Expand 10 after
2550 // forwards most functions to the appropriate semispace. 2580 // forwards most functions to the appropriate semispace.
2551 2581
2552 class NewSpace : public Space { 2582 class NewSpace : public Space {
2553 public: 2583 public:
2554 // Constructor. 2584 // Constructor.
2555 explicit NewSpace(Heap* heap) 2585 explicit NewSpace(Heap* heap)
2556 : Space(heap, NEW_SPACE, NOT_EXECUTABLE), 2586 : Space(heap, NEW_SPACE, NOT_EXECUTABLE),
2557 to_space_(heap, kToSpace), 2587 to_space_(heap, kToSpace),
2558 from_space_(heap, kFromSpace), 2588 from_space_(heap, kFromSpace),
2559 reservation_(), 2589 reservation_(),
2560 top_on_previous_step_(0), 2590 top_on_previous_step_(0) {}
2561 inline_allocation_observers_paused_(false) {}
2562 2591
2563 // Sets up the new space using the given chunk. 2592 // Sets up the new space using the given chunk.
2564 bool SetUp(int reserved_semispace_size_, int max_semi_space_size); 2593 bool SetUp(int reserved_semispace_size_, int max_semi_space_size);
2565 2594
2566 // Tears down the space. Heap memory was not allocated by the space, so it 2595 // Tears down the space. Heap memory was not allocated by the space, so it
2567 // is not deallocated here. 2596 // is not deallocated here.
2568 void TearDown(); 2597 void TearDown();
2569 2598
2570 // True if the space has been set up but not torn down. 2599 // True if the space has been set up but not torn down.
2571 bool HasBeenSetUp() { 2600 bool HasBeenSetUp() {
(...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after
2723 int size_in_bytes, AllocationAlignment alignment)); 2752 int size_in_bytes, AllocationAlignment alignment));
2724 2753
2725 MUST_USE_RESULT inline AllocationResult AllocateRawSynchronized( 2754 MUST_USE_RESULT inline AllocationResult AllocateRawSynchronized(
2726 int size_in_bytes, AllocationAlignment alignment); 2755 int size_in_bytes, AllocationAlignment alignment);
2727 2756
2728 // Reset the allocation pointer to the beginning of the active semispace. 2757 // Reset the allocation pointer to the beginning of the active semispace.
2729 void ResetAllocationInfo(); 2758 void ResetAllocationInfo();
2730 2759
2731 void UpdateInlineAllocationLimit(int size_in_bytes); 2760 void UpdateInlineAllocationLimit(int size_in_bytes);
2732 2761
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() { 2762 void DisableInlineAllocationSteps() {
2743 top_on_previous_step_ = 0; 2763 top_on_previous_step_ = 0;
2744 UpdateInlineAllocationLimit(0); 2764 UpdateInlineAllocationLimit(0);
2745 } 2765 }
2746 2766
2767 // Allows observation of inline allocation. The observer->Step() method gets
2768 // called after every step_size bytes have been allocated (approximately).
2769 // This works by adjusting the allocation limit to a lower value and adjusting
2770 // it after each step.
2771 void AddAllocationObserver(AllocationObserver* observer) override;
2772
2773 void RemoveAllocationObserver(AllocationObserver* observer) override;
2774
2747 // Get the extent of the inactive semispace (for use as a marking stack, 2775 // 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 2776 // or to zap it). Notice: space-addresses are not necessarily on the
2749 // same page, so FromSpaceStart() might be above FromSpaceEnd(). 2777 // same page, so FromSpaceStart() might be above FromSpaceEnd().
2750 Address FromSpacePageLow() { return from_space_.page_low(); } 2778 Address FromSpacePageLow() { return from_space_.page_low(); }
2751 Address FromSpacePageHigh() { return from_space_.page_high(); } 2779 Address FromSpacePageHigh() { return from_space_.page_high(); }
2752 Address FromSpaceStart() { return from_space_.space_start(); } 2780 Address FromSpaceStart() { return from_space_.space_start(); }
2753 Address FromSpaceEnd() { return from_space_.space_end(); } 2781 Address FromSpaceEnd() { return from_space_.space_end(); }
2754 2782
2755 // Get the extent of the active semispace's pages' memory. 2783 // Get the extent of the active semispace's pages' memory.
2756 Address ToSpaceStart() { return to_space_.space_start(); } 2784 Address ToSpaceStart() { return to_space_.space_start(); }
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
2807 2835
2808 bool UncommitFromSpace() { 2836 bool UncommitFromSpace() {
2809 if (!from_space_.is_committed()) return true; 2837 if (!from_space_.is_committed()) return true;
2810 return from_space_.Uncommit(); 2838 return from_space_.Uncommit();
2811 } 2839 }
2812 2840
2813 bool IsFromSpaceCommitted() { return from_space_.is_committed(); } 2841 bool IsFromSpaceCommitted() { return from_space_.is_committed(); }
2814 2842
2815 SemiSpace* active_space() { return &to_space_; } 2843 SemiSpace* active_space() { return &to_space_; }
2816 2844
2845 void PauseAllocationObservers() override;
2846 void ResumeAllocationObservers() override;
2847
2817 private: 2848 private:
2818 // Update allocation info to match the current to-space page. 2849 // Update allocation info to match the current to-space page.
2819 void UpdateAllocationInfo(); 2850 void UpdateAllocationInfo();
2820 2851
2821 base::Mutex mutex_; 2852 base::Mutex mutex_;
2822 2853
2823 Address chunk_base_; 2854 Address chunk_base_;
2824 uintptr_t chunk_size_; 2855 uintptr_t chunk_size_;
2825 2856
2826 // The semispaces. 2857 // The semispaces.
2827 SemiSpace to_space_; 2858 SemiSpace to_space_;
2828 SemiSpace from_space_; 2859 SemiSpace from_space_;
2829 base::VirtualMemory reservation_; 2860 base::VirtualMemory reservation_;
2830 int pages_used_; 2861 int pages_used_;
2831 2862
2832 // Start address and bit mask for containment testing. 2863 // Start address and bit mask for containment testing.
2833 Address start_; 2864 Address start_;
2834 uintptr_t address_mask_; 2865 uintptr_t address_mask_;
2835 uintptr_t object_mask_; 2866 uintptr_t object_mask_;
2836 uintptr_t object_expected_; 2867 uintptr_t object_expected_;
2837 2868
2838 // Allocation pointer and limit for normal allocation and allocation during 2869 // Allocation pointer and limit for normal allocation and allocation during
2839 // mark-compact collection. 2870 // mark-compact collection.
2840 AllocationInfo allocation_info_; 2871 AllocationInfo allocation_info_;
2841 2872
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_; 2873 Address top_on_previous_step_;
2849 bool inline_allocation_observers_paused_;
2850 2874
2851 HistogramInfo* allocated_histogram_; 2875 HistogramInfo* allocated_histogram_;
2852 HistogramInfo* promoted_histogram_; 2876 HistogramInfo* promoted_histogram_;
2853 2877
2854 bool EnsureAllocation(int size_in_bytes, AllocationAlignment alignment); 2878 bool EnsureAllocation(int size_in_bytes, AllocationAlignment alignment);
2855 2879
2856 // If we are doing inline allocation in steps, this method performs the 'step' 2880 // 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 2881 // 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 2882 // 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 2883 // 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 2884 // 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. 2885 // different when we cross a page boundary or reset the space.
2862 void InlineAllocationStep(Address top, Address new_top, Address soon_object, 2886 void InlineAllocationStep(Address top, Address new_top, Address soon_object,
2863 size_t size); 2887 size_t size);
2864 intptr_t GetNextInlineAllocationStepSize(); 2888 intptr_t GetNextInlineAllocationStepSize();
2865 void StartNextInlineAllocationStep(); 2889 void StartNextInlineAllocationStep();
2866 void PauseInlineAllocationObservers();
2867 void ResumeInlineAllocationObservers();
2868 2890
2869 friend class PauseInlineAllocationObserversScope;
2870 friend class SemiSpaceIterator; 2891 friend class SemiSpaceIterator;
2871 }; 2892 };
2872 2893
2873 class PauseInlineAllocationObserversScope { 2894 class PauseAllocationObserversScope {
2874 public: 2895 public:
2875 explicit PauseInlineAllocationObserversScope(NewSpace* new_space) 2896 explicit PauseAllocationObserversScope(Heap* heap);
2876 : new_space_(new_space) { 2897 ~PauseAllocationObserversScope();
2877 new_space_->PauseInlineAllocationObservers();
2878 }
2879 ~PauseInlineAllocationObserversScope() {
2880 new_space_->ResumeInlineAllocationObservers();
2881 }
2882 2898
2883 private: 2899 private:
2884 NewSpace* new_space_; 2900 Heap* heap_;
2885 DISALLOW_COPY_AND_ASSIGN(PauseInlineAllocationObserversScope); 2901 DISALLOW_COPY_AND_ASSIGN(PauseAllocationObserversScope);
2886 }; 2902 };
2887 2903
2888 // ----------------------------------------------------------------------------- 2904 // -----------------------------------------------------------------------------
2889 // Compaction space that is used temporarily during compaction. 2905 // Compaction space that is used temporarily during compaction.
2890 2906
2891 class CompactionSpace : public PagedSpace { 2907 class CompactionSpace : public PagedSpace {
2892 public: 2908 public:
2893 CompactionSpace(Heap* heap, AllocationSpace id, Executability executable) 2909 CompactionSpace(Heap* heap, AllocationSpace id, Executability executable)
2894 : PagedSpace(heap, id, executable) {} 2910 : PagedSpace(heap, id, executable) {}
2895 2911
(...skipping 232 matching lines...) Expand 10 before | Expand all | Expand 10 after
3128 count = 0; 3144 count = 0;
3129 } 3145 }
3130 // Must be small, since an iteration is used for lookup. 3146 // Must be small, since an iteration is used for lookup.
3131 static const int kMaxComments = 64; 3147 static const int kMaxComments = 64;
3132 }; 3148 };
3133 #endif 3149 #endif
3134 } // namespace internal 3150 } // namespace internal
3135 } // namespace v8 3151 } // namespace v8
3136 3152
3137 #endif // V8_HEAP_SPACES_H_ 3153 #endif // V8_HEAP_SPACES_H_
OLDNEW
« no previous file with comments | « src/heap/incremental-marking.cc ('k') | src/heap/spaces.cc » ('j') | src/heap/spaces.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698