OLD | NEW |
(Empty) | |
| 1 // Copyright 2017 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/sequential-marking-deque.h" |
| 6 |
| 7 #include "src/allocation.h" |
| 8 #include "src/base/bits.h" |
| 9 #include "src/heap/heap-inl.h" |
| 10 #include "src/heap/heap.h" |
| 11 |
| 12 namespace v8 { |
| 13 namespace internal { |
| 14 |
| 15 void SequentialMarkingDeque::SetUp() { |
| 16 backing_store_ = new base::VirtualMemory(kMaxSize); |
| 17 backing_store_committed_size_ = 0; |
| 18 if (backing_store_ == nullptr) { |
| 19 V8::FatalProcessOutOfMemory("SequentialMarkingDeque::SetUp"); |
| 20 } |
| 21 } |
| 22 |
| 23 void SequentialMarkingDeque::TearDown() { delete backing_store_; } |
| 24 |
| 25 void SequentialMarkingDeque::StartUsing() { |
| 26 base::LockGuard<base::Mutex> guard(&mutex_); |
| 27 if (in_use_) { |
| 28 // This can happen in mark-compact GC if the incremental marker already |
| 29 // started using the marking deque. |
| 30 return; |
| 31 } |
| 32 in_use_ = true; |
| 33 EnsureCommitted(); |
| 34 array_ = reinterpret_cast<HeapObject**>(backing_store_->address()); |
| 35 size_t size = FLAG_force_marking_deque_overflows |
| 36 ? 64 * kPointerSize |
| 37 : backing_store_committed_size_; |
| 38 DCHECK( |
| 39 base::bits::IsPowerOfTwo32(static_cast<uint32_t>(size / kPointerSize))); |
| 40 mask_ = static_cast<int>((size / kPointerSize) - 1); |
| 41 top_ = bottom_ = 0; |
| 42 overflowed_ = false; |
| 43 } |
| 44 |
| 45 void SequentialMarkingDeque::StopUsing() { |
| 46 base::LockGuard<base::Mutex> guard(&mutex_); |
| 47 if (!in_use_) return; |
| 48 DCHECK(IsEmpty()); |
| 49 DCHECK(!overflowed_); |
| 50 top_ = bottom_ = mask_ = 0; |
| 51 in_use_ = false; |
| 52 if (FLAG_concurrent_sweeping) { |
| 53 StartUncommitTask(); |
| 54 } else { |
| 55 Uncommit(); |
| 56 } |
| 57 } |
| 58 |
| 59 void SequentialMarkingDeque::Clear() { |
| 60 DCHECK(in_use_); |
| 61 top_ = bottom_ = 0; |
| 62 overflowed_ = false; |
| 63 } |
| 64 |
| 65 void SequentialMarkingDeque::Uncommit() { |
| 66 DCHECK(!in_use_); |
| 67 bool success = backing_store_->Uncommit(backing_store_->address(), |
| 68 backing_store_committed_size_); |
| 69 backing_store_committed_size_ = 0; |
| 70 CHECK(success); |
| 71 } |
| 72 |
| 73 void SequentialMarkingDeque::EnsureCommitted() { |
| 74 DCHECK(in_use_); |
| 75 if (backing_store_committed_size_ > 0) return; |
| 76 |
| 77 for (size_t size = kMaxSize; size >= kMinSize; size /= 2) { |
| 78 if (backing_store_->Commit(backing_store_->address(), size, false)) { |
| 79 backing_store_committed_size_ = size; |
| 80 break; |
| 81 } |
| 82 } |
| 83 if (backing_store_committed_size_ == 0) { |
| 84 V8::FatalProcessOutOfMemory("SequentialMarkingDeque::EnsureCommitted"); |
| 85 } |
| 86 } |
| 87 |
| 88 void SequentialMarkingDeque::StartUncommitTask() { |
| 89 if (!uncommit_task_pending_) { |
| 90 uncommit_task_pending_ = true; |
| 91 UncommitTask* task = new UncommitTask(heap_->isolate(), this); |
| 92 V8::GetCurrentPlatform()->CallOnBackgroundThread( |
| 93 task, v8::Platform::kShortRunningTask); |
| 94 } |
| 95 } |
| 96 |
| 97 } // namespace internal |
| 98 } // namespace v8 |
OLD | NEW |