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

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

Issue 2481873005: clang-format runtime/vm (Closed)
Patch Set: Merge Created 4 years, 1 month 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 | « runtime/vm/gc_marker.h ('k') | runtime/vm/gc_sweeper.cc » ('j') | no next file with comments »
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 "vm/allocation.h" 7 #include "vm/allocation.h"
8 #include "vm/dart_api_state.h" 8 #include "vm/dart_api_state.h"
9 #include "vm/isolate.h" 9 #include "vm/isolate.h"
10 #include "vm/log.h" 10 #include "vm/log.h"
11 #include "vm/pages.h" 11 #include "vm/pages.h"
12 #include "vm/raw_object.h" 12 #include "vm/raw_object.h"
13 #include "vm/stack_frame.h" 13 #include "vm/stack_frame.h"
14 #include "vm/store_buffer.h" 14 #include "vm/store_buffer.h"
15 #include "vm/thread_barrier.h" 15 #include "vm/thread_barrier.h"
16 #include "vm/thread_pool.h" 16 #include "vm/thread_pool.h"
17 #include "vm/thread_registry.h" 17 #include "vm/thread_registry.h"
18 #include "vm/timeline.h" 18 #include "vm/timeline.h"
19 #include "vm/visitor.h" 19 #include "vm/visitor.h"
20 #include "vm/object_id_ring.h" 20 #include "vm/object_id_ring.h"
21 21
22 namespace dart { 22 namespace dart {
23 23
24 class SkippedCodeFunctions : public ZoneAllocated { 24 class SkippedCodeFunctions : public ZoneAllocated {
25 public: 25 public:
26 SkippedCodeFunctions() {} 26 SkippedCodeFunctions() {}
27 27
28 void Add(RawFunction* func) { 28 void Add(RawFunction* func) { skipped_code_functions_.Add(func); }
29 skipped_code_functions_.Add(func);
30 }
31 29
32 void DetachCode() { 30 void DetachCode() {
33 #if defined(DART_PRECOMPILED_RUNTIME) 31 #if defined(DART_PRECOMPILED_RUNTIME)
34 UNREACHABLE(); 32 UNREACHABLE();
35 #else 33 #else
36 intptr_t unoptimized_code_count = 0; 34 intptr_t unoptimized_code_count = 0;
37 intptr_t current_code_count = 0; 35 intptr_t current_code_count = 0;
38 for (int i = 0; i < skipped_code_functions_.length(); i++) { 36 for (int i = 0; i < skipped_code_functions_.length(); i++) {
39 RawFunction* func = skipped_code_functions_[i]; 37 RawFunction* func = skipped_code_functions_[i];
40 RawCode* code = func->ptr()->code_; 38 RawCode* code = func->ptr()->code_;
41 if (!code->IsMarked()) { 39 if (!code->IsMarked()) {
42 // If the code wasn't strongly visited through other references 40 // If the code wasn't strongly visited through other references
43 // after skipping the function's code pointer, then we disconnect the 41 // after skipping the function's code pointer, then we disconnect the
44 // code from the function. 42 // code from the function.
45 func->StorePointer( 43 func->StorePointer(&(func->ptr()->code_),
46 &(func->ptr()->code_), 44 StubCode::LazyCompile_entry()->code());
47 StubCode::LazyCompile_entry()->code());
48 uword entry_point = StubCode::LazyCompile_entry()->EntryPoint(); 45 uword entry_point = StubCode::LazyCompile_entry()->EntryPoint();
49 func->ptr()->entry_point_ = entry_point; 46 func->ptr()->entry_point_ = entry_point;
50 if (FLAG_log_code_drop) { 47 if (FLAG_log_code_drop) {
51 // NOTE: This code runs while GC is in progress and runs within 48 // NOTE: This code runs while GC is in progress and runs within
52 // a NoHandleScope block. Hence it is not okay to use a regular Zone 49 // a NoHandleScope block. Hence it is not okay to use a regular Zone
53 // or Scope handle. We use a direct stack handle so the raw pointer in 50 // or Scope handle. We use a direct stack handle so the raw pointer in
54 // this handle is not traversed. The use of a handle is mainly to 51 // this handle is not traversed. The use of a handle is mainly to
55 // be able to reuse the handle based code and avoid having to add 52 // be able to reuse the handle based code and avoid having to add
56 // helper functions to the raw object interface. 53 // helper functions to the raw object interface.
57 String name; 54 String name;
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
134 // Fail fast on attempts to mark after finalizing. 131 // Fail fast on attempts to mark after finalizing.
135 marking_stack_ = NULL; 132 marking_stack_ = NULL;
136 } 133 }
137 134
138 private: 135 private:
139 MarkingStack::Block* work_; 136 MarkingStack::Block* work_;
140 MarkingStack* marking_stack_; 137 MarkingStack* marking_stack_;
141 }; 138 };
142 139
143 140
144 template<bool sync> 141 template <bool sync>
145 class MarkingVisitorBase : public ObjectPointerVisitor { 142 class MarkingVisitorBase : public ObjectPointerVisitor {
146 public: 143 public:
147 MarkingVisitorBase(Isolate* isolate, 144 MarkingVisitorBase(Isolate* isolate,
148 Heap* heap, 145 Heap* heap,
149 PageSpace* page_space, 146 PageSpace* page_space,
150 MarkingStack* marking_stack, 147 MarkingStack* marking_stack,
151 SkippedCodeFunctions* skipped_code_functions) 148 SkippedCodeFunctions* skipped_code_functions)
152 : ObjectPointerVisitor(isolate), 149 : ObjectPointerVisitor(isolate),
153 thread_(Thread::Current()), 150 thread_(Thread::Current()),
154 heap_(heap), 151 heap_(heap),
155 vm_heap_(Dart::vm_isolate()->heap()), 152 vm_heap_(Dart::vm_isolate()->heap()),
156 class_stats_count_(isolate->class_table()->NumCids()), 153 class_stats_count_(isolate->class_table()->NumCids()),
157 class_stats_size_(isolate->class_table()->NumCids()), 154 class_stats_size_(isolate->class_table()->NumCids()),
158 page_space_(page_space), 155 page_space_(page_space),
159 work_list_(marking_stack), 156 work_list_(marking_stack),
160 delayed_weak_properties_(NULL), 157 delayed_weak_properties_(NULL),
161 visiting_old_object_(NULL), 158 visiting_old_object_(NULL),
162 skipped_code_functions_(skipped_code_functions), 159 skipped_code_functions_(skipped_code_functions),
163 marked_bytes_(0) { 160 marked_bytes_(0) {
164 ASSERT(heap_ != vm_heap_); 161 ASSERT(heap_ != vm_heap_);
165 ASSERT(thread_->isolate() == isolate); 162 ASSERT(thread_->isolate() == isolate);
166 class_stats_count_.SetLength(isolate->class_table()->NumCids()); 163 class_stats_count_.SetLength(isolate->class_table()->NumCids());
167 class_stats_size_.SetLength(isolate->class_table()->NumCids()); 164 class_stats_size_.SetLength(isolate->class_table()->NumCids());
168 for (intptr_t i = 0; i < class_stats_count_.length(); ++i) { 165 for (intptr_t i = 0; i < class_stats_count_.length(); ++i) {
169 class_stats_count_[i] = 0; 166 class_stats_count_[i] = 0;
170 class_stats_size_[i] = 0; 167 class_stats_size_[i] = 0;
171 } 168 }
172 } 169 }
173 170
174 uintptr_t marked_bytes() const { return marked_bytes_; } 171 uintptr_t marked_bytes() const { return marked_bytes_; }
175 172
176 intptr_t live_count(intptr_t class_id) { 173 intptr_t live_count(intptr_t class_id) {
177 return class_stats_count_[class_id]; 174 return class_stats_count_[class_id];
178 } 175 }
179 176
180 intptr_t live_size(intptr_t class_id) { 177 intptr_t live_size(intptr_t class_id) { return class_stats_size_[class_id]; }
181 return class_stats_size_[class_id];
182 }
183 178
184 bool ProcessPendingWeakProperties() { 179 bool ProcessPendingWeakProperties() {
185 bool marked = false; 180 bool marked = false;
186 RawWeakProperty* cur_weak = delayed_weak_properties_; 181 RawWeakProperty* cur_weak = delayed_weak_properties_;
187 delayed_weak_properties_ = NULL; 182 delayed_weak_properties_ = NULL;
188 while (cur_weak != NULL) { 183 while (cur_weak != NULL) {
189 uword next_weak = cur_weak->ptr()->next_; 184 uword next_weak = cur_weak->ptr()->next_;
190 RawObject* raw_key = cur_weak->ptr()->key_; 185 RawObject* raw_key = cur_weak->ptr()->key_;
191 // Reset the next pointer in the weak property. 186 // Reset the next pointer in the weak property.
192 cur_weak->ptr()->next_ = 0; 187 cur_weak->ptr()->next_ = 0;
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
243 } while (raw_obj != NULL); 238 } while (raw_obj != NULL);
244 VisitingOldObject(NULL); 239 VisitingOldObject(NULL);
245 } 240 }
246 241
247 void VisitPointers(RawObject** first, RawObject** last) { 242 void VisitPointers(RawObject** first, RawObject** last) {
248 for (RawObject** current = first; current <= last; current++) { 243 for (RawObject** current = first; current <= last; current++) {
249 MarkObject(*current, current); 244 MarkObject(*current, current);
250 } 245 }
251 } 246 }
252 247
253 bool visit_function_code() const { 248 bool visit_function_code() const { return skipped_code_functions_ == NULL; }
254 return skipped_code_functions_ == NULL;
255 }
256 249
257 virtual void add_skipped_code_function(RawFunction* func) { 250 virtual void add_skipped_code_function(RawFunction* func) {
258 ASSERT(!visit_function_code()); 251 ASSERT(!visit_function_code());
259 skipped_code_functions_->Add(func); 252 skipped_code_functions_->Add(func);
260 } 253 }
261 254
262 void EnqueueWeakProperty(RawWeakProperty* raw_weak) { 255 void EnqueueWeakProperty(RawWeakProperty* raw_weak) {
263 ASSERT(raw_weak->IsHeapObject()); 256 ASSERT(raw_weak->IsHeapObject());
264 ASSERT(raw_weak->IsOldObject()); 257 ASSERT(raw_weak->IsOldObject());
265 ASSERT(raw_weak->IsWeakProperty()); 258 ASSERT(raw_weak->IsWeakProperty());
266 ASSERT(raw_weak->IsMarked()); 259 ASSERT(raw_weak->IsMarked());
267 ASSERT(raw_weak->ptr()->next_ == 0); 260 ASSERT(raw_weak->ptr()->next_ == 0);
268 raw_weak->ptr()->next_ = reinterpret_cast<uword>(delayed_weak_properties_); 261 raw_weak->ptr()->next_ = reinterpret_cast<uword>(delayed_weak_properties_);
269 delayed_weak_properties_ = raw_weak; 262 delayed_weak_properties_ = raw_weak;
270 } 263 }
271 264
272 intptr_t ProcessWeakProperty(RawWeakProperty* raw_weak) { 265 intptr_t ProcessWeakProperty(RawWeakProperty* raw_weak) {
273 // The fate of the weak property is determined by its key. 266 // The fate of the weak property is determined by its key.
274 RawObject* raw_key = raw_weak->ptr()->key_; 267 RawObject* raw_key = raw_weak->ptr()->key_;
275 if (raw_key->IsHeapObject() && 268 if (raw_key->IsHeapObject() && raw_key->IsOldObject() &&
276 raw_key->IsOldObject() &&
277 !raw_key->IsMarked()) { 269 !raw_key->IsMarked()) {
278 // Key was white. Enqueue the weak property. 270 // Key was white. Enqueue the weak property.
279 EnqueueWeakProperty(raw_weak); 271 EnqueueWeakProperty(raw_weak);
280 return raw_weak->Size(); 272 return raw_weak->Size();
281 } 273 }
282 // Key is gray or black. Make the weak property black. 274 // Key is gray or black. Make the weak property black.
283 return raw_weak->VisitPointers(this); 275 return raw_weak->VisitPointers(this);
284 } 276 }
285 277
286 // Called when all marking is complete. 278 // Called when all marking is complete.
(...skipping 19 matching lines...) Expand all
306 } 298 }
307 299
308 void VisitingOldObject(RawObject* obj) { 300 void VisitingOldObject(RawObject* obj) {
309 ASSERT((obj == NULL) || obj->IsOldObject()); 301 ASSERT((obj == NULL) || obj->IsOldObject());
310 visiting_old_object_ = obj; 302 visiting_old_object_ = obj;
311 } 303 }
312 304
313 private: 305 private:
314 void PushMarked(RawObject* raw_obj) { 306 void PushMarked(RawObject* raw_obj) {
315 ASSERT(raw_obj->IsHeapObject()); 307 ASSERT(raw_obj->IsHeapObject());
316 ASSERT((FLAG_verify_before_gc || FLAG_verify_before_gc) ? 308 ASSERT((FLAG_verify_before_gc || FLAG_verify_before_gc)
317 page_space_->Contains(RawObject::ToAddr(raw_obj)) : 309 ? page_space_->Contains(RawObject::ToAddr(raw_obj))
318 true); 310 : true);
319 311
320 // Push the marked object on the marking stack. 312 // Push the marked object on the marking stack.
321 ASSERT(raw_obj->IsMarked()); 313 ASSERT(raw_obj->IsMarked());
322 // We acquired the mark bit => no other task is modifying the header. 314 // We acquired the mark bit => no other task is modifying the header.
323 // TODO(koda): For concurrent mutator, this needs synchronization. Consider 315 // TODO(koda): For concurrent mutator, this needs synchronization. Consider
324 // clearing these bits already in the CAS for the mark bit. 316 // clearing these bits already in the CAS for the mark bit.
325 raw_obj->ClearRememberedBitUnsynchronized(); 317 raw_obj->ClearRememberedBitUnsynchronized();
326 work_list_.Push(raw_obj); 318 work_list_.Push(raw_obj);
327 } 319 }
328 320
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
431 } 423 }
432 if (!raw_obj->IsOldObject()) { 424 if (!raw_obj->IsOldObject()) {
433 return false; 425 return false;
434 } 426 }
435 return !raw_obj->IsMarked(); 427 return !raw_obj->IsMarked();
436 } 428 }
437 429
438 430
439 class MarkingWeakVisitor : public HandleVisitor { 431 class MarkingWeakVisitor : public HandleVisitor {
440 public: 432 public:
441 MarkingWeakVisitor(Thread* thread, FinalizationQueue* queue) : 433 MarkingWeakVisitor(Thread* thread, FinalizationQueue* queue)
442 HandleVisitor(thread), queue_(queue) { } 434 : HandleVisitor(thread), queue_(queue) {}
443 435
444 void VisitHandle(uword addr) { 436 void VisitHandle(uword addr) {
445 FinalizablePersistentHandle* handle = 437 FinalizablePersistentHandle* handle =
446 reinterpret_cast<FinalizablePersistentHandle*>(addr); 438 reinterpret_cast<FinalizablePersistentHandle*>(addr);
447 RawObject* raw_obj = handle->raw(); 439 RawObject* raw_obj = handle->raw();
448 if (IsUnreachable(raw_obj)) { 440 if (IsUnreachable(raw_obj)) {
449 handle->UpdateUnreachable(thread()->isolate(), queue_); 441 handle->UpdateUnreachable(thread()->isolate(), queue_);
450 } 442 }
451 } 443 }
452 444
(...skipping 16 matching lines...) Expand all
469 461
470 void GCMarker::Epilogue(Isolate* isolate, bool invoke_api_callbacks) { 462 void GCMarker::Epilogue(Isolate* isolate, bool invoke_api_callbacks) {
471 if (invoke_api_callbacks && (isolate->gc_epilogue_callback() != NULL)) { 463 if (invoke_api_callbacks && (isolate->gc_epilogue_callback() != NULL)) {
472 (isolate->gc_epilogue_callback())(); 464 (isolate->gc_epilogue_callback())();
473 } 465 }
474 } 466 }
475 467
476 468
477 void GCMarker::IterateRoots(Isolate* isolate, 469 void GCMarker::IterateRoots(Isolate* isolate,
478 ObjectPointerVisitor* visitor, 470 ObjectPointerVisitor* visitor,
479 intptr_t slice_index, intptr_t num_slices) { 471 intptr_t slice_index,
472 intptr_t num_slices) {
480 ASSERT(0 <= slice_index && slice_index < num_slices); 473 ASSERT(0 <= slice_index && slice_index < num_slices);
481 if ((slice_index == 0) || (num_slices <= 1)) { 474 if ((slice_index == 0) || (num_slices <= 1)) {
482 isolate->VisitObjectPointers(visitor, 475 isolate->VisitObjectPointers(visitor,
483 StackFrameIterator::kDontValidateFrames); 476 StackFrameIterator::kDontValidateFrames);
484 } 477 }
485 if ((slice_index == 1) || (num_slices <= 1)) { 478 if ((slice_index == 1) || (num_slices <= 1)) {
486 heap_->new_space()->VisitObjectPointers(visitor); 479 heap_->new_space()->VisitObjectPointers(visitor);
487 } 480 }
488 481
489 // For now, we just distinguish two parts of the root set, so any remaining 482 // For now, we just distinguish two parts of the root set, so any remaining
490 // slices are empty. 483 // slices are empty.
491 } 484 }
492 485
493 486
494 void GCMarker::IterateWeakRoots(Isolate* isolate, HandleVisitor* visitor) { 487 void GCMarker::IterateWeakRoots(Isolate* isolate, HandleVisitor* visitor) {
495 ApiState* state = isolate->api_state(); 488 ApiState* state = isolate->api_state();
496 ASSERT(state != NULL); 489 ASSERT(state != NULL);
497 isolate->VisitWeakPersistentHandles(visitor); 490 isolate->VisitWeakPersistentHandles(visitor);
498 } 491 }
499 492
500 493
501 void GCMarker::ProcessWeakTables(PageSpace* page_space) { 494 void GCMarker::ProcessWeakTables(PageSpace* page_space) {
502 for (int sel = 0; 495 for (int sel = 0; sel < Heap::kNumWeakSelectors; sel++) {
503 sel < Heap::kNumWeakSelectors; 496 WeakTable* table =
504 sel++) { 497 heap_->GetWeakTable(Heap::kOld, static_cast<Heap::WeakSelector>(sel));
505 WeakTable* table = heap_->GetWeakTable(
506 Heap::kOld, static_cast<Heap::WeakSelector>(sel));
507 intptr_t size = table->size(); 498 intptr_t size = table->size();
508 for (intptr_t i = 0; i < size; i++) { 499 for (intptr_t i = 0; i < size; i++) {
509 if (table->IsValidEntryAt(i)) { 500 if (table->IsValidEntryAt(i)) {
510 RawObject* raw_obj = table->ObjectAt(i); 501 RawObject* raw_obj = table->ObjectAt(i);
511 ASSERT(raw_obj->IsHeapObject()); 502 ASSERT(raw_obj->IsHeapObject());
512 if (!raw_obj->IsMarked()) { 503 if (!raw_obj->IsMarked()) {
513 table->InvalidateAt(i); 504 table->InvalidateAt(i);
514 } 505 }
515 } 506 }
516 } 507 }
517 } 508 }
518 } 509 }
519 510
520 511
521 class ObjectIdRingClearPointerVisitor : public ObjectPointerVisitor { 512 class ObjectIdRingClearPointerVisitor : public ObjectPointerVisitor {
522 public: 513 public:
523 explicit ObjectIdRingClearPointerVisitor(Isolate* isolate) : 514 explicit ObjectIdRingClearPointerVisitor(Isolate* isolate)
524 ObjectPointerVisitor(isolate) {} 515 : ObjectPointerVisitor(isolate) {}
525 516
526 517
527 void VisitPointers(RawObject** first, RawObject** last) { 518 void VisitPointers(RawObject** first, RawObject** last) {
528 for (RawObject** current = first; current <= last; current++) { 519 for (RawObject** current = first; current <= last; current++) {
529 RawObject* raw_obj = *current; 520 RawObject* raw_obj = *current;
530 ASSERT(raw_obj->IsHeapObject()); 521 ASSERT(raw_obj->IsHeapObject());
531 if (raw_obj->IsOldObject() && !raw_obj->IsMarked()) { 522 if (raw_obj->IsOldObject() && !raw_obj->IsMarked()) {
532 // Object has become garbage. Replace it will null. 523 // Object has become garbage. Replace it will null.
533 *current = Object::null(); 524 *current = Object::null();
534 } 525 }
(...skipping 29 matching lines...) Expand all
564 uintptr_t* num_busy) 555 uintptr_t* num_busy)
565 : marker_(marker), 556 : marker_(marker),
566 isolate_(isolate), 557 isolate_(isolate),
567 heap_(heap), 558 heap_(heap),
568 page_space_(page_space), 559 page_space_(page_space),
569 marking_stack_(marking_stack), 560 marking_stack_(marking_stack),
570 barrier_(barrier), 561 barrier_(barrier),
571 collect_code_(collect_code), 562 collect_code_(collect_code),
572 task_index_(task_index), 563 task_index_(task_index),
573 num_tasks_(num_tasks), 564 num_tasks_(num_tasks),
574 num_busy_(num_busy) { 565 num_busy_(num_busy) {}
575 }
576 566
577 virtual void Run() { 567 virtual void Run() {
578 bool result = 568 bool result =
579 Thread::EnterIsolateAsHelper(isolate_, Thread::kMarkerTask, true); 569 Thread::EnterIsolateAsHelper(isolate_, Thread::kMarkerTask, true);
580 ASSERT(result); 570 ASSERT(result);
581 { 571 {
582 Thread* thread = Thread::Current(); 572 Thread* thread = Thread::Current();
583 TIMELINE_FUNCTION_GC_DURATION(thread, "MarkTask"); 573 TIMELINE_FUNCTION_GC_DURATION(thread, "MarkTask");
584 StackZone stack_zone(thread); 574 StackZone stack_zone(thread);
585 Zone* zone = stack_zone.GetZone(); 575 Zone* zone = stack_zone.GetZone();
586 SkippedCodeFunctions* skipped_code_functions = 576 SkippedCodeFunctions* skipped_code_functions =
587 collect_code_ ? new(zone) SkippedCodeFunctions() : NULL; 577 collect_code_ ? new (zone) SkippedCodeFunctions() : NULL;
588 SyncMarkingVisitor visitor(isolate_, heap_, page_space_, marking_stack_, 578 SyncMarkingVisitor visitor(isolate_, heap_, page_space_, marking_stack_,
589 skipped_code_functions); 579 skipped_code_functions);
590 // Phase 1: Iterate over roots and drain marking stack in tasks. 580 // Phase 1: Iterate over roots and drain marking stack in tasks.
591 marker_->IterateRoots(isolate_, &visitor, task_index_, num_tasks_); 581 marker_->IterateRoots(isolate_, &visitor, task_index_, num_tasks_);
592 582
593 bool more_to_mark = false; 583 bool more_to_mark = false;
594 do { 584 do {
595 do { 585 do {
596 visitor.DrainMarkingStack(); 586 visitor.DrainMarkingStack();
597 587
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
641 more_to_mark = true; 631 more_to_mark = true;
642 } 632 }
643 barrier_->Sync(); 633 barrier_->Sync();
644 } while (more_to_mark); 634 } while (more_to_mark);
645 635
646 // Phase 2: Weak processing and follow-up marking on main thread. 636 // Phase 2: Weak processing and follow-up marking on main thread.
647 barrier_->Sync(); 637 barrier_->Sync();
648 638
649 // Phase 3: Finalize results from all markers (detach code, etc.). 639 // Phase 3: Finalize results from all markers (detach code, etc.).
650 if (FLAG_log_marker_tasks) { 640 if (FLAG_log_marker_tasks) {
651 THR_Print("Task %" Pd " marked %" Pd " bytes.\n", 641 THR_Print("Task %" Pd " marked %" Pd " bytes.\n", task_index_,
652 task_index_, visitor.marked_bytes()); 642 visitor.marked_bytes());
653 } 643 }
654 marker_->FinalizeResultsFrom(&visitor); 644 marker_->FinalizeResultsFrom(&visitor);
655 } 645 }
656 Thread::ExitIsolateAsHelper(true); 646 Thread::ExitIsolateAsHelper(true);
657 647
658 // This task is done. Notify the original thread. 648 // This task is done. Notify the original thread.
659 barrier_->Exit(); 649 barrier_->Exit();
660 } 650 }
661 651
662 private: 652 private:
663 GCMarker* marker_; 653 GCMarker* marker_;
664 Isolate* isolate_; 654 Isolate* isolate_;
665 Heap* heap_; 655 Heap* heap_;
666 PageSpace* page_space_; 656 PageSpace* page_space_;
667 MarkingStack* marking_stack_; 657 MarkingStack* marking_stack_;
668 ThreadBarrier* barrier_; 658 ThreadBarrier* barrier_;
669 bool collect_code_; 659 bool collect_code_;
670 const intptr_t task_index_; 660 const intptr_t task_index_;
671 const intptr_t num_tasks_; 661 const intptr_t num_tasks_;
672 uintptr_t* num_busy_; 662 uintptr_t* num_busy_;
673 663
674 DISALLOW_COPY_AND_ASSIGN(MarkTask); 664 DISALLOW_COPY_AND_ASSIGN(MarkTask);
675 }; 665 };
676 666
677 667
678 template<class MarkingVisitorType> 668 template <class MarkingVisitorType>
679 void GCMarker::FinalizeResultsFrom(MarkingVisitorType* visitor) { 669 void GCMarker::FinalizeResultsFrom(MarkingVisitorType* visitor) {
680 { 670 {
681 MutexLocker ml(&stats_mutex_); 671 MutexLocker ml(&stats_mutex_);
682 marked_bytes_ += visitor->marked_bytes(); 672 marked_bytes_ += visitor->marked_bytes();
683 #ifndef PRODUCT 673 #ifndef PRODUCT
684 // Class heap stats are not themselves thread-safe yet, so we update the 674 // Class heap stats are not themselves thread-safe yet, so we update the
685 // stats while holding stats_mutex_. 675 // stats while holding stats_mutex_.
686 ClassTable* table = heap_->isolate()->class_table(); 676 ClassTable* table = heap_->isolate()->class_table();
687 for (intptr_t i = 0; i < table->NumCids(); ++i) { 677 for (intptr_t i = 0; i < table->NumCids(); ++i) {
688 const intptr_t count = visitor->live_count(i); 678 const intptr_t count = visitor->live_count(i);
(...skipping 18 matching lines...) Expand all
707 { 697 {
708 Thread* thread = Thread::Current(); 698 Thread* thread = Thread::Current();
709 StackZone stack_zone(thread); 699 StackZone stack_zone(thread);
710 Zone* zone = stack_zone.GetZone(); 700 Zone* zone = stack_zone.GetZone();
711 MarkingStack marking_stack; 701 MarkingStack marking_stack;
712 marked_bytes_ = 0; 702 marked_bytes_ = 0;
713 const int num_tasks = FLAG_marker_tasks; 703 const int num_tasks = FLAG_marker_tasks;
714 if (num_tasks == 0) { 704 if (num_tasks == 0) {
715 // Mark everything on main thread. 705 // Mark everything on main thread.
716 SkippedCodeFunctions* skipped_code_functions = 706 SkippedCodeFunctions* skipped_code_functions =
717 collect_code ? new(zone) SkippedCodeFunctions() : NULL; 707 collect_code ? new (zone) SkippedCodeFunctions() : NULL;
718 UnsyncMarkingVisitor mark(isolate, heap_, page_space, &marking_stack, 708 UnsyncMarkingVisitor mark(isolate, heap_, page_space, &marking_stack,
719 skipped_code_functions); 709 skipped_code_functions);
720 IterateRoots(isolate, &mark, 0, 1); 710 IterateRoots(isolate, &mark, 0, 1);
721 mark.DrainMarkingStack(); 711 mark.DrainMarkingStack();
722 { 712 {
723 TIMELINE_FUNCTION_GC_DURATION(thread, "WeakHandleProcessing"); 713 TIMELINE_FUNCTION_GC_DURATION(thread, "WeakHandleProcessing");
724 if (FLAG_background_finalization) { 714 if (FLAG_background_finalization) {
725 FinalizationQueue* queue = new FinalizationQueue(); 715 FinalizationQueue* queue = new FinalizationQueue();
726 MarkingWeakVisitor mark_weak(thread, queue); 716 MarkingWeakVisitor mark_weak(thread, queue);
727 IterateWeakRoots(isolate, &mark_weak); 717 IterateWeakRoots(isolate, &mark_weak);
728 if (queue->length() > 0) { 718 if (queue->length() > 0) {
729 Dart::thread_pool()->Run(new BackgroundFinalizer(isolate, queue)); 719 Dart::thread_pool()->Run(new BackgroundFinalizer(isolate, queue));
730 } else { 720 } else {
731 delete queue; 721 delete queue;
732 } 722 }
733 } else { 723 } else {
734 MarkingWeakVisitor mark_weak(thread, NULL); 724 MarkingWeakVisitor mark_weak(thread, NULL);
735 IterateWeakRoots(isolate, &mark_weak); 725 IterateWeakRoots(isolate, &mark_weak);
736 } 726 }
737 } 727 }
738 // All marking done; detach code, etc. 728 // All marking done; detach code, etc.
739 FinalizeResultsFrom(&mark); 729 FinalizeResultsFrom(&mark);
740 } else { 730 } else {
741 ThreadBarrier barrier(num_tasks + 1, 731 ThreadBarrier barrier(num_tasks + 1, heap_->barrier(),
742 heap_->barrier(),
743 heap_->barrier_done()); 732 heap_->barrier_done());
744 // Used to coordinate draining among tasks; all start out as 'busy'. 733 // Used to coordinate draining among tasks; all start out as 'busy'.
745 uintptr_t num_busy = num_tasks; 734 uintptr_t num_busy = num_tasks;
746 // Phase 1: Iterate over roots and drain marking stack in tasks. 735 // Phase 1: Iterate over roots and drain marking stack in tasks.
747 for (intptr_t i = 0; i < num_tasks; ++i) { 736 for (intptr_t i = 0; i < num_tasks; ++i) {
748 MarkTask* mark_task = 737 MarkTask* mark_task =
749 new MarkTask(this, isolate, heap_, page_space, &marking_stack, 738 new MarkTask(this, isolate, heap_, page_space, &marking_stack,
750 &barrier, collect_code, 739 &barrier, collect_code, i, num_tasks, &num_busy);
751 i, num_tasks, &num_busy);
752 ThreadPool* pool = Dart::thread_pool(); 740 ThreadPool* pool = Dart::thread_pool();
753 pool->Run(mark_task); 741 pool->Run(mark_task);
754 } 742 }
755 bool more_to_mark = false; 743 bool more_to_mark = false;
756 do { 744 do {
757 // Wait for all markers to stop. 745 // Wait for all markers to stop.
758 barrier.Sync(); 746 barrier.Sync();
759 #if defined(DEBUG) 747 #if defined(DEBUG)
760 ASSERT(AtomicOperations::LoadRelaxed(&num_busy) == 0); 748 ASSERT(AtomicOperations::LoadRelaxed(&num_busy) == 0);
761 // Caveat: must not allow any marker to continue past the barrier 749 // Caveat: must not allow any marker to continue past the barrier
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
795 // Phase 3: Finalize results from all markers (detach code, etc.). 783 // Phase 3: Finalize results from all markers (detach code, etc.).
796 barrier.Exit(); 784 barrier.Exit();
797 } 785 }
798 ProcessWeakTables(page_space); 786 ProcessWeakTables(page_space);
799 ProcessObjectIdTable(isolate); 787 ProcessObjectIdTable(isolate);
800 } 788 }
801 Epilogue(isolate, invoke_api_callbacks); 789 Epilogue(isolate, invoke_api_callbacks);
802 } 790 }
803 791
804 } // namespace dart 792 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/gc_marker.h ('k') | runtime/vm/gc_sweeper.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698