OLD | NEW |
1 // Copyright 2017 the V8 project authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/heap/concurrent-marking.h" | 5 #include "src/heap/concurrent-marking.h" |
6 | 6 |
7 #include <stack> | 7 #include <stack> |
8 #include <unordered_map> | 8 #include <unordered_map> |
9 | 9 |
10 #include "src/heap/concurrent-marking-deque.h" | 10 #include "src/heap/concurrent-marking-deque.h" |
(...skipping 12 matching lines...) Expand all Loading... |
23 namespace internal { | 23 namespace internal { |
24 | 24 |
25 class ConcurrentMarkingVisitor final | 25 class ConcurrentMarkingVisitor final |
26 : public HeapVisitor<int, ConcurrentMarkingVisitor> { | 26 : public HeapVisitor<int, ConcurrentMarkingVisitor> { |
27 public: | 27 public: |
28 using BaseClass = HeapVisitor<int, ConcurrentMarkingVisitor>; | 28 using BaseClass = HeapVisitor<int, ConcurrentMarkingVisitor>; |
29 | 29 |
30 explicit ConcurrentMarkingVisitor(ConcurrentMarkingDeque* deque) | 30 explicit ConcurrentMarkingVisitor(ConcurrentMarkingDeque* deque) |
31 : deque_(deque) {} | 31 : deque_(deque) {} |
32 | 32 |
| 33 bool ShouldVisit(HeapObject* object) override { |
| 34 return ObjectMarking::GreyToBlack<MarkBit::AccessMode::ATOMIC>( |
| 35 object, marking_state(object)); |
| 36 } |
| 37 |
33 void VisitPointers(HeapObject* host, Object** start, Object** end) override { | 38 void VisitPointers(HeapObject* host, Object** start, Object** end) override { |
34 for (Object** p = start; p < end; p++) { | 39 for (Object** p = start; p < end; p++) { |
35 if (!(*p)->IsHeapObject()) continue; | 40 if (!(*p)->IsHeapObject()) continue; |
36 MarkObject(HeapObject::cast(*p)); | 41 MarkObject(HeapObject::cast(*p)); |
37 } | 42 } |
38 } | 43 } |
39 | 44 |
40 // =========================================================================== | 45 // =========================================================================== |
41 // JS object ================================================================= | 46 // JS object ================================================================= |
42 // =========================================================================== | 47 // =========================================================================== |
(...skipping 18 matching lines...) Expand all Loading... |
61 int VisitFixedArray(Map* map, FixedArray* object) override { | 66 int VisitFixedArray(Map* map, FixedArray* object) override { |
62 // TODO(ulan): implement iteration with prefetched length. | 67 // TODO(ulan): implement iteration with prefetched length. |
63 return BaseClass::VisitFixedArray(map, object); | 68 return BaseClass::VisitFixedArray(map, object); |
64 } | 69 } |
65 | 70 |
66 // =========================================================================== | 71 // =========================================================================== |
67 // Code object =============================================================== | 72 // Code object =============================================================== |
68 // =========================================================================== | 73 // =========================================================================== |
69 | 74 |
70 int VisitCode(Map* map, Code* object) override { | 75 int VisitCode(Map* map, Code* object) override { |
71 // TODO(ulan): push the object to the bail-out deque. | 76 deque_->Push(object, MarkingThread::kConcurrent, TargetDeque::kBailout); |
72 return 0; | 77 return 0; |
73 } | 78 } |
74 | 79 |
75 // =========================================================================== | 80 // =========================================================================== |
76 // Objects with weak fields and/or side-effectiful visitation. | 81 // Objects with weak fields and/or side-effectiful visitation. |
77 // =========================================================================== | 82 // =========================================================================== |
78 | 83 |
79 int VisitBytecodeArray(Map* map, BytecodeArray* object) override { | 84 int VisitBytecodeArray(Map* map, BytecodeArray* object) override { |
80 // TODO(ulan): implement iteration of strong fields and push the object to | 85 // TODO(ulan): implement iteration of strong fields. |
81 // the bailout deque. | 86 deque_->Push(object, MarkingThread::kConcurrent, TargetDeque::kBailout); |
82 return 0; | 87 return 0; |
83 } | 88 } |
84 | 89 |
85 int VisitJSFunction(Map* map, JSFunction* object) override { | 90 int VisitJSFunction(Map* map, JSFunction* object) override { |
86 // TODO(ulan): implement iteration of strong fields and push the object to | 91 // TODO(ulan): implement iteration of strong fields. |
87 // the bailout deque. | 92 deque_->Push(object, MarkingThread::kConcurrent, TargetDeque::kBailout); |
88 return 0; | 93 return 0; |
89 } | 94 } |
90 | 95 |
91 int VisitMap(Map* map, Map* object) override { | 96 int VisitMap(Map* map, Map* object) override { |
92 // TODO(ulan): implement iteration of strong fields and push the object to | 97 // TODO(ulan): implement iteration of strong fields. |
93 // the bailout deque. | 98 deque_->Push(object, MarkingThread::kConcurrent, TargetDeque::kBailout); |
94 return 0; | 99 return 0; |
95 } | 100 } |
96 | 101 |
97 int VisitNativeContext(Map* map, Context* object) override { | 102 int VisitNativeContext(Map* map, Context* object) override { |
98 // TODO(ulan): implement iteration of strong fields and push the object to | 103 // TODO(ulan): implement iteration of strong fields. |
99 // the bailout deque. | 104 deque_->Push(object, MarkingThread::kConcurrent, TargetDeque::kBailout); |
100 return 0; | 105 return 0; |
101 } | 106 } |
102 | 107 |
103 int VisitSharedFunctionInfo(Map* map, SharedFunctionInfo* object) override { | 108 int VisitSharedFunctionInfo(Map* map, SharedFunctionInfo* object) override { |
104 // TODO(ulan): implement iteration of strong fields and push the object to | 109 // TODO(ulan): implement iteration of strong fields. |
105 // the bailout deque. | 110 deque_->Push(object, MarkingThread::kConcurrent, TargetDeque::kBailout); |
106 return 0; | 111 return 0; |
107 } | 112 } |
108 | 113 |
109 int VisitTransitionArray(Map* map, TransitionArray* object) override { | 114 int VisitTransitionArray(Map* map, TransitionArray* object) override { |
110 // TODO(ulan): implement iteration of strong fields and push the object to | 115 // TODO(ulan): implement iteration of strong fields. |
111 // the bailout deque. | 116 deque_->Push(object, MarkingThread::kConcurrent, TargetDeque::kBailout); |
112 return 0; | 117 return 0; |
113 } | 118 } |
114 | 119 |
115 int VisitWeakCell(Map* map, WeakCell* object) override { | 120 int VisitWeakCell(Map* map, WeakCell* object) override { |
116 // TODO(ulan): implement iteration of strong fields and push the object to | 121 // TODO(ulan): implement iteration of strong fields. |
117 // the bailout deque. | 122 deque_->Push(object, MarkingThread::kConcurrent, TargetDeque::kBailout); |
118 return 0; | 123 return 0; |
119 } | 124 } |
120 | 125 |
121 int VisitJSWeakCollection(Map* map, JSWeakCollection* object) override { | 126 int VisitJSWeakCollection(Map* map, JSWeakCollection* object) override { |
122 // TODO(ulan): implement iteration of strong fields and push the object to | 127 // TODO(ulan): implement iteration of strong fields. |
123 // the bailout deque. | 128 deque_->Push(object, MarkingThread::kConcurrent, TargetDeque::kBailout); |
124 return 0; | 129 return 0; |
125 } | 130 } |
126 | 131 |
127 void MarkObject(HeapObject* obj) { | 132 void MarkObject(HeapObject* object) { |
128 deque_->Push(obj, MarkingThread::kConcurrent, TargetDeque::kShared); | 133 if (ObjectMarking::WhiteToGrey<MarkBit::AccessMode::ATOMIC>( |
| 134 object, marking_state(object))) { |
| 135 deque_->Push(object, MarkingThread::kConcurrent, TargetDeque::kShared); |
| 136 } |
129 } | 137 } |
130 | 138 |
131 private: | 139 private: |
| 140 MarkingState marking_state(HeapObject* object) const { |
| 141 return MarkingState::Internal(object); |
| 142 } |
| 143 |
132 ConcurrentMarkingDeque* deque_; | 144 ConcurrentMarkingDeque* deque_; |
133 }; | 145 }; |
134 | 146 |
135 class ConcurrentMarking::Task : public CancelableTask { | 147 class ConcurrentMarking::Task : public CancelableTask { |
136 public: | 148 public: |
137 Task(Isolate* isolate, ConcurrentMarking* concurrent_marking, | 149 Task(Isolate* isolate, ConcurrentMarking* concurrent_marking, |
138 base::Semaphore* on_finish) | 150 base::Semaphore* on_finish) |
139 : CancelableTask(isolate), | 151 : CancelableTask(isolate), |
140 concurrent_marking_(concurrent_marking), | 152 concurrent_marking_(concurrent_marking), |
141 on_finish_(on_finish) {} | 153 on_finish_(on_finish) {} |
(...skipping 26 matching lines...) Expand all Loading... |
168 | 180 |
169 ConcurrentMarking::~ConcurrentMarking() { delete visitor_; } | 181 ConcurrentMarking::~ConcurrentMarking() { delete visitor_; } |
170 | 182 |
171 void ConcurrentMarking::Run() { | 183 void ConcurrentMarking::Run() { |
172 double time_ms = heap_->MonotonicallyIncreasingTimeInMs(); | 184 double time_ms = heap_->MonotonicallyIncreasingTimeInMs(); |
173 size_t bytes_marked = 0; | 185 size_t bytes_marked = 0; |
174 { | 186 { |
175 TimedScope scope(&time_ms); | 187 TimedScope scope(&time_ms); |
176 HeapObject* object; | 188 HeapObject* object; |
177 while ((object = deque_->Pop(MarkingThread::kConcurrent)) != nullptr) { | 189 while ((object = deque_->Pop(MarkingThread::kConcurrent)) != nullptr) { |
178 bytes_marked += visitor_->IterateBody(object); | 190 bytes_marked += visitor_->Visit(object); |
179 } | 191 } |
180 } | 192 } |
181 if (FLAG_trace_concurrent_marking) { | 193 if (FLAG_trace_concurrent_marking) { |
182 heap_->isolate()->PrintWithTimestamp("concurrently marked %dKB in %.2fms\n", | 194 heap_->isolate()->PrintWithTimestamp("concurrently marked %dKB in %.2fms\n", |
183 static_cast<int>(bytes_marked / KB), | 195 static_cast<int>(bytes_marked / KB), |
184 time_ms); | 196 time_ms); |
185 } | 197 } |
186 } | 198 } |
187 | 199 |
188 void ConcurrentMarking::StartTask() { | 200 void ConcurrentMarking::StartTask() { |
(...skipping 11 matching lines...) Expand all Loading... |
200 } | 212 } |
201 | 213 |
202 void ConcurrentMarking::EnsureTaskCompleted() { | 214 void ConcurrentMarking::EnsureTaskCompleted() { |
203 if (IsTaskPending()) { | 215 if (IsTaskPending()) { |
204 WaitForTaskToComplete(); | 216 WaitForTaskToComplete(); |
205 } | 217 } |
206 } | 218 } |
207 | 219 |
208 } // namespace internal | 220 } // namespace internal |
209 } // namespace v8 | 221 } // namespace v8 |
OLD | NEW |