Line data Source code
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_
6 : #define V8_HEAP_CONCURRENT_MARKING_
7 :
8 : #include "src/allocation.h"
9 : #include "src/cancelable-task.h"
10 : #include "src/heap/spaces.h"
11 : #include "src/heap/worklist.h"
12 : #include "src/utils.h"
13 : #include "src/v8.h"
14 :
15 : namespace v8 {
16 : namespace internal {
17 :
18 : class Heap;
19 : class Isolate;
20 : class MajorNonAtomicMarkingState;
21 : struct WeakObjects;
22 :
23 : using LiveBytesMap =
24 : std::unordered_map<MemoryChunk*, intptr_t, MemoryChunk::Hasher>;
25 :
26 53377 : class ConcurrentMarking {
27 : public:
28 : // When the scope is entered, the concurrent marking tasks
29 : // are paused and are not looking at the heap objects.
30 : class PauseScope {
31 : public:
32 : explicit PauseScope(ConcurrentMarking* concurrent_marking);
33 : ~PauseScope();
34 :
35 : private:
36 : ConcurrentMarking* concurrent_marking_;
37 : };
38 :
39 : static const int kMaxTasks = 4;
40 : using MarkingWorklist = Worklist<HeapObject*, 64 /* segment size */>;
41 :
42 : ConcurrentMarking(Heap* heap, MarkingWorklist* shared,
43 : MarkingWorklist* bailout, MarkingWorklist* on_hold,
44 : WeakObjects* weak_objects);
45 :
46 : void ScheduleTasks();
47 : void WaitForTasks();
48 : void EnsureCompleted();
49 : void RescheduleTasksIfNeeded();
50 : // Flushes the local live bytes into the given marking state.
51 : void FlushLiveBytes(MajorNonAtomicMarkingState* marking_state);
52 : // This function is called for a new space page that was cleared after
53 : // scavenge and is going to be re-used.
54 : void ClearLiveness(MemoryChunk* chunk);
55 :
56 : int TaskCount() { return task_count_; }
57 :
58 : size_t TotalMarkedBytes();
59 :
60 : private:
61 1083880 : struct TaskState {
62 : // When the concurrent marking task has this lock, then objects in the
63 : // heap are guaranteed to not move.
64 : base::Mutex lock;
65 : // The main thread sets this flag to true, when it wants the concurrent
66 : // maker to give up the lock.
67 : base::AtomicValue<bool> interrupt_request;
68 : // The concurrent marker waits on this condition until the request
69 : // flag is cleared by the main thread.
70 : base::ConditionVariable interrupt_condition;
71 : LiveBytesMap live_bytes;
72 : size_t marked_bytes;
73 : char cache_line_padding[64];
74 : };
75 : class Task;
76 : void Run(int task_id, TaskState* task_state);
77 : Heap* heap_;
78 : MarkingWorklist* shared_;
79 : MarkingWorklist* bailout_;
80 : MarkingWorklist* on_hold_;
81 : WeakObjects* weak_objects_;
82 : TaskState task_state_[kMaxTasks + 1];
83 : base::AtomicNumber<size_t> total_marked_bytes_;
84 : base::Mutex pending_lock_;
85 : base::ConditionVariable pending_condition_;
86 : int pending_task_count_;
87 : bool is_pending_[kMaxTasks + 1];
88 : CancelableTaskManager::Id cancelable_id_[kMaxTasks + 1];
89 : int task_count_;
90 : };
91 :
92 : } // namespace internal
93 : } // namespace v8
94 :
95 : #endif // V8_HEAP_PAGE_PARALLEL_JOB_
|