| Index: runtime/vm/store_buffer.h
|
| diff --git a/runtime/vm/store_buffer.h b/runtime/vm/store_buffer.h
|
| index b437f8532fba385e0193574b43129e3a0d5d98f6..b8f36a5e369d70a791d07f16db9eccd25d048dfe 100644
|
| --- a/runtime/vm/store_buffer.h
|
| +++ b/runtime/vm/store_buffer.h
|
| @@ -15,34 +15,37 @@ class Isolate;
|
| class Mutex;
|
| class RawObject;
|
|
|
| +// A set of RawObject*. Must be emptied before destruction (using Pop/Reset).
|
| class StoreBufferBlock {
|
| public:
|
| // Each full block contains kSize pointers.
|
| static const int32_t kSize = 1024;
|
|
|
| - void Reset() { top_ = 0; }
|
| + void Reset() {
|
| + top_ = 0;
|
| + next_ = NULL;
|
| + }
|
|
|
| - // TODO(koda): Make private after adding visitor interface to StoreBuffer.
|
| StoreBufferBlock* next() const { return next_; }
|
|
|
| intptr_t Count() const { return top_; }
|
| bool IsFull() const { return Count() == kSize; }
|
| + bool IsEmpty() const { return Count() == 0; }
|
|
|
| - void Add(RawObject* obj) {
|
| + void Push(RawObject* obj) {
|
| ASSERT(!IsFull());
|
| pointers_[top_++] = obj;
|
| }
|
|
|
| - RawObject* At(intptr_t i) const {
|
| - ASSERT(i >= 0);
|
| - ASSERT(i < top_);
|
| - return pointers_[i];
|
| + RawObject* Pop() {
|
| + ASSERT(!IsEmpty());
|
| + return pointers_[--top_];
|
| }
|
|
|
| #if defined(TESTING)
|
| bool Contains(RawObject* obj) const {
|
| for (intptr_t i = 0; i < Count(); i++) {
|
| - if (At(i) == obj) {
|
| + if (pointers_[i] == obj) {
|
| return true;
|
| }
|
| }
|
| @@ -57,6 +60,9 @@ class StoreBufferBlock {
|
|
|
| private:
|
| StoreBufferBlock() : next_(NULL), top_(0) {}
|
| + ~StoreBufferBlock() {
|
| + ASSERT(IsEmpty()); // Guard against unintentionally discarding pointers.
|
| + }
|
|
|
| StoreBufferBlock* next_;
|
| int32_t top_;
|
| @@ -72,6 +78,10 @@ class StoreBuffer {
|
| public:
|
| StoreBuffer();
|
| ~StoreBuffer();
|
| + static void InitOnce();
|
| +
|
| + // Interrupt when crossing this threshold of non-empty blocks in the buffer.
|
| + static const intptr_t kMaxNonEmpty = 100;
|
|
|
| // Adds and transfers ownership of the block to the buffer.
|
| void PushBlock(StoreBufferBlock* block, bool check_threshold = true);
|
| @@ -82,7 +92,6 @@ class StoreBuffer {
|
| StoreBufferBlock* PopEmptyBlock();
|
|
|
| // Pops and returns all non-empty blocks as a linked list (owned by caller).
|
| - // TODO(koda): Replace with VisitObjectPointers.
|
| StoreBufferBlock* Blocks();
|
|
|
| // Discards the contents of this store buffer.
|
| @@ -106,13 +115,19 @@ class StoreBuffer {
|
|
|
| // Check if we run over the max number of deduplication sets.
|
| // If we did schedule an interrupt.
|
| - void CheckThreshold();
|
| + void CheckThresholdNonEmpty();
|
| +
|
| + // If needed, trims the the global cache of empty blocks.
|
| + static void TrimGlobalEmpty();
|
|
|
| List full_;
|
| List partial_;
|
| - // TODO(koda): static List empty_
|
| Mutex* mutex_;
|
|
|
| + static const intptr_t kMaxGlobalEmpty = 100;
|
| + static List* global_empty_;
|
| + static Mutex* global_mutex_;
|
| +
|
| DISALLOW_COPY_AND_ASSIGN(StoreBuffer);
|
| };
|
|
|
|
|