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

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