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

Side by Side Diff: src/store-buffer.h

Issue 6745033: On store buffer overflow we mark individidual pages for... (Closed) Base URL: http://v8.googlecode.com/svn/branches/experimental/gc/
Patch Set: '' Created 9 years, 9 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 | Annotate | Revision Log
OLDNEW
1 // Copyright 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
11 // with the distribution. 11 // with the distribution.
12 // * Neither the name of Google Inc. nor the names of its 12 // * Neither the name of Google Inc. nor the names of its
13 // contributors may be used to endorse or promote products derived 13 // contributors may be used to endorse or promote products derived
14 // from this software without specific prior written permission. 14 // from this software without specific prior written permission.
15 // 15 //
16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 27
28 #ifndef V8_WRITE_BARRIER_H_ 28 #ifndef V8_STORE_BUFFER_H_
29 #define V8_WRITE_BARRIER_H_ 29 #define V8_STORE_BUFFER_H_
30 30
31 #include "allocation.h" 31 #include "allocation.h"
32 #include "checks.h" 32 #include "checks.h"
33 #include "globals.h" 33 #include "globals.h"
34 #include "platform.h" 34 #include "platform.h"
35 #include "v8globals.h"
35 36
36 namespace v8 { 37 namespace v8 {
37 namespace internal { 38 namespace internal {
38 39
40
39 typedef void (*ObjectSlotCallback)(HeapObject** from, HeapObject* to); 41 typedef void (*ObjectSlotCallback)(HeapObject** from, HeapObject* to);
40 42
43
41 // Used to implement the write barrier by collecting addresses of pointers 44 // Used to implement the write barrier by collecting addresses of pointers
42 // between spaces. 45 // between spaces.
43 class StoreBuffer : public AllStatic { 46 class StoreBuffer : public AllStatic {
44 public: 47 public:
45 static inline Address TopAddress(); 48 static inline Address TopAddress();
46 49
47 static void Setup(); 50 static void Setup();
48 static void TearDown(); 51 static void TearDown();
49 52
50 // This is used by the mutator to enter addresses into the store buffer. 53 // This is used by the mutator to enter addresses into the store buffer.
51 static inline void Mark(Address addr); 54 static inline void Mark(Address addr);
52 55
53 // This is used by the heap traversal to enter the addresses into the store 56 // This is used by the heap traversal to enter the addresses into the store
54 // buffer that should still be in the store buffer after GC. It enters 57 // buffer that should still be in the store buffer after GC. It enters
55 // addresses directly into the old buffer because the GC starts by wiping the 58 // addresses directly into the old buffer because the GC starts by wiping the
56 // old buffer and thereafter only visits each cell once so there is no need 59 // old buffer and thereafter only visits each cell once so there is no need
57 // to attempt to remove any dupes. During the first part of a scavenge we 60 // to attempt to remove any dupes. During the first part of a GC we
58 // are using the store buffer to access the old spaces and at the same time 61 // are using the store buffer to access the old spaces and at the same time
59 // we are rebuilding the store buffer using this function. There is, however 62 // we are rebuilding the store buffer using this function. There is, however
60 // no issue of overwriting the buffer we are iterating over, because this 63 // no issue of overwriting the buffer we are iterating over, because this
61 // stage of the scavenge can only reduce the number of addresses in the store 64 // stage of the scavenge can only reduce the number of addresses in the store
62 // buffer (some objects are promoted so pointers to them do not need to be in 65 // buffer (some objects are promoted so pointers to them do not need to be in
63 // the store buffer). The later parts of the scavenge process the promotion 66 // the store buffer). The later parts of the GC scan the pages that are
64 // queue and they can overflow this buffer, which we must check for. 67 // exempt from the store buffer and process the promotion queue. These steps
68 // can overflow this buffer. We check for this and on overflow we call the
69 // callback set up with the StoreBufferRebuildScope object.
65 static inline void EnterDirectlyIntoStoreBuffer(Address addr); 70 static inline void EnterDirectlyIntoStoreBuffer(Address addr);
66 71
67 // Iterates over all pointers that go from old space to new space. It will 72 // Iterates over all pointers that go from old space to new space. It will
68 // delete the store buffer as it starts so the callback should reenter 73 // delete the store buffer as it starts so the callback should reenter
69 // surviving old-to-new pointers into the store buffer to rebuild it. 74 // surviving old-to-new pointers into the store buffer to rebuild it.
70 static void IteratePointersToNewSpace(ObjectSlotCallback callback); 75 static void IteratePointersToNewSpace(ObjectSlotCallback callback);
71 76
72 static const int kStoreBufferOverflowBit = 1 << 16; 77 static const int kStoreBufferOverflowBit = 1 << 16;
73 static const int kStoreBufferSize = kStoreBufferOverflowBit; 78 static const int kStoreBufferSize = kStoreBufferOverflowBit;
74 static const int kStoreBufferLength = kStoreBufferSize / sizeof(Address); 79 static const int kStoreBufferLength = kStoreBufferSize / sizeof(Address);
75 static const int kOldStoreBufferLength = kStoreBufferLength * 64; 80 static const int kOldStoreBufferLength = kStoreBufferLength * 64;
76 static const int kHashMapLengthLog2 = 12; 81 static const int kHashMapLengthLog2 = 12;
77 static const int kHashMapLength = 1 << kHashMapLengthLog2; 82 static const int kHashMapLength = 1 << kHashMapLengthLog2;
78 83
79 static void Compact(); 84 static void Compact();
80 static void GCPrologue(GCType type, GCCallbackFlags flags); 85 static void GCPrologue(GCType type, GCCallbackFlags flags);
81 static void GCEpilogue(GCType type, GCCallbackFlags flags); 86 static void GCEpilogue(GCType type, GCCallbackFlags flags);
82 87
88 static Object*** Limit() { return reinterpret_cast<Object***>(old_limit_); }
83 static Object*** Start() { return reinterpret_cast<Object***>(old_start_); } 89 static Object*** Start() { return reinterpret_cast<Object***>(old_start_); }
84 static Object*** Top() { return reinterpret_cast<Object***>(old_top_); } 90 static Object*** Top() { return reinterpret_cast<Object***>(old_top_); }
91 static void SetTop(Object*** top) {
92 ASSERT(top >= Start());
93 ASSERT(top <= Limit());
94 old_top_ = reinterpret_cast<Address*>(top);
95 }
85 96
86 enum StoreBufferMode {
87 kStoreBufferFunctional,
88 kStoreBufferDisabled,
89 kStoreBufferBeingRebuilt
90 };
91
92 static StoreBufferMode store_buffer_mode() { return store_buffer_mode_; }
93 static inline void set_store_buffer_mode(StoreBufferMode mode);
94 static bool old_buffer_is_sorted() { return old_buffer_is_sorted_; } 97 static bool old_buffer_is_sorted() { return old_buffer_is_sorted_; }
98 static bool old_buffer_is_filtered() { return old_buffer_is_filtered_; }
95 99
96 // Goes through the store buffer removing pointers to things that have 100 // Goes through the store buffer removing pointers to things that have
97 // been promoted. Rebuilds the store buffer completely if it overflowed. 101 // been promoted. Rebuilds the store buffer completely if it overflowed.
98 static void SortUniq(); 102 static void SortUniq();
103
104 static void HandleFullness();
99 static void Verify(); 105 static void Verify();
100 106
101 static void PrepareForIteration(); 107 static bool PrepareForIteration();
102 108
103 #ifdef DEBUG 109 #ifdef DEBUG
104 static void Clean(); 110 static void Clean();
105 // Slow, for asserts only. 111 // Slow, for asserts only.
106 static bool CellIsInStoreBuffer(Address cell); 112 static bool CellIsInStoreBuffer(Address cell);
107 #endif 113 #endif
108 114
109 private: 115 private:
110 // The store buffer is divided up into a new buffer that is constantly being 116 // The store buffer is divided up into a new buffer that is constantly being
111 // filled by mutator activity and an old buffer that is filled with the data 117 // filled by mutator activity and an old buffer that is filled with the data
112 // from the new buffer after compression. 118 // from the new buffer after compression.
113 static Address* start_; 119 static Address* start_;
114 static Address* limit_; 120 static Address* limit_;
115 121
116 static Address* old_start_; 122 static Address* old_start_;
117 static Address* old_limit_; 123 static Address* old_limit_;
118 static Address* old_top_; 124 static Address* old_top_;
119 125
120 static bool old_buffer_is_sorted_; 126 static bool old_buffer_is_sorted_;
121 static StoreBufferMode store_buffer_mode_; 127 static bool old_buffer_is_filtered_;
122 static bool during_gc_; 128 static bool during_gc_;
129 // The garbage collector iterates over many pointers to new space that are not
130 // handled by the store buffer. This flag indicates whether the pointers
131 // found by the callbacks should be added to the store buffer or not.
123 static bool store_buffer_rebuilding_enabled_; 132 static bool store_buffer_rebuilding_enabled_;
133 static StoreBufferCallback callback_;
124 static bool may_move_store_buffer_entries_; 134 static bool may_move_store_buffer_entries_;
125 135
126 static VirtualMemory* virtual_memory_; 136 static VirtualMemory* virtual_memory_;
127 static uintptr_t* hash_map_1_; 137 static uintptr_t* hash_map_1_;
128 static uintptr_t* hash_map_2_; 138 static uintptr_t* hash_map_2_;
129 139
130 static void CheckForFullBuffer(); 140 static void CheckForFullBuffer();
131 static void Uniq(); 141 static void Uniq();
132 static void ZapHashTables(); 142 static void ZapHashTables();
133 static bool HashTablesAreZapped(); 143 static bool HashTablesAreZapped();
144 static void FilterScanOnScavengeEntries();
145 static void ExemptPopularPages(int prime_sample_step, int threshold);
134 146
135 friend class StoreBufferRebuildScope; 147 friend class StoreBufferRebuildScope;
136 friend class DontMoveStoreBufferEntriesScope; 148 friend class DontMoveStoreBufferEntriesScope;
137 }; 149 };
138 150
139 151
140 class StoreBufferRebuildScope { 152 class StoreBufferRebuildScope {
141 public: 153 public:
142 StoreBufferRebuildScope() : 154 explicit StoreBufferRebuildScope(StoreBufferCallback callback)
143 stored_state_(StoreBuffer::store_buffer_rebuilding_enabled_) { 155 : stored_state_(StoreBuffer::store_buffer_rebuilding_enabled_),
156 stored_callback_(StoreBuffer::callback_) {
144 StoreBuffer::store_buffer_rebuilding_enabled_ = true; 157 StoreBuffer::store_buffer_rebuilding_enabled_ = true;
158 StoreBuffer::callback_ = callback;
159 (*callback)(NULL, kStoreBufferScanningPageEvent);
145 } 160 }
146 161
147 ~StoreBufferRebuildScope() { 162 ~StoreBufferRebuildScope() {
163 StoreBuffer::callback_ = stored_callback_;
148 StoreBuffer::store_buffer_rebuilding_enabled_ = stored_state_; 164 StoreBuffer::store_buffer_rebuilding_enabled_ = stored_state_;
149 StoreBuffer::CheckForFullBuffer(); 165 StoreBuffer::CheckForFullBuffer();
150 } 166 }
151 167
152 private: 168 private:
153 bool stored_state_; 169 bool stored_state_;
170 StoreBufferCallback stored_callback_;
154 }; 171 };
155 172
156 173
157 class DontMoveStoreBufferEntriesScope { 174 class DontMoveStoreBufferEntriesScope {
158 public: 175 public:
159 DontMoveStoreBufferEntriesScope() : 176 DontMoveStoreBufferEntriesScope() :
160 stored_state_(StoreBuffer::may_move_store_buffer_entries_) { 177 stored_state_(StoreBuffer::may_move_store_buffer_entries_) {
161 StoreBuffer::may_move_store_buffer_entries_ = false; 178 StoreBuffer::may_move_store_buffer_entries_ = false;
162 } 179 }
163 180
164 ~DontMoveStoreBufferEntriesScope() { 181 ~DontMoveStoreBufferEntriesScope() {
165 StoreBuffer::may_move_store_buffer_entries_ = stored_state_; 182 StoreBuffer::may_move_store_buffer_entries_ = stored_state_;
166 } 183 }
167 184
168 private: 185 private:
169 bool stored_state_; 186 bool stored_state_;
170 }; 187 };
171 188
172 } } // namespace v8::internal 189 } } // namespace v8::internal
173 190
174 #endif // V8_WRITE_BARRIER_H_ 191 #endif // V8_STORE_BUFFER_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698