Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
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

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
 
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 ()
 
Pagehead () const
 
Pagetail () const
 
- Public Member Functions inherited from dart::ObjectPointerVisitor
 ObjectPointerVisitor (IsolateGroup *isolate_group)
 
virtual ~ObjectPointerVisitor ()
 
IsolateGroupisolate_group () const
 
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 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 132 of file scavenger.cc.

138 thread_(nullptr),
139 scavenger_(scavenger),
140 from_(from),
141 page_space_(scavenger->heap_->old_space()),
142 freelist_(freelist),
143 bytes_promoted_(0),
144 visiting_old_object_(nullptr),
145 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 146 of file scavenger.cc.

146{}

Member Function Documentation

◆ bytes_promoted()

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

Definition at line 251 of file scavenger.cc.

251{ return bytes_promoted_; }

◆ Finalize()

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

Definition at line 332 of file scavenger.cc.

332 {
333 if (!scavenger_->abort_) {
334 promoted_list_.Finalize();
335 weak_array_list_.Finalize();
336 weak_property_list_.Finalize();
337 weak_reference_list_.Finalize();
338 finalizer_entry_list_.Finalize();
339 } else {
340 promoted_list_.AbandonWork();
341 weak_array_list_.AbandonWork();
342 weak_property_list_.AbandonWork();
343 weak_reference_list_.AbandonWork();
344 finalizer_entry_list_.AbandonWork();
345 }
346 }

◆ ForwardOrSetNullIfCollected()

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

Definition at line 1578 of file scavenger.cc.

1580 {
1581 ObjectPtr target = slot->Decompress(parent->heap_base());
1582 if (target->IsImmediateOrOldObject()) {
1583 // Object already null (which is old) or not touched during this GC.
1584 return false;
1585 }
1587 if (IsForwarding(header)) {
1588 // Get the new location of the object.
1590 *slot = target;
1591 if (target->IsNewObject() && parent->IsOldObject() &&
1592 parent->untag()->TryAcquireRememberedBit()) {
1594 }
1595 return false;
1596 }
1597 ASSERT(target->IsHeapObject());
1598 ASSERT(target->IsNewObject());
1599 *slot = Object::null();
1600 return true;
1601}
static ObjectPtr null()
Definition object.h:433
static Thread * Current()
Definition thread.h:361
void StoreBufferAddObjectGC(ObjectPtr obj)
Definition thread.cc:799
#define ASSERT(E)
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 303 of file scavenger.cc.

303 {
304 if (scavenger_->abort_) return false;
305 return (scan_ != tail_) || (scan_ != nullptr && !scan_->IsResolved()) ||
306 !promoted_list_.IsEmpty();
307 }
bool IsResolved() const
Definition page.h:248

◆ head()

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

Definition at line 348 of file scavenger.cc.

348{ return head_; }

◆ ProcessAll()

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

Definition at line 278 of file scavenger.cc.

278 {
279 TIMELINE_FUNCTION_GC_DURATION(thread_, "ProcessToSpace");
280 LongJumpScope jump(thread_);
281 if (setjmp(*jump.Set()) == 0) {
282 do {
283 do {
284 ProcessToSpace();
285 ProcessPromotedList();
286 } while (HasWork());
287 ProcessWeakPropertiesScoped();
288 } while (HasWork());
289 } else {
290 ASSERT(scavenger_->abort_);
291 }
292 }
#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 1348 of file scavenger.cc.

1348 {
1349#if defined(DEBUG)
1350 if (obj->IsNewObject()) {
1351 ASSERT(visiting_old_object_ == nullptr);
1352 } else {
1353 ASSERT(visiting_old_object_ == obj);
1354 ASSERT(!obj->untag()->IsRemembered());
1355 }
1356#endif
1357
1358 intptr_t cid = obj->GetClassId();
1359 if (UNLIKELY(cid == kWeakPropertyCid)) {
1360 WeakPropertyPtr weak_property = static_cast<WeakPropertyPtr>(obj);
1361 if (!IsScavengeSurvivor(weak_property->untag()->key())) {
1362 weak_property_list_.Push(weak_property);
1364 }
1365 } else if (UNLIKELY(cid == kWeakReferenceCid)) {
1366 WeakReferencePtr weak_reference = static_cast<WeakReferencePtr>(obj);
1367 if (!IsScavengeSurvivor(weak_reference->untag()->target())) {
1368#if !defined(DART_COMPRESSED_POINTERS)
1369 ScavengePointer(&weak_reference->untag()->type_arguments_);
1370#else
1371 ScavengeCompressedPointer(weak_reference->heap_base(),
1372 &weak_reference->untag()->type_arguments_);
1373#endif
1374 weak_reference_list_.Push(weak_reference);
1376 }
1377 } else if (UNLIKELY(cid == kWeakArrayCid)) {
1378 WeakArrayPtr weak_array = static_cast<WeakArrayPtr>(obj);
1379 weak_array_list_.Push(weak_array);
1380 return WeakArray::InstanceSize(Smi::Value(weak_array->untag()->length()));
1381 } else if (UNLIKELY(cid == kFinalizerEntryCid)) {
1382 FinalizerEntryPtr finalizer_entry = static_cast<FinalizerEntryPtr>(obj);
1383#if !defined(DART_COMPRESSED_POINTERS)
1384 ScavengePointer(&finalizer_entry->untag()->token_);
1385 ScavengePointer(&finalizer_entry->untag()->next_);
1386#else
1387 ScavengeCompressedPointer(finalizer_entry->heap_base(),
1388 &finalizer_entry->untag()->token_);
1389 ScavengeCompressedPointer(finalizer_entry->heap_base(),
1390 &finalizer_entry->untag()->next_);
1391#endif
1392 finalizer_entry_list_.Push(finalizer_entry);
1394 }
1395 return obj->untag()->VisitPointersNonvirtual(this);
1396}
static intptr_t InstanceSize()
Definition object.h:12986
intptr_t Value() const
Definition object.h:9969
static intptr_t InstanceSize()
Definition object.h:6715
static intptr_t InstanceSize()
Definition object.h:12906
static intptr_t InstanceSize()
Definition object.h:12932
static bool IsScavengeSurvivor(ObjectPtr obj)
const intptr_t cid
#define UNLIKELY(cond)
Definition globals.h:261

◆ ProcessRoots()

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

Definition at line 253 of file scavenger.cc.

253 {
254 thread_ = Thread::Current();
255 page_space_->AcquireLock(freelist_);
256
257 LongJumpScope jump(thread_);
258 if (setjmp(*jump.Set()) == 0) {
259 scavenger_->IterateRoots(this);
260 } else {
261 ASSERT(scavenger_->abort_);
262 }
263 }
void AcquireLock(FreeList *freelist)
Definition pages.cc:426

◆ ProcessSurvivors()

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

Definition at line 265 of file scavenger.cc.

265 {
266 LongJumpScope jump(thread_);
267 if (setjmp(*jump.Set()) == 0) {
268 // Iterate until all work has been drained.
269 do {
270 ProcessToSpace();
271 ProcessPromotedList();
272 } while (HasWork());
273 } else {
274 ASSERT(scavenger_->abort_);
275 }
276 }

◆ ProcessWeak()

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

Definition at line 313 of file scavenger.cc.

313 {
314 if (!scavenger_->abort_) {
315 ASSERT(!HasWork());
316
317 for (Page* page = head_; page != nullptr; page = page->next()) {
318 ASSERT(page->IsResolved());
319 page->RecordSurvivors();
320 }
321
322 MournWeakProperties();
323 MournWeakReferences();
324 MournWeakArrays();
325 MournFinalizerEntries();
326 scavenger_->IterateWeak();
327 }
328 page_space_->ReleaseLock(freelist_);
329 thread_ = nullptr;
330 }
void ReleaseLock(FreeList *freelist)
Definition pages.cc:430

◆ ProcessWeakProperties()

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

Definition at line 294 of file scavenger.cc.

294 {
295 LongJumpScope jump(thread_);
296 if (setjmp(*jump.Set()) == 0) {
297 ProcessWeakPropertiesScoped();
298 } else {
299 ASSERT(scavenger_->abort_);
300 }
301 }

◆ tail()

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

Definition at line 349 of file scavenger.cc.

349{ return tail_; }

◆ VisitingOldObject()

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

Definition at line 241 of file scavenger.cc.

241 {
242 ASSERT((obj == nullptr) || obj->IsOldObject());
243 visiting_old_object_ = obj;
244 if (obj != nullptr) {
245 // Card update happens in Page::VisitRememberedCards.
246 ASSERT(!obj->untag()->IsCardRemembered());
247 }
248 }

◆ VisitPointers()

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

Implements dart::ObjectPointerVisitor.

Definition at line 221 of file scavenger.cc.

221 {
222 ASSERT(Utils::IsAligned(first, sizeof(*first)));
223 ASSERT(Utils::IsAligned(last, sizeof(*last)));
224 for (ObjectPtr* current = first; current <= last; current++) {
225 ScavengePointer(current);
226 }
227 }
static constexpr bool IsAligned(T x, uintptr_t alignment, uintptr_t offset=0)
Definition utils.h:77

◆ VisitTypedDataViewPointers()

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

Reimplemented from dart::ObjectPointerVisitor.

Definition at line 152 of file scavenger.cc.

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

309 {
310 return promoted_list_.WaitForWork(num_busy, scavenger_->abort_);
311 }
bool WaitForWork(RelaxedAtomic< uintptr_t > *num_busy, bool abort=false)

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