@@ -180,6 +180,11 @@ void Heap::CheckExternalGC(Thread* thread) {
180180 ASSERT (thread->no_safepoint_scope_depth () == 0 );
181181 ASSERT (thread->no_callback_scope_depth () == 0 );
182182 ASSERT (!thread->force_growth ());
183+
184+ if (mode_ == Dart_PerformanceMode_Latency) {
185+ return ;
186+ }
187+
183188 if (new_space_.ExternalInWords () >= (4 * new_space_.CapacityInWords ())) {
184189 // Attempt to free some external allocation by a scavenge. (If the total
185190 // remains above the limit, next external alloc will trigger another.)
@@ -426,6 +431,15 @@ void Heap::NotifyIdle(int64_t deadline) {
426431 }
427432}
428433
434+ Dart_PerformanceMode Heap::SetMode (Dart_PerformanceMode new_mode) {
435+ Dart_PerformanceMode old_mode = mode_.exchange (new_mode);
436+ if ((old_mode == Dart_PerformanceMode_Latency) &&
437+ (new_mode == Dart_PerformanceMode_Default)) {
438+ CheckCatchUp (Thread::Current ());
439+ }
440+ return old_mode;
441+ }
442+
429443void Heap::CollectNewSpaceGarbage (Thread* thread,
430444 GCType type,
431445 GCReason reason) {
@@ -564,6 +578,15 @@ void Heap::CollectAllGarbage(GCReason reason, bool compact) {
564578 WaitForSweeperTasks (thread);
565579}
566580
581+ void Heap::CheckCatchUp (Thread* thread) {
582+ ASSERT (thread->CanCollectGarbage ());
583+ if (old_space ()->ReachedHardThreshold ()) {
584+ CollectGarbage (thread, GCType::kMarkSweep , GCReason::kCatchUp );
585+ } else {
586+ CheckConcurrentMarking (thread, GCReason::kCatchUp , 0 );
587+ }
588+ }
589+
567590void Heap::CheckConcurrentMarking (Thread* thread,
568591 GCReason reason,
569592 intptr_t size) {
@@ -859,6 +882,8 @@ const char* Heap::GCReasonToString(GCReason gc_reason) {
859882 return " idle" ;
860883 case GCReason::kDebugging :
861884 return " debugging" ;
885+ case GCReason::kCatchUp :
886+ return " catch-up" ;
862887 default :
863888 UNREACHABLE ();
864889 return " " ;
0 commit comments