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

Unified Diff: src/heap/sequential-marking-deque.h

Issue 2852953004: [heap] Extract marking deque to separate file. (Closed)
Patch Set: fix build.gn Created 3 years, 8 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
« no previous file with comments | « src/heap/mark-compact.cc ('k') | src/heap/sequential-marking-deque.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/heap/sequential-marking-deque.h
diff --git a/src/heap/sequential-marking-deque.h b/src/heap/sequential-marking-deque.h
new file mode 100644
index 0000000000000000000000000000000000000000..a72704817355aa06cd68d1382634697c16cc3ed9
--- /dev/null
+++ b/src/heap/sequential-marking-deque.h
@@ -0,0 +1,163 @@
+// Copyright 2017 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_HEAP_SEQUENTIAL_MARKING_DEQUE_
+#define V8_HEAP_SEQUENTIAL_MARKING_DEQUE_
+
+#include <deque>
+
+#include "src/base/platform/mutex.h"
+#include "src/base/platform/platform.h"
+#include "src/cancelable-task.h"
+
+namespace v8 {
+namespace internal {
+
+class Heap;
+class Isolate;
+class HeapObject;
+
+// ----------------------------------------------------------------------------
+// Marking deque for tracing live objects.
+class SequentialMarkingDeque {
+ public:
+ explicit SequentialMarkingDeque(Heap* heap)
+ : backing_store_(nullptr),
+ backing_store_committed_size_(0),
+ array_(nullptr),
+ top_(0),
+ bottom_(0),
+ mask_(0),
+ overflowed_(false),
+ in_use_(false),
+ uncommit_task_pending_(false),
+ heap_(heap) {}
+
+ void SetUp();
+ void TearDown();
+
+ // Ensures that the marking deque is committed and will stay committed until
+ // StopUsing() is called.
+ void StartUsing();
+ void StopUsing();
+ void Clear();
+
+ inline bool IsFull() { return ((top_ + 1) & mask_) == bottom_; }
+
+ inline bool IsEmpty() { return top_ == bottom_; }
+
+ bool overflowed() const { return overflowed_; }
+
+ void ClearOverflowed() { overflowed_ = false; }
+
+ void SetOverflowed() { overflowed_ = true; }
+
+ // Push the object on the marking stack if there is room, otherwise mark the
+ // deque as overflowed and wait for a rescan of the heap.
+ INLINE(bool Push(HeapObject* object)) {
+ if (IsFull()) {
+ SetOverflowed();
+ return false;
+ } else {
+ array_[top_] = object;
+ top_ = ((top_ + 1) & mask_);
+ return true;
+ }
+ }
+
+ INLINE(HeapObject* Pop()) {
+ DCHECK(!IsEmpty());
+ top_ = ((top_ - 1) & mask_);
+ HeapObject* object = array_[top_];
+ return object;
+ }
+
+ // Unshift the object into the marking stack if there is room, otherwise mark
+ // the deque as overflowed and wait for a rescan of the heap.
+ INLINE(bool Unshift(HeapObject* object)) {
+ if (IsFull()) {
+ SetOverflowed();
+ return false;
+ } else {
+ bottom_ = ((bottom_ - 1) & mask_);
+ array_[bottom_] = object;
+ return true;
+ }
+ }
+
+ template <typename Callback>
+ void Iterate(Callback callback) {
+ int i = bottom_;
+ while (i != top_) {
+ callback(array_[i]);
+ i = (i + 1) & mask_;
+ }
+ }
+
+ HeapObject** array() { return array_; }
+ int bottom() { return bottom_; }
+ int top() { return top_; }
+ int mask() { return mask_; }
+ void set_top(int top) { top_ = top; }
+
+ private:
+ // This task uncommits the marking_deque backing store if
+ // markin_deque->in_use_ is false.
+ class UncommitTask : public CancelableTask {
+ public:
+ explicit UncommitTask(Isolate* isolate,
+ SequentialMarkingDeque* marking_deque)
+ : CancelableTask(isolate), marking_deque_(marking_deque) {}
+
+ private:
+ // CancelableTask override.
+ void RunInternal() override {
+ base::LockGuard<base::Mutex> guard(&marking_deque_->mutex_);
+ if (!marking_deque_->in_use_) {
+ marking_deque_->Uncommit();
+ }
+ marking_deque_->uncommit_task_pending_ = false;
+ }
+
+ SequentialMarkingDeque* marking_deque_;
+ DISALLOW_COPY_AND_ASSIGN(UncommitTask);
+ };
+
+ static const size_t kMaxSize = 4 * MB;
+ static const size_t kMinSize = 256 * KB;
+
+ // Must be called with mutex lock.
+ void EnsureCommitted();
+
+ // Must be called with mutex lock.
+ void Uncommit();
+
+ // Must be called with mutex lock.
+ void StartUncommitTask();
+
+ base::Mutex mutex_;
+
+ base::VirtualMemory* backing_store_;
+ size_t backing_store_committed_size_;
+ HeapObject** array_;
+ // array_[(top - 1) & mask_] is the top element in the deque. The Deque is
+ // empty when top_ == bottom_. It is full when top_ + 1 == bottom
+ // (mod mask + 1).
+ int top_;
+ int bottom_;
+ int mask_;
+ bool overflowed_;
+ // in_use_ == true after taking mutex lock implies that the marking deque is
+ // committed and will stay committed at least until in_use_ == false.
+ bool in_use_;
+ bool uncommit_task_pending_;
+ Heap* heap_;
+
+ DISALLOW_COPY_AND_ASSIGN(SequentialMarkingDeque);
+};
+
+} // namespace internal
+} // namespace v8
+
+#endif // V8_SEQUENTIAL_MARKING_DEQUE_
« no previous file with comments | « src/heap/mark-compact.cc ('k') | src/heap/sequential-marking-deque.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698