• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2011 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "src/heap/store-buffer.h"
6 
7 #include <algorithm>
8 
9 #include "src/counters.h"
10 #include "src/heap/incremental-marking.h"
11 #include "src/isolate.h"
12 #include "src/objects-inl.h"
13 #include "src/v8.h"
14 
15 namespace v8 {
16 namespace internal {
17 
StoreBuffer(Heap * heap)18 StoreBuffer::StoreBuffer(Heap* heap)
19     : heap_(heap),
20       top_(nullptr),
21       start_(nullptr),
22       limit_(nullptr),
23       virtual_memory_(nullptr) {}
24 
SetUp()25 void StoreBuffer::SetUp() {
26   // Allocate 3x the buffer size, so that we can start the new store buffer
27   // aligned to 2x the size.  This lets us use a bit test to detect the end of
28   // the area.
29   virtual_memory_ = new base::VirtualMemory(kStoreBufferSize * 2);
30   uintptr_t start_as_int =
31       reinterpret_cast<uintptr_t>(virtual_memory_->address());
32   start_ = reinterpret_cast<Address*>(RoundUp(start_as_int, kStoreBufferSize));
33   limit_ = start_ + (kStoreBufferSize / kPointerSize);
34 
35   DCHECK(reinterpret_cast<Address>(start_) >= virtual_memory_->address());
36   DCHECK(reinterpret_cast<Address>(limit_) >= virtual_memory_->address());
37   Address* vm_limit = reinterpret_cast<Address*>(
38       reinterpret_cast<char*>(virtual_memory_->address()) +
39       virtual_memory_->size());
40   DCHECK(start_ <= vm_limit);
41   DCHECK(limit_ <= vm_limit);
42   USE(vm_limit);
43   DCHECK((reinterpret_cast<uintptr_t>(limit_) & kStoreBufferMask) == 0);
44 
45   if (!virtual_memory_->Commit(reinterpret_cast<Address>(start_),
46                                kStoreBufferSize,
47                                false)) {  // Not executable.
48     V8::FatalProcessOutOfMemory("StoreBuffer::SetUp");
49   }
50   top_ = start_;
51 }
52 
53 
TearDown()54 void StoreBuffer::TearDown() {
55   delete virtual_memory_;
56   top_ = start_ = limit_ = nullptr;
57 }
58 
59 
StoreBufferOverflow(Isolate * isolate)60 void StoreBuffer::StoreBufferOverflow(Isolate* isolate) {
61   isolate->heap()->store_buffer()->MoveEntriesToRememberedSet();
62   isolate->counters()->store_buffer_overflows()->Increment();
63 }
64 
MoveEntriesToRememberedSet()65 void StoreBuffer::MoveEntriesToRememberedSet() {
66   if (top_ == start_) return;
67   DCHECK(top_ <= limit_);
68   for (Address* current = start_; current < top_; current++) {
69     DCHECK(!heap_->code_space()->Contains(*current));
70     Address addr = *current;
71     Page* page = Page::FromAnyPointerAddress(heap_, addr);
72     RememberedSet<OLD_TO_NEW>::Insert(page, addr);
73   }
74   top_ = start_;
75 }
76 
77 }  // namespace internal
78 }  // namespace v8
79