Files
sdk/runtime/vm/store_buffer.h
T
vegorov@google.com 6c60285f23 Drain StoreBufferBlock into store buffer instead of iterating over it directly.
This will deduplicate its entries. StoreBufferBlock might be contain the same large object dozens of times and without deduplication this will severely degrade GC performance by revisiting the same large object for every time it is recorded in the StoreBufferBlock.

BUG=dart:10048

Review URL: https://codereview.chromium.org//14348026

git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart@21766 260f80e4-7a28-3924-810f-c04153c831b5
2013-04-19 20:14:44 +00:00

131 lines
3.0 KiB
C++

// 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"
#include "vm/hash_set.h"
namespace dart {
// Forward declarations.
class Isolate;
class StoreBufferBlock {
public:
// Each block contains kSize pointers.
static const int32_t kSize = 1024;
StoreBufferBlock() : top_(0) {}
static int top_offset() { return OFFSET_OF(StoreBufferBlock, top_); }
static int pointers_offset() {
return OFFSET_OF(StoreBufferBlock, pointers_);
}
void Reset() { top_ = 0; }
intptr_t Count() const { return top_; }
uword At(intptr_t i) const {
ASSERT(i >= 0);
ASSERT(i < top_);
return pointers_[i];
}
// Add a pointer to the block of pointers. The buffer will be processed if it
// has been filled by this operation.
void AddPointer(uword pointer) {
ASSERT(top_ < kSize);
pointers_[top_++] = pointer;
if (top_ == kSize) {
ProcessBuffer();
}
}
// Process this store buffer and remember its contents in the heap.
void ProcessBuffer();
void ProcessBuffer(Isolate* isolate);
bool Contains(uword pointer);
private:
int32_t top_;
uword pointers_[kSize];
friend class StoreBuffer;
DISALLOW_COPY_AND_ASSIGN(StoreBufferBlock);
};
class StoreBuffer {
public:
// Simple linked list element containing a HashSet of old->new pointers.
class DedupSet {
public:
enum {
kSetSize = 1024,
kFillRatio = 75
};
explicit DedupSet(DedupSet* next)
: next_(next), set_(new HashSet(kSetSize, kFillRatio)) {}
~DedupSet() {
delete set_;
}
DedupSet* next() const { return next_; }
HashSet* set() const { return set_; }
private:
DedupSet* next_;
HashSet* set_;
DISALLOW_COPY_AND_ASSIGN(DedupSet);
};
StoreBuffer() : dedup_sets_(new DedupSet(NULL)), count_(1) {}
~StoreBuffer();
void Reset();
void AddPointer(uword address);
// Drain StoreBufferBlock into deduplication sets.
// Returns true if new sets were created.
bool DrainBlock(StoreBufferBlock* block);
// Drain StoreBufferBlock into deduplication sets.
// Schedule an interrupt if we run over the max number of deduplication sets.
void ProcessBlock(StoreBufferBlock* block);
DedupSet* DedupSets() {
DedupSet* result = dedup_sets_;
dedup_sets_ = new DedupSet(NULL);
count_ = 1;
return result;
}
private:
// Add pointer to deduplication sets. Returns true if the current set is full
// and a new set was created.
bool AddPointerInternal(uword address);
// Check if we run over the max number of deduplication sets.
// If we did schedule an interrupt.
void CheckThreshold();
DedupSet* dedup_sets_;
intptr_t count_;
DISALLOW_COPY_AND_ASSIGN(StoreBuffer);
};
} // namespace dart
#endif // VM_STORE_BUFFER_H_