Revision: 23046
Author:   [email protected]
Date:     Mon Aug 11 14:22:24 2014 UTC
Log:      Move store-buffer to heap and remove some unnecessary includes.

BUG=
[email protected]

Review URL: https://codereview.chromium.org/463523002
http://code.google.com/p/v8/source/detail?r=23046

Added:
 /branches/bleeding_edge/src/heap/store-buffer-inl.h
 /branches/bleeding_edge/src/heap/store-buffer.cc
 /branches/bleeding_edge/src/heap/store-buffer.h
Deleted:
 /branches/bleeding_edge/src/store-buffer-inl.h
 /branches/bleeding_edge/src/store-buffer.cc
 /branches/bleeding_edge/src/store-buffer.h
Modified:
 /branches/bleeding_edge/BUILD.gn
 /branches/bleeding_edge/src/assembler.cc
 /branches/bleeding_edge/src/heap/heap-inl.h
 /branches/bleeding_edge/src/heap/heap.cc
 /branches/bleeding_edge/src/heap/heap.h
 /branches/bleeding_edge/src/heap/spaces.h
 /branches/bleeding_edge/src/objects-inl.h
 /branches/bleeding_edge/src/v8.cc
 /branches/bleeding_edge/tools/gyp/v8.gyp

=======================================
--- /dev/null
+++ /branches/bleeding_edge/src/heap/store-buffer-inl.h Mon Aug 11 14:22:24 2014 UTC
@@ -0,0 +1,63 @@
+// Copyright 2011 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef V8_STORE_BUFFER_INL_H_
+#define V8_STORE_BUFFER_INL_H_
+
+#include "src/heap/store-buffer.h"
+
+namespace v8 {
+namespace internal {
+
+Address StoreBuffer::TopAddress() {
+  return reinterpret_cast<Address>(heap_->store_buffer_top_address());
+}
+
+
+void StoreBuffer::Mark(Address addr) {
+  DCHECK(!heap_->cell_space()->Contains(addr));
+  DCHECK(!heap_->code_space()->Contains(addr));
+  DCHECK(!heap_->old_data_space()->Contains(addr));
+  Address* top = reinterpret_cast<Address*>(heap_->store_buffer_top());
+  *top++ = addr;
+  heap_->public_set_store_buffer_top(top);
+  if ((reinterpret_cast<uintptr_t>(top) & kStoreBufferOverflowBit) != 0) {
+    DCHECK(top == limit_);
+    Compact();
+  } else {
+    DCHECK(top < limit_);
+  }
+}
+
+
+void StoreBuffer::EnterDirectlyIntoStoreBuffer(Address addr) {
+  if (store_buffer_rebuilding_enabled_) {
+    SLOW_DCHECK(!heap_->cell_space()->Contains(addr) &&
+                !heap_->code_space()->Contains(addr) &&
+                !heap_->old_data_space()->Contains(addr) &&
+                !heap_->new_space()->Contains(addr));
+    Address* top = old_top_;
+    *top++ = addr;
+    old_top_ = top;
+    old_buffer_is_sorted_ = false;
+    old_buffer_is_filtered_ = false;
+    if (top >= old_limit_) {
+      DCHECK(callback_ != NULL);
+      (*callback_)(heap_, MemoryChunk::FromAnyPointerAddress(heap_, addr),
+                   kStoreBufferFullEvent);
+    }
+  }
+}
+
+
+void StoreBuffer::ClearDeadObject(HeapObject* object) {
+  Address& map_field = Memory::Address_at(object->address());
+  if (heap_->map_space()->Contains(map_field)) {
+    map_field = NULL;
+  }
+}
+}
+}  // namespace v8::internal
+
+#endif  // V8_STORE_BUFFER_INL_H_
=======================================
--- /dev/null
+++ /branches/bleeding_edge/src/heap/store-buffer.cc Mon Aug 11 14:22:24 2014 UTC
@@ -0,0 +1,589 @@
+// Copyright 2011 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <algorithm>
+
+#include "src/v8.h"
+
+#include "src/base/atomicops.h"
+#include "src/counters.h"
+#include "src/heap/store-buffer-inl.h"
+
+namespace v8 {
+namespace internal {
+
+StoreBuffer::StoreBuffer(Heap* heap)
+    : heap_(heap),
+      start_(NULL),
+      limit_(NULL),
+      old_start_(NULL),
+      old_limit_(NULL),
+      old_top_(NULL),
+      old_reserved_limit_(NULL),
+      old_buffer_is_sorted_(false),
+      old_buffer_is_filtered_(false),
+      during_gc_(false),
+      store_buffer_rebuilding_enabled_(false),
+      callback_(NULL),
+      may_move_store_buffer_entries_(true),
+      virtual_memory_(NULL),
+      hash_set_1_(NULL),
+      hash_set_2_(NULL),
+      hash_sets_are_empty_(true) {}
+
+
+void StoreBuffer::SetUp() {
+  virtual_memory_ = new base::VirtualMemory(kStoreBufferSize * 3);
+  uintptr_t start_as_int =
+      reinterpret_cast<uintptr_t>(virtual_memory_->address());
+  start_ =
+ reinterpret_cast<Address*>(RoundUp(start_as_int, kStoreBufferSize * 2));
+  limit_ = start_ + (kStoreBufferSize / kPointerSize);
+
+  old_virtual_memory_ =
+      new base::VirtualMemory(kOldStoreBufferLength * kPointerSize);
+  old_top_ = old_start_ =
+      reinterpret_cast<Address*>(old_virtual_memory_->address());
+ // Don't know the alignment requirements of the OS, but it is certainly not
+  // less than 0xfff.
+  DCHECK((reinterpret_cast<uintptr_t>(old_start_) & 0xfff) == 0);
+  int initial_length =
+      static_cast<int>(base::OS::CommitPageSize() / kPointerSize);
+  DCHECK(initial_length > 0);
+  DCHECK(initial_length <= kOldStoreBufferLength);
+  old_limit_ = old_start_ + initial_length;
+  old_reserved_limit_ = old_start_ + kOldStoreBufferLength;
+
+  CHECK(old_virtual_memory_->Commit(reinterpret_cast<void*>(old_start_),
+ (old_limit_ - old_start_) * kPointerSize,
+                                    false));
+
+  DCHECK(reinterpret_cast<Address>(start_) >= virtual_memory_->address());
+  DCHECK(reinterpret_cast<Address>(limit_) >= virtual_memory_->address());
+  Address* vm_limit = reinterpret_cast<Address*>(
+      reinterpret_cast<char*>(virtual_memory_->address()) +
+      virtual_memory_->size());
+  DCHECK(start_ <= vm_limit);
+  DCHECK(limit_ <= vm_limit);
+  USE(vm_limit);
+ DCHECK((reinterpret_cast<uintptr_t>(limit_) & kStoreBufferOverflowBit) != 0); + DCHECK((reinterpret_cast<uintptr_t>(limit_ - 1) & kStoreBufferOverflowBit) ==
+         0);
+
+  CHECK(virtual_memory_->Commit(reinterpret_cast<Address>(start_),
+                                kStoreBufferSize,
+                                false));  // Not executable.
+  heap_->public_set_store_buffer_top(start_);
+
+  hash_set_1_ = new uintptr_t[kHashSetLength];
+  hash_set_2_ = new uintptr_t[kHashSetLength];
+  hash_sets_are_empty_ = false;
+
+  ClearFilteringHashSets();
+}
+
+
+void StoreBuffer::TearDown() {
+  delete virtual_memory_;
+  delete old_virtual_memory_;
+  delete[] hash_set_1_;
+  delete[] hash_set_2_;
+  old_start_ = old_top_ = old_limit_ = old_reserved_limit_ = NULL;
+  start_ = limit_ = NULL;
+  heap_->public_set_store_buffer_top(start_);
+}
+
+
+void StoreBuffer::StoreBufferOverflow(Isolate* isolate) {
+  isolate->heap()->store_buffer()->Compact();
+  isolate->counters()->store_buffer_overflows()->Increment();
+}
+
+
+void StoreBuffer::Uniq() {
+  // Remove adjacent duplicates and cells that do not point at new space.
+  Address previous = NULL;
+  Address* write = old_start_;
+  DCHECK(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<Object**>(current))) {
+        *write++ = current;
+      }
+    }
+    previous = current;
+  }
+  old_top_ = write;
+}
+
+
+bool StoreBuffer::SpaceAvailable(intptr_t space_needed) {
+  return old_limit_ - old_top_ >= space_needed;
+}
+
+
+void StoreBuffer::EnsureSpace(intptr_t space_needed) {
+  while (old_limit_ - old_top_ < space_needed &&
+         old_limit_ < old_reserved_limit_) {
+    size_t grow = old_limit_ - old_start_;  // Double size.
+    CHECK(old_virtual_memory_->Commit(reinterpret_cast<void*>(old_limit_),
+                                      grow * kPointerSize, false));
+    old_limit_ += grow;
+  }
+
+  if (SpaceAvailable(space_needed)) return;
+
+  if (old_buffer_is_filtered_) return;
+  DCHECK(may_move_store_buffer_entries_);
+  Compact();
+
+  old_buffer_is_filtered_ = true;
+  bool page_has_scan_on_scavenge_flag = false;
+
+  PointerChunkIterator it(heap_);
+  MemoryChunk* chunk;
+  while ((chunk = it.next()) != NULL) {
+    if (chunk->scan_on_scavenge()) {
+      page_has_scan_on_scavenge_flag = true;
+      break;
+    }
+  }
+
+  if (page_has_scan_on_scavenge_flag) {
+    Filter(MemoryChunk::SCAN_ON_SCAVENGE);
+  }
+
+  if (SpaceAvailable(space_needed)) return;
+
+ // Sample 1 entry in 97 and filter out the pages where we estimate that more
+  // than 1 in 8 pointers are to new space.
+  static const int kSampleFinenesses = 5;
+  static const struct Samples {
+    int prime_sample_step;
+    int threshold;
+  } samples[kSampleFinenesses] = {
+        {97, ((Page::kPageSize / kPointerSize) / 97) / 8},
+        {23, ((Page::kPageSize / kPointerSize) / 23) / 16},
+        {7, ((Page::kPageSize / kPointerSize) / 7) / 32},
+        {3, ((Page::kPageSize / kPointerSize) / 3) / 256},
+        {1, 0}};
+  for (int i = 0; i < kSampleFinenesses; i++) {
+    ExemptPopularPages(samples[i].prime_sample_step, samples[i].threshold);
+ // As a last resort we mark all pages as being exempt from the store buffer.
+    DCHECK(i != (kSampleFinenesses - 1) || old_top_ == old_start_);
+    if (SpaceAvailable(space_needed)) return;
+  }
+  UNREACHABLE();
+}
+
+
+// Sample the store buffer to see if some pages are taking up a lot of space
+// in the store buffer.
+void StoreBuffer::ExemptPopularPages(int prime_sample_step, int threshold) {
+  PointerChunkIterator it(heap_);
+  MemoryChunk* chunk;
+  while ((chunk = it.next()) != NULL) {
+    chunk->set_store_buffer_counter(0);
+  }
+  bool created_new_scan_on_scavenge_pages = false;
+  MemoryChunk* previous_chunk = NULL;
+  for (Address* p = old_start_; p < old_top_; p += prime_sample_step) {
+    Address addr = *p;
+    MemoryChunk* containing_chunk = NULL;
+    if (previous_chunk != NULL && previous_chunk->Contains(addr)) {
+      containing_chunk = previous_chunk;
+    } else {
+      containing_chunk = MemoryChunk::FromAnyPointerAddress(heap_, addr);
+    }
+    int old_counter = containing_chunk->store_buffer_counter();
+    if (old_counter >= threshold) {
+      containing_chunk->set_scan_on_scavenge(true);
+      created_new_scan_on_scavenge_pages = true;
+    }
+    containing_chunk->set_store_buffer_counter(old_counter + 1);
+    previous_chunk = containing_chunk;
+  }
+  if (created_new_scan_on_scavenge_pages) {
+    Filter(MemoryChunk::SCAN_ON_SCAVENGE);
+  }
+  old_buffer_is_filtered_ = true;
+}
+
+
+void StoreBuffer::Filter(int flag) {
+  Address* new_top = old_start_;
+  MemoryChunk* previous_chunk = NULL;
+  for (Address* p = old_start_; p < old_top_; p++) {
+    Address addr = *p;
+    MemoryChunk* containing_chunk = NULL;
+    if (previous_chunk != NULL && previous_chunk->Contains(addr)) {
+      containing_chunk = previous_chunk;
+    } else {
+      containing_chunk = MemoryChunk::FromAnyPointerAddress(heap_, addr);
+      previous_chunk = containing_chunk;
+    }
+    if (!containing_chunk->IsFlagSet(flag)) {
+      *new_top++ = addr;
+    }
+  }
+  old_top_ = new_top;
+
+  // Filtering hash sets are inconsistent with the store buffer after this
+  // operation.
+  ClearFilteringHashSets();
+}
+
+
+void StoreBuffer::SortUniq() {
+  Compact();
+  if (old_buffer_is_sorted_) return;
+  std::sort(old_start_, old_top_);
+  Uniq();
+
+  old_buffer_is_sorted_ = true;
+
+  // Filtering hash sets are inconsistent with the store buffer after this
+  // operation.
+  ClearFilteringHashSets();
+}
+
+
+bool StoreBuffer::PrepareForIteration() {
+  Compact();
+  PointerChunkIterator it(heap_);
+  MemoryChunk* chunk;
+  bool page_has_scan_on_scavenge_flag = false;
+  while ((chunk = it.next()) != NULL) {
+    if (chunk->scan_on_scavenge()) {
+      page_has_scan_on_scavenge_flag = true;
+      break;
+    }
+  }
+
+  if (page_has_scan_on_scavenge_flag) {
+    Filter(MemoryChunk::SCAN_ON_SCAVENGE);
+  }
+
+  // Filtering hash sets are inconsistent with the store buffer after
+  // iteration.
+  ClearFilteringHashSets();
+
+  return page_has_scan_on_scavenge_flag;
+}
+
+
+#ifdef DEBUG
+void StoreBuffer::Clean() {
+  ClearFilteringHashSets();
+  Uniq();  // Also removes things that no longer point to new space.
+  EnsureSpace(kStoreBufferSize / 2);
+}
+
+
+static Address* in_store_buffer_1_element_cache = NULL;
+
+
+bool StoreBuffer::CellIsInStoreBuffer(Address cell_address) {
+  if (!FLAG_enable_slow_asserts) return true;
+  if (in_store_buffer_1_element_cache != NULL &&
+      *in_store_buffer_1_element_cache == cell_address) {
+    return true;
+  }
+  Address* top = reinterpret_cast<Address*>(heap_->store_buffer_top());
+  for (Address* current = top - 1; current >= start_; current--) {
+    if (*current == cell_address) {
+      in_store_buffer_1_element_cache = current;
+      return true;
+    }
+  }
+  for (Address* current = old_top_ - 1; current >= old_start_; current--) {
+    if (*current == cell_address) {
+      in_store_buffer_1_element_cache = current;
+      return true;
+    }
+  }
+  return false;
+}
+#endif
+
+
+void StoreBuffer::ClearFilteringHashSets() {
+  if (!hash_sets_are_empty_) {
+    memset(reinterpret_cast<void*>(hash_set_1_), 0,
+           sizeof(uintptr_t) * kHashSetLength);
+    memset(reinterpret_cast<void*>(hash_set_2_), 0,
+           sizeof(uintptr_t) * kHashSetLength);
+    hash_sets_are_empty_ = true;
+  }
+}
+
+
+void StoreBuffer::GCPrologue() {
+  ClearFilteringHashSets();
+  during_gc_ = true;
+}
+
+
+#ifdef VERIFY_HEAP
+void StoreBuffer::VerifyPointers(LargeObjectSpace* space) {
+  LargeObjectIterator it(space);
+ for (HeapObject* object = it.Next(); object != NULL; object = it.Next()) {
+    if (object->IsFixedArray()) {
+      Address slot_address = object->address();
+      Address end = object->address() + object->Size();
+
+      while (slot_address < end) {
+        HeapObject** slot = reinterpret_cast<HeapObject**>(slot_address);
+        // When we are not in GC the Heap::InNewSpace() predicate
+        // checks that pointers which satisfy predicate point into
+        // the active semispace.
+        Object* object = reinterpret_cast<Object*>(
+ base::NoBarrier_Load(reinterpret_cast<base::AtomicWord*>(slot)));
+        heap_->InNewSpace(object);
+        slot_address += kPointerSize;
+      }
+    }
+  }
+}
+#endif
+
+
+void StoreBuffer::Verify() {
+#ifdef VERIFY_HEAP
+  VerifyPointers(heap_->lo_space());
+#endif
+}
+
+
+void StoreBuffer::GCEpilogue() {
+  during_gc_ = false;
+#ifdef VERIFY_HEAP
+  if (FLAG_verify_heap) {
+    Verify();
+  }
+#endif
+}
+
+
+void StoreBuffer::FindPointersToNewSpaceInRegion(
+    Address start, Address end, ObjectSlotCallback slot_callback,
+    bool clear_maps) {
+  for (Address slot_address = start; slot_address < end;
+       slot_address += kPointerSize) {
+    Object** slot = reinterpret_cast<Object**>(slot_address);
+    Object* object = reinterpret_cast<Object*>(
+        base::NoBarrier_Load(reinterpret_cast<base::AtomicWord*>(slot)));
+    if (heap_->InNewSpace(object)) {
+      HeapObject* heap_object = reinterpret_cast<HeapObject*>(object);
+      DCHECK(heap_object->IsHeapObject());
+      // The new space object was not promoted if it still contains a map
+      // pointer. Clear the map field now lazily.
+      if (clear_maps) ClearDeadObject(heap_object);
+      slot_callback(reinterpret_cast<HeapObject**>(slot), heap_object);
+      object = reinterpret_cast<Object*>(
+          base::NoBarrier_Load(reinterpret_cast<base::AtomicWord*>(slot)));
+      if (heap_->InNewSpace(object)) {
+        EnterDirectlyIntoStoreBuffer(slot_address);
+      }
+    }
+  }
+}
+
+
+void StoreBuffer::IteratePointersInStoreBuffer(ObjectSlotCallback slot_callback,
+                                               bool clear_maps) {
+  Address* limit = old_top_;
+  old_top_ = old_start_;
+  {
+    DontMoveStoreBufferEntriesScope scope(this);
+    for (Address* current = old_start_; current < limit; current++) {
+#ifdef DEBUG
+      Address* saved_top = old_top_;
+#endif
+      Object** slot = reinterpret_cast<Object**>(*current);
+      Object* object = reinterpret_cast<Object*>(
+          base::NoBarrier_Load(reinterpret_cast<base::AtomicWord*>(slot)));
+      if (heap_->InFromSpace(object)) {
+        HeapObject* heap_object = reinterpret_cast<HeapObject*>(object);
+        // The new space object was not promoted if it still contains a map
+        // pointer. Clear the map field now lazily.
+        if (clear_maps) ClearDeadObject(heap_object);
+        slot_callback(reinterpret_cast<HeapObject**>(slot), heap_object);
+        object = reinterpret_cast<Object*>(
+ base::NoBarrier_Load(reinterpret_cast<base::AtomicWord*>(slot)));
+        if (heap_->InNewSpace(object)) {
+          EnterDirectlyIntoStoreBuffer(reinterpret_cast<Address>(slot));
+        }
+      }
+      DCHECK(old_top_ == saved_top + 1 || old_top_ == saved_top);
+    }
+  }
+}
+
+
+void StoreBuffer::IteratePointersToNewSpace(ObjectSlotCallback slot_callback) {
+  IteratePointersToNewSpace(slot_callback, false);
+}
+
+
+void StoreBuffer::IteratePointersToNewSpaceAndClearMaps(
+    ObjectSlotCallback slot_callback) {
+  IteratePointersToNewSpace(slot_callback, true);
+}
+
+
+void StoreBuffer::IteratePointersToNewSpace(ObjectSlotCallback slot_callback,
+                                            bool clear_maps) {
+ // We do not sort or remove duplicated entries from the store buffer because
+  // we expect that callback will rebuild the store buffer thus removing
+  // all duplicates and pointers to old space.
+  bool some_pages_to_scan = PrepareForIteration();
+
+  // TODO(gc): we want to skip slots on evacuation candidates
+  // but we can't simply figure that out from slot address
+  // because slot can belong to a large object.
+  IteratePointersInStoreBuffer(slot_callback, clear_maps);
+
+ // We are done scanning all the pointers that were in the store buffer, but + // there may be some pages marked scan_on_scavenge that have pointers to new
+  // space that are not in the store buffer.  We must scan them now.  As we
+  // scan, the surviving pointers to new space will be added to the store
+ // buffer. If there are still a lot of pointers to new space then we will + // keep the scan_on_scavenge flag on the page and discard the pointers that
+  // were added to the store buffer.  If there are not many pointers to new
+ // space left on the page we will keep the pointers in the store buffer and
+  // remove the flag from the page.
+  if (some_pages_to_scan) {
+    if (callback_ != NULL) {
+      (*callback_)(heap_, NULL, kStoreBufferStartScanningPagesEvent);
+    }
+    PointerChunkIterator it(heap_);
+    MemoryChunk* chunk;
+    while ((chunk = it.next()) != NULL) {
+      if (chunk->scan_on_scavenge()) {
+        chunk->set_scan_on_scavenge(false);
+        if (callback_ != NULL) {
+          (*callback_)(heap_, chunk, kStoreBufferScanningPageEvent);
+        }
+        if (chunk->owner() == heap_->lo_space()) {
+          LargePage* large_page = reinterpret_cast<LargePage*>(chunk);
+          HeapObject* array = large_page->GetObject();
+          DCHECK(array->IsFixedArray());
+          Address start = array->address();
+          Address end = start + array->Size();
+ FindPointersToNewSpaceInRegion(start, end, slot_callback, clear_maps);
+        } else {
+          Page* page = reinterpret_cast<Page*>(chunk);
+          PagedSpace* owner = reinterpret_cast<PagedSpace*>(page->owner());
+          Address start = page->area_start();
+          Address end = page->area_end();
+          if (owner == heap_->map_space()) {
+            DCHECK(page->WasSweptPrecisely());
+            HeapObjectIterator iterator(page, NULL);
+ for (HeapObject* heap_object = iterator.Next(); heap_object != NULL;
+                 heap_object = iterator.Next()) {
+              // We skip free space objects.
+              if (!heap_object->IsFiller()) {
+                FindPointersToNewSpaceInRegion(
+                    heap_object->address() + HeapObject::kHeaderSize,
+ heap_object->address() + heap_object->Size(), slot_callback,
+                    clear_maps);
+              }
+            }
+          } else {
+            if (!page->SweepingCompleted()) {
+ heap_->mark_compact_collector()->SweepInParallel(page, owner);
+              if (!page->SweepingCompleted()) {
+                // We were not able to sweep that page, i.e., a concurrent
+                // sweeper thread currently owns this page.
+                // TODO(hpayer): This may introduce a huge pause here. We
+ // just care about finish sweeping of the scan on scavenge page.
+                heap_->mark_compact_collector()->EnsureSweepingCompleted();
+              }
+            }
+ // TODO(hpayer): remove the special casing and merge map and pointer
+            // space handling as soon as we removed conservative sweeping.
+            CHECK(page->owner() == heap_->old_pointer_space());
+            if (heap_->old_pointer_space()->swept_precisely()) {
+              HeapObjectIterator iterator(page, NULL);
+              for (HeapObject* heap_object = iterator.Next();
+                   heap_object != NULL; heap_object = iterator.Next()) {
+ // We iterate over objects that contain new space pointers only.
+                if (heap_object->MayContainNewSpacePointers()) {
+                  FindPointersToNewSpaceInRegion(
+                      heap_object->address() + HeapObject::kHeaderSize,
+                      heap_object->address() + heap_object->Size(),
+                      slot_callback, clear_maps);
+                }
+              }
+            } else {
+              FindPointersToNewSpaceInRegion(start, end, slot_callback,
+                                             clear_maps);
+            }
+          }
+        }
+      }
+    }
+    if (callback_ != NULL) {
+      (*callback_)(heap_, NULL, kStoreBufferScanningPageEvent);
+    }
+  }
+}
+
+
+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).
+  DCHECK(top <= limit_);
+  heap_->public_set_store_buffer_top(start_);
+  EnsureSpace(top - start_);
+  DCHECK(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 sets with different hash
+  // functions to reduce the number of unnecessary clashes.
+  hash_sets_are_empty_ = false;  // Hash sets are in use.
+  for (Address* current = start_; current < top; current++) {
+    DCHECK(!heap_->cell_space()->Contains(*current));
+    DCHECK(!heap_->code_space()->Contains(*current));
+    DCHECK(!heap_->old_data_space()->Contains(*current));
+    uintptr_t int_addr = reinterpret_cast<uintptr_t>(*current);
+    // Shift out the last bits including any tags.
+    int_addr >>= kPointerSizeLog2;
+ // The upper part of an address is basically random because of ASLR and OS + // non-determinism, so we use only the bits within a page for hashing to
+    // make v8's behavior (more) deterministic.
+    uintptr_t hash_addr =
+        int_addr & (Page::kPageAlignmentMask >> kPointerSizeLog2);
+    int hash1 = ((hash_addr ^ (hash_addr >> kHashSetLengthLog2)) &
+                 (kHashSetLength - 1));
+    if (hash_set_1_[hash1] == int_addr) continue;
+    uintptr_t hash2 = (hash_addr - (hash_addr >> kHashSetLengthLog2));
+    hash2 ^= hash2 >> (kHashSetLengthLog2 * 2);
+    hash2 &= (kHashSetLength - 1);
+    if (hash_set_2_[hash2] == int_addr) continue;
+    if (hash_set_1_[hash1] == 0) {
+      hash_set_1_[hash1] = int_addr;
+    } else if (hash_set_2_[hash2] == 0) {
+      hash_set_2_[hash2] = int_addr;
+    } else {
+ // Rather than slowing down we just throw away some entries. This will
+      // cause some duplicates to remain undetected.
+      hash_set_1_[hash1] = int_addr;
+      hash_set_2_[hash2] = 0;
+    }
+    old_buffer_is_sorted_ = false;
+    old_buffer_is_filtered_ = false;
+    *old_top_++ = reinterpret_cast<Address>(int_addr << kPointerSizeLog2);
+    DCHECK(old_top_ <= old_limit_);
+  }
+  heap_->isolate()->counters()->store_buffer_compactions()->Increment();
+}
+}
+}  // namespace v8::internal
=======================================
--- /dev/null
+++ /branches/bleeding_edge/src/heap/store-buffer.h Mon Aug 11 14:22:24 2014 UTC
@@ -0,0 +1,221 @@
+// Copyright 2011 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef V8_STORE_BUFFER_H_
+#define V8_STORE_BUFFER_H_
+
+#include "src/allocation.h"
+#include "src/base/logging.h"
+#include "src/base/platform/platform.h"
+#include "src/globals.h"
+
+namespace v8 {
+namespace internal {
+
+class Page;
+class PagedSpace;
+class StoreBuffer;
+
+typedef void (*ObjectSlotCallback)(HeapObject** from, HeapObject* to);
+
+typedef void (StoreBuffer::*RegionCallback)(Address start, Address end,
+ ObjectSlotCallback slot_callback,
+                                            bool clear_maps);
+
+// Used to implement the write barrier by collecting addresses of pointers
+// between spaces.
+class StoreBuffer {
+ public:
+  explicit StoreBuffer(Heap* heap);
+
+  static void StoreBufferOverflow(Isolate* isolate);
+
+  inline Address TopAddress();
+
+  void SetUp();
+  void TearDown();
+
+  // This is used by the mutator to enter addresses into the store buffer.
+  inline void Mark(Address addr);
+
+ // This is used by the heap traversal to enter the addresses into the store
+  // buffer that should still be in the store buffer after GC.  It enters
+ // addresses directly into the old buffer because the GC starts by wiping the + // old buffer and thereafter only visits each cell once so there is no need
+  // to attempt to remove any dupes.  During the first part of a GC we
+ // are using the store buffer to access the old spaces and at the same time + // we are rebuilding the store buffer using this function. There is, however
+  // no issue of overwriting the buffer we are iterating over, because this
+ // stage of the scavenge can only reduce the number of addresses in the store + // buffer (some objects are promoted so pointers to them do not need to be in
+  // the store buffer).  The later parts of the GC scan the pages that are
+ // exempt from the store buffer and process the promotion queue. These steps + // can overflow this buffer. We check for this and on overflow we call the
+  // callback set up with the StoreBufferRebuildScope object.
+  inline void EnterDirectlyIntoStoreBuffer(Address addr);
+
+ // Iterates over all pointers that go from old space to new space. It will
+  // delete the store buffer as it starts so the callback should reenter
+  // surviving old-to-new pointers into the store buffer to rebuild it.
+  void IteratePointersToNewSpace(ObjectSlotCallback callback);
+
+ // Same as IteratePointersToNewSpace but additonally clears maps in objects + // referenced from the store buffer that do not contain a forwarding pointer.
+  void IteratePointersToNewSpaceAndClearMaps(ObjectSlotCallback callback);
+
+  static const int kStoreBufferOverflowBit = 1 << (14 + kPointerSizeLog2);
+  static const int kStoreBufferSize = kStoreBufferOverflowBit;
+  static const int kStoreBufferLength = kStoreBufferSize / sizeof(Address);
+  static const int kOldStoreBufferLength = kStoreBufferLength * 16;
+  static const int kHashSetLengthLog2 = 12;
+  static const int kHashSetLength = 1 << kHashSetLengthLog2;
+
+  void Compact();
+
+  void GCPrologue();
+  void GCEpilogue();
+
+  Object*** Limit() { return reinterpret_cast<Object***>(old_limit_); }
+  Object*** Start() { return reinterpret_cast<Object***>(old_start_); }
+  Object*** Top() { return reinterpret_cast<Object***>(old_top_); }
+  void SetTop(Object*** top) {
+    DCHECK(top >= Start());
+    DCHECK(top <= Limit());
+    old_top_ = reinterpret_cast<Address*>(top);
+  }
+
+  bool old_buffer_is_sorted() { return old_buffer_is_sorted_; }
+  bool old_buffer_is_filtered() { return old_buffer_is_filtered_; }
+
+  // Goes through the store buffer removing pointers to things that have
+  // been promoted.  Rebuilds the store buffer completely if it overflowed.
+  void SortUniq();
+
+  void EnsureSpace(intptr_t space_needed);
+  void Verify();
+
+  bool PrepareForIteration();
+
+#ifdef DEBUG
+  void Clean();
+  // Slow, for asserts only.
+  bool CellIsInStoreBuffer(Address cell);
+#endif
+
+  void Filter(int flag);
+
+ private:
+  Heap* heap_;
+
+ // The store buffer is divided up into a new buffer that is constantly being + // filled by mutator activity and an old buffer that is filled with the data
+  // from the new buffer after compression.
+  Address* start_;
+  Address* limit_;
+
+  Address* old_start_;
+  Address* old_limit_;
+  Address* old_top_;
+  Address* old_reserved_limit_;
+  base::VirtualMemory* old_virtual_memory_;
+
+  bool old_buffer_is_sorted_;
+  bool old_buffer_is_filtered_;
+  bool during_gc_;
+ // The garbage collector iterates over many pointers to new space that are not
+  // handled by the store buffer.  This flag indicates whether the pointers
+  // found by the callbacks should be added to the store buffer or not.
+  bool store_buffer_rebuilding_enabled_;
+  StoreBufferCallback callback_;
+  bool may_move_store_buffer_entries_;
+
+  base::VirtualMemory* virtual_memory_;
+
+  // Two hash sets used for filtering.
+  // If address is in the hash set then it is guaranteed to be in the
+  // old part of the store buffer.
+  uintptr_t* hash_set_1_;
+  uintptr_t* hash_set_2_;
+  bool hash_sets_are_empty_;
+
+  void ClearFilteringHashSets();
+
+  bool SpaceAvailable(intptr_t space_needed);
+  void Uniq();
+  void ExemptPopularPages(int prime_sample_step, int threshold);
+
+  // Set the map field of the object to NULL if contains a map.
+  inline void ClearDeadObject(HeapObject* object);
+
+ void IteratePointersToNewSpace(ObjectSlotCallback callback, bool clear_maps);
+
+  void FindPointersToNewSpaceInRegion(Address start, Address end,
+                                      ObjectSlotCallback slot_callback,
+                                      bool clear_maps);
+
+  // For each region of pointers on a page in use from an old space call
+  // visit_pointer_region callback.
+  // If either visit_pointer_region or callback can cause an allocation
+  // in old space and changes in allocation watermark then
+  // can_preallocate_during_iteration should be set to true.
+  void IteratePointersOnPage(PagedSpace* space, Page* page,
+                             RegionCallback region_callback,
+                             ObjectSlotCallback slot_callback);
+
+  void IteratePointersInStoreBuffer(ObjectSlotCallback slot_callback,
+                                    bool clear_maps);
+
+#ifdef VERIFY_HEAP
+  void VerifyPointers(LargeObjectSpace* space);
+#endif
+
+  friend class StoreBufferRebuildScope;
+  friend class DontMoveStoreBufferEntriesScope;
+};
+
+
+class StoreBufferRebuildScope {
+ public:
+  explicit StoreBufferRebuildScope(Heap* heap, StoreBuffer* store_buffer,
+                                   StoreBufferCallback callback)
+      : store_buffer_(store_buffer),
+        stored_state_(store_buffer->store_buffer_rebuilding_enabled_),
+        stored_callback_(store_buffer->callback_) {
+    store_buffer_->store_buffer_rebuilding_enabled_ = true;
+    store_buffer_->callback_ = callback;
+    (*callback)(heap, NULL, kStoreBufferStartScanningPagesEvent);
+  }
+
+  ~StoreBufferRebuildScope() {
+    store_buffer_->callback_ = stored_callback_;
+    store_buffer_->store_buffer_rebuilding_enabled_ = stored_state_;
+  }
+
+ private:
+  StoreBuffer* store_buffer_;
+  bool stored_state_;
+  StoreBufferCallback stored_callback_;
+};
+
+
+class DontMoveStoreBufferEntriesScope {
+ public:
+  explicit DontMoveStoreBufferEntriesScope(StoreBuffer* store_buffer)
+      : store_buffer_(store_buffer),
+        stored_state_(store_buffer->may_move_store_buffer_entries_) {
+    store_buffer_->may_move_store_buffer_entries_ = false;
+  }
+
+  ~DontMoveStoreBufferEntriesScope() {
+    store_buffer_->may_move_store_buffer_entries_ = stored_state_;
+  }
+
+ private:
+  StoreBuffer* store_buffer_;
+  bool stored_state_;
+};
+}
+}  // namespace v8::internal
+
+#endif  // V8_STORE_BUFFER_H_
=======================================
--- /branches/bleeding_edge/src/store-buffer-inl.h Mon Aug 4 11:34:54 2014 UTC
+++ /dev/null
@@ -1,65 +0,0 @@
-// Copyright 2011 the V8 project authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef V8_STORE_BUFFER_INL_H_
-#define V8_STORE_BUFFER_INL_H_
-
-#include "src/store-buffer.h"
-
-namespace v8 {
-namespace internal {
-
-Address StoreBuffer::TopAddress() {
-  return reinterpret_cast<Address>(heap_->store_buffer_top_address());
-}
-
-
-void StoreBuffer::Mark(Address addr) {
-  DCHECK(!heap_->cell_space()->Contains(addr));
-  DCHECK(!heap_->code_space()->Contains(addr));
-  DCHECK(!heap_->old_data_space()->Contains(addr));
-  Address* top = reinterpret_cast<Address*>(heap_->store_buffer_top());
-  *top++ = addr;
-  heap_->public_set_store_buffer_top(top);
-  if ((reinterpret_cast<uintptr_t>(top) & kStoreBufferOverflowBit) != 0) {
-    DCHECK(top == limit_);
-    Compact();
-  } else {
-    DCHECK(top < limit_);
-  }
-}
-
-
-void StoreBuffer::EnterDirectlyIntoStoreBuffer(Address addr) {
-  if (store_buffer_rebuilding_enabled_) {
-    SLOW_DCHECK(!heap_->cell_space()->Contains(addr) &&
-                !heap_->code_space()->Contains(addr) &&
-                !heap_->old_data_space()->Contains(addr) &&
-                !heap_->new_space()->Contains(addr));
-    Address* top = old_top_;
-    *top++ = addr;
-    old_top_ = top;
-    old_buffer_is_sorted_ = false;
-    old_buffer_is_filtered_ = false;
-    if (top >= old_limit_) {
-      DCHECK(callback_ != NULL);
-      (*callback_)(heap_,
-                   MemoryChunk::FromAnyPointerAddress(heap_, addr),
-                   kStoreBufferFullEvent);
-    }
-  }
-}
-
-
-void StoreBuffer::ClearDeadObject(HeapObject* object) {
-  Address& map_field = Memory::Address_at(object->address());
-  if (heap_->map_space()->Contains(map_field)) {
-    map_field = NULL;
-  }
-}
-
-
-} }  // namespace v8::internal
-
-#endif  // V8_STORE_BUFFER_INL_H_
=======================================
--- /branches/bleeding_edge/src/store-buffer.cc Mon Aug  4 11:34:54 2014 UTC
+++ /dev/null
@@ -1,601 +0,0 @@
-// Copyright 2011 the V8 project authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "src/store-buffer.h"
-
-#include <algorithm>
-
-#include "src/v8.h"
-
-#include "src/base/atomicops.h"
-#include "src/counters.h"
-#include "src/store-buffer-inl.h"
-
-namespace v8 {
-namespace internal {
-
-StoreBuffer::StoreBuffer(Heap* heap)
-    : heap_(heap),
-      start_(NULL),
-      limit_(NULL),
-      old_start_(NULL),
-      old_limit_(NULL),
-      old_top_(NULL),
-      old_reserved_limit_(NULL),
-      old_buffer_is_sorted_(false),
-      old_buffer_is_filtered_(false),
-      during_gc_(false),
-      store_buffer_rebuilding_enabled_(false),
-      callback_(NULL),
-      may_move_store_buffer_entries_(true),
-      virtual_memory_(NULL),
-      hash_set_1_(NULL),
-      hash_set_2_(NULL),
-      hash_sets_are_empty_(true) {
-}
-
-
-void StoreBuffer::SetUp() {
-  virtual_memory_ = new base::VirtualMemory(kStoreBufferSize * 3);
-  uintptr_t start_as_int =
-      reinterpret_cast<uintptr_t>(virtual_memory_->address());
-  start_ =
- reinterpret_cast<Address*>(RoundUp(start_as_int, kStoreBufferSize * 2));
-  limit_ = start_ + (kStoreBufferSize / kPointerSize);
-
-  old_virtual_memory_ =
-      new base::VirtualMemory(kOldStoreBufferLength * kPointerSize);
-  old_top_ = old_start_ =
-      reinterpret_cast<Address*>(old_virtual_memory_->address());
- // Don't know the alignment requirements of the OS, but it is certainly not
-  // less than 0xfff.
-  DCHECK((reinterpret_cast<uintptr_t>(old_start_) & 0xfff) == 0);
-  int initial_length =
-      static_cast<int>(base::OS::CommitPageSize() / kPointerSize);
-  DCHECK(initial_length > 0);
-  DCHECK(initial_length <= kOldStoreBufferLength);
-  old_limit_ = old_start_ + initial_length;
-  old_reserved_limit_ = old_start_ + kOldStoreBufferLength;
-
-  CHECK(old_virtual_memory_->Commit(
-            reinterpret_cast<void*>(old_start_),
-            (old_limit_ - old_start_) * kPointerSize,
-            false));
-
-  DCHECK(reinterpret_cast<Address>(start_) >= virtual_memory_->address());
-  DCHECK(reinterpret_cast<Address>(limit_) >= virtual_memory_->address());
-  Address* vm_limit = reinterpret_cast<Address*>(
-      reinterpret_cast<char*>(virtual_memory_->address()) +
-          virtual_memory_->size());
-  DCHECK(start_ <= vm_limit);
-  DCHECK(limit_ <= vm_limit);
-  USE(vm_limit);
- DCHECK((reinterpret_cast<uintptr_t>(limit_) & kStoreBufferOverflowBit) != 0); - DCHECK((reinterpret_cast<uintptr_t>(limit_ - 1) & kStoreBufferOverflowBit) ==
-         0);
-
-  CHECK(virtual_memory_->Commit(reinterpret_cast<Address>(start_),
-                                kStoreBufferSize,
-                                false));  // Not executable.
-  heap_->public_set_store_buffer_top(start_);
-
-  hash_set_1_ = new uintptr_t[kHashSetLength];
-  hash_set_2_ = new uintptr_t[kHashSetLength];
-  hash_sets_are_empty_ = false;
-
-  ClearFilteringHashSets();
-}
-
-
-void StoreBuffer::TearDown() {
-  delete virtual_memory_;
-  delete old_virtual_memory_;
-  delete[] hash_set_1_;
-  delete[] hash_set_2_;
-  old_start_ = old_top_ = old_limit_ = old_reserved_limit_ = NULL;
-  start_ = limit_ = NULL;
-  heap_->public_set_store_buffer_top(start_);
-}
-
-
-void StoreBuffer::StoreBufferOverflow(Isolate* isolate) {
-  isolate->heap()->store_buffer()->Compact();
-  isolate->counters()->store_buffer_overflows()->Increment();
-}
-
-
-void StoreBuffer::Uniq() {
-  // Remove adjacent duplicates and cells that do not point at new space.
-  Address previous = NULL;
-  Address* write = old_start_;
-  DCHECK(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<Object**>(current))) {
-        *write++ = current;
-      }
-    }
-    previous = current;
-  }
-  old_top_ = write;
-}
-
-
-bool StoreBuffer::SpaceAvailable(intptr_t space_needed) {
-  return old_limit_ - old_top_ >= space_needed;
-}
-
-
-void StoreBuffer::EnsureSpace(intptr_t space_needed) {
-  while (old_limit_ - old_top_ < space_needed &&
-         old_limit_ < old_reserved_limit_) {
-    size_t grow = old_limit_ - old_start_;  // Double size.
-    CHECK(old_virtual_memory_->Commit(reinterpret_cast<void*>(old_limit_),
-                                      grow * kPointerSize,
-                                      false));
-    old_limit_ += grow;
-  }
-
-  if (SpaceAvailable(space_needed)) return;
-
-  if (old_buffer_is_filtered_) return;
-  DCHECK(may_move_store_buffer_entries_);
-  Compact();
-
-  old_buffer_is_filtered_ = true;
-  bool page_has_scan_on_scavenge_flag = false;
-
-  PointerChunkIterator it(heap_);
-  MemoryChunk* chunk;
-  while ((chunk = it.next()) != NULL) {
-    if (chunk->scan_on_scavenge()) {
-      page_has_scan_on_scavenge_flag = true;
-      break;
-    }
-  }
-
-  if (page_has_scan_on_scavenge_flag) {
-    Filter(MemoryChunk::SCAN_ON_SCAVENGE);
-  }
-
-  if (SpaceAvailable(space_needed)) return;
-
- // Sample 1 entry in 97 and filter out the pages where we estimate that more
-  // than 1 in 8 pointers are to new space.
-  static const int kSampleFinenesses = 5;
-  static const struct Samples {
-    int prime_sample_step;
-    int threshold;
-  } samples[kSampleFinenesses] =  {
-    { 97, ((Page::kPageSize / kPointerSize) / 97) / 8 },
-    { 23, ((Page::kPageSize / kPointerSize) / 23) / 16 },
-    { 7, ((Page::kPageSize / kPointerSize) / 7) / 32 },
-    { 3, ((Page::kPageSize / kPointerSize) / 3) / 256 },
-    { 1, 0}
-  };
-  for (int i = 0; i < kSampleFinenesses; i++) {
-    ExemptPopularPages(samples[i].prime_sample_step, samples[i].threshold);
- // As a last resort we mark all pages as being exempt from the store buffer.
-    DCHECK(i != (kSampleFinenesses - 1) || old_top_ == old_start_);
-    if (SpaceAvailable(space_needed)) return;
-  }
-  UNREACHABLE();
-}
-
-
-// Sample the store buffer to see if some pages are taking up a lot of space
-// in the store buffer.
-void StoreBuffer::ExemptPopularPages(int prime_sample_step, int threshold) {
-  PointerChunkIterator it(heap_);
-  MemoryChunk* chunk;
-  while ((chunk = it.next()) != NULL) {
-    chunk->set_store_buffer_counter(0);
-  }
-  bool created_new_scan_on_scavenge_pages = false;
-  MemoryChunk* previous_chunk = NULL;
-  for (Address* p = old_start_; p < old_top_; p += prime_sample_step) {
-    Address addr = *p;
-    MemoryChunk* containing_chunk = NULL;
-    if (previous_chunk != NULL && previous_chunk->Contains(addr)) {
-      containing_chunk = previous_chunk;
-    } else {
-      containing_chunk = MemoryChunk::FromAnyPointerAddress(heap_, addr);
-    }
-    int old_counter = containing_chunk->store_buffer_counter();
-    if (old_counter >= threshold) {
-      containing_chunk->set_scan_on_scavenge(true);
-      created_new_scan_on_scavenge_pages = true;
-    }
-    containing_chunk->set_store_buffer_counter(old_counter + 1);
-    previous_chunk = containing_chunk;
-  }
-  if (created_new_scan_on_scavenge_pages) {
-    Filter(MemoryChunk::SCAN_ON_SCAVENGE);
-  }
-  old_buffer_is_filtered_ = true;
-}
-
-
-void StoreBuffer::Filter(int flag) {
-  Address* new_top = old_start_;
-  MemoryChunk* previous_chunk = NULL;
-  for (Address* p = old_start_; p < old_top_; p++) {
-    Address addr = *p;
-    MemoryChunk* containing_chunk = NULL;
-    if (previous_chunk != NULL && previous_chunk->Contains(addr)) {
-      containing_chunk = previous_chunk;
-    } else {
-      containing_chunk = MemoryChunk::FromAnyPointerAddress(heap_, addr);
-      previous_chunk = containing_chunk;
-    }
-    if (!containing_chunk->IsFlagSet(flag)) {
-      *new_top++ = addr;
-    }
-  }
-  old_top_ = new_top;
-
-  // Filtering hash sets are inconsistent with the store buffer after this
-  // operation.
-  ClearFilteringHashSets();
-}
-
-
-void StoreBuffer::SortUniq() {
-  Compact();
-  if (old_buffer_is_sorted_) return;
-  std::sort(old_start_, old_top_);
-  Uniq();
-
-  old_buffer_is_sorted_ = true;
-
-  // Filtering hash sets are inconsistent with the store buffer after this
-  // operation.
-  ClearFilteringHashSets();
-}
-
-
-bool StoreBuffer::PrepareForIteration() {
-  Compact();
-  PointerChunkIterator it(heap_);
-  MemoryChunk* chunk;
-  bool page_has_scan_on_scavenge_flag = false;
-  while ((chunk = it.next()) != NULL) {
-    if (chunk->scan_on_scavenge()) {
-      page_has_scan_on_scavenge_flag = true;
-      break;
-    }
-  }
-
-  if (page_has_scan_on_scavenge_flag) {
-    Filter(MemoryChunk::SCAN_ON_SCAVENGE);
-  }
-
-  // Filtering hash sets are inconsistent with the store buffer after
-  // iteration.
-  ClearFilteringHashSets();
-
-  return page_has_scan_on_scavenge_flag;
-}
-
-
-#ifdef DEBUG
-void StoreBuffer::Clean() {
-  ClearFilteringHashSets();
-  Uniq();  // Also removes things that no longer point to new space.
-  EnsureSpace(kStoreBufferSize / 2);
-}
-
-
-static Address* in_store_buffer_1_element_cache = NULL;
-
-
-bool StoreBuffer::CellIsInStoreBuffer(Address cell_address) {
-  if (!FLAG_enable_slow_asserts) return true;
-  if (in_store_buffer_1_element_cache != NULL &&
-      *in_store_buffer_1_element_cache == cell_address) {
-    return true;
-  }
-  Address* top = reinterpret_cast<Address*>(heap_->store_buffer_top());
-  for (Address* current = top - 1; current >= start_; current--) {
-    if (*current == cell_address) {
-      in_store_buffer_1_element_cache = current;
-      return true;
-    }
-  }
-  for (Address* current = old_top_ - 1; current >= old_start_; current--) {
-    if (*current == cell_address) {
-      in_store_buffer_1_element_cache = current;
-      return true;
-    }
-  }
-  return false;
-}
-#endif
-
-
-void StoreBuffer::ClearFilteringHashSets() {
-  if (!hash_sets_are_empty_) {
-    memset(reinterpret_cast<void*>(hash_set_1_),
-           0,
-           sizeof(uintptr_t) * kHashSetLength);
-    memset(reinterpret_cast<void*>(hash_set_2_),
-           0,
-           sizeof(uintptr_t) * kHashSetLength);
-    hash_sets_are_empty_ = true;
-  }
-}
-
-
-void StoreBuffer::GCPrologue() {
-  ClearFilteringHashSets();
-  during_gc_ = true;
-}
-
-
-#ifdef VERIFY_HEAP
-void StoreBuffer::VerifyPointers(LargeObjectSpace* space) {
-  LargeObjectIterator it(space);
- for (HeapObject* object = it.Next(); object != NULL; object = it.Next()) {
-    if (object->IsFixedArray()) {
-      Address slot_address = object->address();
-      Address end = object->address() + object->Size();
-
-      while (slot_address < end) {
-        HeapObject** slot = reinterpret_cast<HeapObject**>(slot_address);
-        // When we are not in GC the Heap::InNewSpace() predicate
-        // checks that pointers which satisfy predicate point into
-        // the active semispace.
-        Object* object = reinterpret_cast<Object*>(
- base::NoBarrier_Load(reinterpret_cast<base::AtomicWord*>(slot)));
-        heap_->InNewSpace(object);
-        slot_address += kPointerSize;
-      }
-    }
-  }
-}
-#endif
-
-
-void StoreBuffer::Verify() {
-#ifdef VERIFY_HEAP
-  VerifyPointers(heap_->lo_space());
-#endif
-}
-
-
-void StoreBuffer::GCEpilogue() {
-  during_gc_ = false;
-#ifdef VERIFY_HEAP
-  if (FLAG_verify_heap) {
-    Verify();
-  }
-#endif
-}
-
-
-void StoreBuffer::FindPointersToNewSpaceInRegion(
-    Address start,
-    Address end,
-    ObjectSlotCallback slot_callback,
-    bool clear_maps) {
-  for (Address slot_address = start;
-       slot_address < end;
-       slot_address += kPointerSize) {
-    Object** slot = reinterpret_cast<Object**>(slot_address);
-    Object* object = reinterpret_cast<Object*>(
-        base::NoBarrier_Load(reinterpret_cast<base::AtomicWord*>(slot)));
-    if (heap_->InNewSpace(object)) {
-      HeapObject* heap_object = reinterpret_cast<HeapObject*>(object);
-      DCHECK(heap_object->IsHeapObject());
-      // The new space object was not promoted if it still contains a map
-      // pointer. Clear the map field now lazily.
-      if (clear_maps) ClearDeadObject(heap_object);
-      slot_callback(reinterpret_cast<HeapObject**>(slot), heap_object);
-      object = reinterpret_cast<Object*>(
-          base::NoBarrier_Load(reinterpret_cast<base::AtomicWord*>(slot)));
-      if (heap_->InNewSpace(object)) {
-        EnterDirectlyIntoStoreBuffer(slot_address);
-      }
-    }
-  }
-}
-
-
-void StoreBuffer::IteratePointersInStoreBuffer(
-    ObjectSlotCallback slot_callback,
-    bool clear_maps) {
-  Address* limit = old_top_;
-  old_top_ = old_start_;
-  {
-    DontMoveStoreBufferEntriesScope scope(this);
-    for (Address* current = old_start_; current < limit; current++) {
-#ifdef DEBUG
-      Address* saved_top = old_top_;
-#endif
-      Object** slot = reinterpret_cast<Object**>(*current);
-      Object* object = reinterpret_cast<Object*>(
-          base::NoBarrier_Load(reinterpret_cast<base::AtomicWord*>(slot)));
-      if (heap_->InFromSpace(object)) {
-        HeapObject* heap_object = reinterpret_cast<HeapObject*>(object);
-        // The new space object was not promoted if it still contains a map
-        // pointer. Clear the map field now lazily.
-        if (clear_maps) ClearDeadObject(heap_object);
-        slot_callback(reinterpret_cast<HeapObject**>(slot), heap_object);
-        object = reinterpret_cast<Object*>(
- base::NoBarrier_Load(reinterpret_cast<base::AtomicWord*>(slot)));
-        if (heap_->InNewSpace(object)) {
-          EnterDirectlyIntoStoreBuffer(reinterpret_cast<Address>(slot));
-        }
-      }
-      DCHECK(old_top_ == saved_top + 1 || old_top_ == saved_top);
-    }
-  }
-}
-
-
-void StoreBuffer::IteratePointersToNewSpace(ObjectSlotCallback slot_callback) {
-  IteratePointersToNewSpace(slot_callback, false);
-}
-
-
-void StoreBuffer::IteratePointersToNewSpaceAndClearMaps(
-    ObjectSlotCallback slot_callback) {
-  IteratePointersToNewSpace(slot_callback, true);
-}
-
-
-void StoreBuffer::IteratePointersToNewSpace(ObjectSlotCallback slot_callback,
-                                            bool clear_maps) {
- // We do not sort or remove duplicated entries from the store buffer because
-  // we expect that callback will rebuild the store buffer thus removing
-  // all duplicates and pointers to old space.
-  bool some_pages_to_scan = PrepareForIteration();
-
-  // TODO(gc): we want to skip slots on evacuation candidates
-  // but we can't simply figure that out from slot address
-  // because slot can belong to a large object.
-  IteratePointersInStoreBuffer(slot_callback, clear_maps);
-
- // We are done scanning all the pointers that were in the store buffer, but - // there may be some pages marked scan_on_scavenge that have pointers to new
-  // space that are not in the store buffer.  We must scan them now.  As we
-  // scan, the surviving pointers to new space will be added to the store
- // buffer. If there are still a lot of pointers to new space then we will - // keep the scan_on_scavenge flag on the page and discard the pointers that
-  // were added to the store buffer.  If there are not many pointers to new
- // space left on the page we will keep the pointers in the store buffer and
-  // remove the flag from the page.
-  if (some_pages_to_scan) {
-    if (callback_ != NULL) {
-      (*callback_)(heap_, NULL, kStoreBufferStartScanningPagesEvent);
-    }
-    PointerChunkIterator it(heap_);
-    MemoryChunk* chunk;
-    while ((chunk = it.next()) != NULL) {
-      if (chunk->scan_on_scavenge()) {
-        chunk->set_scan_on_scavenge(false);
-        if (callback_ != NULL) {
-          (*callback_)(heap_, chunk, kStoreBufferScanningPageEvent);
-        }
-        if (chunk->owner() == heap_->lo_space()) {
-          LargePage* large_page = reinterpret_cast<LargePage*>(chunk);
-          HeapObject* array = large_page->GetObject();
-          DCHECK(array->IsFixedArray());
-          Address start = array->address();
-          Address end = start + array->Size();
- FindPointersToNewSpaceInRegion(start, end, slot_callback, clear_maps);
-        } else {
-          Page* page = reinterpret_cast<Page*>(chunk);
-          PagedSpace* owner = reinterpret_cast<PagedSpace*>(page->owner());
-          Address start = page->area_start();
-          Address end = page->area_end();
-          if (owner == heap_->map_space()) {
-            DCHECK(page->WasSweptPrecisely());
-            HeapObjectIterator iterator(page, NULL);
- for (HeapObject* heap_object = iterator.Next(); heap_object != NULL;
-                 heap_object = iterator.Next()) {
-              // We skip free space objects.
-              if (!heap_object->IsFiller()) {
-                FindPointersToNewSpaceInRegion(
-                    heap_object->address() + HeapObject::kHeaderSize,
- heap_object->address() + heap_object->Size(), slot_callback,
-                    clear_maps);
-              }
-            }
-          } else {
-            if (!page->SweepingCompleted()) {
- heap_->mark_compact_collector()->SweepInParallel(page, owner);
-              if (!page->SweepingCompleted()) {
-                // We were not able to sweep that page, i.e., a concurrent
-                // sweeper thread currently owns this page.
-                // TODO(hpayer): This may introduce a huge pause here. We
- // just care about finish sweeping of the scan on scavenge page.
-                heap_->mark_compact_collector()->EnsureSweepingCompleted();
-              }
-            }
- // TODO(hpayer): remove the special casing and merge map and pointer
-            // space handling as soon as we removed conservative sweeping.
-            CHECK(page->owner() == heap_->old_pointer_space());
-            if (heap_->old_pointer_space()->swept_precisely()) {
-              HeapObjectIterator iterator(page, NULL);
-              for (HeapObject* heap_object = iterator.Next();
-                   heap_object != NULL; heap_object = iterator.Next()) {
- // We iterate over objects that contain new space pointers only.
-                if (heap_object->MayContainNewSpacePointers()) {
-                  FindPointersToNewSpaceInRegion(
-                      heap_object->address() + HeapObject::kHeaderSize,
-                      heap_object->address() + heap_object->Size(),
-                      slot_callback, clear_maps);
-                }
-              }
-            } else {
-              FindPointersToNewSpaceInRegion(start, end, slot_callback,
-                                             clear_maps);
-            }
-          }
-        }
-      }
-    }
-    if (callback_ != NULL) {
-      (*callback_)(heap_, NULL, kStoreBufferScanningPageEvent);
-    }
-  }
-}
-
-
-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).
-  DCHECK(top <= limit_);
-  heap_->public_set_store_buffer_top(start_);
-  EnsureSpace(top - start_);
-  DCHECK(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 sets with different hash
-  // functions to reduce the number of unnecessary clashes.
-  hash_sets_are_empty_ = false;  // Hash sets are in use.
-  for (Address* current = start_; current < top; current++) {
-    DCHECK(!heap_->cell_space()->Contains(*current));
-    DCHECK(!heap_->code_space()->Contains(*current));
-    DCHECK(!heap_->old_data_space()->Contains(*current));
-    uintptr_t int_addr = reinterpret_cast<uintptr_t>(*current);
-    // Shift out the last bits including any tags.
-    int_addr >>= kPointerSizeLog2;
- // The upper part of an address is basically random because of ASLR and OS - // non-determinism, so we use only the bits within a page for hashing to
-    // make v8's behavior (more) deterministic.
-    uintptr_t hash_addr =
-        int_addr & (Page::kPageAlignmentMask >> kPointerSizeLog2);
-    int hash1 = ((hash_addr ^ (hash_addr >> kHashSetLengthLog2)) &
-                 (kHashSetLength - 1));
-    if (hash_set_1_[hash1] == int_addr) continue;
-    uintptr_t hash2 = (hash_addr - (hash_addr >> kHashSetLengthLog2));
-    hash2 ^= hash2 >> (kHashSetLengthLog2 * 2);
-    hash2 &= (kHashSetLength - 1);
-    if (hash_set_2_[hash2] == int_addr) continue;
-    if (hash_set_1_[hash1] == 0) {
-      hash_set_1_[hash1] = int_addr;
-    } else if (hash_set_2_[hash2] == 0) {
-      hash_set_2_[hash2] = int_addr;
-    } else {
- // Rather than slowing down we just throw away some entries. This will
-      // cause some duplicates to remain undetected.
-      hash_set_1_[hash1] = int_addr;
-      hash_set_2_[hash2] = 0;
-    }
-    old_buffer_is_sorted_ = false;
-    old_buffer_is_filtered_ = false;
-    *old_top_++ = reinterpret_cast<Address>(int_addr << kPointerSizeLog2);
-    DCHECK(old_top_ <= old_limit_);
-  }
-  heap_->isolate()->counters()->store_buffer_compactions()->Increment();
-}
-
-} }  // namespace v8::internal
=======================================
--- /branches/bleeding_edge/src/store-buffer.h  Mon Aug  4 11:34:54 2014 UTC
+++ /dev/null
@@ -1,226 +0,0 @@
-// Copyright 2011 the V8 project authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef V8_STORE_BUFFER_H_
-#define V8_STORE_BUFFER_H_
-
-#include "src/allocation.h"
-#include "src/base/logging.h"
-#include "src/base/platform/platform.h"
-#include "src/globals.h"
-
-namespace v8 {
-namespace internal {
-
-class Page;
-class PagedSpace;
-class StoreBuffer;
-
-typedef void (*ObjectSlotCallback)(HeapObject** from, HeapObject* to);
-
-typedef void (StoreBuffer::*RegionCallback)(Address start,
-                                            Address end,
- ObjectSlotCallback slot_callback,
-                                            bool clear_maps);
-
-// Used to implement the write barrier by collecting addresses of pointers
-// between spaces.
-class StoreBuffer {
- public:
-  explicit StoreBuffer(Heap* heap);
-
-  static void StoreBufferOverflow(Isolate* isolate);
-
-  inline Address TopAddress();
-
-  void SetUp();
-  void TearDown();
-
-  // This is used by the mutator to enter addresses into the store buffer.
-  inline void Mark(Address addr);
-
- // This is used by the heap traversal to enter the addresses into the store
-  // buffer that should still be in the store buffer after GC.  It enters
- // addresses directly into the old buffer because the GC starts by wiping the - // old buffer and thereafter only visits each cell once so there is no need
-  // to attempt to remove any dupes.  During the first part of a GC we
- // are using the store buffer to access the old spaces and at the same time - // we are rebuilding the store buffer using this function. There is, however
-  // no issue of overwriting the buffer we are iterating over, because this
- // stage of the scavenge can only reduce the number of addresses in the store - // buffer (some objects are promoted so pointers to them do not need to be in
-  // the store buffer).  The later parts of the GC scan the pages that are
- // exempt from the store buffer and process the promotion queue. These steps - // can overflow this buffer. We check for this and on overflow we call the
-  // callback set up with the StoreBufferRebuildScope object.
-  inline void EnterDirectlyIntoStoreBuffer(Address addr);
-
- // Iterates over all pointers that go from old space to new space. It will
-  // delete the store buffer as it starts so the callback should reenter
-  // surviving old-to-new pointers into the store buffer to rebuild it.
-  void IteratePointersToNewSpace(ObjectSlotCallback callback);
-
- // Same as IteratePointersToNewSpace but additonally clears maps in objects - // referenced from the store buffer that do not contain a forwarding pointer.
-  void IteratePointersToNewSpaceAndClearMaps(ObjectSlotCallback callback);
-
-  static const int kStoreBufferOverflowBit = 1 << (14 + kPointerSizeLog2);
-  static const int kStoreBufferSize = kStoreBufferOverflowBit;
-  static const int kStoreBufferLength = kStoreBufferSize / sizeof(Address);
-  static const int kOldStoreBufferLength = kStoreBufferLength * 16;
-  static const int kHashSetLengthLog2 = 12;
-  static const int kHashSetLength = 1 << kHashSetLengthLog2;
-
-  void Compact();
-
-  void GCPrologue();
-  void GCEpilogue();
-
-  Object*** Limit() { return reinterpret_cast<Object***>(old_limit_); }
-  Object*** Start() { return reinterpret_cast<Object***>(old_start_); }
-  Object*** Top() { return reinterpret_cast<Object***>(old_top_); }
-  void SetTop(Object*** top) {
-    DCHECK(top >= Start());
-    DCHECK(top <= Limit());
-    old_top_ = reinterpret_cast<Address*>(top);
-  }
-
-  bool old_buffer_is_sorted() { return old_buffer_is_sorted_; }
-  bool old_buffer_is_filtered() { return old_buffer_is_filtered_; }
-
-  // Goes through the store buffer removing pointers to things that have
-  // been promoted.  Rebuilds the store buffer completely if it overflowed.
-  void SortUniq();
-
-  void EnsureSpace(intptr_t space_needed);
-  void Verify();
-
-  bool PrepareForIteration();
-
-#ifdef DEBUG
-  void Clean();
-  // Slow, for asserts only.
-  bool CellIsInStoreBuffer(Address cell);
-#endif
-
-  void Filter(int flag);
-
- private:
-  Heap* heap_;
-
- // The store buffer is divided up into a new buffer that is constantly being - // filled by mutator activity and an old buffer that is filled with the data
-  // from the new buffer after compression.
-  Address* start_;
-  Address* limit_;
-
-  Address* old_start_;
-  Address* old_limit_;
-  Address* old_top_;
-  Address* old_reserved_limit_;
-  base::VirtualMemory* old_virtual_memory_;
-
-  bool old_buffer_is_sorted_;
-  bool old_buffer_is_filtered_;
-  bool during_gc_;
- // The garbage collector iterates over many pointers to new space that are not
-  // handled by the store buffer.  This flag indicates whether the pointers
-  // found by the callbacks should be added to the store buffer or not.
-  bool store_buffer_rebuilding_enabled_;
-  StoreBufferCallback callback_;
-  bool may_move_store_buffer_entries_;
-
-  base::VirtualMemory* virtual_memory_;
-
-  // Two hash sets used for filtering.
-  // If address is in the hash set then it is guaranteed to be in the
-  // old part of the store buffer.
-  uintptr_t* hash_set_1_;
-  uintptr_t* hash_set_2_;
-  bool hash_sets_are_empty_;
-
-  void ClearFilteringHashSets();
-
-  bool SpaceAvailable(intptr_t space_needed);
-  void Uniq();
-  void ExemptPopularPages(int prime_sample_step, int threshold);
-
-  // Set the map field of the object to NULL if contains a map.
-  inline void ClearDeadObject(HeapObject *object);
-
- void IteratePointersToNewSpace(ObjectSlotCallback callback, bool clear_maps);
-
-  void FindPointersToNewSpaceInRegion(Address start,
-                                      Address end,
-                                      ObjectSlotCallback slot_callback,
-                                      bool clear_maps);
-
-  // For each region of pointers on a page in use from an old space call
-  // visit_pointer_region callback.
-  // If either visit_pointer_region or callback can cause an allocation
-  // in old space and changes in allocation watermark then
-  // can_preallocate_during_iteration should be set to true.
-  void IteratePointersOnPage(
-      PagedSpace* space,
-      Page* page,
-      RegionCallback region_callback,
-      ObjectSlotCallback slot_callback);
-
-  void IteratePointersInStoreBuffer(ObjectSlotCallback slot_callback,
-                                    bool clear_maps);
-
-#ifdef VERIFY_HEAP
-  void VerifyPointers(LargeObjectSpace* space);
-#endif
-
-  friend class StoreBufferRebuildScope;
-  friend class DontMoveStoreBufferEntriesScope;
-};
-
-
-class StoreBufferRebuildScope {
- public:
-  explicit StoreBufferRebuildScope(Heap* heap,
-                                   StoreBuffer* store_buffer,
-                                   StoreBufferCallback callback)
-      : store_buffer_(store_buffer),
-        stored_state_(store_buffer->store_buffer_rebuilding_enabled_),
-        stored_callback_(store_buffer->callback_) {
-    store_buffer_->store_buffer_rebuilding_enabled_ = true;
-    store_buffer_->callback_ = callback;
-    (*callback)(heap, NULL, kStoreBufferStartScanningPagesEvent);
-  }
-
-  ~StoreBufferRebuildScope() {
-    store_buffer_->callback_ = stored_callback_;
-    store_buffer_->store_buffer_rebuilding_enabled_ = stored_state_;
-  }
-
- private:
-  StoreBuffer* store_buffer_;
-  bool stored_state_;
-  StoreBufferCallback stored_callback_;
-};
-
-
-class DontMoveStoreBufferEntriesScope {
- public:
-  explicit DontMoveStoreBufferEntriesScope(StoreBuffer* store_buffer)
-      : store_buffer_(store_buffer),
-        stored_state_(store_buffer->may_move_store_buffer_entries_) {
-    store_buffer_->may_move_store_buffer_entries_ = false;
-  }
-
-  ~DontMoveStoreBufferEntriesScope() {
-    store_buffer_->may_move_store_buffer_entries_ = stored_state_;
-  }
-
- private:
-  StoreBuffer* store_buffer_;
-  bool stored_state_;
-};
-
-} }  // namespace v8::internal
-
-#endif  // V8_STORE_BUFFER_H_
=======================================
--- /branches/bleeding_edge/BUILD.gn    Sat Aug  9 10:02:42 2014 UTC
+++ /branches/bleeding_edge/BUILD.gn    Mon Aug 11 14:22:24 2014 UTC
@@ -646,6 +646,9 @@
     "src/heap/spaces-inl.h",
     "src/heap/spaces.cc",
     "src/heap/spaces.h",
+    "src/heap/store-buffer-inl.h",
+    "src/heap/store-buffer.cc",
+    "src/heap/store-buffer.h",
     "src/heap/sweeper-thread.h",
     "src/heap/sweeper-thread.cc",
     "src/hydrogen-alias-analysis.h",
@@ -803,9 +806,6 @@
     "src/snapshot-source-sink.cc",
     "src/snapshot-source-sink.h",
     "src/snapshot.h",
-    "src/store-buffer-inl.h",
-    "src/store-buffer.cc",
-    "src/store-buffer.h",
     "src/string-search.cc",
     "src/string-search.h",
     "src/string-stream.cc",
=======================================
--- /branches/bleeding_edge/src/assembler.cc    Wed Aug  6 17:48:31 2014 UTC
+++ /branches/bleeding_edge/src/assembler.cc    Mon Aug 11 14:22:24 2014 UTC
@@ -52,7 +52,6 @@
 #include "src/regexp-stack.h"
 #include "src/runtime.h"
 #include "src/serialize.h"
-#include "src/store-buffer-inl.h"
 #include "src/stub-cache.h"
 #include "src/token.h"

=======================================
--- /branches/bleeding_edge/src/heap/heap-inl.h Tue Aug  5 08:18:22 2014 UTC
+++ /branches/bleeding_edge/src/heap/heap-inl.h Mon Aug 11 14:22:24 2014 UTC
@@ -10,12 +10,12 @@
 #include "src/base/platform/platform.h"
 #include "src/cpu-profiler.h"
 #include "src/heap/heap.h"
+#include "src/heap/store-buffer.h"
+#include "src/heap/store-buffer-inl.h"
 #include "src/heap-profiler.h"
 #include "src/isolate.h"
 #include "src/list-inl.h"
 #include "src/objects.h"
-#include "src/store-buffer.h"
-#include "src/store-buffer-inl.h"

 namespace v8 {
 namespace internal {
=======================================
--- /branches/bleeding_edge/src/heap/heap.cc    Thu Aug  7 12:21:01 2014 UTC
+++ /branches/bleeding_edge/src/heap/heap.cc    Mon Aug 11 14:22:24 2014 UTC
@@ -20,13 +20,13 @@
 #include "src/heap/mark-compact.h"
 #include "src/heap/objects-visiting-inl.h"
 #include "src/heap/objects-visiting.h"
+#include "src/heap/store-buffer.h"
 #include "src/heap-profiler.h"
 #include "src/isolate-inl.h"
 #include "src/natives.h"
 #include "src/runtime-profiler.h"
 #include "src/scopeinfo.h"
 #include "src/snapshot.h"
-#include "src/store-buffer.h"
 #include "src/utils.h"
 #include "src/v8threads.h"
 #include "src/vm-state-inl.h"
=======================================
--- /branches/bleeding_edge/src/heap/heap.h     Thu Aug  7 12:21:01 2014 UTC
+++ /branches/bleeding_edge/src/heap/heap.h     Mon Aug 11 14:22:24 2014 UTC
@@ -16,9 +16,9 @@
 #include "src/heap/mark-compact.h"
 #include "src/heap/objects-visiting.h"
 #include "src/heap/spaces.h"
+#include "src/heap/store-buffer.h"
 #include "src/list.h"
 #include "src/splay-tree-inl.h"
-#include "src/store-buffer.h"

 namespace v8 {
 namespace internal {
=======================================
--- /branches/bleeding_edge/src/heap/spaces.h   Tue Aug  5 08:18:22 2014 UTC
+++ /branches/bleeding_edge/src/heap/spaces.h   Mon Aug 11 14:22:24 2014 UTC
@@ -38,7 +38,7 @@
 // may be larger than the page size.
 //
// A store-buffer based write barrier is used to keep track of intergenerational
-// references.  See store-buffer.h.
+// references.  See heap/store-buffer.h.
 //
 // During scavenges and mark-sweep collections we sometimes (after a store
// buffer overflow) iterate intergenerational pointers without decoding heap
=======================================
--- /branches/bleeding_edge/src/objects-inl.h   Mon Aug 11 14:00:58 2014 UTC
+++ /branches/bleeding_edge/src/objects-inl.h   Mon Aug 11 14:22:24 2014 UTC
@@ -23,12 +23,12 @@
 #include "src/heap/incremental-marking.h"
 #include "src/heap/objects-visiting.h"
 #include "src/heap/spaces.h"
+#include "src/heap/store-buffer.h"
 #include "src/isolate.h"
 #include "src/lookup.h"
 #include "src/objects.h"
 #include "src/property.h"
 #include "src/prototype.h"
-#include "src/store-buffer.h"
 #include "src/transitions-inl.h"
 #include "src/v8memory.h"

=======================================
--- /branches/bleeding_edge/src/v8.cc   Tue Aug  5 13:20:26 2014 UTC
+++ /branches/bleeding_edge/src/v8.cc   Mon Aug 11 14:22:24 2014 UTC
@@ -13,6 +13,7 @@
 #include "src/deoptimizer.h"
 #include "src/elements.h"
 #include "src/frames.h"
+#include "src/heap/store-buffer.h"
 #include "src/heap-profiler.h"
 #include "src/hydrogen.h"
 #include "src/isolate.h"
@@ -21,7 +22,6 @@
 #include "src/runtime-profiler.h"
 #include "src/sampler.h"
 #include "src/serialize.h"
-#include "src/store-buffer.h"


 namespace v8 {
=======================================
--- /branches/bleeding_edge/tools/gyp/v8.gyp    Fri Aug  8 11:42:59 2014 UTC
+++ /branches/bleeding_edge/tools/gyp/v8.gyp    Mon Aug 11 14:22:24 2014 UTC
@@ -530,6 +530,9 @@
         '../../src/heap/spaces-inl.h',
         '../../src/heap/spaces.cc',
         '../../src/heap/spaces.h',
+        '../../src/heap/store-buffer-inl.h',
+        '../../src/heap/store-buffer.cc',
+        '../../src/heap/store-buffer.h',
         '../../src/heap/sweeper-thread.h',
         '../../src/heap/sweeper-thread.cc',
         '../../src/hydrogen-alias-analysis.h',
@@ -688,9 +691,6 @@
         '../../src/snapshot.h',
         '../../src/snapshot-source-sink.cc',
         '../../src/snapshot-source-sink.h',
-        '../../src/store-buffer-inl.h',
-        '../../src/store-buffer.cc',
-        '../../src/store-buffer.h',
         '../../src/string-search.cc',
         '../../src/string-search.h',
         '../../src/string-stream.cc',

--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
--- You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.

Reply via email to