blob: a982eb3c40280f96d883c870161363f1a2656ae9 [file] [log] [blame]
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001// 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
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005#include "src/heap/store-buffer.h"
6
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007#include <algorithm>
8
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009#include "src/counters.h"
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000010#include "src/heap/incremental-marking.h"
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000011#include "src/isolate.h"
12#include "src/objects-inl.h"
13#include "src/v8.h"
Ben Murdochb8a8cc12014-11-26 15:28:44 +000014
15namespace v8 {
16namespace internal {
17
18StoreBuffer::StoreBuffer(Heap* heap)
Ben Murdochda12d292016-06-02 14:46:10 +010019 : heap_(heap),
20 top_(nullptr),
21 start_(nullptr),
22 limit_(nullptr),
23 virtual_memory_(nullptr) {}
Ben Murdochb8a8cc12014-11-26 15:28:44 +000024
25void StoreBuffer::SetUp() {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000026 // 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.
Ben Murdochda12d292016-06-02 14:46:10 +010029 virtual_memory_ = new base::VirtualMemory(kStoreBufferSize * 2);
Ben Murdochb8a8cc12014-11-26 15:28:44 +000030 uintptr_t start_as_int =
31 reinterpret_cast<uintptr_t>(virtual_memory_->address());
Ben Murdochda12d292016-06-02 14:46:10 +010032 start_ = reinterpret_cast<Address*>(RoundUp(start_as_int, kStoreBufferSize));
Ben Murdochb8a8cc12014-11-26 15:28:44 +000033 limit_ = start_ + (kStoreBufferSize / kPointerSize);
34
Ben Murdochb8a8cc12014-11-26 15:28:44 +000035 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);
Ben Murdochda12d292016-06-02 14:46:10 +010043 DCHECK((reinterpret_cast<uintptr_t>(limit_) & kStoreBufferMask) == 0);
Ben Murdochb8a8cc12014-11-26 15:28:44 +000044
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000045 if (!virtual_memory_->Commit(reinterpret_cast<Address>(start_),
46 kStoreBufferSize,
47 false)) { // Not executable.
48 V8::FatalProcessOutOfMemory("StoreBuffer::SetUp");
49 }
Ben Murdochda12d292016-06-02 14:46:10 +010050 top_ = start_;
Ben Murdochb8a8cc12014-11-26 15:28:44 +000051}
52
53
54void StoreBuffer::TearDown() {
55 delete virtual_memory_;
Ben Murdochda12d292016-06-02 14:46:10 +010056 top_ = start_ = limit_ = nullptr;
Ben Murdochb8a8cc12014-11-26 15:28:44 +000057}
58
59
60void StoreBuffer::StoreBufferOverflow(Isolate* isolate) {
Ben Murdoch097c5b22016-05-18 11:27:45 +010061 isolate->heap()->store_buffer()->MoveEntriesToRememberedSet();
Ben Murdochb8a8cc12014-11-26 15:28:44 +000062 isolate->counters()->store_buffer_overflows()->Increment();
63}
64
Ben Murdoch097c5b22016-05-18 11:27:45 +010065void StoreBuffer::MoveEntriesToRememberedSet() {
Ben Murdochda12d292016-06-02 14:46:10 +010066 if (top_ == start_) return;
67 DCHECK(top_ <= limit_);
68 for (Address* current = start_; current < top_; current++) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +000069 DCHECK(!heap_->code_space()->Contains(*current));
Ben Murdoch097c5b22016-05-18 11:27:45 +010070 Address addr = *current;
71 Page* page = Page::FromAnyPointerAddress(heap_, addr);
72 RememberedSet<OLD_TO_NEW>::Insert(page, addr);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000073 }
Ben Murdochda12d292016-06-02 14:46:10 +010074 top_ = start_;
Ben Murdochb8a8cc12014-11-26 15:28:44 +000075}
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000076
77} // namespace internal
78} // namespace v8