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

Constructor & Destructor Documentation

◆ PageSpace()

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

Definition at line 54 of file pages.cc.

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

◆ ~PageSpace()

dart::PageSpace::~PageSpace ( )

Definition at line 93 of file pages.cc.

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

Member Function Documentation

◆ AbandonMarkingForShutdown()

void dart::PageSpace::AbandonMarkingForShutdown ( )

Definition at line 581 of file pages.cc.

581 {
582 delete marker_;
583 marker_ = nullptr;
584}

◆ AcquireLock()

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

Definition at line 426 of file pages.cc.

426 {
427 freelist->mutex()->Lock();
428}

◆ AddGCTime()

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

Definition at line 252 of file pages.h.

252{ gc_time_micros_ += micros; }

◆ AddRegionsToObjectSet()

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

Definition at line 637 of file pages.cc.

637 {
638 ASSERT((pages_ != nullptr) || (exec_pages_ != nullptr) ||
639 (large_pages_ != nullptr));
640 for (ExclusivePageIterator it(this); !it.Done(); it.Advance()) {
641 set->AddRegion(it.page()->object_start(), it.page()->object_end());
642 }
643}
friend class ExclusivePageIterator
Definition pages.h:491
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 266 of file pages.h.

266 {
267 allocated_black_in_words_.fetch_add(size >> kWordSizeLog2);
268 }
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

◆ AllocatedExternal()

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

Definition at line 273 of file pages.h.

273 {
274 ASSERT(size >= 0);
275 intptr_t size_in_words = size >> kWordSizeLog2;
276 intptr_t expected = usage_.external_in_words.load();
277 intptr_t desired;
278 do {
279 desired = expected + size_in_words;
280 if (desired < 0 || desired > kMaxAddrSpaceInWords) {
281 return false;
282 }
283 ASSERT(desired >= 0);
284 } while (
285 !usage_.external_in_words.compare_exchange_weak(expected, desired));
286 return true;
287 }
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
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

◆ 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 904 of file pages.cc.

904 {
905 if (phase() == PageSpace::kMarking) {
906 ml->Exit();
908 ml->Enter();
909 }
910 if ((phase() == kSweepingLarge) || (phase() == kSweepingRegular)) {
911 ml->Exit();
912 Sweep(/*exclusive*/ false);
913 SweepLarge();
914 ml->Enter();
915 }
916}
void IncrementalMarkWithUnlimitedBudget(PageSpace *page_space)
Definition marker.cc:1048
Phase phase() const
Definition pages.h:336

◆ CapacityInWords()

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

Definition at line 190 of file pages.h.

190 {
191 MutexLocker ml(&pages_lock_);
192 return usage_.capacity_in_words;
193 }
RelaxedAtomic< intptr_t > capacity_in_words
Definition spaces.h:20

◆ CodeContains()

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

Definition at line 619 of file pages.cc.

619 {
620 for (ExclusiveCodePageIterator it(this); !it.Done(); it.Advance()) {
621 if (it.page()->Contains(addr)) {
622 return true;
623 }
624 }
625 return false;
626}
friend class ExclusiveCodePageIterator
Definition pages.h:492

◆ CollectGarbage()

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

Definition at line 961 of file pages.cc.

961 {
962 ASSERT(!Thread::Current()->force_growth());
963
964 if (!finalize) {
965 if (!enable_concurrent_mark()) return; // Disabled.
966 if (FLAG_marker_tasks == 0) return; // Disabled.
967 }
968
969 GcSafepointOperationScope safepoint_scope(thread);
970
971 // Wait for pending tasks to complete and then account for the driver task.
972 {
973 MonitorLocker locker(tasks_lock());
974 if (!finalize &&
975 (phase() == kMarking || phase() == kAwaitingFinalization)) {
976 // Concurrent mark is already running.
977 return;
978 }
979
980 AssistTasks(&locker);
981 while (tasks() > 0) {
982 locker.Wait();
983 }
985 set_tasks(1);
986 }
987
988 // Ensure that all threads for this isolate are at a safepoint (either
989 // stopped or in native code). We have guards around Newgen GC and oldgen GC
990 // to ensure that if two threads are racing to collect at the same time the
991 // loser skips collection and goes straight to allocation.
992 CollectGarbageHelper(thread, compact, finalize);
993
994 // Done, reset the task count.
995 {
996 MonitorLocker ml(tasks_lock());
997 set_tasks(tasks() - 1);
998 ml.NotifyAll();
999 }
1000}
void set_tasks(intptr_t val)
Definition pages.h:311
bool enable_concurrent_mark() const
Definition pages.h:346
static Thread * Current()
Definition thread.h:361

◆ collections()

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

Definition at line 258 of file pages.h.

258{ return collections_; }

◆ concurrent_marker_tasks()

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

Definition at line 315 of file pages.h.

315 {
317 return concurrent_marker_tasks_;
318 }
#define DEBUG_ASSERT(cond)
Definition assert.h:321
bool IsOwnedByCurrentThread() const
Definition os_thread.h:370

◆ concurrent_marker_tasks_active()

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

Definition at line 324 of file pages.h.

324 {
326 return concurrent_marker_tasks_active_;
327 }

◆ Contains()

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

Definition at line 601 of file pages.cc.

601 {
602 for (ExclusivePageIterator it(this); !it.Done(); it.Advance()) {
603 if (it.page()->Contains(addr)) {
604 return true;
605 }
606 }
607 return false;
608}

◆ ContainsUnsafe()

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

Definition at line 610 of file pages.cc.

610 {
611 for (UnsafeExclusivePageIterator it(this); !it.Done(); it.Advance()) {
612 if (it.page()->Contains(addr)) {
613 return true;
614 }
615 }
616 return false;
617}

◆ DataContains()

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

Definition at line 628 of file pages.cc.

628 {
629 for (ExclusivePageIterator it(this); !it.Done(); it.Advance()) {
630 if (!it.page()->is_executable() && it.page()->Contains(addr)) {
631 return true;
632 }
633 }
634 return false;
635}

◆ DataFreeList()

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

Definition at line 296 of file pages.h.

296 {
297 return &freelists_[kDataFreelist + i];
298 }

◆ enable_concurrent_mark()

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

Definition at line 346 of file pages.h.

346{ 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 }
void EvaluateAfterLoading(SpaceUsage after)
Definition pages.cc:1517

◆ ExternalInWords()

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

Definition at line 207 of file pages.h.

207{ return usage_.external_in_words; }

◆ FreedExternal()

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

Definition at line 288 of file pages.h.

288 {
289 ASSERT(size >= 0);
290 intptr_t size_in_words = size >> kWordSizeLog2;
291 usage_.external_in_words -= size_in_words;
292 ASSERT(usage_.external_in_words >= 0);
293 }

◆ gc_time_micros()

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

Definition at line 254 of file pages.h.

254{ return gc_time_micros_; }

◆ GetCurrentUsage()

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

Definition at line 208 of file pages.h.

208 {
209 MutexLocker ml(&pages_lock_);
210 return usage_;
211 }

◆ ImageInWords()

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

Definition at line 212 of file pages.h.

212 {
213 intptr_t size = 0;
214 MutexLocker ml(&pages_lock_);
215 for (Page* page = image_pages_; page != nullptr; page = page->next()) {
216 size += page->memory_->size();
217 }
218 return size >> kWordSizeLog2;
219 }

◆ IncreaseCapacityInWords()

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

Definition at line 194 of file pages.h.

194 {
195 MutexLocker ml(&pages_lock_);
196 IncreaseCapacityInWordsLocked(increase_in_words);
197 }
void IncreaseCapacityInWordsLocked(intptr_t increase_in_words)
Definition pages.h:198

◆ IncreaseCapacityInWordsLocked()

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

Definition at line 198 of file pages.h.

198 {
200 usage_.capacity_in_words += increase_in_words;
202 }
bool IsOwnedByCurrentThread() const
Definition os_thread.h:401

◆ IncrementalMarkWithSizeBudget()

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

Definition at line 892 of file pages.cc.

892 {
893 if (marker_ != nullptr) {
894 marker_->IncrementalMarkWithSizeBudget(this, size);
895 }
896}
void IncrementalMarkWithSizeBudget(PageSpace *page_space, intptr_t size)
Definition marker.cc:1066

◆ IncrementalMarkWithTimeBudget()

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

Definition at line 898 of file pages.cc.

898 {
899 if (marker_ != nullptr) {
900 marker_->IncrementalMarkWithTimeBudget(this, deadline);
901 }
902}
void IncrementalMarkWithTimeBudget(PageSpace *page_space, int64_t deadline)
Definition marker.cc:1090

◆ IncrementCollections()

void dart::PageSpace::IncrementCollections ( )
inline

Definition at line 256 of file pages.h.

256{ collections_++; }

◆ IsObjectFromImagePages()

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

Definition at line 1357 of file pages.cc.

1357 {
1358 uword object_addr = UntaggedObject::ToAddr(object);
1359 Page* image_page = image_pages_;
1360 while (image_page != nullptr) {
1361 if (image_page->Contains(object_addr)) {
1362 return true;
1363 }
1364 image_page = image_page->next();
1365 }
1366 return false;
1367}
Page * next() const
Definition page.h:86
static uword ToAddr(const UntaggedObject *raw_obj)
Definition raw_object.h:501

◆ IsValidAddress()

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

Definition at line 225 of file pages.h.

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

◆ marker()

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

Definition at line 353 of file pages.h.

353{ return marker_; }

◆ MarkReservation()

bool dart::PageSpace::MarkReservation ( )

Definition at line 928 of file pages.cc.

928 {
929 if (oom_reservation_ == nullptr) {
930 return false;
931 }
932 UntaggedObject* ptr = reinterpret_cast<UntaggedObject*>(oom_reservation_);
933 if (!ptr->IsMarked()) {
934 ptr->SetMarkBit();
935 }
936 return true;
937}

◆ pause_concurrent_marking()

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

Definition at line 333 of file pages.h.

333 {
334 return pause_concurrent_marking_.load() != 0;
335 }
T load(std::memory_order order=std::memory_order_acquire) const
Definition atomic.h:101

◆ PauseConcurrentMarking()

void dart::PageSpace::PauseConcurrentMarking ( )

Definition at line 437 of file pages.cc.

437 {
438 MonitorLocker ml(&tasks_lock_);
439 ASSERT(pause_concurrent_marking_.load() == 0);
440 pause_concurrent_marking_.store(1);
441 while (concurrent_marker_tasks_active_ != 0) {
442 ml.Wait();
443 }
444}
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 336 of file pages.h.

336{ return phase_; }

◆ PrintHeapMapToJSONStream()

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

Definition at line 765 of file pages.cc.

766 {
767 JSONObject heap_map(stream);
768 heap_map.AddProperty("type", "HeapMap");
769 heap_map.AddProperty("freeClassId", static_cast<intptr_t>(kFreeListElement));
770 heap_map.AddProperty("unitSizeBytes",
771 static_cast<intptr_t>(kObjectAlignment));
772 heap_map.AddProperty("pageSizeBytes", kPageSizeInWords * kWordSize);
773 {
774 JSONObject class_list(&heap_map, "classList");
775 isolate_group->class_table()->PrintToJSONObject(&class_list);
776 }
777 {
778 // "pages" is an array [page0, page1, ..., pageN], each page of the form
779 // {"object_start": "0x...", "objects": [size, class id, size, ...]}
780 // TODO(19445): Use ExclusivePageIterator once HeapMap supports large pages.
782 MutexLocker ml(&pages_lock_);
783 MakeIterable();
784 JSONArray all_pages(&heap_map, "pages");
785 for (Page* page = pages_; page != nullptr; page = page->next()) {
786 JSONObject page_container(&all_pages);
787 page_container.AddPropertyF("objectStart", "0x%" Px "",
788 page->object_start());
789 JSONArray page_map(&page_container, "objects");
790 HeapMapAsJSONVisitor printer(&page_map);
791 page->VisitObjects(&printer);
792 }
793 for (Page* page = exec_pages_; page != nullptr; page = page->next()) {
794 JSONObject page_container(&all_pages);
795 page_container.AddPropertyF("objectStart", "0x%" Px "",
796 page->object_start());
797 JSONArray page_map(&page_container, "objects");
798 HeapMapAsJSONVisitor printer(&page_map);
799 page->VisitObjects(&printer);
800 }
801 }
802}
friend class HeapIterationScope
Definition pages.h:494
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 728 of file pages.cc.

728 {
729 auto isolate_group = IsolateGroup::Current();
730 ASSERT(isolate_group != nullptr);
731 JSONObject space(object, "old");
732 space.AddProperty("type", "HeapSpace");
733 space.AddProperty("name", "old");
734 space.AddProperty("vmName", "PageSpace");
735 space.AddProperty("collections", collections());
736 space.AddProperty64("used", UsedInWords() * kWordSize);
737 space.AddProperty64("capacity", CapacityInWords() * kWordSize);
738 space.AddProperty64("external", ExternalInWords() * kWordSize);
739 space.AddProperty("time", MicrosecondsToSeconds(gc_time_micros()));
740 if (collections() > 0) {
741 int64_t run_time = isolate_group->UptimeMicros();
742 run_time = Utils::Maximum(run_time, static_cast<int64_t>(0));
743 double run_time_millis = MicrosecondsToMilliseconds(run_time);
744 double avg_time_between_collections =
745 run_time_millis / static_cast<double>(collections());
746 space.AddProperty("avgCollectionPeriodMillis",
747 avg_time_between_collections);
748 } else {
749 space.AddProperty("avgCollectionPeriodMillis", 0.0);
750 }
751}
static IsolateGroup * Current()
Definition isolate.h:534
intptr_t UsedInWords() const
Definition pages.h:189
int64_t gc_time_micros() const
Definition pages.h:254
intptr_t collections() const
Definition pages.h:258
intptr_t CapacityInWords() const
Definition pages.h:190
intptr_t ExternalInWords() const
Definition pages.h:207
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 305 of file pages.h.

305 {
306 pause_concurrent_marking_.fetch_or(0);
307 }
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:1385

◆ 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:1405

◆ 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:1395

◆ ReleaseBumpAllocation()

void dart::PageSpace::ReleaseBumpAllocation ( )

Definition at line 574 of file pages.cc.

574 {
575 for (intptr_t i = 0; i < num_freelists_; i++) {
576 size_t leftover = freelists_[i].ReleaseBumpAllocation();
577 usage_.used_in_words -= (leftover >> kWordSizeLog2);
578 }
579}
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 430 of file pages.cc.

430 {
431 usage_.used_in_words +=
432 (freelist->TakeUnaccountedSizeLocked() >> kWordSizeLog2);
433 freelist->mutex()->Unlock();
434 usage_.used_in_words -= (freelist->ReleaseBumpAllocation() >> kWordSizeLog2);
435}

◆ ResetProgressBars()

void dart::PageSpace::ResetProgressBars ( ) const

Definition at line 709 of file pages.cc.

709 {
710 for (Page* page = large_pages_; page != nullptr; page = page->next()) {
711 page->ResetProgressBar();
712 }
713}

◆ ResumeConcurrentMarking()

void dart::PageSpace::ResumeConcurrentMarking ( )

Definition at line 446 of file pages.cc.

446 {
447 MonitorLocker ml(&tasks_lock_);
448 ASSERT(pause_concurrent_marking_.load() != 0);
449 pause_concurrent_marking_.store(0);
450 ml.NotifyAll();
451}

◆ set_concurrent_marker_tasks()

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

Definition at line 319 of file pages.h.

319 {
320 ASSERT(val >= 0);
322 concurrent_marker_tasks_ = val;
323 }

◆ set_concurrent_marker_tasks_active()

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

Definition at line 328 of file pages.h.

328 {
329 ASSERT(val >= 0);
331 concurrent_marker_tasks_active_ = val;
332 }

◆ set_enable_concurrent_mark()

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

Definition at line 347 of file pages.h.

347 {
348 enable_concurrent_mark_ = enable_concurrent_mark;
349 }

◆ set_phase()

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

Definition at line 337 of file pages.h.

337{ phase_ = val; }

◆ set_tasks()

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

Definition at line 311 of file pages.h.

311 {
312 ASSERT(val >= 0);
313 tasks_ = val;
314 }

◆ SetupImagePage()

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

Definition at line 1323 of file pages.cc.

1323 {
1324 // Setup a Page so precompiled Instructions can be traversed.
1325 // Instructions are contiguous at [pointer, pointer + size). Page
1326 // expects to find objects at [memory->start() + ObjectStartOffset,
1327 // memory->end()).
1329 pointer = reinterpret_cast<void*>(reinterpret_cast<uword>(pointer) - offset);
1331 size += offset;
1332
1333 VirtualMemory* memory = VirtualMemory::ForImagePage(pointer, size);
1334 ASSERT(memory != nullptr);
1335 Page* page = reinterpret_cast<Page*>(malloc(sizeof(Page)));
1337 if (is_executable) {
1339 }
1340 page->flags_ = flags;
1341 page->memory_ = memory;
1342 page->next_ = nullptr;
1343 page->forwarding_page_ = nullptr;
1344 page->card_table_ = nullptr;
1345 page->progress_bar_ = 0;
1346 page->owner_ = nullptr;
1347 page->top_ = memory->end();
1348 page->end_ = memory->end();
1349 page->survivor_end_ = 0;
1350 page->resolved_top_ = 0;
1351
1352 MutexLocker ml(&pages_lock_);
1353 page->next_ = image_pages_;
1354 image_pages_ = page;
1355}
static constexpr intptr_t OldObjectStartOffset()
Definition page.h:119
@ 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:77
static VirtualMemory * ForImagePage(void *pointer, uword size)
FlutterSemanticsFlag flags
void * malloc(size_t size)
Definition allocation.cc:19
Point offset

◆ ShouldPerformIdleMarkCompact()

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

Definition at line 853 of file pages.cc.

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

◆ ShouldStartIdleMarkSweep()

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

Definition at line 826 of file pages.cc.

826 {
827 // To make a consistent decision, we should not yield for a safepoint in the
828 // middle of deciding whether to perform an idle GC.
829 NoSafepointScope no_safepoint;
830
831 if (!page_space_controller_.ReachedIdleThreshold(usage_)) {
832 return false;
833 }
834
835 {
836 MonitorLocker locker(tasks_lock());
837 if (tasks() > 0) {
838 // A concurrent sweeper is running. If we start a mark sweep now
839 // we'll have to wait for it, and this wait time is not included in
840 // mark_words_per_micro_.
841 return false;
842 }
843 }
844
845 // This uses the size of new-space because the pause time to start concurrent
846 // marking is related to the size of the root set, which is mostly new-space.
847 int64_t estimated_mark_completion =
849 heap_->new_space()->UsedInWords() / mark_words_per_micro_;
850 return estimated_mark_completion <= deadline;
851}
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 310 of file pages.h.

310{ return tasks_; }

◆ tasks_lock()

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

Definition at line 309 of file pages.h.

309{ 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 918 of file pages.cc.

918 {
921 if (oom_reservation_ == nullptr) return;
922 uword addr = reinterpret_cast<uword>(oom_reservation_);
923 intptr_t size = oom_reservation_->HeapSize();
924 oom_reservation_ = nullptr;
925 freelists_[kDataFreelist].Free(addr, size);
926}
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 939 of file pages.cc.

939 {
940 if (oom_reservation_ == nullptr) {
941 uword addr = TryAllocate(kOOMReservationSize, /*exec*/ false,
942 kForceGrowth /* Don't re-enter GC */);
943 if (addr != 0) {
944 oom_reservation_ = FreeListElement::AsElement(addr, kOOMReservationSize);
945 }
946 }
947}
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 586 of file pages.cc.

586 {
587 ASSERT(heap_ != nullptr);
588 ASSERT(heap_->isolate_group() != nullptr);
589 auto isolate_group = heap_->isolate_group();
590 isolate_group->GetHeapOldCapacityMaxMetric()->SetValue(
591 static_cast<int64_t>(usage_.capacity_in_words) * kWordSize);
592}
IsolateGroup * isolate_group() const
Definition heap.h:273

◆ UpdateMaxUsed()

void dart::PageSpace::UpdateMaxUsed ( )

Definition at line 594 of file pages.cc.

594 {
595 ASSERT(heap_ != nullptr);
596 ASSERT(heap_->isolate_group() != nullptr);
597 auto isolate_group = heap_->isolate_group();
598 isolate_group->GetHeapOldUsedMaxMetric()->SetValue(UsedInWords() * kWordSize);
599}

◆ UsedInWords()

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

Definition at line 189 of file pages.h.

189{ return usage_.used_in_words; }

◆ VisitObjectPointers()

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

Definition at line 673 of file pages.cc.

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

◆ VisitObjects()

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

Definition at line 645 of file pages.cc.

645 {
646 for (ExclusivePageIterator it(this); !it.Done(); it.Advance()) {
647 it.page()->VisitObjects(visitor);
648 }
649}

◆ VisitObjectsImagePages()

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

Definition at line 659 of file pages.cc.

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

◆ VisitObjectsNoImagePages()

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

Definition at line 651 of file pages.cc.

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

◆ VisitObjectsUnsafe()

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

Definition at line 667 of file pages.cc.

667 {
668 for (UnsafeExclusivePageIterator it(this); !it.Done(); it.Advance()) {
669 it.page()->VisitObjectsUnsafe(visitor);
670 }
671}

◆ VisitRememberedCards()

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

Definition at line 679 of file pages.cc.

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

◆ VisitRoots()

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

Definition at line 949 of file pages.cc.

949 {
950 if (oom_reservation_ != nullptr) {
951 // FreeListElements are generally held untagged, but ObjectPointerVisitors
952 // expect tagged pointers.
953 ObjectPtr ptr =
954 UntaggedObject::FromAddr(reinterpret_cast<uword>(oom_reservation_));
955 visitor->VisitPointer(&ptr);
956 oom_reservation_ =
957 reinterpret_cast<FreeListElement*>(UntaggedObject::ToAddr(ptr));
958 }
959}
static ObjectPtr FromAddr(uword addr)
Definition raw_object.h:495

◆ WriteProtect()

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

Definition at line 715 of file pages.cc.

715 {
716 if (read_only) {
717 // Avoid MakeIterable trying to write to the heap.
719 }
720 for (ExclusivePageIterator it(this); !it.Done(); it.Advance()) {
721 if (!it.page()->is_image()) {
722 it.page()->WriteProtect(read_only);
723 }
724 }
725}
void ReleaseBumpAllocation()
Definition pages.cc:574

◆ WriteProtectCode()

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

Definition at line 805 of file pages.cc.

805 {
806 if (FLAG_write_protect_code) {
807 MutexLocker ml(&pages_lock_);
808 NoSafepointScope no_safepoint;
809 // No need to go through all of the data pages first.
810 Page* page = exec_pages_;
811 while (page != nullptr) {
812 ASSERT(page->is_executable());
813 page->WriteProtect(read_only);
814 page = page->next();
815 }
816 page = large_pages_;
817 while (page != nullptr) {
818 if (page->is_executable()) {
819 page->WriteProtect(read_only);
820 }
821 page = page->next();
822 }
823 }
824}

◆ YieldConcurrentMarking()

void dart::PageSpace::YieldConcurrentMarking ( )

Definition at line 453 of file pages.cc.

453 {
454 MonitorLocker ml(&tasks_lock_);
455 if (pause_concurrent_marking_.load() != 0) {
457 concurrent_marker_tasks_active_--;
458 if (concurrent_marker_tasks_active_ == 0) {
459 ml.NotifyAll();
460 }
461 while (pause_concurrent_marking_.load() != 0) {
462 ml.Wait();
463 }
464 concurrent_marker_tasks_active_++;
465 }
466}
#define TIMELINE_FUNCTION_GC_DURATION(thread, name)
Definition timeline.h:41

Friends And Related Symbol Documentation

◆ BasePageIterator

friend class BasePageIterator
friend

Definition at line 490 of file pages.h.

◆ Code

friend class Code
friend

Definition at line 500 of file pages.h.

◆ CompactorTask

friend class CompactorTask
friend

Definition at line 499 of file pages.h.

◆ ConcurrentSweeperTask

friend class ConcurrentSweeperTask
friend

Definition at line 497 of file pages.h.

◆ ExclusiveCodePageIterator

friend class ExclusiveCodePageIterator
friend

Definition at line 492 of file pages.h.

◆ ExclusiveLargePageIterator

friend class ExclusiveLargePageIterator
friend

Definition at line 493 of file pages.h.

◆ ExclusivePageIterator

friend class ExclusivePageIterator
friend

Definition at line 491 of file pages.h.

◆ GCCompactor

friend class GCCompactor
friend

Definition at line 498 of file pages.h.

◆ HeapIterationScope

friend class HeapIterationScope
friend

Definition at line 494 of file pages.h.

◆ HeapSnapshotWriter

friend class HeapSnapshotWriter
friend

Definition at line 495 of file pages.h.

◆ PageSpaceController

friend class PageSpaceController
friend

Definition at line 496 of file pages.h.


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