Chromium Code Reviews| Index: runtime/vm/store_buffer.cc |
| diff --git a/runtime/vm/store_buffer.cc b/runtime/vm/store_buffer.cc |
| index acf7ca6eac6cfbbdb144facf752c0bf0ffc32c88..9020340458aec40c783b14c8ea0cca6d040f22d0 100644 |
| --- a/runtime/vm/store_buffer.cc |
| +++ b/runtime/vm/store_buffer.cc |
| @@ -5,71 +5,102 @@ |
| #include "vm/store_buffer.h" |
| #include "platform/assert.h" |
| +#include "vm/lockers.h" |
| #include "vm/runtime_entry.h" |
| namespace dart { |
| -DEFINE_LEAF_RUNTIME_ENTRY(void, StoreBufferBlockProcess, 1, Isolate* isolate) { |
| - StoreBuffer* buffer = isolate->store_buffer(); |
| - buffer->Expand(true); |
| +DEFINE_LEAF_RUNTIME_ENTRY(void, StoreBufferBlockProcess, 1, Thread* thread) { |
| + thread->StoreBufferBlockProcess(true); |
| } |
| END_LEAF_RUNTIME_ENTRY |
| +StoreBuffer::StoreBuffer() : mutex_(new Mutex()) { |
| +} |
| + |
| + |
| StoreBuffer::~StoreBuffer() { |
| - StoreBufferBlock* block = blocks_; |
| - blocks_ = NULL; |
| - while (block != NULL) { |
| - StoreBufferBlock* next = block->next(); |
| - delete block; |
| - block = next; |
| - } |
| + Reset(); |
| + delete mutex_; |
| } |
| void StoreBuffer::Reset() { |
| - StoreBufferBlock* block = blocks_->next_; |
| - while (block != NULL) { |
| - StoreBufferBlock* next = block->next_; |
| - delete block; |
| - block = next; |
| - } |
| - blocks_->next_ = NULL; |
| - blocks_->top_ = 0; |
| - full_count_ = 0; |
| + MutexLocker ml(mutex_); |
| + // TODO(koda): Reuse and share empty blocks between isolates. |
| + while (full_.length() > 0) delete full_.Pop(); |
|
Ivan Posva
2015/06/08 13:05:21
while (full_.head != NULL) {
delete full_.Pop();
koda
2015/06/09 13:10:30
Done, using IsEmpty.
|
| + while (partial_.length() > 0) delete partial_.Pop(); |
| } |
| -bool StoreBuffer::Contains(RawObject* raw) { |
| - StoreBufferBlock* block = blocks_; |
| - while (block != NULL) { |
| - intptr_t count = block->Count(); |
| - for (intptr_t i = 0; i < count; i++) { |
| - if (block->At(i) == raw) { |
| - return true; |
| - } |
| - } |
| - block = block->next_; |
| +StoreBufferBlock* StoreBuffer::Blocks() { |
| + MutexLocker ml(mutex_); |
| + while (partial_.length() > 0) { |
|
Ivan Posva
2015/06/08 13:05:21
ditto.
koda
2015/06/09 13:10:30
Done.
|
| + full_.Push(partial_.Pop()); |
| } |
| - return false; |
| + return full_.PopAll(); |
| } |
| -void StoreBuffer::Expand(bool check) { |
| - ASSERT(blocks_->Count() == StoreBufferBlock::kSize); |
| - blocks_ = new StoreBufferBlock(blocks_); |
| - full_count_++; |
| - if (check) { |
| +void StoreBuffer::Push(StoreBufferBlock* block, bool check_threshold) { |
| + MutexLocker ml(mutex_); |
| + List* list = block->IsFull() ? &full_ : &partial_; |
| + list->Push(block); |
| + if (check_threshold) { |
| CheckThreshold(); |
| } |
| } |
| +StoreBufferBlock* StoreBuffer::PopPartialOrEmpty() { |
| + MutexLocker ml(mutex_); |
| + return (partial_.length() > 0) ? partial_.Pop() : PopEmpty(); |
|
Ivan Posva
2015/06/08 13:05:21
ditto.
koda
2015/06/09 13:10:29
Done.
|
| +} |
| + |
| + |
| +StoreBufferBlock* StoreBuffer::PopEmpty() { |
| + // TODO(koda): Reuse and share empty blocks between isolates. |
| + return new StoreBufferBlock(); |
| +} |
| + |
| + |
| +StoreBuffer::List::~List() { |
| + while (length() > 0) { |
|
Ivan Posva
2015/06/08 13:05:21
ditto.
koda
2015/06/09 13:10:29
Done.
|
| + delete Pop(); |
| + } |
| +} |
| + |
| + |
| +StoreBufferBlock* StoreBuffer::List::Pop() { |
| + StoreBufferBlock* result = head_; |
| + head_ = head_->next_; |
| + --length_; |
| + result->next_ = NULL; |
| + return result; |
| +} |
| + |
| + |
| +StoreBufferBlock* StoreBuffer::List::PopAll() { |
| + StoreBufferBlock* result = head_; |
| + head_ = NULL; |
| + length_ = 0; |
| + return result; |
| +} |
| + |
| + |
| +void StoreBuffer::List::Push(StoreBufferBlock* block) { |
| + block->next_ = head_; |
| + head_ = block; |
| + ++length_; |
| +} |
| + |
| + |
| void StoreBuffer::CheckThreshold() { |
| // Schedule an interrupt if we have run over the max number of |
| // StoreBufferBlocks. |
| - // TODO(iposva): Fix magic number. |
| - if (full_count_ > 100) { |
| + // TODO(koda): Pass threshold and callback in constructor. |
| + if (full_.length() > 100) { |
|
Ivan Posva
2015/06/08 13:05:21
Wondering whether we should be using the total num
koda
2015/06/09 13:10:29
Yes, I suppose there could be a temporary explosio
|
| Isolate::Current()->ScheduleInterrupts(Isolate::kStoreBufferInterrupt); |
| } |
| } |