V8 API Reference, 7.2.502.16 (for Deno 0.2.4)
concurrent-marking.h
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 #ifndef V8_HEAP_CONCURRENT_MARKING_H_
6 #define V8_HEAP_CONCURRENT_MARKING_H_
7 
8 #include "include/v8-platform.h"
9 #include "src/allocation.h"
10 #include "src/base/atomic-utils.h"
11 #include "src/base/platform/condition-variable.h"
12 #include "src/base/platform/mutex.h"
13 #include "src/cancelable-task.h"
14 #include "src/heap/spaces.h"
15 #include "src/heap/worklist.h"
16 #include "src/utils.h"
17 #include "src/v8.h"
18 
19 namespace v8 {
20 namespace internal {
21 
22 class Heap;
23 class Isolate;
24 class MajorNonAtomicMarkingState;
25 struct WeakObjects;
26 
27 using LiveBytesMap =
28  std::unordered_map<MemoryChunk*, intptr_t, MemoryChunk::Hasher>;
29 
31  public:
32  // When the scope is entered, the concurrent marking tasks
33  // are preempted and are not looking at the heap objects, concurrent marking
34  // is resumed when the scope is exited.
35  class PauseScope {
36  public:
37  explicit PauseScope(ConcurrentMarking* concurrent_marking);
38  ~PauseScope();
39 
40  private:
41  ConcurrentMarking* const concurrent_marking_;
42  const bool resume_on_exit_;
43  };
44 
45  enum class StopRequest {
46  // Preempt ongoing tasks ASAP (and cancel unstarted tasks).
47  PREEMPT_TASKS,
48  // Wait for ongoing tasks to complete (and cancels unstarted tasks).
49  COMPLETE_ONGOING_TASKS,
50  // Wait for all scheduled tasks to complete (only use this in tests that
51  // control the full stack -- otherwise tasks cancelled by the platform can
52  // make this call hang).
53  COMPLETE_TASKS_FOR_TESTING,
54  };
55 
56  // TODO(gab): The only thing that prevents this being above 7 is
57  // Worklist::kMaxNumTasks being maxed at 8 (concurrent marking doesn't use
58  // task 0, reserved for the main thread).
59  static constexpr int kMaxTasks = 7;
60  using MarkingWorklist = Worklist<HeapObject*, 64 /* segment size */>;
61  using EmbedderTracingWorklist = Worklist<HeapObject*, 16 /* segment size */>;
62 
63  ConcurrentMarking(Heap* heap, MarkingWorklist* shared,
64  MarkingWorklist* bailout, MarkingWorklist* on_hold,
65  WeakObjects* weak_objects,
66  EmbedderTracingWorklist* embedder_objects);
67 
68  // Schedules asynchronous tasks to perform concurrent marking. Objects in the
69  // heap should not be moved while these are active (can be stopped safely via
70  // Stop() or PauseScope).
71  void ScheduleTasks();
72 
73  // Stops concurrent marking per |stop_request|'s semantics. Returns true
74  // if concurrent marking was in progress, false otherwise.
75  bool Stop(StopRequest stop_request);
76 
77  void RescheduleTasksIfNeeded();
78  // Flushes the local live bytes into the given marking state.
79  void FlushLiveBytes(MajorNonAtomicMarkingState* marking_state);
80  // This function is called for a new space page that was cleared after
81  // scavenge and is going to be re-used.
82  void ClearLiveness(MemoryChunk* chunk);
83 
84  int TaskCount() { return task_count_; }
85 
86  // Checks if all threads are stopped.
87  bool IsStopped();
88 
89  size_t TotalMarkedBytes();
90 
91  void set_ephemeron_marked(bool ephemeron_marked) {
92  ephemeron_marked_.store(ephemeron_marked);
93  }
94  bool ephemeron_marked() { return ephemeron_marked_.load(); }
95 
96  private:
97  struct TaskState {
98  // The main thread sets this flag to true when it wants the concurrent
99  // marker to give up the worker thread.
100  std::atomic<bool> preemption_request;
101 
102  LiveBytesMap live_bytes;
103  size_t marked_bytes = 0;
104  char cache_line_padding[64];
105  };
106  class Task;
107  void Run(int task_id, TaskState* task_state);
108  Heap* const heap_;
109  MarkingWorklist* const shared_;
110  MarkingWorklist* const bailout_;
111  MarkingWorklist* const on_hold_;
112  WeakObjects* const weak_objects_;
113  EmbedderTracingWorklist* const embedder_objects_;
114  TaskState task_state_[kMaxTasks + 1];
115  std::atomic<size_t> total_marked_bytes_{0};
116  std::atomic<bool> ephemeron_marked_{false};
117  base::Mutex pending_lock_;
118  base::ConditionVariable pending_condition_;
119  int pending_task_count_ = 0;
120  bool is_pending_[kMaxTasks + 1] = {};
121  CancelableTaskManager::Id cancelable_id_[kMaxTasks + 1] = {};
122  int task_count_ = 0;
123 };
124 
125 } // namespace internal
126 } // namespace v8
127 
128 #endif // V8_HEAP_CONCURRENT_MARKING_H_
Definition: libplatform.h:13