Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
Classes | Public Types | Public Member Functions | Static Public Member Functions | Static Public Attributes | Friends | List of all members
dart::Heap Class Reference

#include <heap.h>

Public Types

enum  Space { kNew , kOld , kCode }
 
enum  WeakSelector {
  kPeers = 0 , kIdentityHashes , kCanonicalHashes , kObjectIds ,
  kLoadingUnits , kHeapSamplingData , kNumWeakSelectors
}
 

Public Member Functions

 ~Heap ()
 
Scavengernew_space ()
 
PageSpaceold_space ()
 
uword Allocate (Thread *thread, intptr_t size, Space space)
 
bool AllocatedExternal (intptr_t size, Space space)
 
void FreedExternal (intptr_t size, Space space)
 
void PromotedExternal (intptr_t size)
 
void CheckExternalGC (Thread *thread)
 
bool Contains (uword addr) const
 
bool NewContains (uword addr) const
 
bool OldContains (uword addr) const
 
bool CodeContains (uword addr) const
 
bool DataContains (uword addr) const
 
void NotifyIdle (int64_t deadline)
 
void NotifyDestroyed ()
 
Dart_PerformanceMode mode () const
 
Dart_PerformanceMode SetMode (Dart_PerformanceMode mode)
 
void CollectGarbage (Thread *thread, GCType type, GCReason reason)
 
void CollectAllGarbage (GCReason reason=GCReason::kFull, bool compact=false)
 
void CheckCatchUp (Thread *thread)
 
void CheckConcurrentMarking (Thread *thread, GCReason reason, intptr_t size)
 
void CheckFinalizeMarking (Thread *thread)
 
void StartConcurrentMarking (Thread *thread, GCReason reason)
 
void WaitForMarkerTasks (Thread *thread)
 
void WaitForSweeperTasks (Thread *thread)
 
void WaitForSweeperTasksAtSafepoint (Thread *thread)
 
void WriteProtect (bool read_only)
 
void WriteProtectCode (bool read_only)
 
bool Verify (const char *msg, MarkExpectation mark_expectation=kForbidMarked)
 
void PrintSizes () const
 
intptr_t UsedInWords (Space space) const
 
intptr_t CapacityInWords (Space space) const
 
intptr_t ExternalInWords (Space space) const
 
intptr_t TotalUsedInWords () const
 
intptr_t TotalCapacityInWords () const
 
intptr_t TotalExternalInWords () const
 
int64_t GCTimeInMicros (Space space) const
 
intptr_t Collections (Space space) const
 
ObjectSetCreateAllocatedObjectSet (Zone *zone, MarkExpectation mark_expectation)
 
void SetPeer (ObjectPtr raw_obj, void *peer)
 
void * GetPeer (ObjectPtr raw_obj) const
 
int64_t PeerCount () const
 
intptr_t SetHashIfNotSet (ObjectPtr raw_obj, intptr_t hash)
 
intptr_t GetHash (ObjectPtr raw_obj) const
 
void SetCanonicalHash (ObjectPtr raw_obj, intptr_t hash)
 
intptr_t GetCanonicalHash (ObjectPtr raw_obj) const
 
void ResetCanonicalHashTable ()
 
void SetObjectId (ObjectPtr raw_obj, intptr_t object_id)
 
intptr_t GetObjectId (ObjectPtr raw_obj) const
 
void ResetObjectIdTable ()
 
void SetLoadingUnit (ObjectPtr raw_obj, intptr_t unit_id)
 
intptr_t GetLoadingUnit (ObjectPtr raw_obj) const
 
void SetHeapSamplingData (ObjectPtr obj, void *data)
 
intptr_t GetWeakEntry (ObjectPtr raw_obj, WeakSelector sel) const
 
void SetWeakEntry (ObjectPtr raw_obj, WeakSelector sel, intptr_t val)
 
intptr_t SetWeakEntryIfNonExistent (ObjectPtr raw_obj, WeakSelector sel, intptr_t val)
 
WeakTableGetWeakTable (Space space, WeakSelector selector) const
 
void SetWeakTable (Space space, WeakSelector selector, WeakTable *value)
 
void ForwardWeakEntries (ObjectPtr before_object, ObjectPtr after_object)
 
void ForwardWeakTables (ObjectPointerVisitor *visitor)
 
void ReportSurvivingAllocations (Dart_HeapSamplingReportCallback callback, void *context)
 
void UpdateGlobalMaxUsed ()
 
void PrintToJSONObject (Space space, JSONObject *object) const
 
void PrintMemoryUsageJSON (JSONStream *stream) const
 
void PrintMemoryUsageJSON (JSONObject *jsobj) const
 
void PrintHeapMapToJSONStream (IsolateGroup *isolate_group, JSONStream *stream)
 
intptr_t ReachabilityBarrier ()
 
IsolateGroupisolate_group () const
 
bool is_vm_isolate () const
 
void SetupImagePage (void *pointer, uword size, bool is_executable)
 
Space SpaceForExternal (intptr_t size) const
 
void CollectOnNthAllocation (intptr_t num_allocations)
 

Static Public Member Functions

static void Init (IsolateGroup *isolate_group, bool is_vm_isolate, intptr_t max_new_gen_words, intptr_t max_old_gen_words)
 
static const char * GCTypeToString (GCType type)
 
static const char * GCReasonToString (GCReason reason)
 

Static Public Attributes

static constexpr uint8_t kZapByte = 0xf3
 

Friends

class Become
 
class GCCompactor
 
class Precompiler
 
class ServiceEvent
 
class Scavenger
 
class PageSpace
 
class ProgramReloadContext
 
class ClassFinalizer
 
class HeapIterationScope
 
class GCMarker
 
class ProgramVisitor
 
class Serializer
 
class HeapTestHelper
 
class GCTestHelper
 

Detailed Description

Definition at line 35 of file heap.h.

Member Enumeration Documentation

◆ Space

Enumerator
kNew 
kOld 
kCode 

Definition at line 37 of file heap.h.

37 {
38 kNew,
39 kOld,
40 kCode,
41 };
@ kCode
Definition heap.h:40
@ kNew
Definition heap.h:38
@ kOld
Definition heap.h:39

◆ WeakSelector

Enumerator
kPeers 
kIdentityHashes 
kCanonicalHashes 
kObjectIds 
kLoadingUnits 
kHeapSamplingData 
kNumWeakSelectors 

Definition at line 43 of file heap.h.

43 {
44 kPeers = 0,
45#if !defined(HASH_IN_OBJECT_HEADER)
47#endif
51#if !defined(PRODUCT) || defined(FORCE_INCLUDE_SAMPLING_HEAP_PROFILER)
53#endif
55 };
@ kIdentityHashes
Definition heap.h:46
@ kCanonicalHashes
Definition heap.h:48
@ kHeapSamplingData
Definition heap.h:52
@ kObjectIds
Definition heap.h:49
@ kNumWeakSelectors
Definition heap.h:54
@ kLoadingUnits
Definition heap.h:50
@ kPeers
Definition heap.h:44

Constructor & Destructor Documentation

◆ ~Heap()

dart::Heap::~Heap ( )

Definition at line 62 of file heap.cc.

62 {
63#if !defined(PRODUCT) || defined(FORCE_INCLUDE_SAMPLING_HEAP_PROFILER)
66 if (cleanup != nullptr) {
67 new_weak_tables_[kHeapSamplingData]->CleanupValues(cleanup);
68 old_weak_tables_[kHeapSamplingData]->CleanupValues(cleanup);
69 }
70#endif
71
72 for (int sel = 0; sel < kNumWeakSelectors; sel++) {
73 delete new_weak_tables_[sel];
74 delete old_weak_tables_[sel];
75 }
76}
static Dart_HeapSamplingDeleteCallback delete_callback()
Definition sampler.h:54
void CleanupValues(Dart_HeapSamplingDeleteCallback cleanup)
void(* Dart_HeapSamplingDeleteCallback)(void *data)
Definition dart_api.h:1287

Member Function Documentation

◆ Allocate()

uword dart::Heap::Allocate ( Thread thread,
intptr_t  size,
Space  space 
)
inline

Definition at line 65 of file heap.h.

65 {
66 ASSERT(!read_only_);
67 switch (space) {
68 case kNew:
69 // Do not attempt to allocate very large objects in new space.
70 if (!IsAllocatableInNewSpace(size)) {
71 return AllocateOld(thread, size, /*executable*/ false);
72 }
73 return AllocateNew(thread, size);
74 case kOld:
75 return AllocateOld(thread, size, /*executable*/ false);
76 case kCode:
77 return AllocateOld(thread, size, /*executable*/ true);
78 default:
80 }
81 return 0;
82 }
#define UNREACHABLE()
Definition assert.h:248
#define ASSERT(E)
bool IsAllocatableInNewSpace(intptr_t size)
Definition spaces.h:57

◆ AllocatedExternal()

bool dart::Heap::AllocatedExternal ( intptr_t  size,
Space  space 
)

Definition at line 179 of file heap.cc.

179 {
180 if (space == kNew) {
181 if (!new_space_.AllocatedExternal(size)) {
182 return false;
183 }
184 } else {
185 ASSERT(space == kOld);
186 if (!old_space_.AllocatedExternal(size)) {
187 return false;
188 }
189 }
190
191 Thread* thread = Thread::Current();
192 if ((thread->no_callback_scope_depth() == 0) && !thread->force_growth()) {
193 CheckExternalGC(thread);
194 } else {
195 // Check delayed until Dart_TypedDataRelease/~ForceGrowthScope.
196 }
197 return true;
198}
void CheckExternalGC(Thread *thread)
Definition heap.cc:214
bool AllocatedExternal(intptr_t size)
Definition pages.h:273
bool AllocatedExternal(intptr_t size)
Definition scavenger.h:202
static Thread * Current()
Definition thread.h:361

◆ CapacityInWords()

intptr_t dart::Heap::CapacityInWords ( Space  space) const

Definition at line 795 of file heap.cc.

795 {
796 return space == kNew ? new_space_.CapacityInWords()
797 : old_space_.CapacityInWords();
798}
intptr_t CapacityInWords() const
Definition pages.h:190
intptr_t CapacityInWords() const
Definition scavenger.h:164

◆ CheckCatchUp()

void dart::Heap::CheckCatchUp ( Thread thread)

Definition at line 574 of file heap.cc.

574 {
575 ASSERT(!thread->force_growth());
576 if (old_space()->ReachedHardThreshold()) {
578 } else {
580 }
581}
void CheckConcurrentMarking(Thread *thread, GCReason reason, intptr_t size)
Definition heap.cc:583
PageSpace * old_space()
Definition heap.h:63
void CollectGarbage(Thread *thread, GCType type, GCReason reason)
Definition heap.cc:547

◆ CheckConcurrentMarking()

void dart::Heap::CheckConcurrentMarking ( Thread thread,
GCReason  reason,
intptr_t  size 
)

Definition at line 583 of file heap.cc.

585 {
586 ASSERT(!thread->force_growth());
587
588 PageSpace::Phase phase;
589 {
590 MonitorLocker ml(old_space_.tasks_lock());
591 phase = old_space_.phase();
592 }
593
594 switch (phase) {
596 if (mode_ != Dart_PerformanceMode_Latency) {
597 old_space_.IncrementalMarkWithSizeBudget(size);
598 }
599 return;
602 return; // Busy.
604 CollectOldSpaceGarbage(thread, GCType::kMarkSweep, GCReason::kFinalize);
605 return;
606 case PageSpace::kDone:
607 if (old_space_.ReachedSoftThreshold()) {
608 StartConcurrentMarking(thread, reason);
609 }
610 return;
611 default:
612 UNREACHABLE();
613 }
614}
void StartConcurrentMarking(Thread *thread, GCReason reason)
Definition heap.cc:630
bool ReachedSoftThreshold() const
Definition pages.h:179
void IncrementalMarkWithSizeBudget(intptr_t size)
Definition pages.cc:892
@ kAwaitingFinalization
Definition pages.h:133
Monitor * tasks_lock() const
Definition pages.h:309
Phase phase() const
Definition pages.h:336
@ Dart_PerformanceMode_Latency
Definition dart_api.h:1379

◆ CheckExternalGC()

void dart::Heap::CheckExternalGC ( Thread thread)

Definition at line 214 of file heap.cc.

214 {
215 ASSERT(thread->no_safepoint_scope_depth() == 0);
216 ASSERT(thread->no_callback_scope_depth() == 0);
217 ASSERT(!thread->force_growth());
218
219 if (mode_ == Dart_PerformanceMode_Latency) {
220 return;
221 }
222
223 if (new_space_.ExternalInWords() >= (4 * new_space_.CapacityInWords())) {
224 // Attempt to free some external allocation by a scavenge. (If the total
225 // remains above the limit, next external alloc will trigger another.)
227 // Promotion may have pushed old space over its limit. Fall through for old
228 // space GC check.
229 }
230
231 if (old_space_.ReachedHardThreshold()) {
233 } else {
235 }
236}
bool ReachedHardThreshold() const
Definition pages.h:176
intptr_t ExternalInWords() const
Definition scavenger.h:168

◆ CheckFinalizeMarking()

void dart::Heap::CheckFinalizeMarking ( Thread thread)

Definition at line 616 of file heap.cc.

616 {
617 ASSERT(!thread->force_growth());
618
619 PageSpace::Phase phase;
620 {
621 MonitorLocker ml(old_space_.tasks_lock());
622 phase = old_space_.phase();
623 }
624
626 CollectOldSpaceGarbage(thread, GCType::kMarkSweep, GCReason::kFinalize);
627 }
628}

◆ CodeContains()

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

Definition at line 250 of file heap.cc.

250 {
251 return old_space_.CodeContains(addr);
252}
bool CodeContains(uword addr) const
Definition pages.cc:619

◆ CollectAllGarbage()

void dart::Heap::CollectAllGarbage ( GCReason  reason = GCReason::kFull,
bool  compact = false 
)

Definition at line 562 of file heap.cc.

562 {
563 Thread* thread = Thread::Current();
564 if (thread->is_marking()) {
565 // If incremental marking is happening, we need to finish the GC cycle
566 // and perform a follow-up GC to purge any "floating garbage" that may be
567 // retained by the incremental barrier.
568 CollectOldSpaceGarbage(thread, GCType::kMarkSweep, reason);
569 }
570 CollectOldSpaceGarbage(
571 thread, compact ? GCType::kMarkCompact : GCType::kMarkSweep, reason);
572}
GCType
Definition spaces.h:32

◆ CollectGarbage()

void dart::Heap::CollectGarbage ( Thread thread,
GCType  type,
GCReason  reason 
)

Definition at line 547 of file heap.cc.

547 {
548 switch (type) {
551 CollectNewSpaceGarbage(thread, type, reason);
552 break;
555 CollectOldSpaceGarbage(thread, type, reason);
556 break;
557 default:
558 UNREACHABLE();
559 }
560}

◆ Collections()

intptr_t dart::Heap::Collections ( Space  space) const

Definition at line 824 of file heap.cc.

824 {
825 if (space == kNew) {
826 return new_space_.collections();
827 }
828 return old_space_.collections();
829}
intptr_t collections() const
Definition pages.h:258
intptr_t collections() const
Definition scavenger.h:193

◆ CollectOnNthAllocation()

void dart::Heap::CollectOnNthAllocation ( intptr_t  num_allocations)

Definition at line 709 of file heap.cc.

709 {
710 // Prevent generated code from using the TLAB fast path on next allocation.
712 gc_on_nth_allocation_ = num_allocations;
713}
void AbandonRemainingTLABForDebugging(Thread *thread)

◆ Contains()

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

Definition at line 238 of file heap.cc.

238 {
239 return new_space_.Contains(addr) || old_space_.Contains(addr);
240}
bool Contains(uword addr) const
Definition pages.cc:601
bool Contains(uword addr) const
Definition scavenger.h:136

◆ CreateAllocatedObjectSet()

ObjectSet * dart::Heap::CreateAllocatedObjectSet ( Zone zone,
MarkExpectation  mark_expectation 
)

Definition at line 732 of file heap.cc.

733 {
734 ObjectSet* allocated_set = new (zone) ObjectSet(zone);
735
736 this->AddRegionsToObjectSet(allocated_set);
737 Isolate* vm_isolate = Dart::vm_isolate();
738 vm_isolate->group()->heap()->AddRegionsToObjectSet(allocated_set);
739
740 {
741 VerifyObjectVisitor object_visitor(isolate_group(), allocated_set,
742 mark_expectation);
743 this->VisitObjectsNoImagePages(&object_visitor);
744 }
745 {
746 VerifyObjectVisitor object_visitor(isolate_group(), allocated_set,
748 this->VisitObjectsImagePages(&object_visitor);
749 }
750 {
751 // VM isolate heap is premarked.
752 VerifyObjectVisitor vm_object_visitor(isolate_group(), allocated_set,
754 vm_isolate->group()->heap()->VisitObjects(&vm_object_visitor);
755 }
756
757 return allocated_set;
758}
static Isolate * vm_isolate()
Definition dart.h:68
IsolateGroup * isolate_group() const
Definition heap.h:273
@ kRequireMarked
Definition verifier.h:21

◆ DataContains()

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

Definition at line 254 of file heap.cc.

254 {
255 return old_space_.DataContains(addr);
256}
bool DataContains(uword addr) const
Definition pages.cc:628

◆ ExternalInWords()

intptr_t dart::Heap::ExternalInWords ( Space  space) const

Definition at line 800 of file heap.cc.

800 {
801 return space == kNew ? new_space_.ExternalInWords()
802 : old_space_.ExternalInWords();
803}
intptr_t ExternalInWords() const
Definition pages.h:207

◆ ForwardWeakEntries()

void dart::Heap::ForwardWeakEntries ( ObjectPtr  before_object,
ObjectPtr  after_object 
)

Definition at line 919 of file heap.cc.

919 {
920 const auto before_space =
921 before_object->IsImmediateOrOldObject() ? Heap::kOld : Heap::kNew;
922 const auto after_space =
923 after_object->IsImmediateOrOldObject() ? Heap::kOld : Heap::kNew;
924
925 for (int sel = 0; sel < Heap::kNumWeakSelectors; sel++) {
926 const auto selector = static_cast<Heap::WeakSelector>(sel);
927 auto before_table = GetWeakTable(before_space, selector);
928 intptr_t entry = before_table->RemoveValueExclusive(before_object);
929 if (entry != 0) {
930 auto after_table = GetWeakTable(after_space, selector);
931 after_table->SetValueExclusive(after_object, entry);
932 }
933 }
934
936 [&](Isolate* isolate) {
937 auto before_table = before_object->IsImmediateOrOldObject()
938 ? isolate->forward_table_old()
939 : isolate->forward_table_new();
940 if (before_table != nullptr) {
941 intptr_t entry = before_table->RemoveValueExclusive(before_object);
942 if (entry != 0) {
943 auto after_table = after_object->IsImmediateOrOldObject()
944 ? isolate->forward_table_old()
945 : isolate->forward_table_new();
946 ASSERT(after_table != nullptr);
947 after_table->SetValueExclusive(after_object, entry);
948 }
949 }
950 },
951 /*at_safepoint=*/true);
952}
WeakSelector
Definition heap.h:43
WeakTable * GetWeakTable(Space space, WeakSelector selector) const
Definition heap.h:225
void ForEachIsolate(std::function< void(Isolate *isolate)> function, bool at_safepoint=false)
Definition isolate.cc:2798

◆ ForwardWeakTables()

void dart::Heap::ForwardWeakTables ( ObjectPointerVisitor visitor)

Definition at line 954 of file heap.cc.

954 {
955 // NOTE: This method is only used by the compactor, so there is no need to
956 // process the `Heap::kNew` tables.
957 for (int sel = 0; sel < Heap::kNumWeakSelectors; sel++) {
958 WeakSelector selector = static_cast<Heap::WeakSelector>(sel);
959 GetWeakTable(Heap::kOld, selector)->Forward(visitor);
960 }
961
962 // Isolates might have forwarding tables (used for during snapshotting in
963 // isolate communication).
965 [&](Isolate* isolate) {
966 auto table_old = isolate->forward_table_old();
967 if (table_old != nullptr) table_old->Forward(visitor);
968 },
969 /*at_safepoint=*/true);
970}
void Forward(ObjectPointerVisitor *visitor)

◆ FreedExternal()

void dart::Heap::FreedExternal ( intptr_t  size,
Space  space 
)

Definition at line 200 of file heap.cc.

200 {
201 if (space == kNew) {
202 new_space_.FreedExternal(size);
203 } else {
204 ASSERT(space == kOld);
205 old_space_.FreedExternal(size);
206 }
207}
void FreedExternal(intptr_t size)
Definition pages.h:288
void FreedExternal(intptr_t size)
Definition scavenger.h:218

◆ GCReasonToString()

const char * dart::Heap::GCReasonToString ( GCReason  reason)
static

Definition at line 849 of file heap.cc.

849 {
850 switch (gc_reason) {
852 return "new space";
854 return "store buffer";
856 return "promotion";
858 return "old space";
860 return "finalize";
861 case GCReason::kFull:
862 return "full";
864 return "external";
865 case GCReason::kIdle:
866 return "idle";
868 return "destroyed";
870 return "debugging";
872 return "catch-up";
873 default:
874 UNREACHABLE();
875 return "";
876 }
877}

◆ GCTimeInMicros()

int64_t dart::Heap::GCTimeInMicros ( Space  space) const

Definition at line 817 of file heap.cc.

817 {
818 if (space == kNew) {
819 return new_space_.gc_time_micros();
820 }
821 return old_space_.gc_time_micros();
822}
int64_t gc_time_micros() const
Definition pages.h:254
int64_t gc_time_micros() const
Definition scavenger.h:189

◆ GCTypeToString()

const char * dart::Heap::GCTypeToString ( GCType  type)
static

Definition at line 831 of file heap.cc.

831 {
832 switch (type) {
834 return "Scavenge";
836 return "Evacuate";
838 return "StartCMark";
840 return "MarkSweep";
842 return "MarkCompact";
843 default:
844 UNREACHABLE();
845 return "";
846 }
847}

◆ GetCanonicalHash()

intptr_t dart::Heap::GetCanonicalHash ( ObjectPtr  raw_obj) const
inline

Definition at line 186 of file heap.h.

186 {
187 return GetWeakEntry(raw_obj, kCanonicalHashes);
188 }
intptr_t GetWeakEntry(ObjectPtr raw_obj, WeakSelector sel) const
Definition heap.cc:893

◆ GetHash()

intptr_t dart::Heap::GetHash ( ObjectPtr  raw_obj) const
inline

Definition at line 178 of file heap.h.

178 {
179 return GetWeakEntry(raw_obj, kIdentityHashes);
180 }

◆ GetLoadingUnit()

intptr_t dart::Heap::GetLoadingUnit ( ObjectPtr  raw_obj) const
inline

Definition at line 207 of file heap.h.

207 {
208 ASSERT(Thread::Current()->IsDartMutatorThread());
209 return GetWeakEntry(raw_obj, kLoadingUnits);
210 }

◆ GetObjectId()

intptr_t dart::Heap::GetObjectId ( ObjectPtr  raw_obj) const
inline

Definition at line 197 of file heap.h.

197 {
198 ASSERT(Thread::Current()->IsDartMutatorThread());
199 return GetWeakEntry(raw_obj, kObjectIds);
200 }

◆ GetPeer()

void * dart::Heap::GetPeer ( ObjectPtr  raw_obj) const
inline

Definition at line 167 of file heap.h.

167 {
168 return reinterpret_cast<void*>(GetWeakEntry(raw_obj, kPeers));
169 }

◆ GetWeakEntry()

intptr_t dart::Heap::GetWeakEntry ( ObjectPtr  raw_obj,
WeakSelector  sel 
) const

Definition at line 893 of file heap.cc.

893 {
894 if (raw_obj->IsImmediateOrOldObject()) {
895 return old_weak_tables_[sel]->GetValue(raw_obj);
896 } else {
897 return new_weak_tables_[sel]->GetValue(raw_obj);
898 }
899}
intptr_t GetValue(ObjectPtr key)
Definition weak_table.h:55

◆ GetWeakTable()

WeakTable * dart::Heap::GetWeakTable ( Space  space,
WeakSelector  selector 
) const
inline

Definition at line 225 of file heap.h.

225 {
226 if (space == kNew) {
227 return new_weak_tables_[selector];
228 }
229 ASSERT(space == kOld);
230 return old_weak_tables_[selector];
231 }

◆ Init()

void dart::Heap::Init ( IsolateGroup isolate_group,
bool  is_vm_isolate,
intptr_t  max_new_gen_words,
intptr_t  max_old_gen_words 
)
static

Definition at line 693 of file heap.cc.

696 {
697 ASSERT(isolate_group->heap() == nullptr);
698 std::unique_ptr<Heap> heap(new Heap(isolate_group, is_vm_isolate,
699 max_new_gen_words, max_old_gen_words));
700 isolate_group->set_heap(std::move(heap));
701}
bool is_vm_isolate() const
Definition heap.h:274
Heap * heap() const
Definition isolate.h:295

◆ is_vm_isolate()

bool dart::Heap::is_vm_isolate ( ) const
inline

Definition at line 274 of file heap.h.

274{ return is_vm_isolate_; }

◆ isolate_group()

IsolateGroup * dart::Heap::isolate_group ( ) const
inline

Definition at line 273 of file heap.h.

273{ return isolate_group_; }

◆ mode()

Dart_PerformanceMode dart::Heap::mode ( ) const
inline

Definition at line 103 of file heap.h.

103{ return mode_; }

◆ new_space()

Scavenger * dart::Heap::new_space ( )
inline

Definition at line 62 of file heap.h.

62{ return &new_space_; }

◆ NewContains()

bool dart::Heap::NewContains ( uword  addr) const

Definition at line 242 of file heap.cc.

242 {
243 return new_space_.Contains(addr);
244}

◆ NotifyDestroyed()

void dart::Heap::NotifyDestroyed ( )

Definition at line 435 of file heap.cc.

435 {
437 CollectAllGarbage(GCReason::kDestroyed, /*compact=*/true);
439}
void CollectAllGarbage(GCReason reason=GCReason::kFull, bool compact=false)
Definition heap.cc:562
static void ClearCache()
Definition page.cc:36
#define TIMELINE_FUNCTION_GC_DURATION(thread, name)
Definition timeline.h:41

◆ NotifyIdle()

void dart::Heap::NotifyIdle ( int64_t  deadline)

Definition at line 374 of file heap.cc.

374 {
375 Thread* thread = Thread::Current();
376 TIMELINE_FUNCTION_GC_DURATION(thread, "NotifyIdle");
377 {
378 GcSafepointOperationScope safepoint_operation(thread);
379
380 // Check if we want to collect new-space first, because if we want to
381 // collect both new-space and old-space, the new-space collection should run
382 // first to shrink the root set (make old-space GC faster) and avoid
383 // intergenerational garbage (make old-space GC free more memory).
384 if (new_space_.ShouldPerformIdleScavenge(deadline)) {
385 CollectNewSpaceGarbage(thread, GCType::kScavenge, GCReason::kIdle);
386 }
387
388 // Check if we want to collect old-space, in decreasing order of cost.
389 // Because we use a deadline instead of a timeout, we automatically take any
390 // time used up by a scavenge into account when deciding if we can complete
391 // a mark-sweep on time.
392 if (old_space_.ShouldPerformIdleMarkCompact(deadline)) {
393 // We prefer mark-compact over other old space GCs if we have enough time,
394 // since it removes old space fragmentation and frees up most memory.
395 // Blocks for O(heap), roughly twice as costly as mark-sweep.
396 CollectOldSpaceGarbage(thread, GCType::kMarkCompact, GCReason::kIdle);
397 } else if (old_space_.ReachedHardThreshold()) {
398 // Even though the following GC may exceed our idle deadline, we need to
399 // ensure than that promotions during idle scavenges do not lead to
400 // unbounded growth of old space. If a program is allocating only in new
401 // space and all scavenges happen during idle time, then NotifyIdle will
402 // be the only place that checks the old space allocation limit.
403 // Compare the tail end of Heap::CollectNewSpaceGarbage.
404 // Blocks for O(heap).
405 CollectOldSpaceGarbage(thread, GCType::kMarkSweep, GCReason::kIdle);
406 } else if (old_space_.ShouldStartIdleMarkSweep(deadline) ||
407 old_space_.ReachedSoftThreshold()) {
408 // If we have both work to do and enough time, start or finish GC.
409 // If we have crossed the soft threshold, ignore time; the next old-space
410 // allocation will trigger this work anyway, so we try to pay at least
411 // some of that cost with idle time.
412 // Blocks for O(roots).
413 PageSpace::Phase phase;
414 {
415 MonitorLocker ml(old_space_.tasks_lock());
416 phase = old_space_.phase();
417 }
419 CollectOldSpaceGarbage(thread, GCType::kMarkSweep, GCReason::kFinalize);
420 } else if (phase == PageSpace::kDone) {
422 }
423 }
424 }
425
426 if (FLAG_mark_when_idle) {
427 old_space_.IncrementalMarkWithTimeBudget(deadline);
428 }
429
430 if (OS::GetCurrentMonotonicMicros() < deadline) {
432 }
433}
static int64_t GetCurrentMonotonicMicros()
bool ShouldStartIdleMarkSweep(int64_t deadline)
Definition pages.cc:826
bool ShouldPerformIdleMarkCompact(int64_t deadline)
Definition pages.cc:853
void IncrementalMarkWithTimeBudget(int64_t deadline)
Definition pages.cc:898
bool ShouldPerformIdleScavenge(int64_t deadline)

◆ old_space()

PageSpace * dart::Heap::old_space ( )
inline

Definition at line 63 of file heap.h.

63{ return &old_space_; }

◆ OldContains()

bool dart::Heap::OldContains ( uword  addr) const

Definition at line 246 of file heap.cc.

246 {
247 return old_space_.Contains(addr);
248}

◆ PeerCount()

int64_t dart::Heap::PeerCount ( ) const

Definition at line 879 of file heap.cc.

879 {
880 return new_weak_tables_[kPeers]->count() + old_weak_tables_[kPeers]->count();
881}
intptr_t count() const
Definition weak_table.h:51

◆ PrintHeapMapToJSONStream()

void dart::Heap::PrintHeapMapToJSONStream ( IsolateGroup isolate_group,
JSONStream stream 
)
inline

Definition at line 265 of file heap.h.

266 {
267 old_space_.PrintHeapMapToJSONStream(isolate_group, stream);
268 }
void PrintHeapMapToJSONStream(IsolateGroup *isolate_group, JSONStream *stream) const
Definition pages.cc:765

◆ PrintMemoryUsageJSON() [1/2]

void dart::Heap::PrintMemoryUsageJSON ( JSONObject jsobj) const

Definition at line 986 of file heap.cc.

986 {
987 jsobj->AddProperty("type", "MemoryUsage");
988 jsobj->AddProperty64("heapUsage", TotalUsedInWords() * kWordSize);
989 jsobj->AddProperty64("heapCapacity", TotalCapacityInWords() * kWordSize);
990 jsobj->AddProperty64("externalUsage", TotalExternalInWords() * kWordSize);
991}
intptr_t TotalExternalInWords() const
Definition heap.cc:813
intptr_t TotalCapacityInWords() const
Definition heap.cc:809
intptr_t TotalUsedInWords() const
Definition heap.cc:805
constexpr intptr_t kWordSize
Definition globals.h:509

◆ PrintMemoryUsageJSON() [2/2]

void dart::Heap::PrintMemoryUsageJSON ( JSONStream stream) const

Definition at line 981 of file heap.cc.

981 {
982 JSONObject obj(stream);
984}
void PrintMemoryUsageJSON(JSONStream *stream) const
Definition heap.cc:981

◆ PrintSizes()

void dart::Heap::PrintSizes ( ) const

Definition at line 782 of file heap.cc.

782 {
784 "New space (%" Pd "k of %" Pd
785 "k) "
786 "Old space (%" Pd "k of %" Pd "k)\n",
789}
intptr_t UsedInWords(Space space) const
Definition heap.cc:791
intptr_t CapacityInWords(Space space) const
Definition heap.cc:795
static void static void PrintErr(const char *format,...) PRINTF_ATTRIBUTE(1
constexpr intptr_t KBInWords
Definition globals.h:535
#define Pd
Definition globals.h:408

◆ PrintToJSONObject()

void dart::Heap::PrintToJSONObject ( Space  space,
JSONObject object 
) const

Definition at line 973 of file heap.cc.

973 {
974 if (space == kNew) {
975 new_space_.PrintToJSONObject(object);
976 } else {
977 old_space_.PrintToJSONObject(object);
978 }
979}
void PrintToJSONObject(JSONObject *object) const
Definition pages.cc:728
void PrintToJSONObject(JSONObject *object) const

◆ PromotedExternal()

void dart::Heap::PromotedExternal ( intptr_t  size)

Definition at line 209 of file heap.cc.

209 {
210 new_space_.FreedExternal(size);
211 old_space_.AllocatedExternal(size);
212}

◆ ReachabilityBarrier()

intptr_t dart::Heap::ReachabilityBarrier ( )
inline

Definition at line 271 of file heap.h.

271{ return old_space_.collections(); }

◆ ReportSurvivingAllocations()

void dart::Heap::ReportSurvivingAllocations ( Dart_HeapSamplingReportCallback  callback,
void *  context 
)
inline

Definition at line 245 of file heap.h.

246 {
248 context);
250 context);
251 }
void ReportSurvivingAllocations(Dart_HeapSamplingReportCallback callback, void *context)
FlKeyEvent uint64_t FlKeyResponderAsyncCallback callback

◆ ResetCanonicalHashTable()

void dart::Heap::ResetCanonicalHashTable ( )

Definition at line 883 of file heap.cc.

883 {
884 new_weak_tables_[kCanonicalHashes]->Reset();
885 old_weak_tables_[kCanonicalHashes]->Reset();
886}

◆ ResetObjectIdTable()

void dart::Heap::ResetObjectIdTable ( )

Definition at line 888 of file heap.cc.

888 {
889 new_weak_tables_[kObjectIds]->Reset();
890 old_weak_tables_[kObjectIds]->Reset();
891}

◆ SetCanonicalHash()

void dart::Heap::SetCanonicalHash ( ObjectPtr  raw_obj,
intptr_t  hash 
)
inline

Definition at line 183 of file heap.h.

183 {
185 }
static uint32_t hash(const SkShaderBase::GradientInfo &v)
void SetWeakEntry(ObjectPtr raw_obj, WeakSelector sel, intptr_t val)
Definition heap.cc:901

◆ SetHashIfNotSet()

intptr_t dart::Heap::SetHashIfNotSet ( ObjectPtr  raw_obj,
intptr_t  hash 
)
inline

Definition at line 175 of file heap.h.

175 {
177 }
intptr_t SetWeakEntryIfNonExistent(ObjectPtr raw_obj, WeakSelector sel, intptr_t val)
Definition heap.cc:909

◆ SetHeapSamplingData()

void dart::Heap::SetHeapSamplingData ( ObjectPtr  obj,
void *  data 
)
inline

Definition at line 213 of file heap.h.

213 {
214 SetWeakEntry(obj, kHeapSamplingData, reinterpret_cast<intptr_t>(data));
215 }
static int8_t data[kExtLength]

◆ SetLoadingUnit()

void dart::Heap::SetLoadingUnit ( ObjectPtr  raw_obj,
intptr_t  unit_id 
)
inline

Definition at line 203 of file heap.h.

203 {
204 ASSERT(Thread::Current()->IsDartMutatorThread());
205 SetWeakEntry(raw_obj, kLoadingUnits, unit_id);
206 }

◆ SetMode()

Dart_PerformanceMode dart::Heap::SetMode ( Dart_PerformanceMode  mode)

Definition at line 441 of file heap.cc.

441 {
442 Dart_PerformanceMode old_mode = mode_.exchange(new_mode);
443 if ((old_mode == Dart_PerformanceMode_Latency) &&
444 (new_mode == Dart_PerformanceMode_Default)) {
446 }
447 return old_mode;
448}
void CheckCatchUp(Thread *thread)
Definition heap.cc:574
T exchange(T arg, std::memory_order order=std::memory_order_relaxed)
Definition atomic.h:48
Dart_PerformanceMode
Definition dart_api.h:1368
@ Dart_PerformanceMode_Default
Definition dart_api.h:1372

◆ SetObjectId()

void dart::Heap::SetObjectId ( ObjectPtr  raw_obj,
intptr_t  object_id 
)
inline

Definition at line 193 of file heap.h.

193 {
194 ASSERT(Thread::Current()->IsDartMutatorThread());
195 SetWeakEntry(raw_obj, kObjectIds, object_id);
196 }

◆ SetPeer()

void dart::Heap::SetPeer ( ObjectPtr  raw_obj,
void *  peer 
)
inline

Definition at line 164 of file heap.h.

164 {
165 SetWeakEntry(raw_obj, kPeers, reinterpret_cast<intptr_t>(peer));
166 }

◆ SetupImagePage()

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

Definition at line 276 of file heap.h.

276 {
277 old_space_.SetupImagePage(pointer, size, is_executable);
278 }
void SetupImagePage(void *pointer, uword size, bool is_executable)
Definition pages.cc:1323

◆ SetWeakEntry()

void dart::Heap::SetWeakEntry ( ObjectPtr  raw_obj,
WeakSelector  sel,
intptr_t  val 
)

Definition at line 901 of file heap.cc.

901 {
902 if (raw_obj->IsImmediateOrOldObject()) {
903 old_weak_tables_[sel]->SetValue(raw_obj, val);
904 } else {
905 new_weak_tables_[sel]->SetValue(raw_obj, val);
906 }
907}
void SetValue(ObjectPtr key, intptr_t val)
Definition weak_table.h:60

◆ SetWeakEntryIfNonExistent()

intptr_t dart::Heap::SetWeakEntryIfNonExistent ( ObjectPtr  raw_obj,
WeakSelector  sel,
intptr_t  val 
)

Definition at line 909 of file heap.cc.

911 {
912 if (raw_obj->IsImmediateOrOldObject()) {
913 return old_weak_tables_[sel]->SetValueIfNonExistent(raw_obj, val);
914 } else {
915 return new_weak_tables_[sel]->SetValueIfNonExistent(raw_obj, val);
916 }
917}
intptr_t SetValueIfNonExistent(ObjectPtr key, intptr_t val)
Definition weak_table.h:65

◆ SetWeakTable()

void dart::Heap::SetWeakTable ( Space  space,
WeakSelector  selector,
WeakTable value 
)
inline

Definition at line 232 of file heap.h.

232 {
233 if (space == kNew) {
234 new_weak_tables_[selector] = value;
235 } else {
236 ASSERT(space == kOld);
237 old_weak_tables_[selector] = value;
238 }
239 }
uint8_t value

◆ SpaceForExternal()

Heap::Space dart::Heap::SpaceForExternal ( intptr_t  size) const

Definition at line 1130 of file heap.cc.

1130 {
1131 // If 'size' would be a significant fraction of new space, then use old.
1132 const int kExtNewRatio = 16;
1133 if (size > (new_space_.ThresholdInWords() * kWordSize) / kExtNewRatio) {
1134 return Heap::kOld;
1135 } else {
1136 return Heap::kNew;
1137 }
1138}
intptr_t ThresholdInWords() const
Definition scavenger.h:176

◆ StartConcurrentMarking()

void dart::Heap::StartConcurrentMarking ( Thread thread,
GCReason  reason 
)

Definition at line 630 of file heap.cc.

630 {
631 GcSafepointOperationScope safepoint_operation(thread);
632 RecordBeforeGC(GCType::kStartConcurrentMark, reason);
633 VMTagScope tagScope(thread, reason == GCReason::kIdle
634 ? VMTag::kGCIdleTagId
635 : VMTag::kGCOldSpaceTagId);
636 TIMELINE_FUNCTION_GC_DURATION(thread, "StartConcurrentMarking");
637 old_space_.CollectGarbage(thread, /*compact=*/false, /*finalize=*/false);
638 RecordAfterGC(GCType::kStartConcurrentMark);
639 PrintStats();
640#if defined(SUPPORT_TIMELINE)
641 PrintStatsToTimeline(&tbes, reason);
642#endif
643}
void CollectGarbage(Thread *thread, bool compact, bool finalize)
Definition pages.cc:961

◆ TotalCapacityInWords()

intptr_t dart::Heap::TotalCapacityInWords ( ) const

Definition at line 809 of file heap.cc.

809 {
811}

◆ TotalExternalInWords()

intptr_t dart::Heap::TotalExternalInWords ( ) const

Definition at line 813 of file heap.cc.

813 {
815}
intptr_t ExternalInWords(Space space) const
Definition heap.cc:800

◆ TotalUsedInWords()

intptr_t dart::Heap::TotalUsedInWords ( ) const

Definition at line 805 of file heap.cc.

805 {
806 return UsedInWords(kNew) + UsedInWords(kOld);
807}

◆ UpdateGlobalMaxUsed()

void dart::Heap::UpdateGlobalMaxUsed ( )

Definition at line 678 of file heap.cc.

678 {
679 ASSERT(isolate_group_ != nullptr);
680 // We are accessing the used in words count for both new and old space
681 // without synchronizing. The value of this metric is approximate.
682 isolate_group_->GetHeapGlobalUsedMaxMetric()->SetValue(
685}

◆ UsedInWords()

intptr_t dart::Heap::UsedInWords ( Space  space) const

Definition at line 791 of file heap.cc.

791 {
792 return space == kNew ? new_space_.UsedInWords() : old_space_.UsedInWords();
793}
intptr_t UsedInWords() const
Definition pages.h:189
intptr_t UsedInWords() const
Definition scavenger.h:160

◆ Verify()

bool dart::Heap::Verify ( const char *  msg,
MarkExpectation  mark_expectation = kForbidMarked 
)

Definition at line 760 of file heap.cc.

760 {
761 if (FLAG_disable_heap_verification) {
762 return true;
763 }
764 HeapIterationScope heap_iteration_scope(Thread::Current());
765 return VerifyGC(msg, mark_expectation);
766}
friend class HeapIterationScope
Definition heap.h:384

◆ WaitForMarkerTasks()

void dart::Heap::WaitForMarkerTasks ( Thread thread)

Definition at line 645 of file heap.cc.

645 {
646 MonitorLocker ml(old_space_.tasks_lock());
647 while ((old_space_.phase() == PageSpace::kMarking) ||
648 (old_space_.phase() == PageSpace::kAwaitingFinalization)) {
649 while (old_space_.phase() == PageSpace::kMarking) {
650 ml.WaitWithSafepointCheck(thread);
651 }
652 if (old_space_.phase() == PageSpace::kAwaitingFinalization) {
653 ml.Exit();
654 CollectOldSpaceGarbage(thread, GCType::kMarkSweep, GCReason::kFinalize);
655 ml.Enter();
656 }
657 }
658}

◆ WaitForSweeperTasks()

void dart::Heap::WaitForSweeperTasks ( Thread thread)

Definition at line 660 of file heap.cc.

660 {
661 ASSERT(!thread->OwnsGCSafepoint());
662 MonitorLocker ml(old_space_.tasks_lock());
663 while ((old_space_.phase() == PageSpace::kSweepingLarge) ||
664 (old_space_.phase() == PageSpace::kSweepingRegular)) {
665 ml.WaitWithSafepointCheck(thread);
666 }
667}

◆ WaitForSweeperTasksAtSafepoint()

void dart::Heap::WaitForSweeperTasksAtSafepoint ( Thread thread)

Definition at line 669 of file heap.cc.

669 {
670 ASSERT(thread->OwnsGCSafepoint());
671 MonitorLocker ml(old_space_.tasks_lock());
672 while ((old_space_.phase() == PageSpace::kSweepingLarge) ||
673 (old_space_.phase() == PageSpace::kSweepingRegular)) {
674 ml.Wait();
675 }
676}

◆ WriteProtect()

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

Definition at line 687 of file heap.cc.

687 {
688 read_only_ = read_only;
689 new_space_.WriteProtect(read_only);
690 old_space_.WriteProtect(read_only);
691}
void WriteProtect(bool read_only)
Definition pages.cc:715
void WriteProtect(bool read_only)

◆ WriteProtectCode()

void dart::Heap::WriteProtectCode ( bool  read_only)
inline

Definition at line 127 of file heap.h.

127 {
128 old_space_.WriteProtectCode(read_only);
129 }
void WriteProtectCode(bool read_only)
Definition pages.cc:805

Friends And Related Symbol Documentation

◆ Become

friend class Become
friend

Definition at line 376 of file heap.h.

◆ ClassFinalizer

friend class ClassFinalizer
friend

Definition at line 383 of file heap.h.

◆ GCCompactor

friend class GCCompactor
friend

Definition at line 377 of file heap.h.

◆ GCMarker

friend class GCMarker
friend

Definition at line 385 of file heap.h.

◆ GCTestHelper

friend class GCTestHelper
friend

Definition at line 389 of file heap.h.

◆ HeapIterationScope

friend class HeapIterationScope
friend

Definition at line 384 of file heap.h.

◆ HeapTestHelper

friend class HeapTestHelper
friend

Definition at line 388 of file heap.h.

◆ PageSpace

friend class PageSpace
friend

Definition at line 381 of file heap.h.

◆ Precompiler

friend class Precompiler
friend

Definition at line 378 of file heap.h.

◆ ProgramReloadContext

friend class ProgramReloadContext
friend

Definition at line 382 of file heap.h.

◆ ProgramVisitor

friend class ProgramVisitor
friend

Definition at line 386 of file heap.h.

◆ Scavenger

friend class Scavenger
friend

Definition at line 380 of file heap.h.

◆ Serializer

friend class Serializer
friend

Definition at line 387 of file heap.h.

◆ ServiceEvent

friend class ServiceEvent
friend

Definition at line 379 of file heap.h.

Member Data Documentation

◆ kZapByte

constexpr uint8_t dart::Heap::kZapByte = 0xf3
staticconstexpr

Definition at line 58 of file heap.h.


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