Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(564)

Unified Diff: src/store-buffer.cc

Issue 6250076: Start using store buffers. Handle store buffer overflow situation.... (Closed) Base URL: http://v8.googlecode.com/svn/branches/experimental/gc/
Patch Set: Created 9 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: src/store-buffer.cc
===================================================================
--- src/store-buffer.cc (revision 6554)
+++ src/store-buffer.cc (working copy)
@@ -40,9 +40,12 @@
uintptr_t* StoreBuffer::hash_map_1_ = NULL;
uintptr_t* StoreBuffer::hash_map_2_ = NULL;
VirtualMemory* StoreBuffer::virtual_memory_ = NULL;
-bool StoreBuffer::must_scan_entire_memory_ = false;
+StoreBuffer::StoreBufferMode StoreBuffer::store_buffer_mode_ =
+ kStoreBufferFunctional;
bool StoreBuffer::old_buffer_is_sorted_ = false;
bool StoreBuffer::during_gc_ = false;
+bool StoreBuffer::store_buffer_rebuilding_enabled_ = false;
+bool StoreBuffer::may_move_store_buffer_entries_ = true;
void StoreBuffer::Setup() {
virtual_memory_ = new VirtualMemory(kStoreBufferSize * 3);
@@ -126,10 +129,11 @@
// Remove adjacent duplicates and cells that do not point at new space.
Address previous = NULL;
Address* write = old_start_;
+ ASSERT(may_move_store_buffer_entries_);
for (Address* read = old_start_; read < old_top_; read++) {
Address current = *read;
if (current != previous) {
- if (Heap::InNewSpace(*reinterpret_cast<Address*>(current))) {
+ if (Heap::InNewSpace(*reinterpret_cast<Object**>(current))) {
*write++ = current;
}
}
@@ -142,6 +146,10 @@
void StoreBuffer::SortUniq() {
Compact();
if (old_buffer_is_sorted_) return;
+ if (store_buffer_mode_ == kStoreBufferDisabled) {
+ old_top_ = old_start_;
+ return;
+ }
ZapHashTables();
qsort(reinterpret_cast<void*>(old_start_),
old_top_ - old_start_,
@@ -155,9 +163,7 @@
#ifdef DEBUG
void StoreBuffer::Clean() {
- if (must_scan_entire_memory_) {
- // We don't currently have a way to go back to using the store buffer.
- // TODO(gc): We should rebuild the store buffer during GC.
+ if (store_buffer_mode_ == kStoreBufferDisabled) {
old_top_ = old_start_; // Just clear the cache.
return;
}
@@ -199,16 +205,13 @@
void StoreBuffer::GCPrologue(GCType type, GCCallbackFlags flags) {
ZapHashTables();
during_gc_ = true;
- if (type != kGCTypeScavenge) {
- old_top_ = old_start_;
- Heap::public_set_store_buffer_top(start_);
- }
}
void StoreBuffer::Verify() {
#ifdef DEBUG
- if (FLAG_verify_heap && !StoreBuffer::must_scan_entire_memory()) {
+ if (FLAG_verify_heap &&
+ StoreBuffer::store_buffer_mode_ == kStoreBufferFunctional) {
Heap::OldPointerSpaceCheckStoreBuffer(Heap::WATERMARK_SHOULD_BE_VALID);
Heap::MapSpaceCheckStoreBuffer(Heap::WATERMARK_SHOULD_BE_VALID);
Heap::LargeObjectSpaceCheckStoreBuffer();
@@ -219,16 +222,72 @@
void StoreBuffer::GCEpilogue(GCType type, GCCallbackFlags flags) {
during_gc_ = false;
+ if (store_buffer_mode_ == kStoreBufferBeingRebuilt) {
+ store_buffer_mode_ = kStoreBufferFunctional;
+ }
Verify();
}
+void StoreBuffer::IteratePointersToNewSpace(ObjectSlotCallback callback) {
+ if (store_buffer_mode_ != kStoreBufferFunctional) {
+ old_top_ = old_start_;
+ ZapHashTables();
+ Heap::public_set_store_buffer_top(start_);
+ store_buffer_mode_ = kStoreBufferBeingRebuilt;
+ Heap::IteratePointers(Heap::old_pointer_space(),
+ &Heap::IteratePointersToNewSpace,
+ callback,
+ Heap::WATERMARK_SHOULD_BE_VALID);
+
+ Heap::IteratePointers(Heap::map_space(),
+ &Heap::IteratePointersFromMapsToNewSpace,
+ callback,
+ Heap::WATERMARK_SHOULD_BE_VALID);
+
+ Heap::lo_space()->IteratePointersToNewSpace(callback);
+ } else {
+ SortUniq();
+ Address* limit = old_top_;
+ old_top_ = old_start_;
+ {
+ DontMoveStoreBufferEntriesScope scope;
+ for (Address* current = old_start_; current < limit; current++) {
+#ifdef DEBUG
+ Address* saved_top = old_top_;
+#endif
+ Object** cell = reinterpret_cast<Object**>(*current);
+ Object* object = *cell;
+ // May be invalid if object is not in new space.
+ HeapObject* heap_object = reinterpret_cast<HeapObject*>(object);
+ if (Heap::InNewSpace(object)) {
+ callback(reinterpret_cast<HeapObject**>(cell), heap_object);
+ }
+ ASSERT(old_top_ == saved_top + 1 || old_top_ == saved_top);
+ ASSERT((old_top_ == saved_top + 1) ==
+ (Heap::InNewSpace(*cell) &&
+ !Heap::InNewSpace(reinterpret_cast<Address>(cell)) &&
+ Memory::Address_at(heap_object->address()) != NULL));
+ }
+ }
+ }
+}
+
+
void StoreBuffer::Compact() {
Address* top = reinterpret_cast<Address*>(Heap::store_buffer_top());
+
if (top == start_) return;
+
+ // There's no check of the limit in the loop below so we check here for
+ // the worst case (compaction doesn't eliminate any pointers).
ASSERT(top <= limit_);
Heap::public_set_store_buffer_top(start_);
- if (must_scan_entire_memory_) return;
+ if (top - start_ > old_limit_ - old_top_) {
+ CheckForFullBuffer();
+ }
+ if (store_buffer_mode_ == kStoreBufferDisabled) return;
+ ASSERT(may_move_store_buffer_entries_);
// Goes through the addresses in the store buffer attempting to remove
// duplicates. In the interest of speed this is a lossy operation. Some
// duplicates will remain. We have two hash tables with different hash
@@ -281,7 +340,7 @@
// compression to be guaranteed to succeed.
// TODO(gc): Set a flag to scan all of memory.
Counters::store_buffer_overflows.Increment();
- must_scan_entire_memory_ = true;
+ store_buffer_mode_ = kStoreBufferDisabled;
}
}
}
« src/store-buffer.h ('K') | « src/store-buffer.h ('k') | src/store-buffer-inl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698