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

Side by Side Diff: runtime/vm/gc_marker.cc

Issue 2001713002: - Removed the kWatchedBit and the associated weak property handling (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Remove residual watched bit. Created 4 years, 7 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 unified diff | Download patch
« no previous file with comments | « no previous file | runtime/vm/object.cc » ('j') | runtime/vm/raw_object.h » ('J')
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #include "vm/gc_marker.h" 5 #include "vm/gc_marker.h"
6 6
7 #include <map>
8 #include <utility>
9 #include <vector>
10
11 #include "vm/allocation.h" 7 #include "vm/allocation.h"
12 #include "vm/dart_api_state.h" 8 #include "vm/dart_api_state.h"
13 #include "vm/isolate.h" 9 #include "vm/isolate.h"
14 #include "vm/log.h" 10 #include "vm/log.h"
15 #include "vm/pages.h" 11 #include "vm/pages.h"
16 #include "vm/raw_object.h" 12 #include "vm/raw_object.h"
17 #include "vm/stack_frame.h" 13 #include "vm/stack_frame.h"
18 #include "vm/store_buffer.h" 14 #include "vm/store_buffer.h"
19 #include "vm/thread_barrier.h" 15 #include "vm/thread_barrier.h"
20 #include "vm/thread_pool.h" 16 #include "vm/thread_pool.h"
21 #include "vm/thread_registry.h" 17 #include "vm/thread_registry.h"
22 #include "vm/timeline.h" 18 #include "vm/timeline.h"
23 #include "vm/visitor.h" 19 #include "vm/visitor.h"
24 #include "vm/object_id_ring.h" 20 #include "vm/object_id_ring.h"
25 21
26 namespace dart { 22 namespace dart {
27 23
28 class DelaySet {
29 private:
30 typedef std::multimap<RawObject*, RawWeakProperty*> Map;
31 typedef std::pair<RawObject*, RawWeakProperty*> MapEntry;
32
33 public:
34 DelaySet() : mutex_(new Mutex()) {}
35 ~DelaySet() { delete mutex_; }
36
37 // After atomically setting the watched bit on a white key (see
38 // EnsureWatchedIfWhitewhich; this means the mark bit cannot be set
39 // without observing the watched bit), this method atomically
40 // inserts raw_weak if its key is *still* white, so that any future
41 // call to VisitValuesForKey is guaranteed to include its
42 // value. Returns true on success, and false if the key is no longer white.
43 bool InsertIfWhite(RawWeakProperty* raw_weak) {
44 MutexLocker ml(mutex_);
45 RawObject* raw_key = raw_weak->ptr()->key_;
46 if (raw_key->IsMarked()) return false;
47 // The key was white *after* acquiring the lock. Thus any future call to
48 // VisitValuesForKey is guaranteed to include the entry inserted below.
49 delay_set_.insert(std::make_pair(raw_key, raw_weak));
50 return true;
51 }
52
53 void ClearReferences() {
54 MutexLocker ml(mutex_);
55 for (Map::iterator it = delay_set_.begin(); it != delay_set_.end(); ++it) {
56 ASSERT(!it->first->IsMarked());
57 WeakProperty::Clear(it->second);
58 }
59 }
60
61 // Visit all values with a key equal to raw_obj, which must already be marked.
62 void VisitValuesForKey(RawObject* raw_obj, ObjectPointerVisitor* visitor) {
63 ASSERT(raw_obj->IsMarked());
64 // Extract the range into a temporary vector to iterate over it
65 // while delay_set_ may be modified.
66 std::vector<MapEntry> temp_copy;
67 {
68 MutexLocker ml(mutex_);
69 std::pair<Map::iterator, Map::iterator> ret =
70 delay_set_.equal_range(raw_obj);
71 temp_copy.insert(temp_copy.end(), ret.first, ret.second);
72 delay_set_.erase(ret.first, ret.second);
73 }
74 for (std::vector<MapEntry>::iterator it = temp_copy.begin();
75 it != temp_copy.end(); ++it) {
76 it->second->VisitPointers(visitor);
77 }
78 }
79
80 private:
81 Map delay_set_;
82 Mutex* mutex_;
83 };
84
85
86 class SkippedCodeFunctions : public ZoneAllocated { 24 class SkippedCodeFunctions : public ZoneAllocated {
87 public: 25 public:
88 SkippedCodeFunctions() {} 26 SkippedCodeFunctions() {}
89 27
90 void Add(RawFunction* func) { 28 void Add(RawFunction* func) {
91 skipped_code_functions_.Add(func); 29 skipped_code_functions_.Add(func);
92 } 30 }
93 31
94 void DetachCode() { 32 void DetachCode() {
95 intptr_t unoptimized_code_count = 0; 33 intptr_t unoptimized_code_count = 0;
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after
199 }; 137 };
200 138
201 139
202 template<bool sync> 140 template<bool sync>
203 class MarkingVisitorBase : public ObjectPointerVisitor { 141 class MarkingVisitorBase : public ObjectPointerVisitor {
204 public: 142 public:
205 MarkingVisitorBase(Isolate* isolate, 143 MarkingVisitorBase(Isolate* isolate,
206 Heap* heap, 144 Heap* heap,
207 PageSpace* page_space, 145 PageSpace* page_space,
208 MarkingStack* marking_stack, 146 MarkingStack* marking_stack,
209 DelaySet* delay_set,
210 SkippedCodeFunctions* skipped_code_functions) 147 SkippedCodeFunctions* skipped_code_functions)
211 : ObjectPointerVisitor(isolate), 148 : ObjectPointerVisitor(isolate),
212 thread_(Thread::Current()), 149 thread_(Thread::Current()),
213 heap_(heap), 150 heap_(heap),
214 vm_heap_(Dart::vm_isolate()->heap()), 151 vm_heap_(Dart::vm_isolate()->heap()),
215 class_stats_count_(isolate->class_table()->NumCids()), 152 class_stats_count_(isolate->class_table()->NumCids()),
216 class_stats_size_(isolate->class_table()->NumCids()), 153 class_stats_size_(isolate->class_table()->NumCids()),
217 page_space_(page_space), 154 page_space_(page_space),
218 work_list_(marking_stack), 155 work_list_(marking_stack),
219 delay_set_(delay_set), 156 delayed_weak_properties_(NULL),
220 visiting_old_object_(NULL), 157 visiting_old_object_(NULL),
221 skipped_code_functions_(skipped_code_functions), 158 skipped_code_functions_(skipped_code_functions),
222 marked_bytes_(0) { 159 marked_bytes_(0) {
223 ASSERT(heap_ != vm_heap_); 160 ASSERT(heap_ != vm_heap_);
224 ASSERT(thread_->isolate() == isolate); 161 ASSERT(thread_->isolate() == isolate);
225 class_stats_count_.SetLength(isolate->class_table()->NumCids()); 162 class_stats_count_.SetLength(isolate->class_table()->NumCids());
226 class_stats_size_.SetLength(isolate->class_table()->NumCids()); 163 class_stats_size_.SetLength(isolate->class_table()->NumCids());
227 for (intptr_t i = 0; i < class_stats_count_.length(); ++i) { 164 for (intptr_t i = 0; i < class_stats_count_.length(); ++i) {
228 class_stats_count_[i] = 0; 165 class_stats_count_[i] = 0;
229 class_stats_size_[i] = 0; 166 class_stats_size_[i] = 0;
(...skipping 11 matching lines...) Expand all
241 } 178 }
242 179
243 // Returns true if some non-zero amount of work was performed. 180 // Returns true if some non-zero amount of work was performed.
244 bool DrainMarkingStack() { 181 bool DrainMarkingStack() {
245 RawObject* raw_obj = work_list_.Pop(); 182 RawObject* raw_obj = work_list_.Pop();
246 if (raw_obj == NULL) { 183 if (raw_obj == NULL) {
247 ASSERT(visiting_old_object_ == NULL); 184 ASSERT(visiting_old_object_ == NULL);
248 return false; 185 return false;
249 } 186 }
250 do { 187 do {
251 VisitingOldObject(raw_obj); 188 do {
252 const intptr_t class_id = raw_obj->GetClassId(); 189 // First drain the marking stacks.
253 if (class_id != kWeakPropertyCid) { 190 VisitingOldObject(raw_obj);
254 marked_bytes_ += raw_obj->VisitPointers(this); 191 const intptr_t class_id = raw_obj->GetClassId();
255 } else { 192 if (class_id != kWeakPropertyCid) {
256 RawWeakProperty* raw_weak = reinterpret_cast<RawWeakProperty*>(raw_obj); 193 marked_bytes_ += raw_obj->VisitPointers(this);
257 marked_bytes_ += raw_weak->Size(); 194 } else {
258 ProcessWeakProperty(raw_weak); 195 RawWeakProperty* raw_weak =
196 reinterpret_cast<RawWeakProperty*>(raw_obj);
197 marked_bytes_ += ProcessWeakProperty(raw_weak);
198 }
199 raw_obj = work_list_.Pop();
200 } while (raw_obj != NULL);
201
202 // Marking stack is empty.
203 // Process all the pending weak properties in this visitor.
204 RawWeakProperty* cur_weak = delayed_weak_properties_;
205 delayed_weak_properties_ = NULL;
206 while (cur_weak != NULL) {
207 uword next_weak = cur_weak->ptr()->next_;
208 RawObject* raw_key = cur_weak->ptr()->key_;
209 // Reset the next pointer in the weak property.
210 cur_weak->ptr()->next_ = 0;
211 if (raw_key->IsMarked()) {
212 // The key is marked so we make sure to properly visit all pointers
213 // originating from this weak property.
214 VisitingOldObject(cur_weak);
215 cur_weak->VisitPointers(this);
216 } else {
217 // Requeue this weak property to be handled later.
218 EnqueueWeakProperty(cur_weak);
219 }
220 // Advance to next weak property in the queue.
221 cur_weak = reinterpret_cast<RawWeakProperty*>(next_weak);
259 } 222 }
223
224 // Check whether any further work was pushed either by other markers or
225 // by the handling of weak properties.
260 raw_obj = work_list_.Pop(); 226 raw_obj = work_list_.Pop();
261 } while (raw_obj != NULL); 227 } while (raw_obj != NULL);
262 VisitingOldObject(NULL); 228 VisitingOldObject(NULL);
263 return true; 229 return true;
264 } 230 }
265 231
266 void VisitPointers(RawObject** first, RawObject** last) { 232 void VisitPointers(RawObject** first, RawObject** last) {
267 for (RawObject** current = first; current <= last; current++) { 233 for (RawObject** current = first; current <= last; current++) {
268 MarkObject(*current, current); 234 MarkObject(*current, current);
269 } 235 }
270 } 236 }
271 237
272 bool visit_function_code() const { 238 bool visit_function_code() const {
273 return skipped_code_functions_ == NULL; 239 return skipped_code_functions_ == NULL;
274 } 240 }
275 241
276 virtual void add_skipped_code_function(RawFunction* func) { 242 virtual void add_skipped_code_function(RawFunction* func) {
277 ASSERT(!visit_function_code()); 243 ASSERT(!visit_function_code());
278 skipped_code_functions_->Add(func); 244 skipped_code_functions_->Add(func);
279 } 245 }
280 246
281 // If unmarked, sets the watch bit and returns true. 247 void EnqueueWeakProperty(RawWeakProperty* raw_weak) {
282 // If marked, does nothing and returns false. 248 ASSERT(raw_weak->IsHeapObject());
283 static bool EnsureWatchedIfWhite(RawObject* obj) { 249 ASSERT(raw_weak->IsOldObject());
284 if (!sync) { 250 ASSERT(raw_weak->IsWeakProperty());
285 if (obj->IsMarked()) return false; 251 ASSERT(raw_weak->IsMarked());
286 if (!obj->IsWatched()) obj->SetWatchedBitUnsynchronized(); 252 ASSERT(raw_weak->ptr()->next_ == 0);
287 return true; 253 raw_weak->ptr()->next_ = reinterpret_cast<uword>(delayed_weak_properties_);
288 } 254 delayed_weak_properties_ = raw_weak;
289 uword tags = obj->ptr()->tags_;
290 uword old_tags;
291 do {
292 old_tags = tags;
293 if (RawObject::MarkBit::decode(tags)) return false;
294 if (RawObject::WatchedBit::decode(tags)) return true;
295 uword new_tags = RawObject::WatchedBit::update(true, old_tags);
296 tags = AtomicOperations::CompareAndSwapWord(
297 &obj->ptr()->tags_, old_tags, new_tags);
298 } while (tags != old_tags);
299 return true;
300 } 255 }
301 256
302 void ProcessWeakProperty(RawWeakProperty* raw_weak) { 257 intptr_t ProcessWeakProperty(RawWeakProperty* raw_weak) {
303 // The fate of the weak property is determined by its key. 258 // The fate of the weak property is determined by its key.
304 RawObject* raw_key = raw_weak->ptr()->key_; 259 RawObject* raw_key = raw_weak->ptr()->key_;
305 if (raw_key->IsHeapObject() && 260 if (raw_key->IsHeapObject() &&
306 raw_key->IsOldObject() && 261 raw_key->IsOldObject() &&
307 EnsureWatchedIfWhite(raw_key) && 262 !raw_key->IsMarked()) {
308 delay_set_->InsertIfWhite(raw_weak)) { 263 // Key was white. Enqueue the weak property.
309 // Key was white. Delayed the weak property. 264 EnqueueWeakProperty(raw_weak);
310 } else { 265 return raw_weak->Size();
311 // Key is gray or black. Make the weak property black.
312 raw_weak->VisitPointers(this);
313 } 266 }
267 // Key is gray or black. Make the weak property black.
268 return raw_weak->VisitPointers(this);
314 } 269 }
315 270
316 // Called when all marking is complete. 271 // Called when all marking is complete.
317 void Finalize() { 272 void Finalize() {
318 work_list_.Finalize(); 273 work_list_.Finalize();
274 // Detach code from functions.
319 if (skipped_code_functions_ != NULL) { 275 if (skipped_code_functions_ != NULL) {
320 skipped_code_functions_->DetachCode(); 276 skipped_code_functions_->DetachCode();
321 } 277 }
278 // Clear pending weak properties.
279 RawWeakProperty* cur_weak = delayed_weak_properties_;
280 delayed_weak_properties_ = NULL;
281 intptr_t weak_properties_cleared = 0;
282 while (cur_weak != NULL) {
283 uword next_weak = cur_weak->ptr()->next_;
284 cur_weak->ptr()->next_ = 0;
285 WeakProperty::Clear(cur_weak);
siva 2016/05/23 20:35:33 Maybe set next_ to 0 inside Clear so reseting of a
286 weak_properties_cleared++;
287 // Advance to next weak property in the queue.
288 cur_weak = reinterpret_cast<RawWeakProperty*>(next_weak);
289 }
322 } 290 }
323 291
324 void VisitingOldObject(RawObject* obj) { 292 void VisitingOldObject(RawObject* obj) {
325 ASSERT((obj == NULL) || obj->IsOldObject()); 293 ASSERT((obj == NULL) || obj->IsOldObject());
326 visiting_old_object_ = obj; 294 visiting_old_object_ = obj;
327 } 295 }
328 296
329 private: 297 private:
330 void PushMarked(RawObject* raw_obj) { 298 void PushMarked(RawObject* raw_obj) {
331 ASSERT(raw_obj->IsHeapObject()); 299 ASSERT(raw_obj->IsHeapObject());
332 ASSERT((FLAG_verify_before_gc || FLAG_verify_before_gc) ? 300 ASSERT((FLAG_verify_before_gc || FLAG_verify_before_gc) ?
333 page_space_->Contains(RawObject::ToAddr(raw_obj)) : 301 page_space_->Contains(RawObject::ToAddr(raw_obj)) :
334 true); 302 true);
335 303
336 // Push the marked object on the marking stack. 304 // Push the marked object on the marking stack.
337 ASSERT(raw_obj->IsMarked()); 305 ASSERT(raw_obj->IsMarked());
338 const bool is_watched = raw_obj->IsWatched();
339 // We acquired the mark bit => no other task is modifying the header. 306 // We acquired the mark bit => no other task is modifying the header.
340 // TODO(koda): For concurrent mutator, this needs synchronization. Consider 307 // TODO(koda): For concurrent mutator, this needs synchronization. Consider
341 // clearing these bits already in the CAS for the mark bit. 308 // clearing these bits already in the CAS for the mark bit.
342 raw_obj->ClearRememberedBitUnsynchronized(); 309 raw_obj->ClearRememberedBitUnsynchronized();
343 raw_obj->ClearWatchedBitUnsynchronized();
344 if (is_watched) {
345 delay_set_->VisitValuesForKey(raw_obj, this);
346 }
347 work_list_.Push(raw_obj); 310 work_list_.Push(raw_obj);
348 } 311 }
349 312
350 static bool TryAcquireMarkBit(RawObject* raw_obj) { 313 static bool TryAcquireMarkBit(RawObject* raw_obj) {
351 if (!sync) { 314 if (!sync) {
352 if (raw_obj->IsMarked()) return false; 315 if (raw_obj->IsMarked()) return false;
353 raw_obj->SetMarkBitUnsynchronized(); 316 raw_obj->SetMarkBitUnsynchronized();
354 return true; 317 return true;
355 } 318 }
356 return raw_obj->TryAcquireMarkBit(); 319 return raw_obj->TryAcquireMarkBit();
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
423 class_stats_size_[class_id] += size; 386 class_stats_size_[class_id] += size;
424 } 387 }
425 388
426 Thread* thread_; 389 Thread* thread_;
427 Heap* heap_; 390 Heap* heap_;
428 Heap* vm_heap_; 391 Heap* vm_heap_;
429 GrowableArray<intptr_t> class_stats_count_; 392 GrowableArray<intptr_t> class_stats_count_;
430 GrowableArray<intptr_t> class_stats_size_; 393 GrowableArray<intptr_t> class_stats_size_;
431 PageSpace* page_space_; 394 PageSpace* page_space_;
432 MarkerWorkList work_list_; 395 MarkerWorkList work_list_;
433 DelaySet* delay_set_; 396 RawWeakProperty* delayed_weak_properties_;
434 RawObject* visiting_old_object_; 397 RawObject* visiting_old_object_;
435 SkippedCodeFunctions* skipped_code_functions_; 398 SkippedCodeFunctions* skipped_code_functions_;
436 uintptr_t marked_bytes_; 399 uintptr_t marked_bytes_;
437 400
438 DISALLOW_IMPLICIT_CONSTRUCTORS(MarkingVisitorBase); 401 DISALLOW_IMPLICIT_CONSTRUCTORS(MarkingVisitorBase);
439 }; 402 };
440 403
441 404
442 typedef MarkingVisitorBase<false> UnsyncMarkingVisitor; 405 typedef MarkingVisitorBase<false> UnsyncMarkingVisitor;
443 typedef MarkingVisitorBase<true> SyncMarkingVisitor; 406 typedef MarkingVisitorBase<true> SyncMarkingVisitor;
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after
567 } 530 }
568 531
569 532
570 class MarkTask : public ThreadPool::Task { 533 class MarkTask : public ThreadPool::Task {
571 public: 534 public:
572 MarkTask(GCMarker* marker, 535 MarkTask(GCMarker* marker,
573 Isolate* isolate, 536 Isolate* isolate,
574 Heap* heap, 537 Heap* heap,
575 PageSpace* page_space, 538 PageSpace* page_space,
576 MarkingStack* marking_stack, 539 MarkingStack* marking_stack,
577 DelaySet* delay_set,
578 ThreadBarrier* barrier, 540 ThreadBarrier* barrier,
579 bool collect_code, 541 bool collect_code,
580 intptr_t task_index, 542 intptr_t task_index,
581 intptr_t num_tasks, 543 intptr_t num_tasks,
582 uintptr_t* num_busy) 544 uintptr_t* num_busy)
583 : marker_(marker), 545 : marker_(marker),
584 isolate_(isolate), 546 isolate_(isolate),
585 heap_(heap), 547 heap_(heap),
586 page_space_(page_space), 548 page_space_(page_space),
587 marking_stack_(marking_stack), 549 marking_stack_(marking_stack),
588 delay_set_(delay_set),
589 barrier_(barrier), 550 barrier_(barrier),
590 collect_code_(collect_code), 551 collect_code_(collect_code),
591 task_index_(task_index), 552 task_index_(task_index),
592 num_tasks_(num_tasks), 553 num_tasks_(num_tasks),
593 num_busy_(num_busy) { 554 num_busy_(num_busy) {
594 } 555 }
595 556
596 virtual void Run() { 557 virtual void Run() {
597 bool result = 558 bool result =
598 Thread::EnterIsolateAsHelper(isolate_, Thread::kMarkerTask, true); 559 Thread::EnterIsolateAsHelper(isolate_, Thread::kMarkerTask, true);
599 ASSERT(result); 560 ASSERT(result);
600 { 561 {
601 Thread* thread = Thread::Current(); 562 Thread* thread = Thread::Current();
602 TIMELINE_FUNCTION_GC_DURATION(thread, "MarkTask"); 563 TIMELINE_FUNCTION_GC_DURATION(thread, "MarkTask");
603 StackZone stack_zone(thread); 564 StackZone stack_zone(thread);
604 Zone* zone = stack_zone.GetZone(); 565 Zone* zone = stack_zone.GetZone();
605 SkippedCodeFunctions* skipped_code_functions = 566 SkippedCodeFunctions* skipped_code_functions =
606 collect_code_ ? new(zone) SkippedCodeFunctions() : NULL; 567 collect_code_ ? new(zone) SkippedCodeFunctions() : NULL;
607 SyncMarkingVisitor visitor(isolate_, heap_, page_space_, marking_stack_, 568 SyncMarkingVisitor visitor(isolate_, heap_, page_space_, marking_stack_,
608 delay_set_, skipped_code_functions); 569 skipped_code_functions);
609 // Phase 1: Iterate over roots and drain marking stack in tasks. 570 // Phase 1: Iterate over roots and drain marking stack in tasks.
610 marker_->IterateRoots(isolate_, &visitor, task_index_, num_tasks_); 571 marker_->IterateRoots(isolate_, &visitor, task_index_, num_tasks_);
611 do { 572 do {
612 visitor.DrainMarkingStack(); 573 visitor.DrainMarkingStack();
613 574
614 // I can't find more work right now. If no other task is busy, 575 // I can't find more work right now. If no other task is busy,
615 // then there will never be more work (NB: 1 is *before* decrement). 576 // then there will never be more work (NB: 1 is *before* decrement).
616 if (AtomicOperations::FetchAndDecrement(num_busy_) == 1) break; 577 if (AtomicOperations::FetchAndDecrement(num_busy_) == 1) break;
617 578
618 // Wait for some work to appear. 579 // Wait for some work to appear.
(...skipping 27 matching lines...) Expand all
646 // This task is done. Notify the original thread. 607 // This task is done. Notify the original thread.
647 barrier_->Exit(); 608 barrier_->Exit();
648 } 609 }
649 610
650 private: 611 private:
651 GCMarker* marker_; 612 GCMarker* marker_;
652 Isolate* isolate_; 613 Isolate* isolate_;
653 Heap* heap_; 614 Heap* heap_;
654 PageSpace* page_space_; 615 PageSpace* page_space_;
655 MarkingStack* marking_stack_; 616 MarkingStack* marking_stack_;
656 DelaySet* delay_set_;
657 ThreadBarrier* barrier_; 617 ThreadBarrier* barrier_;
658 bool collect_code_; 618 bool collect_code_;
659 const intptr_t task_index_; 619 const intptr_t task_index_;
660 const intptr_t num_tasks_; 620 const intptr_t num_tasks_;
661 uintptr_t* num_busy_; 621 uintptr_t* num_busy_;
662 622
663 DISALLOW_COPY_AND_ASSIGN(MarkTask); 623 DISALLOW_COPY_AND_ASSIGN(MarkTask);
664 }; 624 };
665 625
666 626
(...skipping 21 matching lines...) Expand all
688 PageSpace* page_space, 648 PageSpace* page_space,
689 bool invoke_api_callbacks, 649 bool invoke_api_callbacks,
690 bool collect_code) { 650 bool collect_code) {
691 Prologue(isolate, invoke_api_callbacks); 651 Prologue(isolate, invoke_api_callbacks);
692 // The API prologue/epilogue may create/destroy zones, so we must not 652 // The API prologue/epilogue may create/destroy zones, so we must not
693 // depend on zone allocations surviving beyond the epilogue callback. 653 // depend on zone allocations surviving beyond the epilogue callback.
694 { 654 {
695 StackZone stack_zone(Thread::Current()); 655 StackZone stack_zone(Thread::Current());
696 Zone* zone = stack_zone.GetZone(); 656 Zone* zone = stack_zone.GetZone();
697 MarkingStack marking_stack; 657 MarkingStack marking_stack;
698 DelaySet delay_set;
699 marked_bytes_ = 0; 658 marked_bytes_ = 0;
700 const int num_tasks = FLAG_marker_tasks; 659 const int num_tasks = FLAG_marker_tasks;
701 if (num_tasks == 0) { 660 if (num_tasks == 0) {
702 // Mark everything on main thread. 661 // Mark everything on main thread.
703 SkippedCodeFunctions* skipped_code_functions = 662 SkippedCodeFunctions* skipped_code_functions =
704 collect_code ? new(zone) SkippedCodeFunctions() : NULL; 663 collect_code ? new(zone) SkippedCodeFunctions() : NULL;
705 UnsyncMarkingVisitor mark(isolate, heap_, page_space, &marking_stack, 664 UnsyncMarkingVisitor mark(isolate, heap_, page_space, &marking_stack,
706 &delay_set, skipped_code_functions); 665 skipped_code_functions);
707 IterateRoots(isolate, &mark, 0, 1); 666 IterateRoots(isolate, &mark, 0, 1);
708 mark.DrainMarkingStack(); 667 mark.DrainMarkingStack();
709 MarkingWeakVisitor mark_weak; 668 MarkingWeakVisitor mark_weak;
710 IterateWeakRoots(isolate, &mark_weak); 669 IterateWeakRoots(isolate, &mark_weak);
711 // All marking done; detach code, etc. 670 // All marking done; detach code, etc.
712 FinalizeResultsFrom(&mark); 671 FinalizeResultsFrom(&mark);
713 } else { 672 } else {
714 ThreadBarrier barrier(num_tasks + 1, 673 ThreadBarrier barrier(num_tasks + 1,
715 heap_->barrier(), 674 heap_->barrier(),
716 heap_->barrier_done()); 675 heap_->barrier_done());
717 // Used to coordinate draining among tasks; all start out as 'busy'. 676 // Used to coordinate draining among tasks; all start out as 'busy'.
718 uintptr_t num_busy = num_tasks; 677 uintptr_t num_busy = num_tasks;
719 // Phase 1: Iterate over roots and drain marking stack in tasks. 678 // Phase 1: Iterate over roots and drain marking stack in tasks.
720 for (intptr_t i = 0; i < num_tasks; ++i) { 679 for (intptr_t i = 0; i < num_tasks; ++i) {
721 MarkTask* mark_task = 680 MarkTask* mark_task =
722 new MarkTask(this, isolate, heap_, page_space, &marking_stack, 681 new MarkTask(this, isolate, heap_, page_space, &marking_stack,
723 &delay_set, &barrier, collect_code, 682 &barrier, collect_code,
724 i, num_tasks, &num_busy); 683 i, num_tasks, &num_busy);
725 ThreadPool* pool = Dart::thread_pool(); 684 ThreadPool* pool = Dart::thread_pool();
726 pool->Run(mark_task); 685 pool->Run(mark_task);
727 } 686 }
728 barrier.Sync(); 687 barrier.Sync();
729 688
730 // Phase 2: Weak processing and follow-up marking on main thread. 689 // Phase 2: Weak processing on main thread.
731 SkippedCodeFunctions* skipped_code_functions =
732 collect_code ? new(zone) SkippedCodeFunctions() : NULL;
733 SyncMarkingVisitor mark(isolate, heap_, page_space, &marking_stack,
734 &delay_set, skipped_code_functions);
735 MarkingWeakVisitor mark_weak; 690 MarkingWeakVisitor mark_weak;
736 IterateWeakRoots(isolate, &mark_weak); 691 IterateWeakRoots(isolate, &mark_weak);
737 barrier.Sync(); 692 barrier.Sync();
738 693
739 // Phase 3: Finalize results from all markers (detach code, etc.). 694 // Phase 3: Finalize results from all markers (detach code, etc.).
740 if (FLAG_log_marker_tasks) {
741 THR_Print("Main thread marked %" Pd " bytes.\n",
742 mark.marked_bytes());
743 }
744 FinalizeResultsFrom(&mark);
745 barrier.Exit(); 695 barrier.Exit();
746 } 696 }
747 delay_set.ClearReferences();
748 ProcessWeakTables(page_space); 697 ProcessWeakTables(page_space);
749 ProcessObjectIdTable(isolate); 698 ProcessObjectIdTable(isolate);
750 } 699 }
751 Epilogue(isolate, invoke_api_callbacks); 700 Epilogue(isolate, invoke_api_callbacks);
752 } 701 }
753 702
754 } // namespace dart 703 } // namespace dart
OLDNEW
« no previous file with comments | « no previous file | runtime/vm/object.cc » ('j') | runtime/vm/raw_object.h » ('J')

Powered by Google App Engine
This is Rietveld 408576698