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

Side by Side Diff: runtime/vm/store_buffer.cc

Issue 1350933004: Distinct block sizes for StoreBuffer/MarkingStack. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Address review comments. Created 5 years, 3 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 | « runtime/vm/store_buffer.h ('k') | runtime/vm/thread.h » ('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 (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #include "vm/store_buffer.h" 5 #include "vm/store_buffer.h"
6 6
7 #include "platform/assert.h" 7 #include "platform/assert.h"
8 #include "vm/lockers.h" 8 #include "vm/lockers.h"
9 #include "vm/runtime_entry.h" 9 #include "vm/runtime_entry.h"
10 10
11 namespace dart { 11 namespace dart {
12 12
13 DEFINE_LEAF_RUNTIME_ENTRY(void, StoreBufferBlockProcess, 1, Thread* thread) { 13 DEFINE_LEAF_RUNTIME_ENTRY(void, StoreBufferBlockProcess, 1, Thread* thread) {
14 thread->StoreBufferBlockProcess(true); 14 thread->StoreBufferBlockProcess(StoreBuffer::kCheckThreshold);
15 } 15 }
16 END_LEAF_RUNTIME_ENTRY 16 END_LEAF_RUNTIME_ENTRY
17 17
18 18 template<int BlockSize>
19 StoreBuffer::List* StoreBuffer::global_empty_ = NULL; 19 typename BlockStack<BlockSize>::List*
20 Mutex* StoreBuffer::global_mutex_ = NULL; 20 BlockStack<BlockSize>::global_empty_ = NULL;
21 template<int BlockSize>
22 Mutex* BlockStack<BlockSize>::global_mutex_ = NULL;
21 23
22 24
23 void StoreBuffer::InitOnce() { 25 template<int BlockSize>
26 void BlockStack<BlockSize>::InitOnce() {
24 global_empty_ = new List(); 27 global_empty_ = new List();
25 global_mutex_ = new Mutex(); 28 global_mutex_ = new Mutex();
26 } 29 }
27 30
28 31
29 void StoreBuffer::ShutDown() { 32 template<int BlockSize>
33 void BlockStack<BlockSize>::ShutDown() {
30 delete global_empty_; 34 delete global_empty_;
31 delete global_mutex_; 35 delete global_mutex_;
32 } 36 }
33 37
34 38
35 StoreBuffer::StoreBuffer() : mutex_(new Mutex()) { 39 template<int BlockSize>
40 BlockStack<BlockSize>::BlockStack() : mutex_(new Mutex()) {
36 } 41 }
37 42
38 43
39 StoreBuffer::~StoreBuffer() { 44 template<int BlockSize>
45 BlockStack<BlockSize>::~BlockStack() {
40 Reset(); 46 Reset();
41 delete mutex_; 47 delete mutex_;
42 } 48 }
43 49
44 50
45 void StoreBuffer::Reset() { 51 template<int BlockSize>
52 void BlockStack<BlockSize>::Reset() {
46 MutexLocker local_mutex_locker(mutex_); 53 MutexLocker local_mutex_locker(mutex_);
47 { 54 {
48 // Empty all blocks and move them to the global cache. 55 // Empty all blocks and move them to the global cache.
49 MutexLocker global_mutex_locker(global_mutex_); 56 MutexLocker global_mutex_locker(global_mutex_);
50 while (!full_.IsEmpty()) { 57 while (!full_.IsEmpty()) {
51 StoreBufferBlock* block = full_.Pop(); 58 Block* block = full_.Pop();
52 block->Reset(); 59 block->Reset();
53 global_empty_->Push(block); 60 global_empty_->Push(block);
54 } 61 }
55 while (!partial_.IsEmpty()) { 62 while (!partial_.IsEmpty()) {
56 StoreBufferBlock* block = partial_.Pop(); 63 Block* block = partial_.Pop();
57 block->Reset(); 64 block->Reset();
58 global_empty_->Push(block); 65 global_empty_->Push(block);
59 } 66 }
60 TrimGlobalEmpty(); 67 TrimGlobalEmpty();
61 } 68 }
62 } 69 }
63 70
64 71
65 StoreBufferBlock* StoreBuffer::Blocks() { 72 template<int BlockSize>
73 typename BlockStack<BlockSize>::Block* BlockStack<BlockSize>::Blocks() {
66 MutexLocker ml(mutex_); 74 MutexLocker ml(mutex_);
67 while (!partial_.IsEmpty()) { 75 while (!partial_.IsEmpty()) {
68 full_.Push(partial_.Pop()); 76 full_.Push(partial_.Pop());
69 } 77 }
70 return full_.PopAll(); 78 return full_.PopAll();
71 } 79 }
72 80
73 81
74 void StoreBuffer::PushBlock(StoreBufferBlock* block, bool check_threshold) { 82 template<int BlockSize>
83 void BlockStack<BlockSize>::PushBlockImpl(Block* block) {
75 ASSERT(block->next() == NULL); // Should be just a single block. 84 ASSERT(block->next() == NULL); // Should be just a single block.
76 if (block->IsFull()) { 85 if (block->IsFull()) {
77 MutexLocker ml(mutex_); 86 MutexLocker ml(mutex_);
78 full_.Push(block); 87 full_.Push(block);
79 } else if (block->IsEmpty()) { 88 } else if (block->IsEmpty()) {
80 MutexLocker ml(global_mutex_); 89 MutexLocker ml(global_mutex_);
81 global_empty_->Push(block); 90 global_empty_->Push(block);
82 TrimGlobalEmpty(); 91 TrimGlobalEmpty();
83 } else { 92 } else {
84 MutexLocker ml(mutex_); 93 MutexLocker ml(mutex_);
85 partial_.Push(block); 94 partial_.Push(block);
86 } 95 }
87 if (check_threshold && Overflowed()) { 96 }
97
98
99 void StoreBuffer::PushBlock(Block* block, ThresholdPolicy policy) {
100 BlockStack<Block::kSize>::PushBlockImpl(block);
101 if ((policy == kCheckThreshold) && Overflowed()) {
88 MutexLocker ml(mutex_); 102 MutexLocker ml(mutex_);
89 Isolate* isolate = Isolate::Current(); 103 Isolate* isolate = Isolate::Current();
90 // Sanity check: it makes no sense to schedule the GC in another isolate. 104 // Sanity check: it makes no sense to schedule the GC in another isolate.
91 // (If Isolate ever gets multiple store buffers, we should avoid this 105 // (If Isolate ever gets multiple store buffers, we should avoid this
92 // coupling by passing in an explicit callback+parameter at construction.) 106 // coupling by passing in an explicit callback+parameter at construction.)
93 ASSERT(isolate->store_buffer() == this); 107 ASSERT(isolate->store_buffer() == this);
94 isolate->ScheduleInterrupts(Isolate::kVMInterrupt); 108 isolate->ScheduleInterrupts(Isolate::kVMInterrupt);
95 } 109 }
96 } 110 }
97 111
98 112
99 StoreBufferBlock* StoreBuffer::PopNonFullBlock() { 113 template<int BlockSize>
114 typename BlockStack<BlockSize>::Block*
115 BlockStack<BlockSize>::PopNonFullBlock() {
100 { 116 {
101 MutexLocker ml(mutex_); 117 MutexLocker ml(mutex_);
102 if (!partial_.IsEmpty()) { 118 if (!partial_.IsEmpty()) {
103 return partial_.Pop(); 119 return partial_.Pop();
104 } 120 }
105 } 121 }
106 return PopEmptyBlock(); 122 return PopEmptyBlock();
107 } 123 }
108 124
109 125
110 StoreBufferBlock* StoreBuffer::PopEmptyBlock() { 126 template<int BlockSize>
127 typename BlockStack<BlockSize>::Block* BlockStack<BlockSize>::PopEmptyBlock() {
111 { 128 {
112 MutexLocker ml(global_mutex_); 129 MutexLocker ml(global_mutex_);
113 if (!global_empty_->IsEmpty()) { 130 if (!global_empty_->IsEmpty()) {
114 return global_empty_->Pop(); 131 return global_empty_->Pop();
115 } 132 }
116 } 133 }
117 return new StoreBufferBlock(); 134 return new Block();
118 } 135 }
119 136
120 137
121 StoreBufferBlock* StoreBuffer::PopNonEmptyBlock() { 138 template<int BlockSize>
139 typename BlockStack<BlockSize>::Block*
140 BlockStack<BlockSize>::PopNonEmptyBlock() {
122 MutexLocker ml(mutex_); 141 MutexLocker ml(mutex_);
123 if (!full_.IsEmpty()) { 142 if (!full_.IsEmpty()) {
124 return full_.Pop(); 143 return full_.Pop();
125 } else if (!partial_.IsEmpty()) { 144 } else if (!partial_.IsEmpty()) {
126 return partial_.Pop(); 145 return partial_.Pop();
127 } else { 146 } else {
128 return NULL; 147 return NULL;
129 } 148 }
130 } 149 }
131 150
132 151
133 bool StoreBuffer::IsEmpty() { 152 template<int BlockSize>
134 MutexLocker ml(global_mutex_); 153 bool BlockStack<BlockSize>::IsEmpty() {
154 MutexLocker ml(mutex_);
135 return full_.IsEmpty() && partial_.IsEmpty(); 155 return full_.IsEmpty() && partial_.IsEmpty();
136 } 156 }
137 157
138 158
139 StoreBuffer::List::~List() { 159 template<int BlockSize>
160 BlockStack<BlockSize>::List::~List() {
140 while (!IsEmpty()) { 161 while (!IsEmpty()) {
141 delete Pop(); 162 delete Pop();
142 } 163 }
143 } 164 }
144 165
145 166
146 StoreBufferBlock* StoreBuffer::List::Pop() { 167 template<int BlockSize>
147 StoreBufferBlock* result = head_; 168 typename BlockStack<BlockSize>::Block* BlockStack<BlockSize>::List::Pop() {
169 Block* result = head_;
148 head_ = head_->next_; 170 head_ = head_->next_;
149 --length_; 171 --length_;
150 result->next_ = NULL; 172 result->next_ = NULL;
151 return result; 173 return result;
152 } 174 }
153 175
154 176
155 StoreBufferBlock* StoreBuffer::List::PopAll() { 177 template<int BlockSize>
156 StoreBufferBlock* result = head_; 178 typename BlockStack<BlockSize>::Block* BlockStack<BlockSize>::List::PopAll() {
179 Block* result = head_;
157 head_ = NULL; 180 head_ = NULL;
158 length_ = 0; 181 length_ = 0;
159 return result; 182 return result;
160 } 183 }
161 184
162 185
163 void StoreBuffer::List::Push(StoreBufferBlock* block) { 186 template<int BlockSize>
187 void BlockStack<BlockSize>::List::Push(Block* block) {
164 ASSERT(block->next_ == NULL); 188 ASSERT(block->next_ == NULL);
165 block->next_ = head_; 189 block->next_ = head_;
166 head_ = block; 190 head_ = block;
167 ++length_; 191 ++length_;
168 } 192 }
169 193
170 194
171 bool StoreBuffer::Overflowed() { 195 bool StoreBuffer::Overflowed() {
172 MutexLocker ml(mutex_); 196 MutexLocker ml(mutex_);
173 return (full_.length() + partial_.length()) > kMaxNonEmpty; 197 return (full_.length() + partial_.length()) > kMaxNonEmpty;
174 } 198 }
175 199
176 200
177 void StoreBuffer::TrimGlobalEmpty() { 201 template<int BlockSize>
202 void BlockStack<BlockSize>::TrimGlobalEmpty() {
178 DEBUG_ASSERT(global_mutex_->IsOwnedByCurrentThread()); 203 DEBUG_ASSERT(global_mutex_->IsOwnedByCurrentThread());
179 while (global_empty_->length() > kMaxGlobalEmpty) { 204 while (global_empty_->length() > kMaxGlobalEmpty) {
180 delete global_empty_->Pop(); 205 delete global_empty_->Pop();
181 } 206 }
182 } 207 }
183 208
209
210 template class BlockStack<kStoreBufferBlockSize>;
211 template class BlockStack<kMarkingStackBlockSize>;
212
184 } // namespace dart 213 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/store_buffer.h ('k') | runtime/vm/thread.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698