blob: 69cb803eee8286f62b58153a75e9541ed7cd005e [file] [log] [blame]
// 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_