Flutter Engine
The Flutter Engine
Public Member Functions | Static Public Member Functions | List of all members
dart::MarkingVisitorBase< sync > Class Template Reference
Inheritance diagram for dart::MarkingVisitorBase< sync >:
dart::ObjectPointerVisitor

Public Member Functions

 MarkingVisitorBase (IsolateGroup *isolate_group, PageSpace *page_space, MarkingStack *old_marking_stack, MarkingStack *new_marking_stack, MarkingStack *tlab_deferred_marking_stack, MarkingStack *deferred_marking_stack)
 
 ~MarkingVisitorBase ()
 
uintptr_t marked_bytes () const
 
int64_t marked_micros () const
 
void AddMicros (int64_t micros)
 
void set_concurrent (bool value)
 
void FinishedRoots ()
 
bool ProcessPendingWeakProperties ()
 
DART_NOINLINE void YieldConcurrentMarking ()
 
void DrainMarkingStackWithPauseChecks ()
 
intptr_t VisitCards (ArrayPtr obj)
 
void DrainMarkingStack ()
 
void ProcessOldMarkingStackUntil (int64_t deadline)
 
bool ProcessOldMarkingStack (intptr_t remaining_budget)
 
NO_SANITIZE_THREAD ObjectPtr LoadPointerIgnoreRace (ObjectPtr *ptr)
 
NO_SANITIZE_THREAD CompressedObjectPtr LoadCompressedPointerIgnoreRace (CompressedObjectPtr *ptr)
 
void VisitPointers (ObjectPtr *first, ObjectPtr *last) override
 
intptr_t ProcessWeakProperty (WeakPropertyPtr raw_weak)
 
intptr_t ProcessWeakReference (WeakReferencePtr raw_weak)
 
intptr_t ProcessWeakArray (WeakArrayPtr raw_weak)
 
intptr_t ProcessFinalizerEntry (FinalizerEntryPtr raw_entry)
 
void ProcessDeferredMarking ()
 
void FinalizeMarking ()
 
void MournWeakProperties ()
 
void MournWeakReferences ()
 
void MournWeakArrays ()
 
void MournFinalizerEntries ()
 
bool WaitForWork (RelaxedAtomic< uintptr_t > *num_busy)
 
void Flush (GCLinkedLists *global_list)
 
void Adopt (GCLinkedLists *other)
 
void AbandonWork ()
 
void FinalizeIncremental (GCLinkedLists *global_list)
 
GCLinkedListsdelayed ()
 
- Public Member Functions inherited from dart::ObjectPointerVisitor
 ObjectPointerVisitor (IsolateGroup *isolate_group)
 
virtual ~ObjectPointerVisitor ()
 
IsolateGroupisolate_group () const
 
virtual void VisitTypedDataViewPointers (TypedDataViewPtr view, CompressedObjectPtr *first, CompressedObjectPtr *last)
 
virtual void VisitPointers (ObjectPtr *first, ObjectPtr *last)=0
 
void VisitCompressedPointers (uword heap_base, CompressedObjectPtr *first, CompressedObjectPtr *last)
 
void VisitPointers (ObjectPtr *p, intptr_t len)
 
void VisitPointer (ObjectPtr *p)
 
const char * gc_root_type () const
 
void set_gc_root_type (const char *gc_root_type)
 
void clear_gc_root_type ()
 
virtual bool visit_weak_persistent_handles () const
 
virtual bool trace_values_through_fields () const
 
const ClassTableclass_table () const
 
virtual bool CanVisitSuspendStatePointers (SuspendStatePtr suspend_state)
 

Static Public Member Functions

static bool IsMarked (ObjectPtr raw)
 
static bool ForwardOrSetNullIfCollected (ObjectPtr parent, CompressedObjectPtr *slot)
 

Detailed Description

template<bool sync>
class dart::MarkingVisitorBase< sync >

Definition at line 28 of file marker.cc.

Constructor & Destructor Documentation

◆ MarkingVisitorBase()

template<bool sync>
dart::MarkingVisitorBase< sync >::MarkingVisitorBase ( IsolateGroup isolate_group,
PageSpace page_space,
MarkingStack old_marking_stack,
MarkingStack new_marking_stack,
MarkingStack tlab_deferred_marking_stack,
MarkingStack deferred_marking_stack 
)
inline

Definition at line 30 of file marker.cc.

37 page_space_(page_space),
38 old_work_list_(old_marking_stack),
39 new_work_list_(new_marking_stack),
40 tlab_deferred_work_list_(tlab_deferred_marking_stack),
41 deferred_work_list_(deferred_marking_stack),
42 marked_bytes_(0),
43 marked_micros_(0),
44 concurrent_(true),
45 has_evacuation_candidate_(false) {}
IsolateGroup * isolate_group() const
Definition: visitor.h:25
ObjectPointerVisitor(IsolateGroup *isolate_group)
Definition: visitor.cc:11

◆ ~MarkingVisitorBase()

template<bool sync>
dart::MarkingVisitorBase< sync >::~MarkingVisitorBase ( )
inline

Definition at line 46 of file marker.cc.

46{ ASSERT(delayed_.IsEmpty()); }
#define ASSERT(E)

Member Function Documentation

◆ AbandonWork()

template<bool sync>
void dart::MarkingVisitorBase< sync >::AbandonWork ( )
inline

Definition at line 605 of file marker.cc.

605 {
606 old_work_list_.AbandonWork();
607 new_work_list_.AbandonWork();
608 tlab_deferred_work_list_.AbandonWork();
609 deferred_work_list_.AbandonWork();
610 delayed_.Release();
611 }

◆ AddMicros()

template<bool sync>
void dart::MarkingVisitorBase< sync >::AddMicros ( int64_t  micros)
inline

Definition at line 50 of file marker.cc.

50{ marked_micros_ += micros; }

◆ Adopt()

template<bool sync>
void dart::MarkingVisitorBase< sync >::Adopt ( GCLinkedLists other)
inline

Definition at line 600 of file marker.cc.

600 {
601 ASSERT(delayed_.IsEmpty());
602 other->FlushInto(&delayed_);
603 }

◆ delayed()

template<bool sync>
GCLinkedLists * dart::MarkingVisitorBase< sync >::delayed ( )
inline

Definition at line 625 of file marker.cc.

625{ return &delayed_; }

◆ DrainMarkingStack()

template<bool sync>
void dart::MarkingVisitorBase< sync >::DrainMarkingStack ( )
inline

Definition at line 234 of file marker.cc.

234 {
235 ASSERT(!concurrent_);
236 Thread* thread = Thread::Current();
237 do {
238 ObjectPtr obj;
239 while (MarkerWorkList::Pop(&old_work_list_, &new_work_list_, &obj)) {
240 ASSERT(!has_evacuation_candidate_);
241
242 const intptr_t class_id = obj->GetClassId();
243 ASSERT(class_id != kIllegalCid);
244 ASSERT(class_id != kFreeListElement);
245 ASSERT(class_id != kForwardingCorpse);
246
247 intptr_t size;
248 if (class_id == kWeakPropertyCid) {
249 size = ProcessWeakProperty(static_cast<WeakPropertyPtr>(obj));
250 } else if (class_id == kWeakReferenceCid) {
251 size = ProcessWeakReference(static_cast<WeakReferencePtr>(obj));
252 } else if (class_id == kWeakArrayCid) {
253 size = ProcessWeakArray(static_cast<WeakArrayPtr>(obj));
254 } else if (class_id == kFinalizerEntryCid) {
255 size = ProcessFinalizerEntry(static_cast<FinalizerEntryPtr>(obj));
256 } else {
257 if (obj->untag()->IsCardRemembered()) {
258 ASSERT((class_id == kArrayCid) || (class_id == kImmutableArrayCid));
259 size = VisitCards(static_cast<ArrayPtr>(obj));
260 } else {
261 size = obj->untag()->VisitPointersNonvirtual(this);
262 }
263 }
264 if (has_evacuation_candidate_) {
265 has_evacuation_candidate_ = false;
266 if (!obj->untag()->IsCardRemembered() &&
267 obj->untag()->TryAcquireRememberedBit()) {
268 thread->StoreBufferAddObjectGC(obj);
269 }
270 }
271 if (!obj->IsNewObject()) {
272 marked_bytes_ += size;
273 }
274 }
276 }
DART_FORCE_INLINE bool Pop(ObjectPtr *object)
intptr_t ProcessWeakProperty(WeakPropertyPtr raw_weak)
Definition: marker.cc:396
intptr_t VisitCards(ArrayPtr obj)
Definition: marker.cc:190
intptr_t ProcessWeakArray(WeakArrayPtr raw_weak)
Definition: marker.cc:439
intptr_t ProcessWeakReference(WeakReferencePtr raw_weak)
Definition: marker.cc:411
intptr_t ProcessFinalizerEntry(FinalizerEntryPtr raw_entry)
Definition: marker.cc:444
bool ProcessPendingWeakProperties()
Definition: marker.cc:67
static Thread * Current()
Definition: thread.h:362
@ kForwardingCorpse
Definition: class_id.h:225
@ kIllegalCid
Definition: class_id.h:214
@ kFreeListElement
Definition: class_id.h:224
it will be possible to load the file into Perfetto s trace viewer disable asset Prevents usage of any non test fonts unless they were explicitly Loaded via prefetched default font Indicates whether the embedding started a prefetch of the default font manager before creating the engine run In non interactive keep the shell running after the Dart script has completed enable serial On low power devices with low core running concurrent GC tasks on threads can cause them to contend with the UI thread which could potentially lead to jank This option turns off all concurrent GC activities domain network JSON encoded network policy per domain This overrides the DisallowInsecureConnections switch Embedder can specify whether to allow or disallow insecure connections at a domain level old gen heap size
Definition: switches.h:259

◆ DrainMarkingStackWithPauseChecks()

template<bool sync>
void dart::MarkingVisitorBase< sync >::DrainMarkingStackWithPauseChecks ( )
inline

Definition at line 117 of file marker.cc.

117 {
118 ASSERT(concurrent_);
119 Thread* thread = Thread::Current();
120 do {
121 ObjectPtr obj;
122 while (MarkerWorkList::Pop(&old_work_list_, &new_work_list_, &obj)) {
123 ASSERT(!has_evacuation_candidate_);
124
125 if (obj->IsNewObject()) {
126 Page* page = Page::Of(obj);
127 uword top = page->original_top();
128 uword end = page->original_end();
129 uword addr = static_cast<uword>(obj);
130 if (top <= addr && addr < end) {
131 // New-space objects still in a TLAB are deferred. This allows the
132 // compiler to remove write barriers for freshly allocated objects.
133 tlab_deferred_work_list_.Push(obj);
134 if (UNLIKELY(page_space_->pause_concurrent_marking())) {
136 }
137 continue;
138 }
139 }
140
141 const intptr_t class_id = obj->GetClassId();
142 ASSERT(class_id != kIllegalCid);
143 ASSERT(class_id != kFreeListElement);
144 ASSERT(class_id != kForwardingCorpse);
145
146 intptr_t size;
147 if (class_id == kWeakPropertyCid) {
148 size = ProcessWeakProperty(static_cast<WeakPropertyPtr>(obj));
149 } else if (class_id == kWeakReferenceCid) {
150 size = ProcessWeakReference(static_cast<WeakReferencePtr>(obj));
151 } else if (class_id == kWeakArrayCid) {
152 size = ProcessWeakArray(static_cast<WeakArrayPtr>(obj));
153 } else if (class_id == kFinalizerEntryCid) {
154 size = ProcessFinalizerEntry(static_cast<FinalizerEntryPtr>(obj));
155 } else if (class_id == kSuspendStateCid) {
156 // Shape changing is not compatible with concurrent marking.
157 deferred_work_list_.Push(obj);
158 size = obj->untag()->HeapSize();
159 } else if (obj->untag()->IsCardRemembered()) {
160 ASSERT((class_id == kArrayCid) || (class_id == kImmutableArrayCid));
161 size = VisitCards(static_cast<ArrayPtr>(obj));
162 } else {
163 size = obj->untag()->VisitPointersNonvirtual(this);
164 }
165 if (has_evacuation_candidate_) {
166 has_evacuation_candidate_ = false;
167 if (!obj->untag()->IsCardRemembered()) {
168 if (obj->untag()->TryAcquireRememberedBit()) {
169 thread->StoreBufferAddObjectGC(obj);
170 }
171 }
172 }
173 if (!obj->IsNewObject()) {
174 marked_bytes_ += size;
175 }
176
177 if (UNLIKELY(page_space_->pause_concurrent_marking())) {
179 }
180 }
182
183 ASSERT(old_work_list_.IsLocalEmpty());
184 // In case of scavenge before final marking.
185 new_work_list_.Flush();
186 tlab_deferred_work_list_.Flush();
187 deferred_work_list_.Flush();
188 }
void Push(ObjectPtr raw_obj)
DART_NOINLINE void YieldConcurrentMarking()
Definition: marker.cc:106
bool pause_concurrent_marking() const
Definition: pages.h:338
static Page * Of(ObjectPtr obj)
Definition: page.h:162
glong glong end
uintptr_t uword
Definition: globals.h:501
#define UNLIKELY(cond)
Definition: globals.h:261

◆ FinalizeIncremental()

template<bool sync>
void dart::MarkingVisitorBase< sync >::FinalizeIncremental ( GCLinkedLists global_list)
inline

Definition at line 613 of file marker.cc.

613 {
614 old_work_list_.Flush();
615 old_work_list_.Finalize();
616 new_work_list_.Flush();
617 new_work_list_.Finalize();
618 tlab_deferred_work_list_.Flush();
619 tlab_deferred_work_list_.Finalize();
620 deferred_work_list_.Flush();
621 deferred_work_list_.Finalize();
622 delayed_.FlushInto(global_list);
623 }
void FlushInto(GCLinkedLists *to)
Definition: gc_shared.cc:34

◆ FinalizeMarking()

template<bool sync>
void dart::MarkingVisitorBase< sync >::FinalizeMarking ( )
inline

Definition at line 503 of file marker.cc.

503 {
504 old_work_list_.Finalize();
505 new_work_list_.Finalize();
506 tlab_deferred_work_list_.Finalize();
507 deferred_work_list_.Finalize();
509 // MournFinalizerEntries inserts newly discovered dead entries into the
510 // linked list attached to the Finalizer. This might create
511 // cross-generational references which might be added to the store
512 // buffer. Release the store buffer to satisfy the invariant that
513 // thread local store buffer is empty after marking and all references
514 // are processed.
516 }
void MournFinalizerEntries()
Definition: marker.cc:552
void ReleaseStoreBuffer()
Definition: thread.cc:677

◆ FinishedRoots()

template<bool sync>
void dart::MarkingVisitorBase< sync >::FinishedRoots ( )
inline

Definition at line 62 of file marker.cc.

62 {
63 // Nothing to remember for roots. Don't carry over to objects.
64 has_evacuation_candidate_ = false;
65 }

◆ Flush()

template<bool sync>
void dart::MarkingVisitorBase< sync >::Flush ( GCLinkedLists global_list)
inline

Definition at line 592 of file marker.cc.

592 {
593 old_work_list_.Flush();
594 new_work_list_.Flush();
595 tlab_deferred_work_list_.Flush();
596 deferred_work_list_.Flush();
597 delayed_.FlushInto(global_list);
598 }

◆ ForwardOrSetNullIfCollected()

template<bool sync>
static bool dart::MarkingVisitorBase< sync >::ForwardOrSetNullIfCollected ( ObjectPtr  parent,
CompressedObjectPtr slot 
)
inlinestatic

Definition at line 563 of file marker.cc.

564 {
565 ObjectPtr target = slot->Decompress(parent->heap_base());
566 if (target->IsImmediateObject()) {
567 // Object not touched during this GC.
568 return false;
569 }
570 if (target->untag()->IsMarked()) {
571 // Object already null (which is permanently marked) or has survived this
572 // GC.
573 if (target->untag()->IsEvacuationCandidate()) {
574 if (parent->untag()->IsCardRemembered()) {
575 Page::Of(parent)->RememberCard(slot);
576 } else {
577 if (parent->untag()->TryAcquireRememberedBit()) {
579 }
580 }
581 }
582 return false;
583 }
584 *slot = Object::null();
585 return true;
586 }
static ObjectPtr null()
Definition: object.h:433
void RememberCard(ObjectPtr const *slot)
Definition: page.h:185
void StoreBufferAddObjectGC(ObjectPtr obj)
Definition: thread.cc:804
uint32_t * target

◆ IsMarked()

template<bool sync>
static bool dart::MarkingVisitorBase< sync >::IsMarked ( ObjectPtr  raw)
inlinestatic

Definition at line 57 of file marker.cc.

57 {
58 ASSERT(raw->IsHeapObject());
59 return raw->untag()->IsMarked();
60 }

◆ LoadCompressedPointerIgnoreRace()

template<bool sync>
NO_SANITIZE_THREAD CompressedObjectPtr dart::MarkingVisitorBase< sync >::LoadCompressedPointerIgnoreRace ( CompressedObjectPtr ptr)
inline

Definition at line 370 of file marker.cc.

371 {
372 return *ptr;
373 }

◆ LoadPointerIgnoreRace()

template<bool sync>
NO_SANITIZE_THREAD ObjectPtr dart::MarkingVisitorBase< sync >::LoadPointerIgnoreRace ( ObjectPtr ptr)
inline

Definition at line 368 of file marker.cc.

368{ return *ptr; }

◆ marked_bytes()

template<bool sync>
uintptr_t dart::MarkingVisitorBase< sync >::marked_bytes ( ) const
inline

Definition at line 48 of file marker.cc.

48{ return marked_bytes_; }

◆ marked_micros()

template<bool sync>
int64_t dart::MarkingVisitorBase< sync >::marked_micros ( ) const
inline

Definition at line 49 of file marker.cc.

49{ return marked_micros_; }

◆ MournFinalizerEntries()

template<bool sync>
void dart::MarkingVisitorBase< sync >::MournFinalizerEntries ( )
inline

Definition at line 552 of file marker.cc.

552 {
553 FinalizerEntryPtr current = delayed_.finalizer_entries.Release();
554 while (current != FinalizerEntry::null()) {
555 FinalizerEntryPtr next = current->untag()->next_seen_by_gc();
556 current->untag()->next_seen_by_gc_ = FinalizerEntry::null();
557 MournFinalizerEntry(this, current);
558 current = next;
559 }
560 }
static float next(float f)
void MournFinalizerEntry(GCVisitorType *visitor, FinalizerEntryPtr current_entry)
Definition: gc_shared.h:162

◆ MournWeakArrays()

template<bool sync>
void dart::MarkingVisitorBase< sync >::MournWeakArrays ( )
inline

Definition at line 539 of file marker.cc.

539 {
540 WeakArrayPtr current = delayed_.weak_arrays.Release();
541 while (current != WeakArray::null()) {
542 WeakArrayPtr next = current->untag()->next_seen_by_gc();
543 current->untag()->next_seen_by_gc_ = WeakArray::null();
544 intptr_t length = Smi::Value(current->untag()->length());
545 for (intptr_t i = 0; i < length; i++) {
546 ForwardOrSetNullIfCollected(current, &current->untag()->data()[i]);
547 }
548 current = next;
549 }
550 }
static bool ForwardOrSetNullIfCollected(ObjectPtr parent, CompressedObjectPtr *slot)
Definition: marker.cc:563
intptr_t Value() const
Definition: object.h:9990
size_t length

◆ MournWeakProperties()

template<bool sync>
void dart::MarkingVisitorBase< sync >::MournWeakProperties ( )
inline

Definition at line 518 of file marker.cc.

518 {
519 WeakPropertyPtr current = delayed_.weak_properties.Release();
520 while (current != WeakProperty::null()) {
521 WeakPropertyPtr next = current->untag()->next_seen_by_gc();
522 current->untag()->next_seen_by_gc_ = WeakProperty::null();
523 current->untag()->key_ = Object::null();
524 current->untag()->value_ = Object::null();
525 current = next;
526 }
527 }

◆ MournWeakReferences()

template<bool sync>
void dart::MarkingVisitorBase< sync >::MournWeakReferences ( )
inline

Definition at line 529 of file marker.cc.

529 {
530 WeakReferencePtr current = delayed_.weak_references.Release();
531 while (current != WeakReference::null()) {
532 WeakReferencePtr next = current->untag()->next_seen_by_gc();
533 current->untag()->next_seen_by_gc_ = WeakReference::null();
534 ForwardOrSetNullIfCollected(current, &current->untag()->target_);
535 current = next;
536 }
537 }

◆ ProcessDeferredMarking()

template<bool sync>
void dart::MarkingVisitorBase< sync >::ProcessDeferredMarking ( )
inline

Definition at line 459 of file marker.cc.

459 {
460 Thread* thread = Thread::Current();
461 TIMELINE_FUNCTION_GC_DURATION(thread, "ProcessDeferredMarking");
462
463 ObjectPtr obj;
464 while (deferred_work_list_.Pop(&obj)) {
465 ASSERT(!has_evacuation_candidate_);
466 ASSERT(obj->IsHeapObject());
467 // We need to scan objects even if they were already scanned via ordinary
468 // marking. An object may have changed since its ordinary scan and been
469 // added to deferred marking stack to compensate for write-barrier
470 // elimination.
471 // A given object may be included in the deferred marking stack multiple
472 // times. It may or may not also be in the ordinary marking stack, so
473 // failing to acquire the mark bit here doesn't reliably indicate the
474 // object was already encountered through the deferred marking stack. Our
475 // processing here is idempotent, so repeated visits only hurt performance
476 // but not correctness. Duplication is expected to be low.
477 // By the absence of a special case, we are treating WeakProperties as
478 // strong references here. This guarantees a WeakProperty will only be
479 // added to the delayed_weak_properties_ list of the worker that
480 // encounters it during ordinary marking. This is in the same spirit as
481 // the eliminated write barrier, which would have added the newly written
482 // key and value to the ordinary marking stack.
483 intptr_t size = obj->untag()->VisitPointersNonvirtual(this);
484 // Add the size only if we win the marking race to prevent
485 // double-counting.
486 if (TryAcquireMarkBit(obj)) {
487 if (!obj->IsNewObject()) {
488 marked_bytes_ += size;
489 }
490 }
491 if (has_evacuation_candidate_) {
492 has_evacuation_candidate_ = false;
493 if (!obj->untag()->IsCardRemembered() &&
494 obj->untag()->TryAcquireRememberedBit()) {
495 thread->StoreBufferAddObjectGC(obj);
496 }
497 }
498 }
499 }
#define TIMELINE_FUNCTION_GC_DURATION(thread, name)
Definition: timeline.h:41

◆ ProcessFinalizerEntry()

template<bool sync>
intptr_t dart::MarkingVisitorBase< sync >::ProcessFinalizerEntry ( FinalizerEntryPtr  raw_entry)
inline

Definition at line 444 of file marker.cc.

444 {
445 ASSERT(IsMarked(raw_entry));
446 delayed_.finalizer_entries.Enqueue(raw_entry);
447 // Only visit token and next.
448 if (MarkObject(LoadCompressedPointerIgnoreRace(&raw_entry->untag()->token_)
449 .Decompress(raw_entry->heap_base()))) {
450 has_evacuation_candidate_ = true;
451 }
452 if (MarkObject(LoadCompressedPointerIgnoreRace(&raw_entry->untag()->next_)
453 .Decompress(raw_entry->heap_base()))) {
454 has_evacuation_candidate_ = true;
455 }
456 return raw_entry->untag()->HeapSize();
457 }
static bool IsMarked(ObjectPtr raw)
Definition: marker.cc:57
NO_SANITIZE_THREAD CompressedObjectPtr LoadCompressedPointerIgnoreRace(CompressedObjectPtr *ptr)
Definition: marker.cc:370
ObjectPtr Decompress(uword heap_base) const

◆ ProcessOldMarkingStack()

template<bool sync>
bool dart::MarkingVisitorBase< sync >::ProcessOldMarkingStack ( intptr_t  remaining_budget)
inline

Definition at line 296 of file marker.cc.

296 {
297 Thread* thread = Thread::Current();
298 do {
299 // First drain the marking stacks.
300 ObjectPtr obj;
301 while (old_work_list_.Pop(&obj)) {
302 ASSERT(!has_evacuation_candidate_);
303
304 const intptr_t class_id = obj->GetClassId();
305 ASSERT(class_id != kIllegalCid);
306 ASSERT(class_id != kFreeListElement);
307 ASSERT(class_id != kForwardingCorpse);
308
309 intptr_t size;
310 if (class_id == kWeakPropertyCid) {
311 size = ProcessWeakProperty(static_cast<WeakPropertyPtr>(obj));
312 } else if (class_id == kWeakReferenceCid) {
313 size = ProcessWeakReference(static_cast<WeakReferencePtr>(obj));
314 } else if (class_id == kWeakArrayCid) {
315 size = ProcessWeakArray(static_cast<WeakArrayPtr>(obj));
316 } else if (class_id == kFinalizerEntryCid) {
317 size = ProcessFinalizerEntry(static_cast<FinalizerEntryPtr>(obj));
318 } else if (sync && concurrent_ && class_id == kSuspendStateCid) {
319 // Shape changing is not compatible with concurrent marking.
320 deferred_work_list_.Push(obj);
321 size = obj->untag()->HeapSize();
322 } else {
323 if ((class_id == kArrayCid) || (class_id == kImmutableArrayCid)) {
324 size = obj->untag()->HeapSize();
325 if (size > remaining_budget) {
326 old_work_list_.Push(obj);
327 return true; // More to mark.
328 }
329 }
330 if (obj->untag()->IsCardRemembered()) {
331 ASSERT((class_id == kArrayCid) || (class_id == kImmutableArrayCid));
332 size = VisitCards(static_cast<ArrayPtr>(obj));
333 } else {
334 size = obj->untag()->VisitPointersNonvirtual(this);
335 }
336 }
337 if (has_evacuation_candidate_) {
338 has_evacuation_candidate_ = false;
339 if (!obj->untag()->IsCardRemembered() &&
340 obj->untag()->TryAcquireRememberedBit()) {
341 thread->StoreBufferAddObjectGC(obj);
342 }
343 }
344 marked_bytes_ += size;
345 remaining_budget -= size;
346 if (remaining_budget < 0) {
347 return true; // More to mark.
348 }
349 }
350 // Marking stack is empty.
352
353 return false; // No more work.
354 }

◆ ProcessOldMarkingStackUntil()

template<bool sync>
void dart::MarkingVisitorBase< sync >::ProcessOldMarkingStackUntil ( int64_t  deadline)
inline

Definition at line 278 of file marker.cc.

278 {
279 // We check the clock *before* starting a batch of work, but we want to
280 // *end* work before the deadline. So we compare to the deadline adjusted
281 // by a conservative estimate of the duration of one batch of work.
282 deadline -= 1500;
283
284 // A 512kB budget is chosen to be large enough that we don't waste too much
285 // time on the overhead of exiting ProcessMarkingStack, querying the clock,
286 // and re-entering, and small enough that a few batches can fit in the idle
287 // time between animation frames. This amount of marking takes ~1ms on a
288 // Pixel phone.
289 constexpr intptr_t kBudget = 512 * KB;
290
291 while ((OS::GetCurrentMonotonicMicros() < deadline) &&
292 ProcessOldMarkingStack(kBudget)) {
293 }
294 }
bool ProcessOldMarkingStack(intptr_t remaining_budget)
Definition: marker.cc:296
static int64_t GetCurrentMonotonicMicros()
constexpr intptr_t KB
Definition: globals.h:528

◆ ProcessPendingWeakProperties()

template<bool sync>
bool dart::MarkingVisitorBase< sync >::ProcessPendingWeakProperties ( )
inline

Definition at line 67 of file marker.cc.

67 {
68 bool more_to_mark = false;
69 WeakPropertyPtr cur_weak = delayed_.weak_properties.Release();
70 while (cur_weak != WeakProperty::null()) {
71 WeakPropertyPtr next_weak =
72 cur_weak->untag()->next_seen_by_gc_.Decompress(cur_weak->heap_base());
73 ObjectPtr raw_key = cur_weak->untag()->key();
74 // Reset the next pointer in the weak property.
75 cur_weak->untag()->next_seen_by_gc_ = WeakProperty::null();
76 if (raw_key->IsImmediateObject() || raw_key->untag()->IsMarked()) {
77 ObjectPtr raw_val = cur_weak->untag()->value();
78 if (!raw_val->IsImmediateObject() && !raw_val->untag()->IsMarked()) {
79 more_to_mark = true;
80 }
81
82 // The key is marked so we make sure to properly visit all pointers
83 // originating from this weak property.
84 cur_weak->untag()->VisitPointersNonvirtual(this);
85 if (has_evacuation_candidate_) {
86 has_evacuation_candidate_ = false;
87 if (!cur_weak->untag()->IsCardRemembered()) {
88 if (cur_weak->untag()->TryAcquireRememberedBit()) {
90 }
91 }
92 }
93
94 } else {
95 // Requeue this weak property to be handled later.
96 ASSERT(IsMarked(cur_weak));
97 delayed_.weak_properties.Enqueue(cur_weak);
98 }
99 // Advance to next weak property in the queue.
100 cur_weak = next_weak;
101 }
102 return more_to_mark;
103 }

◆ ProcessWeakArray()

template<bool sync>
intptr_t dart::MarkingVisitorBase< sync >::ProcessWeakArray ( WeakArrayPtr  raw_weak)
inline

Definition at line 439 of file marker.cc.

439 {
440 delayed_.weak_arrays.Enqueue(raw_weak);
441 return raw_weak->untag()->HeapSize();
442 }

◆ ProcessWeakProperty()

template<bool sync>
intptr_t dart::MarkingVisitorBase< sync >::ProcessWeakProperty ( WeakPropertyPtr  raw_weak)
inline

Definition at line 396 of file marker.cc.

396 {
397 // The fate of the weak property is determined by its key.
398 ObjectPtr raw_key =
399 LoadCompressedPointerIgnoreRace(&raw_weak->untag()->key_)
400 .Decompress(raw_weak->heap_base());
401 if (raw_key->IsHeapObject() && !raw_key->untag()->IsMarked()) {
402 // Key was white. Enqueue the weak property.
403 ASSERT(IsMarked(raw_weak));
404 delayed_.weak_properties.Enqueue(raw_weak);
405 return raw_weak->untag()->HeapSize();
406 }
407 // Key is gray or black. Make the weak property black.
408 return raw_weak->untag()->VisitPointersNonvirtual(this);
409 }

◆ ProcessWeakReference()

template<bool sync>
intptr_t dart::MarkingVisitorBase< sync >::ProcessWeakReference ( WeakReferencePtr  raw_weak)
inline

Definition at line 411 of file marker.cc.

411 {
412 // The fate of the target field is determined by the target.
413 // The type arguments always stay alive.
414 ObjectPtr raw_target =
415 LoadCompressedPointerIgnoreRace(&raw_weak->untag()->target_)
416 .Decompress(raw_weak->heap_base());
417 if (raw_target->IsHeapObject()) {
418 if (!raw_target->untag()->IsMarked()) {
419 // Target was white. Enqueue the weak reference. It is potentially dead.
420 // It might still be made alive by weak properties in next rounds.
421 ASSERT(IsMarked(raw_weak));
422 delayed_.weak_references.Enqueue(raw_weak);
423 } else {
424 if (raw_target->untag()->IsEvacuationCandidate()) {
425 has_evacuation_candidate_ = true;
426 }
427 }
428 }
429 // Always visit the type argument.
430 ObjectPtr raw_type_arguments =
431 LoadCompressedPointerIgnoreRace(&raw_weak->untag()->type_arguments_)
432 .Decompress(raw_weak->heap_base());
433 if (MarkObject(raw_type_arguments)) {
434 has_evacuation_candidate_ = true;
435 }
436 return raw_weak->untag()->HeapSize();
437 }

◆ set_concurrent()

template<bool sync>
void dart::MarkingVisitorBase< sync >::set_concurrent ( bool  value)
inline

Definition at line 51 of file marker.cc.

51{ concurrent_ = value; }
uint8_t value

◆ VisitCards()

template<bool sync>
intptr_t dart::MarkingVisitorBase< sync >::VisitCards ( ArrayPtr  obj)
inline

Definition at line 190 of file marker.cc.

190 {
191 ASSERT(obj->IsArray() || obj->IsImmutableArray());
192 ASSERT(obj->untag()->IsCardRemembered());
193 CompressedObjectPtr* obj_from = obj->untag()->from();
194 CompressedObjectPtr* obj_to =
195 obj->untag()->to(Smi::Value(obj->untag()->length()));
196 uword heap_base = obj.heap_base();
197
198 Page* page = Page::Of(obj);
199 for (intptr_t i = 0, n = page->card_table_size(); i < n; i++) {
200 CompressedObjectPtr* card_from =
201 reinterpret_cast<CompressedObjectPtr*>(page) +
203 CompressedObjectPtr* card_to =
204 reinterpret_cast<CompressedObjectPtr*>(card_from) +
205 (1 << Page::kSlotsPerCardLog2) - 1;
206 // Minus 1 because to is inclusive.
207
208 if (card_from < obj_from) {
209 // First card overlaps with header.
210 card_from = obj_from;
211 }
212 if (card_to > obj_to) {
213 // Last card(s) may extend past the object. Array truncation can make
214 // this happen for more than one card.
215 card_to = obj_to;
216 }
217
218 VisitCompressedPointers(heap_base, card_from, card_to);
219 if (has_evacuation_candidate_) {
220 has_evacuation_candidate_ = false;
221 page->RememberCard(card_from);
222 }
223
224 if (((i + 1) % kCardsPerInterruptCheck) == 0) {
225 if (UNLIKELY(page_space_->pause_concurrent_marking())) {
227 }
228 }
229 }
230
231 return obj->untag()->HeapSize();
232 }
void VisitCompressedPointers(uword heap_base, CompressedObjectPtr *first, CompressedObjectPtr *last)
Definition: visitor.h:43
UntaggedObject * untag() const
static constexpr intptr_t kSlotsPerCardLog2
Definition: page.h:174
static constexpr intptr_t kCardsPerInterruptCheck
Definition: page.h:360
ObjectPtr CompressedObjectPtr

◆ VisitPointers()

template<bool sync>
void dart::MarkingVisitorBase< sync >::VisitPointers ( ObjectPtr first,
ObjectPtr last 
)
inlineoverridevirtual

Implements dart::ObjectPointerVisitor.

Definition at line 375 of file marker.cc.

375 {
376 bool has_evacuation_candidate = false;
377 for (ObjectPtr* current = first; current <= last; current++) {
378 has_evacuation_candidate |= MarkObject(LoadPointerIgnoreRace(current));
379 }
380 has_evacuation_candidate_ |= has_evacuation_candidate;
381 }
NO_SANITIZE_THREAD ObjectPtr LoadPointerIgnoreRace(ObjectPtr *ptr)
Definition: marker.cc:368

◆ WaitForWork()

template<bool sync>
bool dart::MarkingVisitorBase< sync >::WaitForWork ( RelaxedAtomic< uintptr_t > *  num_busy)
inline

Definition at line 588 of file marker.cc.

588 {
589 return old_work_list_.WaitForWork(num_busy);
590 }
bool WaitForWork(RelaxedAtomic< uintptr_t > *num_busy, bool abort=false)

◆ YieldConcurrentMarking()

template<bool sync>
DART_NOINLINE void dart::MarkingVisitorBase< sync >::YieldConcurrentMarking ( )
inline

Definition at line 106 of file marker.cc.

106 {
107 old_work_list_.Flush();
108 new_work_list_.Flush();
109 tlab_deferred_work_list_.Flush();
110 deferred_work_list_.Flush();
111 Thread* thread = Thread::Current();
112 thread->StoreBufferReleaseGC();
113 page_space_->YieldConcurrentMarking();
114 thread->StoreBufferAcquireGC();
115 }
void YieldConcurrentMarking()
Definition: pages.cc:459

The documentation for this class was generated from the following file: