// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. #include "vm/store_buffer.h" #include "platform/assert.h" #include "vm/runtime_entry.h" namespace dart { DEFINE_LEAF_RUNTIME_ENTRY(void, StoreBufferBlockProcess, Isolate* isolate) { isolate->store_buffer_block()->ProcessBuffer(isolate); } END_LEAF_RUNTIME_ENTRY void StoreBufferBlock::ProcessBuffer() { ProcessBuffer(Isolate::Current()); } void StoreBufferBlock::ProcessBuffer(Isolate* isolate) { isolate->store_buffer()->ProcessBlock(this); } bool StoreBufferBlock::Contains(uword pointer) { for (int32_t i = 0; i < top_; i++) { if (pointers_[i] == pointer) { return true; } } return false; } StoreBuffer::~StoreBuffer() { DedupSet* current = dedup_sets_; dedup_sets_ = NULL; while (current != NULL) { DedupSet* next = current->next(); delete current; current = next; } } void StoreBuffer::Reset() { DedupSet* current = DedupSets(); while (current != NULL) { DedupSet* next = current->next(); delete current; current = next; } } bool StoreBuffer::AddPointerInternal(uword address) { ASSERT(dedup_sets_ != NULL); ASSERT(Isolate::Current()->heap()->OldContains(address)); ASSERT((address & kSmiTagMask) != kSmiTag); if (!dedup_sets_->set()->Add(address)) { // Add a new DedupSet. dedup_sets_ = new DedupSet(dedup_sets_); count_++; return true; } return false; } void StoreBuffer::AddPointer(uword address) { if (AddPointerInternal(address)) { // Had to create a new DedupSet. CheckThreshold(); } } bool StoreBuffer::DrainBlock(StoreBufferBlock* block) { const intptr_t old_count = count_; intptr_t entries = block->Count(); for (intptr_t i = 0; i < entries; i++) { AddPointerInternal(block->At(i)); } block->Reset(); return (count_ > old_count); } void StoreBuffer::CheckThreshold() { // Schedule an interrupt if we have run over the max number of DedupSets. // TODO(iposva): Fix magic number. if (count_ > 100) { Isolate::Current()->ScheduleInterrupts(Isolate::kStoreBufferInterrupt); } } void StoreBuffer::ProcessBlock(StoreBufferBlock* block) { if (DrainBlock(block)) { CheckThreshold(); } } } // namespace dart