// 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. #ifndef VM_STORE_BUFFER_H_ #define VM_STORE_BUFFER_H_ #include "platform/assert.h" #include "vm/globals.h" namespace dart { // Forward declarations. class Isolate; class RawObject; class StoreBufferBlock { public: // Each block contains kSize pointers. static const int32_t kSize = 1024; explicit StoreBufferBlock(StoreBufferBlock* next) : next_(next), top_(0) {} void Reset() { top_ = 0; } StoreBufferBlock* next() const { return next_; } intptr_t Count() const { return top_; } RawObject* At(intptr_t i) const { ASSERT(i >= 0); ASSERT(i < top_); return pointers_[i]; } static int top_offset() { return OFFSET_OF(StoreBufferBlock, top_); } static int pointers_offset() { return OFFSET_OF(StoreBufferBlock, pointers_); } private: StoreBufferBlock* next_; int32_t top_; RawObject* pointers_[kSize]; friend class StoreBuffer; DISALLOW_COPY_AND_ASSIGN(StoreBufferBlock); }; class StoreBuffer { public: StoreBuffer() : blocks_(new StoreBufferBlock(NULL)), full_count_(0) {} ~StoreBuffer(); intptr_t Count() const { return blocks_->Count() + (full_count_ * StoreBufferBlock::kSize); } void Reset(); void AddObject(RawObject* obj) { StoreBufferBlock* block = blocks_; ASSERT(block->top_ < StoreBufferBlock::kSize); block->pointers_[block->top_++] = obj; if (block->top_ == StoreBufferBlock::kSize) { Expand(true); } } void AddObjectGC(RawObject* obj) { StoreBufferBlock* block = blocks_; ASSERT(block->top_ < StoreBufferBlock::kSize); block->pointers_[block->top_++] = obj; if (block->top_ == StoreBufferBlock::kSize) { Expand(false); } } StoreBufferBlock* Blocks() { StoreBufferBlock* result = blocks_; blocks_ = new StoreBufferBlock(NULL); full_count_ = 0; return result; } // Expand the storage and optionally check whethe to schedule an interrupt. void Expand(bool check); bool Contains(RawObject* raw); static int blocks_offset() { return OFFSET_OF(StoreBuffer, blocks_); } private: // Check if we run over the max number of deduplication sets. // If we did schedule an interrupt. void CheckThreshold(); StoreBufferBlock* blocks_; intptr_t full_count_; DISALLOW_COPY_AND_ASSIGN(StoreBuffer); }; } // namespace dart #endif // VM_STORE_BUFFER_H_