mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
Reland "Add benchmarks to measure dart -> native time (#28492)" (flutter/engine#28726)
This commit is contained in:
parent
c487819422
commit
3ea49f1530
@ -692,6 +692,7 @@ FILE: ../../../flutter/shell/common/canvas_spy.h
|
||||
FILE: ../../../flutter/shell/common/canvas_spy_unittests.cc
|
||||
FILE: ../../../flutter/shell/common/context_options.cc
|
||||
FILE: ../../../flutter/shell/common/context_options.h
|
||||
FILE: ../../../flutter/shell/common/dart_native_benchmarks.cc
|
||||
FILE: ../../../flutter/shell/common/display.h
|
||||
FILE: ../../../flutter/shell/common/display_manager.cc
|
||||
FILE: ../../../flutter/shell/common/display_manager.h
|
||||
|
||||
@ -247,11 +247,9 @@ TEST_F(DartIsolateTest, CanRunDartCodeCodeSynchronously) {
|
||||
|
||||
TEST_F(DartIsolateTest, CanRegisterNativeCallback) {
|
||||
ASSERT_FALSE(DartVMRef::IsInstanceRunning());
|
||||
AddNativeCallback("NotifyNative",
|
||||
CREATE_NATIVE_ENTRY(([this](Dart_NativeArguments args) {
|
||||
FML_LOG(ERROR) << "Hello from Dart!";
|
||||
Signal();
|
||||
})));
|
||||
AddNativeCallback(
|
||||
"NotifyNative",
|
||||
CREATE_NATIVE_ENTRY(([this](Dart_NativeArguments args) { Signal(); })));
|
||||
const auto settings = CreateSettingsForFixture();
|
||||
auto vm_ref = DartVMRef::Create(settings);
|
||||
auto thread = CreateNewThread();
|
||||
@ -524,11 +522,9 @@ TEST_F(DartIsolateTest, DISABLED_ValidLoadingUnitSucceeds) {
|
||||
}
|
||||
|
||||
ASSERT_FALSE(DartVMRef::IsInstanceRunning());
|
||||
AddNativeCallback("NotifyNative",
|
||||
CREATE_NATIVE_ENTRY(([this](Dart_NativeArguments args) {
|
||||
FML_LOG(ERROR) << "Hello from Dart!";
|
||||
Signal();
|
||||
})));
|
||||
AddNativeCallback(
|
||||
"NotifyNative",
|
||||
CREATE_NATIVE_ENTRY(([this](Dart_NativeArguments args) { Signal(); })));
|
||||
AddNativeCallback(
|
||||
"NotifySuccess", CREATE_NATIVE_ENTRY([this](Dart_NativeArguments args) {
|
||||
auto bool_handle = Dart_GetNativeArgument(args, 0);
|
||||
|
||||
@ -158,13 +158,17 @@ if (enable_unittests) {
|
||||
}
|
||||
|
||||
shell_host_executable("shell_benchmarks") {
|
||||
sources = [ "shell_benchmarks.cc" ]
|
||||
sources = [
|
||||
"dart_native_benchmarks.cc",
|
||||
"shell_benchmarks.cc",
|
||||
]
|
||||
|
||||
deps = [
|
||||
":shell_unittests_fixtures",
|
||||
"//flutter/benchmarking",
|
||||
"//flutter/flow",
|
||||
"//flutter/testing:dart",
|
||||
"//flutter/testing:fixture_test",
|
||||
"//flutter/testing:testing_lib",
|
||||
]
|
||||
}
|
||||
|
||||
103
engine/src/flutter/shell/common/dart_native_benchmarks.cc
Normal file
103
engine/src/flutter/shell/common/dart_native_benchmarks.cc
Normal file
@ -0,0 +1,103 @@
|
||||
// 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.
|
||||
|
||||
#include "flutter/shell/common/shell.h"
|
||||
|
||||
#include "flutter/benchmarking/benchmarking.h"
|
||||
#include "flutter/shell/common/thread_host.h"
|
||||
#include "flutter/testing/dart_fixture.h"
|
||||
#include "flutter/testing/dart_isolate_runner.h"
|
||||
#include "flutter/testing/testing.h"
|
||||
#include "fml/synchronization/count_down_latch.h"
|
||||
#include "runtime/dart_vm_lifecycle.h"
|
||||
|
||||
namespace flutter::testing {
|
||||
|
||||
class DartNativeBenchmarks : public DartFixture, public benchmark::Fixture {
|
||||
public:
|
||||
DartNativeBenchmarks() : DartFixture() {}
|
||||
|
||||
void SetUp(const ::benchmark::State& state) {}
|
||||
|
||||
void TearDown(const ::benchmark::State& state) {}
|
||||
|
||||
private:
|
||||
FML_DISALLOW_COPY_AND_ASSIGN(DartNativeBenchmarks);
|
||||
};
|
||||
|
||||
BENCHMARK_F(DartNativeBenchmarks, TimeToFirstNativeMessageFromIsolateInNewVM)
|
||||
(benchmark::State& st) {
|
||||
while (st.KeepRunning()) {
|
||||
fml::AutoResetWaitableEvent latch;
|
||||
st.PauseTiming();
|
||||
ASSERT_FALSE(DartVMRef::IsInstanceRunning());
|
||||
AddNativeCallback("NotifyNative",
|
||||
CREATE_NATIVE_ENTRY(([&latch](Dart_NativeArguments args) {
|
||||
latch.Signal();
|
||||
})));
|
||||
|
||||
const auto settings = CreateSettingsForFixture();
|
||||
DartVMRef vm_ref = DartVMRef::Create(settings);
|
||||
|
||||
ThreadHost thread_host("io.flutter.test.DartNativeBenchmarks.",
|
||||
ThreadHost::Type::Platform | ThreadHost::Type::IO |
|
||||
ThreadHost::Type::UI);
|
||||
TaskRunners task_runners(
|
||||
"test",
|
||||
thread_host.platform_thread->GetTaskRunner(), // platform
|
||||
thread_host.platform_thread->GetTaskRunner(), // raster
|
||||
thread_host.ui_thread->GetTaskRunner(), // ui
|
||||
thread_host.io_thread->GetTaskRunner() // io
|
||||
);
|
||||
|
||||
{
|
||||
st.ResumeTiming();
|
||||
auto isolate =
|
||||
RunDartCodeInIsolate(vm_ref, settings, task_runners, "notifyNative",
|
||||
{}, GetDefaultKernelFilePath());
|
||||
ASSERT_TRUE(isolate);
|
||||
ASSERT_EQ(isolate->get()->GetPhase(), DartIsolate::Phase::Running);
|
||||
latch.Wait();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BENCHMARK_F(DartNativeBenchmarks, MultipleDartToNativeMessages)
|
||||
(benchmark::State& st) {
|
||||
while (st.KeepRunning()) {
|
||||
fml::CountDownLatch latch(1000);
|
||||
st.PauseTiming();
|
||||
ASSERT_FALSE(DartVMRef::IsInstanceRunning());
|
||||
AddNativeCallback("NotifyNative",
|
||||
CREATE_NATIVE_ENTRY(([&latch](Dart_NativeArguments args) {
|
||||
latch.CountDown();
|
||||
})));
|
||||
|
||||
const auto settings = CreateSettingsForFixture();
|
||||
DartVMRef vm_ref = DartVMRef::Create(settings);
|
||||
|
||||
ThreadHost thread_host("io.flutter.test.DartNativeBenchmarks.",
|
||||
ThreadHost::Type::Platform | ThreadHost::Type::IO |
|
||||
ThreadHost::Type::UI);
|
||||
TaskRunners task_runners(
|
||||
"test",
|
||||
thread_host.platform_thread->GetTaskRunner(), // platform
|
||||
thread_host.platform_thread->GetTaskRunner(), // raster
|
||||
thread_host.ui_thread->GetTaskRunner(), // ui
|
||||
thread_host.io_thread->GetTaskRunner() // io
|
||||
);
|
||||
|
||||
{
|
||||
st.ResumeTiming();
|
||||
auto isolate = RunDartCodeInIsolate(vm_ref, settings, task_runners,
|
||||
"thousandCallsToNative", {},
|
||||
GetDefaultKernelFilePath());
|
||||
ASSERT_TRUE(isolate);
|
||||
ASSERT_EQ(isolate->get()->GetPhase(), DartIsolate::Phase::Running);
|
||||
latch.Wait();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace flutter::testing
|
||||
@ -73,8 +73,16 @@ void fixturesAreFunctionalMain() {
|
||||
|
||||
void sayHiFromFixturesAreFunctionalMain() native 'SayHiFromFixturesAreFunctionalMain';
|
||||
|
||||
@pragma('vm:entry-point')
|
||||
void notifyNative() native 'NotifyNative';
|
||||
|
||||
@pragma('vm:entry-point')
|
||||
void thousandCallsToNative() {
|
||||
for (int i = 0; i < 1000; i++) {
|
||||
notifyNative();
|
||||
}
|
||||
}
|
||||
|
||||
void secondaryIsolateMain(String message) {
|
||||
print('Secondary isolate got message: ' + message);
|
||||
notifyNative();
|
||||
|
||||
@ -92,6 +92,8 @@ source_set("fixture_test") {
|
||||
testonly = true
|
||||
|
||||
sources = [
|
||||
"dart_fixture.cc",
|
||||
"dart_fixture.h",
|
||||
"fixture_test.cc",
|
||||
"fixture_test.h",
|
||||
]
|
||||
|
||||
72
engine/src/flutter/testing/dart_fixture.cc
Normal file
72
engine/src/flutter/testing/dart_fixture.cc
Normal file
@ -0,0 +1,72 @@
|
||||
// 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.
|
||||
|
||||
#include "flutter/testing/dart_fixture.h"
|
||||
|
||||
namespace flutter::testing {
|
||||
|
||||
DartFixture::DartFixture()
|
||||
: DartFixture("kernel_blob.bin",
|
||||
kDefaultAOTAppELFFileName,
|
||||
kDefaultAOTAppELFSplitFileName) {}
|
||||
|
||||
DartFixture::DartFixture(std::string kernel_filename,
|
||||
std::string elf_filename,
|
||||
std::string elf_split_filename)
|
||||
: native_resolver_(std::make_shared<TestDartNativeResolver>()),
|
||||
split_aot_symbols_(
|
||||
LoadELFSplitSymbolFromFixturesIfNeccessary(elf_split_filename)),
|
||||
kernel_filename_(kernel_filename),
|
||||
assets_dir_(fml::OpenDirectory(GetFixturesPath(),
|
||||
false,
|
||||
fml::FilePermission::kRead)),
|
||||
aot_symbols_(LoadELFSymbolFromFixturesIfNeccessary(elf_filename)) {}
|
||||
|
||||
Settings DartFixture::CreateSettingsForFixture() {
|
||||
Settings settings;
|
||||
settings.leak_vm = false;
|
||||
settings.task_observer_add = [](intptr_t, fml::closure) {};
|
||||
settings.task_observer_remove = [](intptr_t) {};
|
||||
settings.isolate_create_callback = [this]() {
|
||||
native_resolver_->SetNativeResolverForIsolate();
|
||||
};
|
||||
settings.enable_observatory = false;
|
||||
SetSnapshotsAndAssets(settings);
|
||||
return settings;
|
||||
}
|
||||
|
||||
void DartFixture::SetSnapshotsAndAssets(Settings& settings) {
|
||||
if (!assets_dir_.is_valid()) {
|
||||
return;
|
||||
}
|
||||
|
||||
settings.assets_dir = assets_dir_.get();
|
||||
|
||||
// In JIT execution, all snapshots are present within the binary itself and
|
||||
// don't need to be explicitly supplied by the embedder. In AOT, these
|
||||
// snapshots will be present in the application AOT dylib.
|
||||
if (DartVM::IsRunningPrecompiledCode()) {
|
||||
FML_CHECK(PrepareSettingsForAOTWithSymbols(settings, aot_symbols_));
|
||||
} else {
|
||||
settings.application_kernels = [this]() -> Mappings {
|
||||
std::vector<std::unique_ptr<const fml::Mapping>> kernel_mappings;
|
||||
auto kernel_mapping =
|
||||
fml::FileMapping::CreateReadOnly(assets_dir_, kernel_filename_);
|
||||
if (!kernel_mapping || !kernel_mapping->IsValid()) {
|
||||
FML_LOG(ERROR) << "Could not find kernel blob for test fixture not "
|
||||
"running in precompiled mode.";
|
||||
return kernel_mappings;
|
||||
}
|
||||
kernel_mappings.emplace_back(std::move(kernel_mapping));
|
||||
return kernel_mappings;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
void DartFixture::AddNativeCallback(std::string name,
|
||||
Dart_NativeFunction callback) {
|
||||
native_resolver_->AddNativeCallback(std::move(name), callback);
|
||||
}
|
||||
|
||||
} // namespace flutter::testing
|
||||
49
engine/src/flutter/testing/dart_fixture.h
Normal file
49
engine/src/flutter/testing/dart_fixture.h
Normal file
@ -0,0 +1,49 @@
|
||||
// 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.
|
||||
|
||||
#ifndef FLUTTER_TESTING_DART_FIXTURE_H_
|
||||
#define FLUTTER_TESTING_DART_FIXTURE_H_
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "flutter/common/settings.h"
|
||||
#include "flutter/runtime/dart_vm.h"
|
||||
#include "flutter/testing/elf_loader.h"
|
||||
#include "flutter/testing/test_dart_native_resolver.h"
|
||||
#include "flutter/testing/testing.h"
|
||||
#include "flutter/testing/thread_test.h"
|
||||
|
||||
namespace flutter::testing {
|
||||
|
||||
class DartFixture {
|
||||
public:
|
||||
// Uses the default filenames from the fixtures generator.
|
||||
DartFixture();
|
||||
|
||||
// Allows to customize the kernel, ELF and split ELF filenames.
|
||||
DartFixture(std::string kernel_filename,
|
||||
std::string elf_filename,
|
||||
std::string elf_split_filename);
|
||||
|
||||
virtual Settings CreateSettingsForFixture();
|
||||
|
||||
void AddNativeCallback(std::string name, Dart_NativeFunction callback);
|
||||
|
||||
protected:
|
||||
void SetSnapshotsAndAssets(Settings& settings);
|
||||
|
||||
std::shared_ptr<TestDartNativeResolver> native_resolver_;
|
||||
ELFAOTSymbols split_aot_symbols_;
|
||||
std::string kernel_filename_;
|
||||
std::string elf_filename_;
|
||||
fml::UniqueFD assets_dir_;
|
||||
ELFAOTSymbols aot_symbols_;
|
||||
|
||||
private:
|
||||
FML_DISALLOW_COPY_AND_ASSIGN(DartFixture);
|
||||
};
|
||||
|
||||
} // namespace flutter::testing
|
||||
|
||||
#endif // FLUTTER_TESTING_DART_FIXTURE_H_
|
||||
@ -4,71 +4,17 @@
|
||||
|
||||
#include "flutter/testing/fixture_test.h"
|
||||
|
||||
#include "flutter/testing/dart_fixture.h"
|
||||
|
||||
namespace flutter {
|
||||
namespace testing {
|
||||
|
||||
FixtureTest::FixtureTest()
|
||||
: FixtureTest("kernel_blob.bin",
|
||||
kDefaultAOTAppELFFileName,
|
||||
kDefaultAOTAppELFSplitFileName) {}
|
||||
FixtureTest::FixtureTest() : DartFixture() {}
|
||||
|
||||
FixtureTest::FixtureTest(std::string kernel_filename,
|
||||
std::string elf_filename,
|
||||
std::string elf_split_filename)
|
||||
: native_resolver_(std::make_shared<TestDartNativeResolver>()),
|
||||
split_aot_symbols_(
|
||||
LoadELFSplitSymbolFromFixturesIfNeccessary(elf_split_filename)),
|
||||
kernel_filename_(kernel_filename),
|
||||
assets_dir_(fml::OpenDirectory(GetFixturesPath(),
|
||||
false,
|
||||
fml::FilePermission::kRead)),
|
||||
aot_symbols_(LoadELFSymbolFromFixturesIfNeccessary(elf_filename)) {}
|
||||
|
||||
Settings FixtureTest::CreateSettingsForFixture() {
|
||||
Settings settings;
|
||||
settings.leak_vm = false;
|
||||
settings.task_observer_add = [](intptr_t, fml::closure) {};
|
||||
settings.task_observer_remove = [](intptr_t) {};
|
||||
settings.isolate_create_callback = [this]() {
|
||||
native_resolver_->SetNativeResolverForIsolate();
|
||||
};
|
||||
settings.enable_observatory = false;
|
||||
SetSnapshotsAndAssets(settings);
|
||||
return settings;
|
||||
}
|
||||
|
||||
void FixtureTest::SetSnapshotsAndAssets(Settings& settings) {
|
||||
if (!assets_dir_.is_valid()) {
|
||||
return;
|
||||
}
|
||||
|
||||
settings.assets_dir = assets_dir_.get();
|
||||
|
||||
// In JIT execution, all snapshots are present within the binary itself and
|
||||
// don't need to be explicitly supplied by the embedder. In AOT, these
|
||||
// snapshots will be present in the application AOT dylib.
|
||||
if (DartVM::IsRunningPrecompiledCode()) {
|
||||
FML_CHECK(PrepareSettingsForAOTWithSymbols(settings, aot_symbols_));
|
||||
} else {
|
||||
settings.application_kernels = [this]() -> Mappings {
|
||||
std::vector<std::unique_ptr<const fml::Mapping>> kernel_mappings;
|
||||
auto kernel_mapping =
|
||||
fml::FileMapping::CreateReadOnly(assets_dir_, kernel_filename_);
|
||||
if (!kernel_mapping || !kernel_mapping->IsValid()) {
|
||||
FML_LOG(ERROR) << "Could not find kernel blob for test fixture not "
|
||||
"running in precompiled mode.";
|
||||
return kernel_mappings;
|
||||
}
|
||||
kernel_mappings.emplace_back(std::move(kernel_mapping));
|
||||
return kernel_mappings;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
void FixtureTest::AddNativeCallback(std::string name,
|
||||
Dart_NativeFunction callback) {
|
||||
native_resolver_->AddNativeCallback(std::move(name), callback);
|
||||
}
|
||||
: DartFixture(kernel_filename, elf_filename, elf_split_filename) {}
|
||||
|
||||
} // namespace testing
|
||||
} // namespace flutter
|
||||
|
||||
@ -5,19 +5,12 @@
|
||||
#ifndef FLUTTER_TESTING_FIXTURE_TEST_H_
|
||||
#define FLUTTER_TESTING_FIXTURE_TEST_H_
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "flutter/common/settings.h"
|
||||
#include "flutter/runtime/dart_vm.h"
|
||||
#include "flutter/testing/elf_loader.h"
|
||||
#include "flutter/testing/test_dart_native_resolver.h"
|
||||
#include "flutter/testing/testing.h"
|
||||
#include "flutter/testing/thread_test.h"
|
||||
#include "flutter/testing/dart_fixture.h"
|
||||
|
||||
namespace flutter {
|
||||
namespace testing {
|
||||
|
||||
class FixtureTest : public ThreadTest {
|
||||
class FixtureTest : public DartFixture, public ThreadTest {
|
||||
public:
|
||||
// Uses the default filenames from the fixtures generator.
|
||||
FixtureTest();
|
||||
@ -27,23 +20,7 @@ class FixtureTest : public ThreadTest {
|
||||
std::string elf_filename,
|
||||
std::string elf_split_filename);
|
||||
|
||||
virtual Settings CreateSettingsForFixture();
|
||||
|
||||
void AddNativeCallback(std::string name, Dart_NativeFunction callback);
|
||||
|
||||
protected:
|
||||
void SetSnapshotsAndAssets(Settings& settings);
|
||||
|
||||
std::shared_ptr<TestDartNativeResolver> native_resolver_;
|
||||
|
||||
ELFAOTSymbols split_aot_symbols_;
|
||||
|
||||
private:
|
||||
std::string kernel_filename_;
|
||||
std::string elf_filename_;
|
||||
fml::UniqueFD assets_dir_;
|
||||
ELFAOTSymbols aot_symbols_;
|
||||
|
||||
FML_DISALLOW_COPY_AND_ASSIGN(FixtureTest);
|
||||
};
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user