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

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

Issue 2696563003: [heap] Ensure consistency between store buffer mode and moving all entries to remembered set. (Closed)
Patch Set: rename Created 3 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
« no previous file with comments | « src/heap/heap.cc ('k') | src/heap/store-buffer.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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_STORE_BUFFER_H_ 5 #ifndef V8_STORE_BUFFER_H_
6 #define V8_STORE_BUFFER_H_ 6 #define V8_STORE_BUFFER_H_
7 7
8 #include "src/allocation.h" 8 #include "src/allocation.h"
9 #include "src/base/logging.h" 9 #include "src/base/logging.h"
10 #include "src/base/platform/platform.h" 10 #include "src/base/platform/platform.h"
11 #include "src/cancelable-task.h" 11 #include "src/cancelable-task.h"
12 #include "src/globals.h" 12 #include "src/globals.h"
13 #include "src/heap/remembered-set.h" 13 #include "src/heap/remembered-set.h"
14 #include "src/heap/slot-set.h" 14 #include "src/heap/slot-set.h"
15 15
16 namespace v8 { 16 namespace v8 {
17 namespace internal { 17 namespace internal {
18 18
19 // Intermediate buffer that accumulates old-to-new stores from the generated 19 // Intermediate buffer that accumulates old-to-new stores from the generated
20 // code. Moreover, it stores invalid old-to-new slots with two entries. 20 // code. Moreover, it stores invalid old-to-new slots with two entries.
21 // The first is a tagged address of the start of the invalid range, the second 21 // The first is a tagged address of the start of the invalid range, the second
22 // one is the end address of the invalid range or null if there is just one slot 22 // one is the end address of the invalid range or null if there is just one slot
23 // that needs to be removed from the remembered set. On buffer overflow the 23 // that needs to be removed from the remembered set. On buffer overflow the
24 // slots are moved to the remembered set. 24 // slots are moved to the remembered set.
25 class StoreBuffer { 25 class StoreBuffer {
26 public: 26 public:
27 enum StoreBufferMode { IN_GC, NOT_IN_GC };
28
27 static const int kStoreBufferSize = 1 << (11 + kPointerSizeLog2); 29 static const int kStoreBufferSize = 1 << (11 + kPointerSizeLog2);
28 static const int kStoreBufferMask = kStoreBufferSize - 1; 30 static const int kStoreBufferMask = kStoreBufferSize - 1;
29 static const int kStoreBuffers = 2; 31 static const int kStoreBuffers = 2;
30 static const intptr_t kDeletionTag = 1; 32 static const intptr_t kDeletionTag = 1;
31 33
32 V8_EXPORT_PRIVATE static void StoreBufferOverflow(Isolate* isolate); 34 V8_EXPORT_PRIVATE static void StoreBufferOverflow(Isolate* isolate);
33 35
34 explicit StoreBuffer(Heap* heap); 36 explicit StoreBuffer(Heap* heap);
35 void SetUp(); 37 void SetUp();
36 void TearDown(); 38 void TearDown();
(...skipping 30 matching lines...) Expand all
67 // Deletions coming from the GC are directly deleted from the remembered 69 // Deletions coming from the GC are directly deleted from the remembered
68 // set. Deletions coming from the runtime are added to the store buffer 70 // set. Deletions coming from the runtime are added to the store buffer
69 // to allow concurrent processing. 71 // to allow concurrent processing.
70 deletion_callback(this, start, end); 72 deletion_callback(this, start, end);
71 } 73 }
72 74
73 static void DeleteDuringGarbageCollection(StoreBuffer* store_buffer, 75 static void DeleteDuringGarbageCollection(StoreBuffer* store_buffer,
74 Address start, Address end) { 76 Address start, Address end) {
75 // In GC the store buffer has to be empty at any time. 77 // In GC the store buffer has to be empty at any time.
76 DCHECK(store_buffer->Empty()); 78 DCHECK(store_buffer->Empty());
77 DCHECK(store_buffer->heap()->gc_state() != Heap::NOT_IN_GC); 79 DCHECK(store_buffer->mode() != StoreBuffer::NOT_IN_GC);
78 Page* page = Page::FromAddress(start); 80 Page* page = Page::FromAddress(start);
79 if (end) { 81 if (end) {
80 RememberedSet<OLD_TO_NEW>::RemoveRange(page, start, end, 82 RememberedSet<OLD_TO_NEW>::RemoveRange(page, start, end,
81 SlotSet::PREFREE_EMPTY_BUCKETS); 83 SlotSet::PREFREE_EMPTY_BUCKETS);
82 } else { 84 } else {
83 RememberedSet<OLD_TO_NEW>::Remove(page, start); 85 RememberedSet<OLD_TO_NEW>::Remove(page, start);
84 } 86 }
85 } 87 }
86 88
87 static void DeleteDuringRuntime(StoreBuffer* store_buffer, Address start, 89 static void DeleteDuringRuntime(StoreBuffer* store_buffer, Address start,
88 Address end) { 90 Address end) {
89 DCHECK(store_buffer->heap()->gc_state() == Heap::NOT_IN_GC); 91 DCHECK(store_buffer->mode() == StoreBuffer::NOT_IN_GC);
90 store_buffer->InsertDeletionIntoStoreBuffer(start, end); 92 store_buffer->InsertDeletionIntoStoreBuffer(start, end);
91 } 93 }
92 94
93 void InsertDeletionIntoStoreBuffer(Address start, Address end) { 95 void InsertDeletionIntoStoreBuffer(Address start, Address end) {
94 if (top_ + sizeof(Address) * 2 > limit_[current_]) { 96 if (top_ + sizeof(Address) * 2 > limit_[current_]) {
95 StoreBufferOverflow(heap_->isolate()); 97 StoreBufferOverflow(heap_->isolate());
96 } 98 }
97 *top_ = MarkDeletionAddress(start); 99 *top_ = MarkDeletionAddress(start);
98 top_++; 100 top_++;
99 *top_ = end; 101 *top_ = end;
100 top_++; 102 top_++;
101 } 103 }
102 104
103 static void InsertDuringGarbageCollection(StoreBuffer* store_buffer, 105 static void InsertDuringGarbageCollection(StoreBuffer* store_buffer,
104 Address slot) { 106 Address slot) {
105 DCHECK(store_buffer->heap()->gc_state() != Heap::NOT_IN_GC); 107 DCHECK(store_buffer->mode() != StoreBuffer::NOT_IN_GC);
106 RememberedSet<OLD_TO_NEW>::Insert(Page::FromAddress(slot), slot); 108 RememberedSet<OLD_TO_NEW>::Insert(Page::FromAddress(slot), slot);
107 } 109 }
108 110
109 static void InsertDuringRuntime(StoreBuffer* store_buffer, Address slot) { 111 static void InsertDuringRuntime(StoreBuffer* store_buffer, Address slot) {
110 DCHECK(store_buffer->heap()->gc_state() == Heap::NOT_IN_GC); 112 DCHECK(store_buffer->mode() == StoreBuffer::NOT_IN_GC);
111 store_buffer->InsertIntoStoreBuffer(slot); 113 store_buffer->InsertIntoStoreBuffer(slot);
112 } 114 }
113 115
114 void InsertIntoStoreBuffer(Address slot) { 116 void InsertIntoStoreBuffer(Address slot) {
115 if (top_ + sizeof(Address) > limit_[current_]) { 117 if (top_ + sizeof(Address) > limit_[current_]) {
116 StoreBufferOverflow(heap_->isolate()); 118 StoreBufferOverflow(heap_->isolate());
117 } 119 }
118 *top_ = slot; 120 *top_ = slot;
119 top_++; 121 top_++;
120 } 122 }
121 123
122 void InsertEntry(Address slot) { 124 void InsertEntry(Address slot) {
123 // Insertions coming from the GC are directly inserted into the remembered 125 // Insertions coming from the GC are directly inserted into the remembered
124 // set. Insertions coming from the runtime are added to the store buffer to 126 // set. Insertions coming from the runtime are added to the store buffer to
125 // allow concurrent processing. 127 // allow concurrent processing.
126 insertion_callback(this, slot); 128 insertion_callback(this, slot);
127 } 129 }
128 130
129 void SetMode(Heap::HeapState state) { 131 void SetMode(StoreBufferMode mode) {
130 if (state == Heap::NOT_IN_GC) { 132 mode_ = mode;
133 if (mode == NOT_IN_GC) {
131 insertion_callback = &InsertDuringRuntime; 134 insertion_callback = &InsertDuringRuntime;
132 deletion_callback = &DeleteDuringRuntime; 135 deletion_callback = &DeleteDuringRuntime;
133 } else { 136 } else {
134 insertion_callback = &InsertDuringGarbageCollection; 137 insertion_callback = &InsertDuringGarbageCollection;
135 deletion_callback = &DeleteDuringGarbageCollection; 138 deletion_callback = &DeleteDuringGarbageCollection;
136 } 139 }
137 } 140 }
138 141
139 // Used by the concurrent processing thread to transfer entries from the 142 // Used by the concurrent processing thread to transfer entries from the
140 // store buffer to the remembered set. 143 // store buffer to the remembered set.
(...skipping 27 matching lines...) Expand all
168 virtual ~Task() {} 171 virtual ~Task() {}
169 172
170 private: 173 private:
171 void RunInternal() override { 174 void RunInternal() override {
172 store_buffer_->ConcurrentlyProcessStoreBuffer(); 175 store_buffer_->ConcurrentlyProcessStoreBuffer();
173 } 176 }
174 StoreBuffer* store_buffer_; 177 StoreBuffer* store_buffer_;
175 DISALLOW_COPY_AND_ASSIGN(Task); 178 DISALLOW_COPY_AND_ASSIGN(Task);
176 }; 179 };
177 180
181 StoreBufferMode mode() const { return mode_; }
182
178 void FlipStoreBuffers(); 183 void FlipStoreBuffers();
179 184
180 Heap* heap_; 185 Heap* heap_;
181 186
182 Address* top_; 187 Address* top_;
183 188
184 // The start and the limit of the buffer that contains store slots 189 // The start and the limit of the buffer that contains store slots
185 // added from the generated code. We have two chunks of store buffers. 190 // added from the generated code. We have two chunks of store buffers.
186 // Whenever one fills up, we notify a concurrent processing thread and 191 // Whenever one fills up, we notify a concurrent processing thread and
187 // use the other empty one in the meantime. 192 // use the other empty one in the meantime.
188 Address* start_[kStoreBuffers]; 193 Address* start_[kStoreBuffers];
189 Address* limit_[kStoreBuffers]; 194 Address* limit_[kStoreBuffers];
190 195
191 // At most one lazy_top_ pointer is set at any time. 196 // At most one lazy_top_ pointer is set at any time.
192 Address* lazy_top_[kStoreBuffers]; 197 Address* lazy_top_[kStoreBuffers];
193 base::Mutex mutex_; 198 base::Mutex mutex_;
194 199
195 // We only want to have at most one concurrent processing tas running. 200 // We only want to have at most one concurrent processing tas running.
196 bool task_running_; 201 bool task_running_;
197 202
198 // Points to the current buffer in use. 203 // Points to the current buffer in use.
199 int current_; 204 int current_;
200 205
206 // During GC, entries are directly added to the remembered set without
207 // going through the store buffer. This is signaled by a special
208 // IN_GC mode.
209 StoreBufferMode mode_;
210
201 base::VirtualMemory* virtual_memory_; 211 base::VirtualMemory* virtual_memory_;
202 212
203 // Callbacks are more efficient than reading out the gc state for every 213 // Callbacks are more efficient than reading out the gc state for every
204 // store buffer operation. 214 // store buffer operation.
205 void (*insertion_callback)(StoreBuffer*, Address); 215 void (*insertion_callback)(StoreBuffer*, Address);
206 void (*deletion_callback)(StoreBuffer*, Address, Address); 216 void (*deletion_callback)(StoreBuffer*, Address, Address);
207 }; 217 };
208 218
209 } // namespace internal 219 } // namespace internal
210 } // namespace v8 220 } // namespace v8
211 221
212 #endif // V8_STORE_BUFFER_H_ 222 #endif // V8_STORE_BUFFER_H_
OLDNEW
« no previous file with comments | « src/heap/heap.cc ('k') | src/heap/store-buffer.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698