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

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

Issue 2548213004: [heap] Use callbacks to dispatch store buffer operations. (Closed)
Patch Set: restructure Created 4 years 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"
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
56 } 56 }
57 57
58 inline Address UnmarkDeletionAddress(Address address) { 58 inline Address UnmarkDeletionAddress(Address address) {
59 return reinterpret_cast<Address>(reinterpret_cast<intptr_t>(address) & 59 return reinterpret_cast<Address>(reinterpret_cast<intptr_t>(address) &
60 ~kDeletionTag); 60 ~kDeletionTag);
61 } 61 }
62 62
63 // If we only want to delete a single slot, end should be set to null which 63 // If we only want to delete a single slot, end should be set to null which
64 // will be written into the second field. When processing the store buffer 64 // will be written into the second field. When processing the store buffer
65 // the more efficient Remove method will be called in this case. 65 // the more efficient Remove method will be called in this case.
66 void DeleteEntry(Address start, Address end = nullptr); 66 void DeleteEntry(Address start, Address end = nullptr) {
67 // Deletions coming from the GC are directly deleted from the remembered
68 // set. Deletions coming from the runtime are added to the store buffer
69 // to allow concurrent processing.
70 deletion_callback(this, start, end);
71 }
72
73 static void DeleteDuringGarbageCollection(StoreBuffer* store_buffer,
74 Address start, Address end) {
75 // In GC the store buffer has to be empty at any time.
76 DCHECK(store_buffer->Empty());
77 DCHECK(store_buffer->heap()->gc_state() != Heap::NOT_IN_GC);
78 Page* page = Page::FromAddress(start);
79 if (end) {
80 RememberedSet<OLD_TO_NEW>::RemoveRange(page, start, end,
81 SlotSet::PREFREE_EMPTY_BUCKETS);
82 } else {
83 RememberedSet<OLD_TO_NEW>::Remove(page, start);
84 }
85 }
86
87 static void DeleteDuringRuntime(StoreBuffer* store_buffer, Address start,
88 Address end) {
89 DCHECK(store_buffer->heap()->gc_state() == Heap::NOT_IN_GC);
90 store_buffer->InsertDeletionIntoStoreBuffer(start, end);
91 }
92
93 void InsertDeletionIntoStoreBuffer(Address start, Address end) {
94 if (top_ + sizeof(Address) * 2 > limit_[current_]) {
95 StoreBufferOverflow(heap_->isolate());
96 }
97 *top_ = MarkDeletionAddress(start);
98 top_++;
99 *top_ = end;
100 top_++;
101 }
102
103 static void InsertDuringGarbageCollection(StoreBuffer* store_buffer,
104 Address slot) {
105 DCHECK(store_buffer->heap()->gc_state() != Heap::NOT_IN_GC);
106 RememberedSet<OLD_TO_NEW>::Insert(Page::FromAddress(slot), slot);
107 }
108
109 static void InsertDuringRuntime(StoreBuffer* store_buffer, Address slot) {
110 DCHECK(store_buffer->heap()->gc_state() == Heap::NOT_IN_GC);
111 store_buffer->InsertIntoStoreBuffer(slot);
112 }
113
114 void InsertIntoStoreBuffer(Address slot) {
115 if (top_ + sizeof(Address) > limit_[current_]) {
116 StoreBufferOverflow(heap_->isolate());
117 }
118 *top_ = slot;
119 top_++;
120 }
67 121
68 void InsertEntry(Address slot) { 122 void InsertEntry(Address slot) {
69 // Insertions coming from the GC are directly inserted into the remembered 123 // Insertions coming from the GC are directly inserted into the remembered
70 // set. Insertions coming from the runtime are added to the store buffer to 124 // set. Insertions coming from the runtime are added to the store buffer to
71 // allow concurrent processing. 125 // allow concurrent processing.
72 if (heap_->gc_state() == Heap::NOT_IN_GC) { 126 insertion_callback(this, slot);
73 if (top_ + sizeof(Address) > limit_[current_]) { 127 }
74 StoreBufferOverflow(heap_->isolate()); 128
75 } 129 void SetMode(Heap::HeapState state) {
76 *top_ = slot; 130 if (state == Heap::NOT_IN_GC) {
77 top_++; 131 insertion_callback = &InsertDuringRuntime;
132 deletion_callback = &DeleteDuringRuntime;
78 } else { 133 } else {
79 // In GC the store buffer has to be empty at any time. 134 insertion_callback = &InsertDuringGarbageCollection;
80 DCHECK(Empty()); 135 deletion_callback = &DeleteDuringGarbageCollection;
81 RememberedSet<OLD_TO_NEW>::Insert(Page::FromAddress(slot), slot);
82 } 136 }
83 } 137 }
84 138
85 // Used by the concurrent processing thread to transfer entries from the 139 // Used by the concurrent processing thread to transfer entries from the
86 // store buffer to the remembered set. 140 // store buffer to the remembered set.
87 void ConcurrentlyProcessStoreBuffer(); 141 void ConcurrentlyProcessStoreBuffer();
88 142
89 bool Empty() { 143 bool Empty() {
90 for (int i = 0; i < kStoreBuffers; i++) { 144 for (int i = 0; i < kStoreBuffers; i++) {
91 if (lazy_top_[i]) { 145 if (lazy_top_[i]) {
92 return false; 146 return false;
93 } 147 }
94 } 148 }
95 return top_ == start_[current_]; 149 return top_ == start_[current_];
96 } 150 }
97 151
152 Heap* heap() { return heap_; }
153
98 private: 154 private:
99 // There are two store buffers. If one store buffer fills up, the main thread 155 // There are two store buffers. If one store buffer fills up, the main thread
100 // publishes the top pointer of the store buffer that needs processing in its 156 // publishes the top pointer of the store buffer that needs processing in its
101 // global lazy_top_ field. After that it start the concurrent processing 157 // global lazy_top_ field. After that it start the concurrent processing
102 // thread. The concurrent processing thread uses the pointer in lazy_top_. 158 // thread. The concurrent processing thread uses the pointer in lazy_top_.
103 // It will grab the given mutex and transfer its entries to the remembered 159 // It will grab the given mutex and transfer its entries to the remembered
104 // set. If the concurrent thread does not make progress, the main thread will 160 // set. If the concurrent thread does not make progress, the main thread will
105 // perform the work. 161 // perform the work.
106 // Important: there is an ordering constrained. The store buffer with the 162 // Important: there is an ordering constrained. The store buffer with the
107 // older entries has to be processed first. 163 // older entries has to be processed first.
(...skipping 28 matching lines...) Expand all
136 Address* lazy_top_[kStoreBuffers]; 192 Address* lazy_top_[kStoreBuffers];
137 base::Mutex mutex_; 193 base::Mutex mutex_;
138 194
139 // We only want to have at most one concurrent processing tas running. 195 // We only want to have at most one concurrent processing tas running.
140 bool task_running_; 196 bool task_running_;
141 197
142 // Points to the current buffer in use. 198 // Points to the current buffer in use.
143 int current_; 199 int current_;
144 200
145 base::VirtualMemory* virtual_memory_; 201 base::VirtualMemory* virtual_memory_;
202
203 // Callbacks are more efficient than reading out the gc state for every
204 // store buffer operation.
predrag.rudic 2016/12/23 11:55:17 There is a problem with this code because it fails
Hannes Payer (out of office) 2017/01/23 13:43:52 Interestingly, simple function pointers turned out
205 std::function<void(StoreBuffer*, Address)> insertion_callback;
206 std::function<void(StoreBuffer*, Address, Address)> deletion_callback;
146 }; 207 };
147 208
148 } // namespace internal 209 } // namespace internal
149 } // namespace v8 210 } // namespace v8
150 211
151 #endif // V8_STORE_BUFFER_H_ 212 #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