Flutter Engine
The Flutter Engine
Public Types | Public Member Functions | Friends | List of all members
dart::PageSpace Class Reference

#include <pages.h>

Public Types

enum  GrowthPolicy { kControlGrowth , kForceGrowth }
 
enum  Phase {
  kDone , kMarking , kAwaitingFinalization , kSweepingLarge ,
  kSweepingRegular
}
 

Public Member Functions

 PageSpace (Heap *heap, intptr_t max_capacity_in_words)
 
 ~PageSpace ()
 
uword TryAllocate (intptr_t size, bool is_executable=false, GrowthPolicy growth_policy=kControlGrowth)
 
DART_FORCE_INLINE uword TryAllocatePromoLocked (FreeList *freelist, intptr_t size)
 
DART_FORCE_INLINE uword AllocateSnapshotLocked (FreeList *freelist, intptr_t size)
 
void TryReleaseReservation ()
 
bool MarkReservation ()
 
void TryReserveForOOM ()
 
void VisitRoots (ObjectPointerVisitor *visitor)
 
bool ReachedHardThreshold () const
 
bool ReachedSoftThreshold () const
 
bool ReachedIdleThreshold () const
 
void EvaluateAfterLoading ()
 
intptr_t UsedInWords () const
 
intptr_t CapacityInWords () const
 
void IncreaseCapacityInWords (intptr_t increase_in_words)
 
void IncreaseCapacityInWordsLocked (intptr_t increase_in_words)
 
void UpdateMaxCapacityLocked ()
 
void UpdateMaxUsed ()
 
intptr_t ExternalInWords () const
 
SpaceUsage GetCurrentUsage () const
 
intptr_t ImageInWords () const
 
bool Contains (uword addr) const
 
bool ContainsUnsafe (uword addr) const
 
bool CodeContains (uword addr) const
 
bool DataContains (uword addr) const
 
bool IsValidAddress (uword addr) const
 
void VisitObjects (ObjectVisitor *visitor) const
 
void VisitObjectsNoImagePages (ObjectVisitor *visitor) const
 
void VisitObjectsImagePages (ObjectVisitor *visitor) const
 
void VisitObjectsUnsafe (ObjectVisitor *visitor) const
 
void VisitObjectPointers (ObjectPointerVisitor *visitor) const
 
void VisitRememberedCards (PredicateObjectPointerVisitor *visitor) const
 
void ResetProgressBars () const
 
void CollectGarbage (Thread *thread, bool compact, bool finalize)
 
void AddRegionsToObjectSet (ObjectSet *set) const
 
void WriteProtect (bool read_only)
 
void WriteProtectCode (bool read_only)
 
bool ShouldStartIdleMarkSweep (int64_t deadline)
 
bool ShouldPerformIdleMarkCompact (int64_t deadline)
 
void IncrementalMarkWithSizeBudget (intptr_t size)
 
void IncrementalMarkWithTimeBudget (int64_t deadline)
 
void AssistTasks (MonitorLocker *ml)
 
void AddGCTime (int64_t micros)
 
int64_t gc_time_micros () const
 
void IncrementCollections ()
 
intptr_t collections () const
 
void PrintToJSONObject (JSONObject *object) const
 
void PrintHeapMapToJSONStream (IsolateGroup *isolate_group, JSONStream *stream) const
 
void AllocateBlack (intptr_t size)
 
bool AllocatedExternal (intptr_t size)
 
void FreedExternal (intptr_t size)
 
FreeListDataFreeList (intptr_t i=0)
 
void AcquireLock (FreeList *freelist)
 
void ReleaseLock (FreeList *freelist)
 
void PauseConcurrentMarking ()
 
void ResumeConcurrentMarking ()
 
void YieldConcurrentMarking ()
 
void PushDependencyToConcurrentMarking ()
 
Monitortasks_lock () const
 
intptr_t tasks () const
 
void set_tasks (intptr_t val)
 
intptr_t concurrent_marker_tasks () const
 
void set_concurrent_marker_tasks (intptr_t val)
 
intptr_t concurrent_marker_tasks_active () const
 
void set_concurrent_marker_tasks_active (intptr_t val)
 
bool pause_concurrent_marking () const
 
Phase phase () const
 
void set_phase (Phase val)
 
void SetupImagePage (void *pointer, uword size, bool is_executable)
 
void ReleaseBumpAllocation ()
 
void AbandonMarkingForShutdown ()
 
bool enable_concurrent_mark () const
 
void set_enable_concurrent_mark (bool enable_concurrent_mark)
 
bool IsObjectFromImagePages (ObjectPtr object)
 
GCMarkermarker () const
 

Friends

class BasePageIterator
 
class ExclusivePageIterator
 
class ExclusiveCodePageIterator
 
class ExclusiveLargePageIterator
 
class HeapIterationScope
 
class HeapSnapshotWriter
 
class PageSpaceController
 
class ConcurrentSweeperTask
 
class GCCompactor
 
class GCIncrementalCompactor
 
class PrologueTask
 
class EpilogueTask
 
class CompactorTask
 
class Code
 

Detailed Description

Definition at line 127 of file pages.h.

Member Enumeration Documentation

◆ GrowthPolicy

Enumerator
kControlGrowth 
kForceGrowth 

Definition at line 129 of file pages.h.

◆ Phase

Enumerator
kDone 
kMarking 
kAwaitingFinalization 
kSweepingLarge 
kSweepingRegular 

Definition at line 130 of file pages.h.

130 {
131 kDone,
132 kMarking,
136 };
@ kAwaitingFinalization
Definition: pages.h:133
@ kSweepingRegular
Definition: pages.h:135
@ kSweepingLarge
Definition: pages.h:134

Constructor & Destructor Documentation

◆ PageSpace()

dart::PageSpace::PageSpace ( Heap heap,
intptr_t  max_capacity_in_words 
)

Definition at line 55 of file pages.cc.

56 : heap_(heap),
57 num_freelists_(Utils::Maximum(FLAG_scavenger_tasks, 1) + 1),
58 freelists_(new FreeList[num_freelists_]),
59 pages_lock_(),
60 max_capacity_in_words_(max_capacity_in_words),
61 usage_(),
62 allocated_black_in_words_(0),
63 tasks_lock_(),
64 tasks_(0),
65 concurrent_marker_tasks_(0),
66 concurrent_marker_tasks_active_(0),
67 pause_concurrent_marking_(0),
68 phase_(kDone),
69#if defined(DEBUG)
70 iterating_thread_(nullptr),
71#endif
72 page_space_controller_(heap,
73 FLAG_old_gen_growth_space_ratio,
74 FLAG_old_gen_growth_rate,
75 FLAG_old_gen_growth_time_ratio),
76 marker_(nullptr),
77 gc_time_micros_(0),
78 collections_(0),
79 mark_words_per_micro_(kConservativeInitialMarkSpeed),
80 enable_concurrent_mark_(FLAG_concurrent_mark) {
81 ASSERT(heap != nullptr);
82
83 // We aren't holding the lock but no one can reference us yet.
86
87 for (intptr_t i = 0; i < num_freelists_; i++) {
88 freelists_[i].Reset();
89 }
90
92}
void Reset()
Definition: freelist.cc:211
void UpdateMaxCapacityLocked()
Definition: pages.cc:592
void UpdateMaxUsed()
Definition: pages.cc:600
void TryReserveForOOM()
Definition: pages.cc:952
static constexpr T Maximum(T x, T y)
Definition: utils.h:41
#define ASSERT(E)
static constexpr intptr_t kConservativeInitialMarkSpeed
Definition: pages.cc:53

◆ ~PageSpace()

dart::PageSpace::~PageSpace ( )

Definition at line 94 of file pages.cc.

94 {
95 {
96 MonitorLocker ml(tasks_lock());
97 AssistTasks(&ml);
98 while (tasks() > 0) {
99 ml.Wait();
100 }
101 }
102 FreePages(pages_);
103 FreePages(exec_pages_);
104 FreePages(large_pages_);
105 FreePages(image_pages_);
106 ASSERT(marker_ == nullptr);
107 delete[] freelists_;
108}
intptr_t tasks() const
Definition: pages.h:315
void AssistTasks(MonitorLocker *ml)
Definition: pages.cc:917
Monitor * tasks_lock() const
Definition: pages.h:314

Member Function Documentation

◆ AbandonMarkingForShutdown()

void dart::PageSpace::AbandonMarkingForShutdown ( )

Definition at line 587 of file pages.cc.

587 {
588 delete marker_;
589 marker_ = nullptr;
590}

◆ AcquireLock()

void dart::PageSpace::AcquireLock ( FreeList freelist)

Definition at line 432 of file pages.cc.

432 {
433 freelist->mutex()->Lock();
434}

◆ AddGCTime()

void dart::PageSpace::AddGCTime ( int64_t  micros)
inline

Definition at line 257 of file pages.h.

257{ gc_time_micros_ += micros; }

◆ AddRegionsToObjectSet()

void dart::PageSpace::AddRegionsToObjectSet ( ObjectSet set) const

Definition at line 643 of file pages.cc.

643 {
644 ASSERT((pages_ != nullptr) || (exec_pages_ != nullptr) ||
645 (large_pages_ != nullptr));
646 for (ExclusivePageIterator it(this); !it.Done(); it.Advance()) {
647 set->AddRegion(it.page()->object_start(), it.page()->object_end());
648 }
649}
friend class ExclusivePageIterator
Definition: pages.h:497
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot The VM snapshot data that will be memory mapped as read only SnapshotAssetPath must be present isolate snapshot The isolate snapshot data that will be memory mapped as read only SnapshotAssetPath must be present cache dir Path to the cache directory This is different from the persistent_cache_path in embedder which is used for Skia shader cache icu native lib Path to the library file that exports the ICU data vm service The hostname IP address on which the Dart VM Service should be served If not set
Definition: switches.h:76

◆ AllocateBlack()

void dart::PageSpace::AllocateBlack ( intptr_t  size)
inline

Definition at line 271 of file pages.h.

271 {
272 allocated_black_in_words_.fetch_add(size >> kWordSizeLog2);
273 }
T fetch_add(T arg, std::memory_order order=std::memory_order_relaxed)
Definition: atomic.h:35
constexpr intptr_t kWordSizeLog2
Definition: globals.h:507
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

◆ AllocatedExternal()

bool dart::PageSpace::AllocatedExternal ( intptr_t  size)
inline

Definition at line 278 of file pages.h.

278 {
279 ASSERT(size >= 0);
280 intptr_t size_in_words = size >> kWordSizeLog2;
281 intptr_t expected = usage_.external_in_words.load();
282 intptr_t desired;
283 do {
284 desired = expected + size_in_words;
285 if (desired < 0 || desired > kMaxAddrSpaceInWords) {
286 return false;
287 }
288 ASSERT(desired >= 0);
289 } while (
290 !usage_.external_in_words.compare_exchange_weak(expected, desired));
291 return true;
292 }
T load(std::memory_order order=std::memory_order_relaxed) const
Definition: atomic.h:21
bool compare_exchange_weak(T &expected, T desired, std::memory_order order=std::memory_order_relaxed)
Definition: atomic.h:52
RelaxedAtomic< intptr_t > external_in_words
Definition: spaces.h:22
const intptr_t kMaxAddrSpaceInWords
Definition: globals.h:50

◆ AllocateSnapshotLocked()

DART_FORCE_INLINE uword dart::PageSpace::AllocateSnapshotLocked ( FreeList freelist,
intptr_t  size 
)
inline

Definition at line 161 of file pages.h.

161 {
164 if (freelist->TryAllocateBumpLocked(size, &result)) {
165 return result;
166 }
167 }
168 return AllocateSnapshotLockedSlow(freelist, size);
169 }
GAsyncResult * result
uintptr_t uword
Definition: globals.h:501
bool IsAllocatableViaFreeLists(intptr_t size)
Definition: spaces.h:60
#define LIKELY(cond)
Definition: globals.h:260

◆ AssistTasks()

void dart::PageSpace::AssistTasks ( MonitorLocker ml)

Definition at line 917 of file pages.cc.

917 {
918 if (phase() == PageSpace::kMarking) {
919 ml->Exit();
921 ml->Enter();
922 }
923 if ((phase() == kSweepingLarge) || (phase() == kSweepingRegular)) {
924 ml->Exit();
925 Sweep(/*exclusive*/ false);
926 SweepLarge();
927 ml->Enter();
928 }
929}
void IncrementalMarkWithUnlimitedBudget(PageSpace *page_space)
Definition: marker.cc:1179
Phase phase() const
Definition: pages.h:341

◆ CapacityInWords()

intptr_t dart::PageSpace::CapacityInWords ( ) const
inline

Definition at line 195 of file pages.h.

195 {
196 MutexLocker ml(&pages_lock_);
197 return usage_.capacity_in_words;
198 }
RelaxedAtomic< intptr_t > capacity_in_words
Definition: spaces.h:20

◆ CodeContains()

bool dart::PageSpace::CodeContains ( uword  addr) const

Definition at line 625 of file pages.cc.

625 {
626 for (ExclusiveCodePageIterator it(this); !it.Done(); it.Advance()) {
627 if (it.page()->Contains(addr)) {
628 return true;
629 }
630 }
631 return false;
632}
friend class ExclusiveCodePageIterator
Definition: pages.h:498

◆ CollectGarbage()

void dart::PageSpace::CollectGarbage ( Thread thread,
bool  compact,
bool  finalize 
)

Definition at line 974 of file pages.cc.

974 {
975 ASSERT(!Thread::Current()->force_growth());
976
977 if (!finalize) {
978 if (!enable_concurrent_mark()) return; // Disabled.
979 if (FLAG_marker_tasks == 0) return; // Disabled.
980 }
981
982 GcSafepointOperationScope safepoint_scope(thread);
983
984 // Wait for pending tasks to complete and then account for the driver task.
985 {
986 MonitorLocker locker(tasks_lock());
987 if (!finalize &&
988 (phase() == kMarking || phase() == kAwaitingFinalization)) {
989 // Concurrent mark is already running.
990 return;
991 }
992
993 AssistTasks(&locker);
994 while (tasks() > 0) {
995 locker.Wait();
996 }
998 set_tasks(1);
999 }
1000
1001 // Ensure that all threads for this isolate are at a safepoint (either
1002 // stopped or in native code). We have guards around Newgen GC and oldgen GC
1003 // to ensure that if two threads are racing to collect at the same time the
1004 // loser skips collection and goes straight to allocation.
1005 CollectGarbageHelper(thread, compact, finalize);
1006
1007 // Done, reset the task count.
1008 {
1009 MonitorLocker ml(tasks_lock());
1010 set_tasks(tasks() - 1);
1011 ml.NotifyAll();
1012 }
1013}
void set_tasks(intptr_t val)
Definition: pages.h:316
bool enable_concurrent_mark() const
Definition: pages.h:351
static Thread * Current()
Definition: thread.h:362

◆ collections()

intptr_t dart::PageSpace::collections ( ) const
inline

Definition at line 263 of file pages.h.

263{ return collections_; }

◆ concurrent_marker_tasks()

intptr_t dart::PageSpace::concurrent_marker_tasks ( ) const
inline

Definition at line 320 of file pages.h.

320 {
322 return concurrent_marker_tasks_;
323 }
#define DEBUG_ASSERT(cond)
Definition: assert.h:321
bool IsOwnedByCurrentThread() const
Definition: os_thread.h:371

◆ concurrent_marker_tasks_active()

intptr_t dart::PageSpace::concurrent_marker_tasks_active ( ) const
inline

Definition at line 329 of file pages.h.

329 {
331 return concurrent_marker_tasks_active_;
332 }

◆ Contains()

bool dart::PageSpace::Contains ( uword  addr) const

Definition at line 607 of file pages.cc.

607 {
608 for (ExclusivePageIterator it(this); !it.Done(); it.Advance()) {
609 if (it.page()->Contains(addr)) {
610 return true;
611 }
612 }
613 return false;
614}

◆ ContainsUnsafe()

bool dart::PageSpace::ContainsUnsafe ( uword  addr) const

Definition at line 616 of file pages.cc.

616 {
617 for (UnsafeExclusivePageIterator it(this); !it.Done(); it.Advance()) {
618 if (it.page()->Contains(addr)) {
619 return true;
620 }
621 }
622 return false;
623}

◆ DataContains()

bool dart::PageSpace::DataContains ( uword  addr) const

Definition at line 634 of file pages.cc.

634 {
635 for (ExclusivePageIterator it(this); !it.Done(); it.Advance()) {
636 if (!it.page()->is_executable() && it.page()->Contains(addr)) {
637 return true;
638 }
639 }
640 return false;
641}

◆ DataFreeList()

FreeList * dart::PageSpace::DataFreeList ( intptr_t  i = 0)
inline

Definition at line 301 of file pages.h.

301 {
302 return &freelists_[kDataFreelist + i];
303 }

◆ enable_concurrent_mark()

bool dart::PageSpace::enable_concurrent_mark ( ) const
inline

Definition at line 351 of file pages.h.

351{ return enable_concurrent_mark_; }

◆ EvaluateAfterLoading()

void dart::PageSpace::EvaluateAfterLoading ( )
inline

Definition at line 185 of file pages.h.

185 {
186 page_space_controller_.EvaluateAfterLoading(usage_);
187
188 MutexLocker ml(&pages_lock_);
189 for (Page* page = pages_; page != nullptr; page = page->next()) {
190 page->set_never_evacuate(true);
191 }
192 }
void EvaluateAfterLoading(SpaceUsage after)
Definition: pages.cc:1704

◆ ExternalInWords()

intptr_t dart::PageSpace::ExternalInWords ( ) const
inline

Definition at line 212 of file pages.h.

212{ return usage_.external_in_words; }

◆ FreedExternal()

void dart::PageSpace::FreedExternal ( intptr_t  size)
inline

Definition at line 293 of file pages.h.

293 {
294 ASSERT(size >= 0);
295 intptr_t size_in_words = size >> kWordSizeLog2;
296 usage_.external_in_words -= size_in_words;
297 ASSERT(usage_.external_in_words >= 0);
298 }

◆ gc_time_micros()

int64_t dart::PageSpace::gc_time_micros ( ) const
inline

Definition at line 259 of file pages.h.

259{ return gc_time_micros_; }

◆ GetCurrentUsage()

SpaceUsage dart::PageSpace::GetCurrentUsage ( ) const
inline

Definition at line 213 of file pages.h.

213 {
214 MutexLocker ml(&pages_lock_);
215 return usage_;
216 }

◆ ImageInWords()

intptr_t dart::PageSpace::ImageInWords ( ) const
inline

Definition at line 217 of file pages.h.

217 {
218 intptr_t size = 0;
219 MutexLocker ml(&pages_lock_);
220 for (Page* page = image_pages_; page != nullptr; page = page->next()) {
221 size += page->memory_->size();
222 }
223 return size >> kWordSizeLog2;
224 }

◆ IncreaseCapacityInWords()

void dart::PageSpace::IncreaseCapacityInWords ( intptr_t  increase_in_words)
inline

Definition at line 199 of file pages.h.

199 {
200 MutexLocker ml(&pages_lock_);
201 IncreaseCapacityInWordsLocked(increase_in_words);
202 }
void IncreaseCapacityInWordsLocked(intptr_t increase_in_words)
Definition: pages.h:203

◆ IncreaseCapacityInWordsLocked()

void dart::PageSpace::IncreaseCapacityInWordsLocked ( intptr_t  increase_in_words)
inline

Definition at line 203 of file pages.h.

203 {
205 usage_.capacity_in_words += increase_in_words;
207 }
bool IsOwnedByCurrentThread() const
Definition: os_thread.h:402

◆ IncrementalMarkWithSizeBudget()

void dart::PageSpace::IncrementalMarkWithSizeBudget ( intptr_t  size)

Definition at line 905 of file pages.cc.

905 {
906 if (marker_ != nullptr) {
907 marker_->IncrementalMarkWithSizeBudget(this, size);
908 }
909}
void IncrementalMarkWithSizeBudget(PageSpace *page_space, intptr_t size)
Definition: marker.cc:1198

◆ IncrementalMarkWithTimeBudget()

void dart::PageSpace::IncrementalMarkWithTimeBudget ( int64_t  deadline)

Definition at line 911 of file pages.cc.

911 {
912 if (marker_ != nullptr) {
913 marker_->IncrementalMarkWithTimeBudget(this, deadline);
914 }
915}
void IncrementalMarkWithTimeBudget(PageSpace *page_space, int64_t deadline)
Definition: marker.cc:1223

◆ IncrementCollections()

void dart::PageSpace::IncrementCollections ( )
inline

Definition at line 261 of file pages.h.

261{ collections_++; }

◆ IsObjectFromImagePages()

bool dart::PageSpace::IsObjectFromImagePages ( dart::ObjectPtr  object)

Definition at line 1544 of file pages.cc.

1544 {
1545 uword object_addr = UntaggedObject::ToAddr(object);
1546 Page* image_page = image_pages_;
1547 while (image_page != nullptr) {
1548 if (image_page->Contains(object_addr)) {
1549 return true;
1550 }
1551 image_page = image_page->next();
1552 }
1553 return false;
1554}
Page * next() const
Definition: page.h:102
static uword ToAddr(const UntaggedObject *raw_obj)
Definition: raw_object.h:522

◆ IsValidAddress()

bool dart::PageSpace::IsValidAddress ( uword  addr) const
inline

Definition at line 230 of file pages.h.

230{ return Contains(addr); }
bool Contains(uword addr) const
Definition: pages.cc:607

◆ marker()

GCMarker * dart::PageSpace::marker ( ) const
inline

Definition at line 358 of file pages.h.

358{ return marker_; }

◆ MarkReservation()

bool dart::PageSpace::MarkReservation ( )

Definition at line 941 of file pages.cc.

941 {
942 if (oom_reservation_ == nullptr) {
943 return false;
944 }
945 UntaggedObject* ptr = reinterpret_cast<UntaggedObject*>(oom_reservation_);
946 if (!ptr->IsMarked()) {
947 ptr->SetMarkBit();
948 }
949 return true;
950}

◆ pause_concurrent_marking()

bool dart::PageSpace::pause_concurrent_marking ( ) const
inline

Definition at line 338 of file pages.h.

338 {
339 return pause_concurrent_marking_.load() != 0;
340 }
T load(std::memory_order order=std::memory_order_acquire) const
Definition: atomic.h:101

◆ PauseConcurrentMarking()

void dart::PageSpace::PauseConcurrentMarking ( )

Definition at line 443 of file pages.cc.

443 {
444 MonitorLocker ml(&tasks_lock_);
445 ASSERT(pause_concurrent_marking_.load() == 0);
446 pause_concurrent_marking_.store(1);
447 while (concurrent_marker_tasks_active_ != 0) {
448 ml.Wait();
449 }
450}
void store(T arg, std::memory_order order=std::memory_order_release)
Definition: atomic.h:104

◆ phase()

Phase dart::PageSpace::phase ( ) const
inline

Definition at line 341 of file pages.h.

341{ return phase_; }

◆ PrintHeapMapToJSONStream()

void dart::PageSpace::PrintHeapMapToJSONStream ( IsolateGroup isolate_group,
JSONStream stream 
) const

Definition at line 772 of file pages.cc.

773 {
774 JSONObject heap_map(stream);
775 heap_map.AddProperty("type", "HeapMap");
776 heap_map.AddProperty("freeClassId", static_cast<intptr_t>(kFreeListElement));
777 heap_map.AddProperty("unitSizeBytes",
778 static_cast<intptr_t>(kObjectAlignment));
779 heap_map.AddProperty("pageSizeBytes", kPageSizeInWords * kWordSize);
780 {
781 JSONObject class_list(&heap_map, "classList");
782 isolate_group->class_table()->PrintToJSONObject(&class_list);
783 }
784 {
785 // "pages" is an array [page0, page1, ..., pageN], each page of the form
786 // {"object_start": "0x...", "objects": [size, class id, size, ...]}
787 // TODO(19445): Use ExclusivePageIterator once HeapMap supports large pages.
789 MutexLocker ml(&pages_lock_);
790 MakeIterable();
791 JSONArray all_pages(&heap_map, "pages");
792 for (Page* page = pages_; page != nullptr; page = page->next()) {
793 JSONObject page_container(&all_pages);
794 page_container.AddPropertyF("objectStart", "0x%" Px "",
795 page->object_start());
796 JSONArray page_map(&page_container, "objects");
797 HeapMapAsJSONVisitor printer(&page_map);
798 page->VisitObjects(&printer);
799 }
800 for (Page* page = exec_pages_; page != nullptr; page = page->next()) {
801 JSONObject page_container(&all_pages);
802 page_container.AddPropertyF("objectStart", "0x%" Px "",
803 page->object_start());
804 JSONArray page_map(&page_container, "objects");
805 HeapMapAsJSONVisitor printer(&page_map);
806 page->VisitObjects(&printer);
807 }
808 }
809}
friend class HeapIterationScope
Definition: pages.h:500
static constexpr intptr_t kPageSizeInWords
Definition: page.h:28
@ kFreeListElement
Definition: class_id.h:224
constexpr intptr_t kWordSize
Definition: globals.h:509
static constexpr intptr_t kObjectAlignment
#define Px
Definition: globals.h:410

◆ PrintToJSONObject()

void dart::PageSpace::PrintToJSONObject ( JSONObject object) const

Definition at line 735 of file pages.cc.

735 {
736 auto isolate_group = IsolateGroup::Current();
737 ASSERT(isolate_group != nullptr);
738 JSONObject space(object, "old");
739 space.AddProperty("type", "HeapSpace");
740 space.AddProperty("name", "old");
741 space.AddProperty("vmName", "PageSpace");
742 space.AddProperty("collections", collections());
743 space.AddProperty64("used", UsedInWords() * kWordSize);
744 space.AddProperty64("capacity", CapacityInWords() * kWordSize);
745 space.AddProperty64("external", ExternalInWords() * kWordSize);
746 space.AddProperty("time", MicrosecondsToSeconds(gc_time_micros()));
747 if (collections() > 0) {
748 int64_t run_time = isolate_group->UptimeMicros();
749 run_time = Utils::Maximum(run_time, static_cast<int64_t>(0));
750 double run_time_millis = MicrosecondsToMilliseconds(run_time);
751 double avg_time_between_collections =
752 run_time_millis / static_cast<double>(collections());
753 space.AddProperty("avgCollectionPeriodMillis",
754 avg_time_between_collections);
755 } else {
756 space.AddProperty("avgCollectionPeriodMillis", 0.0);
757 }
758}
static IsolateGroup * Current()
Definition: isolate.h:539
intptr_t UsedInWords() const
Definition: pages.h:194
int64_t gc_time_micros() const
Definition: pages.h:259
intptr_t collections() const
Definition: pages.h:263
intptr_t CapacityInWords() const
Definition: pages.h:195
intptr_t ExternalInWords() const
Definition: pages.h:212
constexpr double MicrosecondsToSeconds(int64_t micros)
Definition: globals.h:571
constexpr double MicrosecondsToMilliseconds(int64_t micros)
Definition: globals.h:574

◆ PushDependencyToConcurrentMarking()

void dart::PageSpace::PushDependencyToConcurrentMarking ( )
inline

Definition at line 310 of file pages.h.

310 {
311 pause_concurrent_marking_.fetch_or(0);
312 }
T fetch_or(T arg, std::memory_order order=std::memory_order_acq_rel)
Definition: atomic.h:114

◆ ReachedHardThreshold()

bool dart::PageSpace::ReachedHardThreshold ( ) const
inline

Definition at line 176 of file pages.h.

176 {
177 return page_space_controller_.ReachedHardThreshold(usage_);
178 }
bool ReachedHardThreshold(SpaceUsage after) const
Definition: pages.cc:1572

◆ ReachedIdleThreshold()

bool dart::PageSpace::ReachedIdleThreshold ( ) const
inline

Definition at line 182 of file pages.h.

182 {
183 return page_space_controller_.ReachedIdleThreshold(usage_);
184 }
bool ReachedIdleThreshold(SpaceUsage current) const
Definition: pages.cc:1592

◆ ReachedSoftThreshold()

bool dart::PageSpace::ReachedSoftThreshold ( ) const
inline

Definition at line 179 of file pages.h.

179 {
180 return page_space_controller_.ReachedSoftThreshold(usage_);
181 }
bool ReachedSoftThreshold(SpaceUsage after) const
Definition: pages.cc:1582

◆ ReleaseBumpAllocation()

void dart::PageSpace::ReleaseBumpAllocation ( )

Definition at line 580 of file pages.cc.

580 {
581 for (intptr_t i = 0; i < num_freelists_; i++) {
582 size_t leftover = freelists_[i].ReleaseBumpAllocation();
583 usage_.used_in_words -= (leftover >> kWordSizeLog2);
584 }
585}
DART_WARN_UNUSED_RESULT intptr_t ReleaseBumpAllocation()
Definition: freelist.h:149
RelaxedAtomic< intptr_t > used_in_words
Definition: spaces.h:21

◆ ReleaseLock()

void dart::PageSpace::ReleaseLock ( FreeList freelist)

Definition at line 436 of file pages.cc.

436 {
437 usage_.used_in_words +=
438 (freelist->TakeUnaccountedSizeLocked() >> kWordSizeLog2);
439 freelist->mutex()->Unlock();
440 usage_.used_in_words -= (freelist->ReleaseBumpAllocation() >> kWordSizeLog2);
441}

◆ ResetProgressBars()

void dart::PageSpace::ResetProgressBars ( ) const

Definition at line 716 of file pages.cc.

716 {
717 for (Page* page = large_pages_; page != nullptr; page = page->next()) {
718 page->ResetProgressBar();
719 }
720}

◆ ResumeConcurrentMarking()

void dart::PageSpace::ResumeConcurrentMarking ( )

Definition at line 452 of file pages.cc.

452 {
453 MonitorLocker ml(&tasks_lock_);
454 ASSERT(pause_concurrent_marking_.load() != 0);
455 pause_concurrent_marking_.store(0);
456 ml.NotifyAll();
457}

◆ set_concurrent_marker_tasks()

void dart::PageSpace::set_concurrent_marker_tasks ( intptr_t  val)
inline

Definition at line 324 of file pages.h.

324 {
325 ASSERT(val >= 0);
327 concurrent_marker_tasks_ = val;
328 }

◆ set_concurrent_marker_tasks_active()

void dart::PageSpace::set_concurrent_marker_tasks_active ( intptr_t  val)
inline

Definition at line 333 of file pages.h.

333 {
334 ASSERT(val >= 0);
336 concurrent_marker_tasks_active_ = val;
337 }

◆ set_enable_concurrent_mark()

void dart::PageSpace::set_enable_concurrent_mark ( bool  enable_concurrent_mark)
inline

Definition at line 352 of file pages.h.

352 {
353 enable_concurrent_mark_ = enable_concurrent_mark;
354 }

◆ set_phase()

void dart::PageSpace::set_phase ( Phase  val)
inline

Definition at line 342 of file pages.h.

342{ phase_ = val; }

◆ set_tasks()

void dart::PageSpace::set_tasks ( intptr_t  val)
inline

Definition at line 316 of file pages.h.

316 {
317 ASSERT(val >= 0);
318 tasks_ = val;
319 }

◆ SetupImagePage()

void dart::PageSpace::SetupImagePage ( void *  pointer,
uword  size,
bool  is_executable 
)

Definition at line 1509 of file pages.cc.

1509 {
1510 // Setup a Page so precompiled Instructions can be traversed.
1511 // Instructions are contiguous at [pointer, pointer + size). Page
1512 // expects to find objects at [memory->start() + ObjectStartOffset,
1513 // memory->end()).
1515 pointer = reinterpret_cast<void*>(reinterpret_cast<uword>(pointer) - offset);
1517 size += offset;
1518
1519 VirtualMemory* memory = VirtualMemory::ForImagePage(pointer, size);
1520 ASSERT(memory != nullptr);
1521 Page* page = reinterpret_cast<Page*>(malloc(sizeof(Page)));
1523 if (is_executable) {
1525 }
1526 page->flags_ = flags;
1527 page->memory_ = memory;
1528 page->next_ = nullptr;
1529 page->forwarding_page_ = nullptr;
1530 page->card_table_ = nullptr;
1531 page->progress_bar_ = 0;
1532 page->owner_ = nullptr;
1533 page->top_ = memory->end();
1534 page->end_ = memory->end();
1535 page->survivor_end_ = 0;
1536 page->resolved_top_ = 0;
1537 page->live_bytes_ = 0;
1538
1539 MutexLocker ml(&pages_lock_);
1540 page->next_ = image_pages_;
1541 image_pages_ = page;
1542}
static constexpr intptr_t OldObjectStartOffset()
Definition: page.h:140
@ kExecutable
Definition: page.h:69
@ kImage
Definition: page.h:71
static constexpr bool IsAligned(T x, uintptr_t alignment, uintptr_t offset=0)
Definition: utils.h:92
static VirtualMemory * ForImagePage(void *pointer, uword size)
FlutterSemanticsFlag flags
void * malloc(size_t size)
Definition: allocation.cc:19
SeparatedVector2 offset

◆ ShouldPerformIdleMarkCompact()

bool dart::PageSpace::ShouldPerformIdleMarkCompact ( int64_t  deadline)

Definition at line 860 of file pages.cc.

860 {
861 // To make a consistent decision, we should not yield for a safepoint in the
862 // middle of deciding whether to perform an idle GC.
863 NoSafepointScope no_safepoint;
864
865 // When enabled, prefer the incremental/evacuating compactor over the
866 // full/sliding compactor.
867 if (FLAG_use_incremental_compactor) {
868 return false;
869 }
870
871 // Discount two pages to account for the newest data and code pages, whose
872 // partial use doesn't indicate fragmentation.
873 const intptr_t excess_in_words =
875 const double excess_ratio = static_cast<double>(excess_in_words) /
876 static_cast<double>(usage_.capacity_in_words);
877 const bool fragmented = excess_ratio > 0.05;
878
879 if (!fragmented && !page_space_controller_.ReachedIdleThreshold(usage_)) {
880 return false;
881 }
882
883 {
884 MonitorLocker locker(tasks_lock());
885 if (tasks() > 0) {
886 // A concurrent sweeper is running. If we start a mark sweep now
887 // we'll have to wait for it, and this wait time is not included in
888 // mark_words_per_micro_.
889 return false;
890 }
891 }
892
893 // Assuming compaction takes as long as marking.
894 intptr_t mark_compact_words_per_micro = mark_words_per_micro_ / 2;
895 if (mark_compact_words_per_micro == 0) {
896 mark_compact_words_per_micro = 1; // Prevent division by zero.
897 }
898
899 int64_t estimated_mark_compact_completion =
901 UsedInWords() / mark_compact_words_per_micro;
902 return estimated_mark_compact_completion <= deadline;
903}
static int64_t GetCurrentMonotonicMicros()

◆ ShouldStartIdleMarkSweep()

bool dart::PageSpace::ShouldStartIdleMarkSweep ( int64_t  deadline)

Definition at line 833 of file pages.cc.

833 {
834 // To make a consistent decision, we should not yield for a safepoint in the
835 // middle of deciding whether to perform an idle GC.
836 NoSafepointScope no_safepoint;
837
838 if (!page_space_controller_.ReachedIdleThreshold(usage_)) {
839 return false;
840 }
841
842 {
843 MonitorLocker locker(tasks_lock());
844 if (tasks() > 0) {
845 // A concurrent sweeper is running. If we start a mark sweep now
846 // we'll have to wait for it, and this wait time is not included in
847 // mark_words_per_micro_.
848 return false;
849 }
850 }
851
852 // This uses the size of new-space because the pause time to start concurrent
853 // marking is related to the size of the root set, which is mostly new-space.
854 int64_t estimated_mark_completion =
856 heap_->new_space()->UsedInWords() / mark_words_per_micro_;
857 return estimated_mark_completion <= deadline;
858}
Scavenger * new_space()
Definition: heap.h:62
intptr_t UsedInWords() const
Definition: scavenger.h:160

◆ tasks()

intptr_t dart::PageSpace::tasks ( ) const
inline

Definition at line 315 of file pages.h.

315{ return tasks_; }

◆ tasks_lock()

Monitor * dart::PageSpace::tasks_lock ( ) const
inline

Definition at line 314 of file pages.h.

314{ return &tasks_lock_; }

◆ TryAllocate()

uword dart::PageSpace::TryAllocate ( intptr_t  size,
bool  is_executable = false,
GrowthPolicy  growth_policy = kControlGrowth 
)
inline

Definition at line 141 of file pages.h.

143 {
144 bool is_protected = (is_executable) && FLAG_write_protect_code;
145 bool is_locked = false;
146 return TryAllocateInternal(
147 size, &freelists_[is_executable ? kExecutableFreelist : kDataFreelist],
148 is_executable, growth_policy, is_protected, is_locked);
149 }

◆ TryAllocatePromoLocked()

DART_FORCE_INLINE uword dart::PageSpace::TryAllocatePromoLocked ( FreeList freelist,
intptr_t  size 
)
inline

Definition at line 151 of file pages.h.

151 {
154 if (freelist->TryAllocateBumpLocked(size, &result)) {
155 return result;
156 }
157 }
158 return TryAllocatePromoLockedSlow(freelist, size);
159 }

◆ TryReleaseReservation()

void dart::PageSpace::TryReleaseReservation ( )

Definition at line 931 of file pages.cc.

931 {
934 if (oom_reservation_ == nullptr) return;
935 uword addr = reinterpret_cast<uword>(oom_reservation_);
936 intptr_t size = oom_reservation_->HeapSize();
937 oom_reservation_ = nullptr;
938 freelists_[kDataFreelist].Free(addr, size);
939}
intptr_t HeapSize()
Definition: freelist.h:31
void Free(uword addr, intptr_t size)
Definition: freelist.cc:193

◆ TryReserveForOOM()

void dart::PageSpace::TryReserveForOOM ( )

Definition at line 952 of file pages.cc.

952 {
953 if (oom_reservation_ == nullptr) {
954 uword addr = TryAllocate(kOOMReservationSize, /*exec*/ false,
955 kForceGrowth /* Don't re-enter GC */);
956 if (addr != 0) {
957 oom_reservation_ = FreeListElement::AsElement(addr, kOOMReservationSize);
958 }
959 }
960}
static FreeListElement * AsElement(uword addr, intptr_t size)
Definition: freelist.cc:16
uword TryAllocate(intptr_t size, bool is_executable=false, GrowthPolicy growth_policy=kControlGrowth)
Definition: pages.h:141

◆ UpdateMaxCapacityLocked()

void dart::PageSpace::UpdateMaxCapacityLocked ( )

Definition at line 592 of file pages.cc.

592 {
593 ASSERT(heap_ != nullptr);
594 ASSERT(heap_->isolate_group() != nullptr);
595 auto isolate_group = heap_->isolate_group();
596 isolate_group->GetHeapOldCapacityMaxMetric()->SetValue(
597 static_cast<int64_t>(usage_.capacity_in_words) * kWordSize);
598}
IsolateGroup * isolate_group() const
Definition: heap.h:273

◆ UpdateMaxUsed()

void dart::PageSpace::UpdateMaxUsed ( )

Definition at line 600 of file pages.cc.

600 {
601 ASSERT(heap_ != nullptr);
602 ASSERT(heap_->isolate_group() != nullptr);
603 auto isolate_group = heap_->isolate_group();
604 isolate_group->GetHeapOldUsedMaxMetric()->SetValue(UsedInWords() * kWordSize);
605}

◆ UsedInWords()

intptr_t dart::PageSpace::UsedInWords ( ) const
inline

Definition at line 194 of file pages.h.

194{ return usage_.used_in_words; }

◆ VisitObjectPointers()

void dart::PageSpace::VisitObjectPointers ( ObjectPointerVisitor visitor) const

Definition at line 679 of file pages.cc.

679 {
680 for (ExclusivePageIterator it(this); !it.Done(); it.Advance()) {
681 it.page()->VisitObjectPointers(visitor);
682 }
683}

◆ VisitObjects()

void dart::PageSpace::VisitObjects ( ObjectVisitor visitor) const

Definition at line 651 of file pages.cc.

651 {
652 for (ExclusivePageIterator it(this); !it.Done(); it.Advance()) {
653 it.page()->VisitObjects(visitor);
654 }
655}

◆ VisitObjectsImagePages()

void dart::PageSpace::VisitObjectsImagePages ( ObjectVisitor visitor) const

Definition at line 665 of file pages.cc.

665 {
666 for (ExclusivePageIterator it(this); !it.Done(); it.Advance()) {
667 if (it.page()->is_image()) {
668 it.page()->VisitObjects(visitor);
669 }
670 }
671}

◆ VisitObjectsNoImagePages()

void dart::PageSpace::VisitObjectsNoImagePages ( ObjectVisitor visitor) const

Definition at line 657 of file pages.cc.

657 {
658 for (ExclusivePageIterator it(this); !it.Done(); it.Advance()) {
659 if (!it.page()->is_image()) {
660 it.page()->VisitObjects(visitor);
661 }
662 }
663}

◆ VisitObjectsUnsafe()

void dart::PageSpace::VisitObjectsUnsafe ( ObjectVisitor visitor) const

Definition at line 673 of file pages.cc.

673 {
674 for (UnsafeExclusivePageIterator it(this); !it.Done(); it.Advance()) {
675 it.page()->VisitObjectsUnsafe(visitor);
676 }
677}

◆ VisitRememberedCards()

void dart::PageSpace::VisitRememberedCards ( PredicateObjectPointerVisitor visitor) const

Definition at line 685 of file pages.cc.

686 {
687 ASSERT(Thread::Current()->OwnsGCSafepoint() ||
688 (Thread::Current()->task_kind() == Thread::kScavengerTask));
689
690 // Wait for the sweeper to finish mutating the large page list.
691 {
692 MonitorLocker ml(tasks_lock());
693 while (phase() == kSweepingLarge) {
694 ml.Wait(); // No safepoint check.
695 }
696 }
697
698 // Large pages may be added concurrently due to promotion in another scavenge
699 // worker, so terminate the traversal when we hit the tail we saw while
700 // holding the pages lock, instead of at nullptr, otherwise we are racing when
701 // we read Page::next_ and Page::remembered_cards_.
702 Page* page;
703 Page* tail;
704 {
705 MutexLocker ml(&pages_lock_);
706 page = large_pages_;
707 tail = large_pages_tail_;
708 }
709 while (page != nullptr) {
710 page->VisitRememberedCards(visitor);
711 if (page == tail) break;
712 page = page->next();
713 }
714}
@ kScavengerTask
Definition: thread.h:352

◆ VisitRoots()

void dart::PageSpace::VisitRoots ( ObjectPointerVisitor visitor)

Definition at line 962 of file pages.cc.

962 {
963 if (oom_reservation_ != nullptr) {
964 // FreeListElements are generally held untagged, but ObjectPointerVisitors
965 // expect tagged pointers.
966 ObjectPtr ptr =
967 UntaggedObject::FromAddr(reinterpret_cast<uword>(oom_reservation_));
968 visitor->VisitPointer(&ptr);
969 oom_reservation_ =
970 reinterpret_cast<FreeListElement*>(UntaggedObject::ToAddr(ptr));
971 }
972}
static ObjectPtr FromAddr(uword addr)
Definition: raw_object.h:516

◆ WriteProtect()

void dart::PageSpace::WriteProtect ( bool  read_only)

Definition at line 722 of file pages.cc.

722 {
723 if (read_only) {
724 // Avoid MakeIterable trying to write to the heap.
726 }
727 for (ExclusivePageIterator it(this); !it.Done(); it.Advance()) {
728 if (!it.page()->is_image()) {
729 it.page()->WriteProtect(read_only);
730 }
731 }
732}
void ReleaseBumpAllocation()
Definition: pages.cc:580

◆ WriteProtectCode()

void dart::PageSpace::WriteProtectCode ( bool  read_only)

Definition at line 812 of file pages.cc.

812 {
813 if (FLAG_write_protect_code) {
814 MutexLocker ml(&pages_lock_);
815 NoSafepointScope no_safepoint;
816 // No need to go through all of the data pages first.
817 Page* page = exec_pages_;
818 while (page != nullptr) {
819 ASSERT(page->is_executable());
820 page->WriteProtect(read_only);
821 page = page->next();
822 }
823 page = large_pages_;
824 while (page != nullptr) {
825 if (page->is_executable()) {
826 page->WriteProtect(read_only);
827 }
828 page = page->next();
829 }
830 }
831}

◆ YieldConcurrentMarking()

void dart::PageSpace::YieldConcurrentMarking ( )

Definition at line 459 of file pages.cc.

459 {
460 MonitorLocker ml(&tasks_lock_);
461 if (pause_concurrent_marking_.load() != 0) {
463 concurrent_marker_tasks_active_--;
464 if (concurrent_marker_tasks_active_ == 0) {
465 ml.NotifyAll();
466 }
467 while (pause_concurrent_marking_.load() != 0) {
468 ml.Wait();
469 }
470 concurrent_marker_tasks_active_++;
471 }
472}
#define TIMELINE_FUNCTION_GC_DURATION(thread, name)
Definition: timeline.h:41

Friends And Related Function Documentation

◆ BasePageIterator

friend class BasePageIterator
friend

Definition at line 496 of file pages.h.

◆ Code

friend class Code
friend

Definition at line 509 of file pages.h.

◆ CompactorTask

friend class CompactorTask
friend

Definition at line 508 of file pages.h.

◆ ConcurrentSweeperTask

friend class ConcurrentSweeperTask
friend

Definition at line 503 of file pages.h.

◆ EpilogueTask

friend class EpilogueTask
friend

Definition at line 507 of file pages.h.

◆ ExclusiveCodePageIterator

friend class ExclusiveCodePageIterator
friend

Definition at line 498 of file pages.h.

◆ ExclusiveLargePageIterator

friend class ExclusiveLargePageIterator
friend

Definition at line 499 of file pages.h.

◆ ExclusivePageIterator

friend class ExclusivePageIterator
friend

Definition at line 497 of file pages.h.

◆ GCCompactor

friend class GCCompactor
friend

Definition at line 504 of file pages.h.

◆ GCIncrementalCompactor

friend class GCIncrementalCompactor
friend

Definition at line 505 of file pages.h.

◆ HeapIterationScope

friend class HeapIterationScope
friend

Definition at line 500 of file pages.h.

◆ HeapSnapshotWriter

friend class HeapSnapshotWriter
friend

Definition at line 501 of file pages.h.

◆ PageSpaceController

friend class PageSpaceController
friend

Definition at line 502 of file pages.h.

◆ PrologueTask

friend class PrologueTask
friend

Definition at line 506 of file pages.h.


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