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

Public Member Functions

 ScavengerVisitorBase (IsolateGroup *isolate_group, Scavenger *scavenger, SemiSpace *from, FreeList *freelist, PromotionStack *promotion_stack)
 
 ~ScavengerVisitorBase ()
 
void VisitTypedDataViewPointers (TypedDataViewPtr view, CompressedObjectPtr *first, CompressedObjectPtr *last) override
 
void VisitPointers (ObjectPtr *first, ObjectPtr *last) override
 
bool PredicateVisitPointers (ObjectPtr *first, ObjectPtr *last) override
 
void VisitingOldObject (ObjectPtr obj)
 
DART_FORCE_INLINE intptr_t ProcessObject (ObjectPtr obj)
 
intptr_t bytes_promoted () const
 
void ProcessRoots ()
 
void ProcessSurvivors ()
 
void ProcessAll ()
 
void ProcessWeakProperties ()
 
bool HasWork ()
 
bool WaitForWork (RelaxedAtomic< uintptr_t > *num_busy)
 
void ProcessWeak ()
 
void Finalize (StoreBuffer *store_buffer)
 
Pagehead () const
 
Pagetail () const
 
void set_pending (StoreBufferBlock *pending)
 
- 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)
 
- Public Member Functions inherited from dart::PredicateObjectPointerVisitor
 PredicateObjectPointerVisitor ()
 
virtual ~PredicateObjectPointerVisitor ()
 
virtual bool PredicateVisitPointers (ObjectPtr *first, ObjectPtr *last)=0
 
bool PredicateVisitCompressedPointers (uword heap_base, CompressedObjectPtr *first, CompressedObjectPtr *last)
 

Static Public Member Functions

static bool ForwardOrSetNullIfCollected (ObjectPtr parent, CompressedObjectPtr *ptr_address)
 

Detailed Description

template<bool parallel>
class dart::ScavengerVisitorBase< parallel >

Definition at line 130 of file scavenger.cc.

Constructor & Destructor Documentation

◆ ScavengerVisitorBase()

template<bool parallel>
dart::ScavengerVisitorBase< parallel >::ScavengerVisitorBase ( IsolateGroup isolate_group,
Scavenger scavenger,
SemiSpace from,
FreeList freelist,
PromotionStack promotion_stack 
)
inlineexplicit

Definition at line 133 of file scavenger.cc.

139 thread_(nullptr),
140 scavenger_(scavenger),
141 from_(from),
142 page_space_(scavenger->heap_->old_space()),
143 freelist_(freelist),
144 bytes_promoted_(0),
145 visiting_old_object_(nullptr),
146 pending_(nullptr),
147 promoted_list_(promotion_stack) {}
IsolateGroup * isolate_group() const
Definition: visitor.h:25
ObjectPointerVisitor(IsolateGroup *isolate_group)
Definition: visitor.cc:11

◆ ~ScavengerVisitorBase()

template<bool parallel>
dart::ScavengerVisitorBase< parallel >::~ScavengerVisitorBase ( )
inline

Definition at line 148 of file scavenger.cc.

148{ ASSERT(pending_ == nullptr); }
#define ASSERT(E)

Member Function Documentation

◆ bytes_promoted()

template<bool parallel>
intptr_t dart::ScavengerVisitorBase< parallel >::bytes_promoted ( ) const
inline

Definition at line 277 of file scavenger.cc.

277{ return bytes_promoted_; }

◆ Finalize()

template<bool parallel>
void dart::ScavengerVisitorBase< parallel >::Finalize ( StoreBuffer store_buffer)
inline

Definition at line 358 of file scavenger.cc.

358 {
359 if (!scavenger_->abort_) {
360 promoted_list_.Finalize();
361 weak_array_list_.Finalize();
362 weak_property_list_.Finalize();
363 weak_reference_list_.Finalize();
364 finalizer_entry_list_.Finalize();
365 ASSERT(pending_ == nullptr);
366 } else {
367 promoted_list_.AbandonWork();
368 weak_array_list_.AbandonWork();
369 weak_property_list_.AbandonWork();
370 weak_reference_list_.AbandonWork();
371 finalizer_entry_list_.AbandonWork();
372 if (pending_ != nullptr) {
373 pending_->Reset();
374 store_buffer->PushBlock(pending_, StoreBuffer::kIgnoreThreshold);
375 pending_ = nullptr;
376 }
377 }
378 }

◆ ForwardOrSetNullIfCollected()

template<bool parallel>
bool dart::ScavengerVisitorBase< parallel >::ForwardOrSetNullIfCollected ( ObjectPtr  parent,
CompressedObjectPtr ptr_address 
)
static

Definition at line 1740 of file scavenger.cc.

1742 {
1743 ObjectPtr target = slot->Decompress(parent->heap_base());
1744 if (target->IsImmediateObject()) {
1745 // Object already null (which is old) or not touched during this GC.
1746 return false;
1747 }
1748 if (target->IsOldObject()) {
1749 if (parent->IsOldObject() && target->untag()->IsEvacuationCandidate()) {
1750 if (!parent->untag()->IsCardRemembered()) {
1751 if (parent->untag()->TryAcquireRememberedBit()) {
1753 }
1754 }
1755 }
1756 return false;
1757 }
1759 if (IsForwarding(header)) {
1760 // Get the new location of the object.
1762 *slot = target;
1763 if (target->IsNewObject() && parent->IsOldObject() &&
1764 parent->untag()->TryAcquireRememberedBit()) {
1766 }
1767 return false;
1768 }
1769 ASSERT(target->IsHeapObject());
1770 ASSERT(target->IsNewObject());
1771 *slot = Object::null();
1772 return true;
1773}
static ObjectPtr null()
Definition: object.h:433
static Thread * Current()
Definition: thread.h:362
void StoreBufferAddObjectGC(ObjectPtr obj)
Definition: thread.cc:804
uint32_t * target
static DART_FORCE_INLINE uword ReadHeaderRelaxed(ObjectPtr obj)
Definition: scavenger.cc:118
static DART_FORCE_INLINE bool IsForwarding(uword header)
Definition: scavenger.cc:66
uintptr_t uword
Definition: globals.h:501
static DART_FORCE_INLINE ObjectPtr ForwardedObj(uword header)
Definition: scavenger.cc:73
static const char header[]
Definition: skpbench.cpp:88

◆ HasWork()

template<bool parallel>
bool dart::ScavengerVisitorBase< parallel >::HasWork ( )
inline

Definition at line 329 of file scavenger.cc.

329 {
330 if (scavenger_->abort_) return false;
331 return (scan_ != tail_) || (scan_ != nullptr && !scan_->IsResolved()) ||
332 !promoted_list_.IsEmpty();
333 }
bool IsResolved() const
Definition: page.h:272

◆ head()

template<bool parallel>
Page * dart::ScavengerVisitorBase< parallel >::head ( ) const
inline

Definition at line 380 of file scavenger.cc.

380{ return head_; }

◆ PredicateVisitPointers()

template<bool parallel>
bool dart::ScavengerVisitorBase< parallel >::PredicateVisitPointers ( ObjectPtr first,
ObjectPtr last 
)
inlineoverridevirtual

Implements dart::PredicateObjectPointerVisitor.

Definition at line 234 of file scavenger.cc.

234 {
235 bool has_new_target = false;
236 for (ObjectPtr* current = first; current <= last; current++) {
237 has_new_target |= PredicateScavengePointer(current);
238 }
239 return has_new_target;
240 }

◆ ProcessAll()

template<bool parallel>
void dart::ScavengerVisitorBase< parallel >::ProcessAll ( )
inline

Definition at line 304 of file scavenger.cc.

304 {
305 TIMELINE_FUNCTION_GC_DURATION(thread_, "ProcessToSpace");
306 LongJumpScope jump(thread_);
307 if (setjmp(*jump.Set()) == 0) {
308 do {
309 do {
310 ProcessToSpace();
311 ProcessPromotedList();
312 } while (HasWork());
313 ProcessWeakPropertiesScoped();
314 } while (HasWork());
315 } else {
316 ASSERT(scavenger_->abort_);
317 }
318 }
#define TIMELINE_FUNCTION_GC_DURATION(thread, name)
Definition: timeline.h:41

◆ ProcessObject()

template<bool parallel>
intptr_t dart::ScavengerVisitorBase< parallel >::ProcessObject ( ObjectPtr  obj)

Definition at line 1407 of file scavenger.cc.

1407 {
1408#if defined(DEBUG)
1409 if (obj->IsNewObject()) {
1410 ASSERT(visiting_old_object_ == nullptr);
1411 } else {
1412 ASSERT(visiting_old_object_ == obj);
1413 ASSERT(!obj->untag()->IsRemembered());
1414 }
1415#endif
1416
1417 intptr_t cid = obj->GetClassId();
1418 if (UNLIKELY(cid == kWeakPropertyCid)) {
1419 WeakPropertyPtr weak_property = static_cast<WeakPropertyPtr>(obj);
1420 if (!IsScavengeSurvivor(weak_property->untag()->key())) {
1421 weak_property_list_.Push(weak_property);
1423 }
1424 } else if (UNLIKELY(cid == kWeakReferenceCid)) {
1425 WeakReferencePtr weak_reference = static_cast<WeakReferencePtr>(obj);
1426 if (!IsScavengeSurvivor(weak_reference->untag()->target())) {
1427#if !defined(DART_COMPRESSED_POINTERS)
1428 ScavengePointer(&weak_reference->untag()->type_arguments_);
1429#else
1430 ScavengeCompressedPointer(weak_reference->heap_base(),
1431 &weak_reference->untag()->type_arguments_);
1432#endif
1433 weak_reference_list_.Push(weak_reference);
1435 }
1436 } else if (UNLIKELY(cid == kWeakArrayCid)) {
1437 WeakArrayPtr weak_array = static_cast<WeakArrayPtr>(obj);
1438 weak_array_list_.Push(weak_array);
1439 return WeakArray::InstanceSize(Smi::Value(weak_array->untag()->length()));
1440 } else if (UNLIKELY(cid == kFinalizerEntryCid)) {
1441 FinalizerEntryPtr finalizer_entry = static_cast<FinalizerEntryPtr>(obj);
1442#if !defined(DART_COMPRESSED_POINTERS)
1443 ScavengePointer(&finalizer_entry->untag()->token_);
1444 ScavengePointer(&finalizer_entry->untag()->next_);
1445#else
1446 ScavengeCompressedPointer(finalizer_entry->heap_base(),
1447 &finalizer_entry->untag()->token_);
1448 ScavengeCompressedPointer(finalizer_entry->heap_base(),
1449 &finalizer_entry->untag()->next_);
1450#endif
1451 finalizer_entry_list_.Push(finalizer_entry);
1453 }
1454 return obj->untag()->VisitPointersNonvirtual(this);
1455}
static intptr_t InstanceSize()
Definition: object.h:13012
intptr_t Value() const
Definition: object.h:9990
static intptr_t InstanceSize()
Definition: object.h:6742
static intptr_t InstanceSize()
Definition: object.h:12932
static intptr_t InstanceSize()
Definition: object.h:12958
static bool IsScavengeSurvivor(ObjectPtr obj)
Definition: scavenger.cc:1401
const intptr_t cid
#define UNLIKELY(cond)
Definition: globals.h:261

◆ ProcessRoots()

template<bool parallel>
void dart::ScavengerVisitorBase< parallel >::ProcessRoots ( )
inline

Definition at line 279 of file scavenger.cc.

279 {
280 thread_ = Thread::Current();
281 page_space_->AcquireLock(freelist_);
282
283 LongJumpScope jump(thread_);
284 if (setjmp(*jump.Set()) == 0) {
285 scavenger_->IterateRoots(this);
286 } else {
287 ASSERT(scavenger_->abort_);
288 }
289 }
void AcquireLock(FreeList *freelist)
Definition: pages.cc:432

◆ ProcessSurvivors()

template<bool parallel>
void dart::ScavengerVisitorBase< parallel >::ProcessSurvivors ( )
inline

Definition at line 291 of file scavenger.cc.

291 {
292 LongJumpScope jump(thread_);
293 if (setjmp(*jump.Set()) == 0) {
294 // Iterate until all work has been drained.
295 do {
296 ProcessToSpace();
297 ProcessPromotedList();
298 } while (HasWork());
299 } else {
300 ASSERT(scavenger_->abort_);
301 }
302 }

◆ ProcessWeak()

template<bool parallel>
void dart::ScavengerVisitorBase< parallel >::ProcessWeak ( )
inline

Definition at line 339 of file scavenger.cc.

339 {
340 if (!scavenger_->abort_) {
341 ASSERT(!HasWork());
342
343 for (Page* page = head_; page != nullptr; page = page->next()) {
344 ASSERT(page->IsResolved());
345 page->RecordSurvivors();
346 }
347
348 MournWeakProperties();
349 MournWeakReferences();
350 MournWeakArrays();
351 MournFinalizerEntries();
352 scavenger_->IterateWeak();
353 }
354 page_space_->ReleaseLock(freelist_);
355 thread_ = nullptr;
356 }
void ReleaseLock(FreeList *freelist)
Definition: pages.cc:436

◆ ProcessWeakProperties()

template<bool parallel>
void dart::ScavengerVisitorBase< parallel >::ProcessWeakProperties ( )
inline

Definition at line 320 of file scavenger.cc.

320 {
321 LongJumpScope jump(thread_);
322 if (setjmp(*jump.Set()) == 0) {
323 ProcessWeakPropertiesScoped();
324 } else {
325 ASSERT(scavenger_->abort_);
326 }
327 }

◆ set_pending()

template<bool parallel>
void dart::ScavengerVisitorBase< parallel >::set_pending ( StoreBufferBlock pending)
inline

Definition at line 382 of file scavenger.cc.

382{ pending_ = pending; }

◆ tail()

template<bool parallel>
Page * dart::ScavengerVisitorBase< parallel >::tail ( ) const
inline

Definition at line 381 of file scavenger.cc.

381{ return tail_; }

◆ VisitingOldObject()

template<bool parallel>
void dart::ScavengerVisitorBase< parallel >::VisitingOldObject ( ObjectPtr  obj)
inline

Definition at line 267 of file scavenger.cc.

267 {
268 ASSERT((obj == nullptr) || obj->IsOldObject());
269 visiting_old_object_ = obj;
270 if (obj != nullptr) {
271 // Card update happens in Page::VisitRememberedCards.
272 ASSERT(!obj->untag()->IsCardRemembered());
273 }
274 }

◆ VisitPointers()

template<bool parallel>
void dart::ScavengerVisitorBase< parallel >::VisitPointers ( ObjectPtr first,
ObjectPtr last 
)
inlineoverridevirtual

Implements dart::ObjectPointerVisitor.

Definition at line 223 of file scavenger.cc.

223 {
224#if !defined(TARGET_ARCH_IA32)
225 // Pointers embedded in Instructions are not aligned.
226 ASSERT(Utils::IsAligned(first, sizeof(*first)));
227 ASSERT(Utils::IsAligned(last, sizeof(*last)));
228#endif
229 for (ObjectPtr* current = first; current <= last; current++) {
230 ScavengePointer(current);
231 }
232 }
static constexpr bool IsAligned(T x, uintptr_t alignment, uintptr_t offset=0)
Definition: utils.h:92

◆ VisitTypedDataViewPointers()

template<bool parallel>
void dart::ScavengerVisitorBase< parallel >::VisitTypedDataViewPointers ( TypedDataViewPtr  view,
CompressedObjectPtr first,
CompressedObjectPtr last 
)
inlineoverridevirtual

Reimplemented from dart::ObjectPointerVisitor.

Definition at line 154 of file scavenger.cc.

156 {
157 // TypedDataViews require extra processing to update their
158 // PointerBase::data_ pointer. If the underlying typed data is external, no
159 // update is needed. If the underlying typed data is internal, the pointer
160 // must be updated if the typed data was copied or promoted. We cannot
161 // safely dereference the underlying typed data to make this distinction.
162 // It may have been forwarded by a different scavenger worker, so the access
163 // could have a data race. Rather than checking the CID of the underlying
164 // typed data, which requires dereferencing the copied/promoted header, we
165 // compare the view's internal pointer to what it should be if the
166 // underlying typed data was internal, and assume that external typed data
167 // never points into the Dart heap. We must do this before VisitPointers
168 // because we want to compare the old pointer and old typed data.
169 const bool is_external =
170 view->untag()->data_ != view->untag()->DataFieldForInternalTypedData();
171
172 // Forward all fields of the typed data view.
173 VisitCompressedPointers(view->heap_base(), first, last);
174
175 if (view->untag()->data_ == nullptr) {
176 ASSERT(RawSmiValue(view->untag()->offset_in_bytes()) == 0 &&
177 RawSmiValue(view->untag()->length()) == 0);
178 ASSERT(is_external);
179 return;
180 }
181
182 // Explicit ifdefs because the compiler does not eliminate the unused
183 // relaxed load.
184#if defined(DEBUG)
185 // Validate 'this' is a typed data view.
186 const uword view_header = ReadHeaderRelaxed(view);
187 ASSERT(!IsForwarding(view_header) || view->IsOldObject());
188 ASSERT(IsTypedDataViewClassId(view->GetClassIdMayBeSmi()) ||
189 IsUnmodifiableTypedDataViewClassId(view->GetClassIdMayBeSmi()));
190
191 // Validate that the backing store is not a forwarding word. There is a data
192 // race reader the backing store's header unless there is only one worker.
193 TypedDataBasePtr td = view->untag()->typed_data();
194 ASSERT(td->IsHeapObject());
195 if (!parallel) {
196 const uword td_header = ReadHeaderRelaxed(td);
197 ASSERT(!IsForwarding(td_header) || td->IsOldObject());
198 if (td != Object::null()) {
199 // Fast object copy temporarily stores null in the typed_data field of
200 // views. This can cause the RecomputeDataFieldForInternalTypedData to
201 // run inappropriately, but when the object copy continues it will fix
202 // the data_ pointer.
203 ASSERT_EQUAL(IsExternalTypedDataClassId(td->GetClassId()), is_external);
204 }
205 }
206#endif
207
208 // If we have external typed data we can simply return since the backing
209 // store lives in C-heap and will not move.
210 if (is_external) {
211 return;
212 }
213
214 // Now we update the inner pointer.
215#if defined(DEBUG)
216 if (!parallel) {
217 ASSERT(IsTypedDataClassId(td->GetClassId()));
218 }
219#endif
220 view->untag()->RecomputeDataFieldForInternalTypedData();
221 }
#define ASSERT_EQUAL(expected, actual)
Definition: assert.h:309
void VisitCompressedPointers(uword heap_base, CompressedObjectPtr *first, CompressedObjectPtr *last)
Definition: visitor.h:43
bool IsTypedDataViewClassId(intptr_t index)
Definition: class_id.h:439
bool IsTypedDataClassId(intptr_t index)
Definition: class_id.h:433
intptr_t RawSmiValue(const SmiPtr raw_value)
bool IsUnmodifiableTypedDataViewClassId(intptr_t index)
Definition: class_id.h:453
bool IsExternalTypedDataClassId(intptr_t index)
Definition: class_id.h:447

◆ WaitForWork()

template<bool parallel>
bool dart::ScavengerVisitorBase< parallel >::WaitForWork ( RelaxedAtomic< uintptr_t > *  num_busy)
inline

Definition at line 335 of file scavenger.cc.

335 {
336 return promoted_list_.WaitForWork(num_busy, scavenger_->abort_);
337 }
bool WaitForWork(RelaxedAtomic< uintptr_t > *num_busy, bool abort=false)

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