diff --git a/common/settings.cc b/common/settings.cc index ec8ddf60f9c8d..2e3a1daf9f576 100644 --- a/common/settings.cc +++ b/common/settings.cc @@ -45,6 +45,7 @@ std::string Settings::ToString() const { stream << "endless_trace_buffer: " << endless_trace_buffer << std::endl; stream << "enable_dart_profiling: " << enable_dart_profiling << std::endl; stream << "disable_dart_asserts: " << disable_dart_asserts << std::endl; + stream << "enable_serial_gc: " << enable_serial_gc << std::endl; stream << "enable_observatory: " << enable_observatory << std::endl; stream << "enable_observatory_publication: " << enable_observatory_publication << std::endl; diff --git a/common/settings.h b/common/settings.h index b13416556f87e..76ec79c5d2012 100644 --- a/common/settings.h +++ b/common/settings.h @@ -140,6 +140,7 @@ struct Settings { bool endless_trace_buffer = false; bool enable_dart_profiling = false; bool disable_dart_asserts = false; + bool enable_serial_gc = false; // Whether embedder only allows secure connections. bool may_insecurely_connect_to_all_domains = true; diff --git a/runtime/dart_vm.cc b/runtime/dart_vm.cc index 1334a150297eb..ad3612b14305e 100644 --- a/runtime/dart_vm.cc +++ b/runtime/dart_vm.cc @@ -59,6 +59,16 @@ static const char* kDartLanguageArgs[] = { static const char* kDartPrecompilationArgs[] = {"--precompilation"}; +static const char* kSerialGCArgs[] = { + // clang-format off + "--concurrent_mark=false", + "--concurrent_sweep=false", + "--compactor_tasks=1", + "--scavenger_tasks=0", + "--marker_tasks=0", + // clang-format on +}; + FML_ALLOW_UNUSED_TYPE static const char* kDartWriteProtectCodeArgs[] = { "--no_write_protect_code", @@ -358,6 +368,13 @@ DartVM::DartVM(std::shared_ptr vm_data, PushBackAll(&args, kDartAssertArgs, fml::size(kDartAssertArgs)); } + // On low power devices with lesser number of cores, using concurrent + // marking or sweeping causes contention for the UI thread leading to + // Jank, this option can be used to turn off all concurrent GC activities. + if (settings_.enable_serial_gc) { + PushBackAll(&args, kSerialGCArgs, fml::size(kSerialGCArgs)); + } + if (settings_.start_paused) { PushBackAll(&args, kDartStartPausedArgs, fml::size(kDartStartPausedArgs)); } diff --git a/shell/common/switches.cc b/shell/common/switches.cc index 64e4065d9fee4..29bc3d5e9e269 100644 --- a/shell/common/switches.cc +++ b/shell/common/switches.cc @@ -300,6 +300,9 @@ Settings SettingsFromCommandLine(const fml::CommandLine& command_line) { settings.trace_startup = command_line.HasOption(FlagForSwitch(Switch::TraceStartup)); + settings.enable_serial_gc = + command_line.HasOption(FlagForSwitch(Switch::EnableSerialGC)); + #if !FLUTTER_RELEASE settings.trace_skia = true; diff --git a/shell/common/switches.h b/shell/common/switches.h index 61e5cc902a270..6f39926e74a58 100644 --- a/shell/common/switches.h +++ b/shell/common/switches.h @@ -193,6 +193,12 @@ DEF_SWITCH(DisableDartAsserts, "disabled. This flag may be specified if the user wishes to run " "with assertions disabled in the debug product mode (i.e. with JIT " "or DBC).") +DEF_SWITCH(EnableSerialGC, + "enable-serial-gc", + "On low power devices with low core counts, 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") DEF_SWITCH(DisallowInsecureConnections, "disallow-insecure-connections", "By default, dart:io allows all socket connections. If this switch " diff --git a/testing/dart/BUILD.gn b/testing/dart/BUILD.gn index df78d209a9a16..aa0b6e2c4915b 100644 --- a/testing/dart/BUILD.gn +++ b/testing/dart/BUILD.gn @@ -34,6 +34,7 @@ tests = [ "platform_view_test.dart", "plugin_utilities_test.dart", "semantics_test.dart", + "serial_gc_test.dart", "spirv_exception_test.dart", "task_order_test.dart", "text_test.dart", diff --git a/testing/dart/serial_gc_test.dart b/testing/dart/serial_gc_test.dart new file mode 100644 index 0000000000000..72ed08372c644 --- /dev/null +++ b/testing/dart/serial_gc_test.dart @@ -0,0 +1,17 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// FlutterTesterOptions=--enable-serial-gc + +import 'package:litetest/litetest.dart'; + +void main() { + test('Serial GC option test ', () async { + bool threw = false; + for (int i = 0; i < 100; i++) { + var a = [100]; + } + expect(threw, false); + }); +}