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

#include <marker.h>

Public Member Functions

 GCMarker (IsolateGroup *isolate_group, Heap *heap)
 
 ~GCMarker ()
 
void StartConcurrentMark (PageSpace *page_space)
 
void IncrementalMarkWithUnlimitedBudget (PageSpace *page_space)
 
void IncrementalMarkWithSizeBudget (PageSpace *page_space, intptr_t size)
 
void IncrementalMarkWithTimeBudget (PageSpace *page_space, int64_t deadline)
 
void MarkObjects (PageSpace *page_space)
 
intptr_t marked_words () const
 
intptr_t MarkedWordsPerMicro () const
 
void PruneWeak (Scavenger *scavenger)
 

Friends

class ConcurrentMarkTask
 
class ParallelMarkTask
 
class Scavenger
 
template<bool sync>
class MarkingVisitorBase
 

Detailed Description

Definition at line 32 of file marker.h.

Constructor & Destructor Documentation

◆ GCMarker()

dart::GCMarker::GCMarker ( IsolateGroup isolate_group,
Heap heap 
)

Definition at line 1088 of file marker.cc.

1089 : isolate_group_(isolate_group),
1090 heap_(heap),
1091 old_marking_stack_(),
1092 new_marking_stack_(),
1093 tlab_deferred_marking_stack_(),
1094 deferred_marking_stack_(),
1095 global_list_(),
1096 visitors_(),
1097 marked_bytes_(0),
1098 marked_micros_(0) {
1099 visitors_ = new SyncMarkingVisitor*[FLAG_marker_tasks];
1100 for (intptr_t i = 0; i < FLAG_marker_tasks; i++) {
1101 visitors_[i] = nullptr;
1102 }
1103}
MarkingVisitorBase< true > SyncMarkingVisitor
Definition: marker.cc:700

◆ ~GCMarker()

dart::GCMarker::~GCMarker ( )

Definition at line 1105 of file marker.cc.

1105 {
1106 // Cleanup in case isolate shutdown happens after starting the concurrent
1107 // marker and before finalizing.
1108 if (isolate_group_->old_marking_stack() != nullptr) {
1109 isolate_group_->DisableIncrementalBarrier();
1110 for (intptr_t i = 0; i < FLAG_marker_tasks; i++) {
1111 visitors_[i]->AbandonWork();
1112 delete visitors_[i];
1113 }
1114 }
1115 delete[] visitors_;
1116}
void DisableIncrementalBarrier()
Definition: isolate.cc:2831
MarkingStack * old_marking_stack() const
Definition: isolate.h:576

Member Function Documentation

◆ IncrementalMarkWithSizeBudget()

void dart::GCMarker::IncrementalMarkWithSizeBudget ( PageSpace page_space,
intptr_t  size 
)

Definition at line 1198 of file marker.cc.

1199 {
1200 // Avoid setup overhead for tiny amounts of marking as the last bits of TLABs
1201 // get filled in.
1202 const intptr_t kMinimumMarkingStep = KB;
1203 if (size < kMinimumMarkingStep) return;
1204
1206 "IncrementalMarkWithSizeBudget");
1207
1208 SyncMarkingVisitor visitor(isolate_group_, page_space, &old_marking_stack_,
1209 &new_marking_stack_, &tlab_deferred_marking_stack_,
1210 &deferred_marking_stack_);
1212 visitor.ProcessOldMarkingStack(size);
1213 int64_t stop = OS::GetCurrentMonotonicMicros();
1214 visitor.AddMicros(stop - start);
1215 {
1216 MonitorLocker ml(page_space->tasks_lock());
1217 visitor.FinalizeIncremental(&global_list_);
1218 marked_bytes_ += visitor.marked_bytes();
1219 marked_micros_ += visitor.marked_micros();
1220 }
1221}
static int64_t GetCurrentMonotonicMicros()
static Thread * Current()
Definition: thread.h:362
constexpr intptr_t KB
Definition: globals.h:528
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
#define TIMELINE_FUNCTION_GC_DURATION(thread, name)
Definition: timeline.h:41

◆ IncrementalMarkWithTimeBudget()

void dart::GCMarker::IncrementalMarkWithTimeBudget ( PageSpace page_space,
int64_t  deadline 
)

Definition at line 1223 of file marker.cc.

1224 {
1226 "IncrementalMarkWithTimeBudget");
1227
1228 SyncMarkingVisitor visitor(isolate_group_, page_space, &old_marking_stack_,
1229 &new_marking_stack_, &tlab_deferred_marking_stack_,
1230 &deferred_marking_stack_);
1232 visitor.ProcessOldMarkingStackUntil(deadline);
1233 int64_t stop = OS::GetCurrentMonotonicMicros();
1234 visitor.AddMicros(stop - start);
1235 {
1236 MonitorLocker ml(page_space->tasks_lock());
1237 visitor.FinalizeIncremental(&global_list_);
1238 marked_bytes_ += visitor.marked_bytes();
1239 marked_micros_ += visitor.marked_micros();
1240 }
1241}

◆ IncrementalMarkWithUnlimitedBudget()

void dart::GCMarker::IncrementalMarkWithUnlimitedBudget ( PageSpace page_space)

Definition at line 1179 of file marker.cc.

1179 {
1181 "IncrementalMarkWithUnlimitedBudget");
1182
1183 SyncMarkingVisitor visitor(isolate_group_, page_space, &old_marking_stack_,
1184 &new_marking_stack_, &tlab_deferred_marking_stack_,
1185 &deferred_marking_stack_);
1187 visitor.ProcessOldMarkingStack(kIntptrMax);
1188 int64_t stop = OS::GetCurrentMonotonicMicros();
1189 visitor.AddMicros(stop - start);
1190 {
1191 MonitorLocker ml(page_space->tasks_lock());
1192 visitor.FinalizeIncremental(&global_list_);
1193 marked_bytes_ += visitor.marked_bytes();
1194 marked_micros_ += visitor.marked_micros();
1195 }
1196}
constexpr intptr_t kIntptrMax
Definition: globals.h:557

◆ marked_words()

intptr_t dart::GCMarker::marked_words ( ) const
inline

Definition at line 51 of file marker.h.

51{ return marked_bytes_ >> kWordSizeLog2; }
constexpr intptr_t kWordSizeLog2
Definition: globals.h:507

◆ MarkedWordsPerMicro()

intptr_t dart::GCMarker::MarkedWordsPerMicro ( ) const

Definition at line 1071 of file marker.cc.

1071 {
1072 intptr_t marked_words_per_job_micro;
1073 if (marked_micros_ == 0) {
1074 marked_words_per_job_micro = marked_words(); // Prevent division by zero.
1075 } else {
1076 marked_words_per_job_micro = marked_words() / marked_micros_;
1077 }
1078 if (marked_words_per_job_micro == 0) {
1079 marked_words_per_job_micro = 1; // Prevent division by zero.
1080 }
1081 intptr_t jobs = FLAG_marker_tasks;
1082 if (jobs == 0) {
1083 jobs = 1; // Marking on main thread is still one job.
1084 }
1085 return marked_words_per_job_micro * jobs;
1086}
intptr_t marked_words() const
Definition: marker.h:51

◆ MarkObjects()

void dart::GCMarker::MarkObjects ( PageSpace page_space)

Definition at line 1291 of file marker.cc.

1291 {
1292 if (isolate_group_->old_marking_stack() != nullptr) {
1293 isolate_group_->DisableIncrementalBarrier();
1294 }
1295
1296 Prologue();
1297 {
1298 Thread* thread = Thread::Current();
1299 const int num_tasks = FLAG_marker_tasks;
1300 if (num_tasks == 0) {
1301 TIMELINE_FUNCTION_GC_DURATION(thread, "Mark");
1303 // Mark everything on main thread.
1304 UnsyncMarkingVisitor visitor(
1305 isolate_group_, page_space, &old_marking_stack_, &new_marking_stack_,
1306 &tlab_deferred_marking_stack_, &deferred_marking_stack_);
1307 visitor.set_concurrent(false);
1308 ResetSlices();
1309 IterateRoots(&visitor);
1310 visitor.FinishedRoots();
1311 visitor.ProcessDeferredMarking();
1312 visitor.DrainMarkingStack();
1313 visitor.ProcessDeferredMarking();
1314 visitor.FinalizeMarking();
1315 visitor.MournWeakProperties();
1316 visitor.MournWeakReferences();
1317 visitor.MournWeakArrays();
1318 visitor.MournFinalizerEntries();
1319 thread->ReleaseStoreBuffer(); // Ahead of IterateWeak
1320 IterateWeakRoots(thread);
1321 // All marking done; detach code, etc.
1322 int64_t stop = OS::GetCurrentMonotonicMicros();
1323 visitor.AddMicros(stop - start);
1324 marked_bytes_ += visitor.marked_bytes();
1325 marked_micros_ += visitor.marked_micros();
1326 } else {
1327 ThreadBarrier* barrier = new ThreadBarrier(num_tasks, 1);
1328
1329 ResetSlices();
1330 // Used to coordinate draining among tasks; all start out as 'busy'.
1331 RelaxedAtomic<uintptr_t> num_busy = 0;
1332 // Phase 1: Iterate over roots and drain marking stack in tasks.
1333
1334 for (intptr_t i = 0; i < num_tasks; ++i) {
1335 SyncMarkingVisitor* visitor = visitors_[i];
1336 // Visitors may or may not have already been created depending on
1337 // whether we did some concurrent marking.
1338 if (visitor == nullptr) {
1339 visitor = new SyncMarkingVisitor(
1340 isolate_group_, page_space, &old_marking_stack_,
1341 &new_marking_stack_, &tlab_deferred_marking_stack_,
1342 &deferred_marking_stack_);
1343 visitors_[i] = visitor;
1344 }
1345
1346 // Move all work from local blocks to the global list. Any given
1347 // visitor might not get to run if it fails to reach TryEnter soon
1348 // enough, and we must fail to visit objects but they're sitting in
1349 // such a visitor's local blocks.
1350 visitor->Flush(&global_list_);
1351 // Need to move weak property list too.
1352
1353 if (i < (num_tasks - 1)) {
1354 // Begin marking on a helper thread.
1356 this, isolate_group_, &old_marking_stack_, barrier, visitor,
1357 &num_busy);
1358 ASSERT(result);
1359 } else {
1360 // Last worker is the main thread.
1361 visitor->Adopt(&global_list_);
1362 ParallelMarkTask task(this, isolate_group_, &old_marking_stack_,
1363 barrier, visitor, &num_busy);
1364 task.RunEnteredIsolateGroup();
1365 barrier->Sync();
1366 barrier->Release();
1367 }
1368 }
1369
1370 for (intptr_t i = 0; i < num_tasks; i++) {
1371 SyncMarkingVisitor* visitor = visitors_[i];
1372 visitor->FinalizeMarking();
1373 marked_bytes_ += visitor->marked_bytes();
1374 marked_micros_ += visitor->marked_micros();
1375 delete visitor;
1376 visitors_[i] = nullptr;
1377 }
1378
1379 ASSERT(global_list_.IsEmpty());
1380 }
1381 }
1382
1383 // Separate from verify_after_gc because that verification interferes with
1384 // concurrent marking.
1385 if (FLAG_verify_after_marking) {
1386 VerifyAfterMarkingVisitor visitor;
1387 heap_->VisitObjects(&visitor);
1388 if (visitor.failed()) {
1389 FATAL("verify after marking");
1390 }
1391 }
1392
1393 Epilogue();
1394}
static ThreadPool * thread_pool()
Definition: dart.h:73
friend class ParallelMarkTask
Definition: marker.h:101
void Flush(GCLinkedLists *global_list)
Definition: marker.cc:592
bool Run(Args &&... args)
Definition: thread_pool.h:45
#define ASSERT(E)
#define FATAL(error)
GAsyncResult * result
MarkingVisitorBase< false > UnsyncMarkingVisitor
Definition: marker.cc:699

◆ PruneWeak()

void dart::GCMarker::PruneWeak ( Scavenger scavenger)

Definition at line 1396 of file marker.cc.

1396 {
1397 scavenger->PruneWeak(&global_list_);
1398 for (intptr_t i = 0, n = FLAG_marker_tasks; i < n; i++) {
1399 scavenger->PruneWeak(visitors_[i]->delayed());
1400 }
1401}

◆ StartConcurrentMark()

void dart::GCMarker::StartConcurrentMark ( PageSpace page_space)

Definition at line 1118 of file marker.cc.

1118 {
1119 isolate_group_->EnableIncrementalBarrier(
1120 &old_marking_stack_, &new_marking_stack_, &deferred_marking_stack_);
1121
1122 const intptr_t num_tasks = FLAG_marker_tasks;
1123
1124 {
1125 // Bulk increase task count before starting any task, instead of
1126 // incrementing as each task is started, to prevent a task which
1127 // races ahead from falsely believing it was the last task to complete.
1128 MonitorLocker ml(page_space->tasks_lock());
1129 ASSERT(page_space->phase() == PageSpace::kDone);
1130 page_space->set_phase(PageSpace::kMarking);
1131 page_space->set_tasks(page_space->tasks() + num_tasks);
1132 page_space->set_concurrent_marker_tasks(
1133 page_space->concurrent_marker_tasks() + num_tasks);
1134 page_space->set_concurrent_marker_tasks_active(
1135 page_space->concurrent_marker_tasks_active() + num_tasks);
1136 }
1137
1138 ResetSlices();
1139 for (intptr_t i = 0; i < num_tasks; i++) {
1140 ASSERT(visitors_[i] == nullptr);
1142 isolate_group_, page_space, &old_marking_stack_, &new_marking_stack_,
1143 &tlab_deferred_marking_stack_, &deferred_marking_stack_);
1144 visitors_[i] = visitor;
1145
1146 if (i < (num_tasks - 1)) {
1147 // Begin marking on a helper thread.
1149 this, isolate_group_, page_space, visitor);
1150 ASSERT(result);
1151 } else {
1152 // For the last visitor, mark roots on the main thread.
1155 IterateRoots(visitor);
1156 visitor->FinishedRoots();
1157 int64_t stop = OS::GetCurrentMonotonicMicros();
1158 visitor->AddMicros(stop - start);
1159 if (FLAG_log_marker_tasks) {
1160 THR_Print("Task marked %" Pd " bytes in %" Pd64 " micros.\n",
1161 visitor->marked_bytes(), visitor->marked_micros());
1162 }
1163 // Continue non-root marking concurrently.
1165 this, isolate_group_, page_space, visitor);
1166 ASSERT(result);
1167 }
1168 }
1169
1170 isolate_group_->DeferredMarkLiveTemporaries();
1171
1172 // Wait for roots to be marked before exiting safepoint.
1173 MonitorLocker ml(&root_slices_monitor_);
1174 while (root_slices_finished_ != root_slices_count_) {
1175 ml.Wait();
1176 }
1177}
friend class ConcurrentMarkTask
Definition: marker.h:100
void DeferredMarkLiveTemporaries()
Definition: isolate.cc:3002
void EnableIncrementalBarrier(MarkingStack *old_marking_stack, MarkingStack *new_marking_stack, MarkingStack *deferred_marking_stack)
Definition: isolate.cc:2817
#define THR_Print(format,...)
Definition: log.h:20
#define Pd64
Definition: globals.h:416
#define Pd
Definition: globals.h:408

Friends And Related Function Documentation

◆ ConcurrentMarkTask

friend class ConcurrentMarkTask
friend

Definition at line 100 of file marker.h.

◆ MarkingVisitorBase

template<bool sync>
friend class MarkingVisitorBase
friend

Definition at line 104 of file marker.h.

◆ ParallelMarkTask

friend class ParallelMarkTask
friend

Definition at line 101 of file marker.h.

◆ Scavenger

friend class Scavenger
friend

Definition at line 102 of file marker.h.


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