未验证 提交 572fea36 编写于 作者: D Dan Field 提交者: GitHub

Revert "Shut down and restart the Dart VM as needed. (#7832)" (#7877)

This reverts commit 0d6ff166.
上级 f4fba6d7
......@@ -355,10 +355,6 @@ FILE: ../../../flutter/runtime/dart_snapshot_buffer.cc
FILE: ../../../flutter/runtime/dart_snapshot_buffer.h
FILE: ../../../flutter/runtime/dart_vm.cc
FILE: ../../../flutter/runtime/dart_vm.h
FILE: ../../../flutter/runtime/dart_vm_data.cc
FILE: ../../../flutter/runtime/dart_vm_data.h
FILE: ../../../flutter/runtime/dart_vm_lifecycle.cc
FILE: ../../../flutter/runtime/dart_vm_lifecycle.h
FILE: ../../../flutter/runtime/dart_vm_unittests.cc
FILE: ../../../flutter/runtime/embedder_resources.cc
FILE: ../../../flutter/runtime/embedder_resources.h
......
......@@ -14,10 +14,8 @@ namespace blink {
Dart_Handle IsolateNameServerNatives::LookupPortByName(
const std::string& name) {
auto name_server = UIDartState::Current()->GetIsolateNameServer();
if (!name_server) {
return Dart_Null();
}
IsolateNameServer* name_server =
UIDartState::Current()->GetIsolateNameServer();
Dart_Port port = name_server->LookupIsolatePortByName(name);
if (port == ILLEGAL_PORT) {
return Dart_Null();
......@@ -28,10 +26,8 @@ Dart_Handle IsolateNameServerNatives::LookupPortByName(
Dart_Handle IsolateNameServerNatives::RegisterPortWithName(
Dart_Handle port_handle,
const std::string& name) {
auto name_server = UIDartState::Current()->GetIsolateNameServer();
if (!name_server) {
return Dart_False();
}
IsolateNameServer* name_server =
UIDartState::Current()->GetIsolateNameServer();
Dart_Port port = ILLEGAL_PORT;
Dart_SendPortGetId(port_handle, &port);
if (!name_server->RegisterIsolatePortWithName(port, name)) {
......@@ -42,10 +38,8 @@ Dart_Handle IsolateNameServerNatives::RegisterPortWithName(
Dart_Handle IsolateNameServerNatives::RemovePortNameMapping(
const std::string& name) {
auto name_server = UIDartState::Current()->GetIsolateNameServer();
if (!name_server) {
return Dart_False();
}
IsolateNameServer* name_server =
UIDartState::Current()->GetIsolateNameServer();
if (!name_server->RemoveIsolateNameMapping(name)) {
return Dart_False();
}
......
......@@ -23,7 +23,7 @@ UIDartState::UIDartState(
std::string advisory_script_entrypoint,
std::string logger_prefix,
UnhandledExceptionCallback unhandled_exception_callback,
std::shared_ptr<IsolateNameServer> isolate_name_server)
IsolateNameServer* isolate_name_server)
: task_runners_(std::move(task_runners)),
add_callback_(std::move(add_callback)),
remove_callback_(std::move(remove_callback)),
......@@ -33,7 +33,7 @@ UIDartState::UIDartState(
advisory_script_entrypoint_(std::move(advisory_script_entrypoint)),
logger_prefix_(std::move(logger_prefix)),
unhandled_exception_callback_(unhandled_exception_callback),
isolate_name_server_(std::move(isolate_name_server)) {
isolate_name_server_(isolate_name_server) {
AddOrRemoveTaskObserver(true /* add */);
}
......@@ -124,7 +124,7 @@ fml::WeakPtr<GrContext> UIDartState::GetResourceContext() const {
return io_manager_->GetResourceContext();
}
std::shared_ptr<IsolateNameServer> UIDartState::GetIsolateNameServer() const {
IsolateNameServer* UIDartState::GetIsolateNameServer() {
return isolate_name_server_;
}
......
......@@ -53,7 +53,7 @@ class UIDartState : public tonic::DartState {
fml::WeakPtr<GrContext> GetResourceContext() const;
std::shared_ptr<IsolateNameServer> GetIsolateNameServer() const;
IsolateNameServer* GetIsolateNameServer();
tonic::DartErrorHandleType GetLastError();
......@@ -81,7 +81,7 @@ class UIDartState : public tonic::DartState {
std::string advisory_script_entrypoint,
std::string logger_prefix,
UnhandledExceptionCallback unhandled_exception_callback,
std::shared_ptr<IsolateNameServer> isolate_name_server);
IsolateNameServer* isolate_name_server);
~UIDartState() override;
......@@ -107,7 +107,7 @@ class UIDartState : public tonic::DartState {
std::unique_ptr<Window> window_;
tonic::DartMicrotaskQueue microtask_queue_;
UnhandledExceptionCallback unhandled_exception_callback_;
const std::shared_ptr<IsolateNameServer> isolate_name_server_;
IsolateNameServer* isolate_name_server_;
void AddOrRemoveTaskObserver(bool add);
};
......
......@@ -36,10 +36,6 @@ source_set("runtime") {
"dart_snapshot_buffer.h",
"dart_vm.cc",
"dart_vm.h",
"dart_vm_data.cc",
"dart_vm_data.h",
"dart_vm_lifecycle.cc",
"dart_vm_lifecycle.h",
"embedder_resources.cc",
"embedder_resources.h",
"runtime_controller.cc",
......@@ -77,9 +73,7 @@ source_set("runtime") {
flutter_runtime_mode != "dynamic_release" && !is_fuchsia) {
# Only link in Observatory in non-release modes on non-Fuchsia. Fuchsia
# instead puts Observatory into the runner's package.
deps += [
"//third_party/dart/runtime/observatory:embedded_observatory_archive",
]
deps += [ "//third_party/dart/runtime/observatory:embedded_observatory_archive" ]
}
}
......@@ -101,7 +95,6 @@ executable("runtime_unittests") {
":runtime_fixtures",
"$flutter_root/fml",
"$flutter_root/lib/snapshot",
"$flutter_root/shell/common",
"$flutter_root/testing",
"//third_party/dart/runtime:libdart_jit",
"//third_party/skia",
......
......@@ -14,7 +14,6 @@
#include "flutter/lib/ui/dart_ui.h"
#include "flutter/runtime/dart_service_isolate.h"
#include "flutter/runtime/dart_vm.h"
#include "flutter/runtime/dart_vm_lifecycle.h"
#include "third_party/dart/runtime/include/dart_api.h"
#include "third_party/dart/runtime/include/dart_tools_api.h"
#include "third_party/tonic/converter/dart_converter.h"
......@@ -30,9 +29,9 @@
namespace blink {
std::weak_ptr<DartIsolate> DartIsolate::CreateRootIsolate(
const Settings& settings,
fml::RefPtr<const DartSnapshot> isolate_snapshot,
fml::RefPtr<const DartSnapshot> shared_snapshot,
DartVM* vm,
fml::RefPtr<DartSnapshot> isolate_snapshot,
fml::RefPtr<DartSnapshot> shared_snapshot,
TaskRunners task_runners,
std::unique_ptr<Window> window,
fml::WeakPtr<SnapshotDelegate> snapshot_delegate,
......@@ -51,7 +50,7 @@ std::weak_ptr<DartIsolate> DartIsolate::CreateRootIsolate(
// isolate lifecycle is entirely managed by the VM).
auto root_embedder_data = std::make_unique<std::shared_ptr<DartIsolate>>(
std::make_shared<DartIsolate>(
settings, // settings
vm, // VM
std::move(isolate_snapshot), // isolate snapshot
std::move(shared_snapshot), // shared snapshot
task_runners, // task runners
......@@ -94,9 +93,9 @@ std::weak_ptr<DartIsolate> DartIsolate::CreateRootIsolate(
return embedder_isolate;
}
DartIsolate::DartIsolate(const Settings& settings,
fml::RefPtr<const DartSnapshot> isolate_snapshot,
fml::RefPtr<const DartSnapshot> shared_snapshot,
DartIsolate::DartIsolate(DartVM* vm,
fml::RefPtr<DartSnapshot> isolate_snapshot,
fml::RefPtr<DartSnapshot> shared_snapshot,
TaskRunners task_runners,
fml::WeakPtr<SnapshotDelegate> snapshot_delegate,
fml::WeakPtr<IOManager> io_manager,
......@@ -104,33 +103,38 @@ DartIsolate::DartIsolate(const Settings& settings,
std::string advisory_script_entrypoint,
ChildIsolatePreparer child_isolate_preparer)
: UIDartState(std::move(task_runners),
settings.task_observer_add,
settings.task_observer_remove,
vm->GetSettings().task_observer_add,
vm->GetSettings().task_observer_remove,
std::move(snapshot_delegate),
std::move(io_manager),
advisory_script_uri,
advisory_script_entrypoint,
settings.log_tag,
settings.unhandled_exception_callback,
DartVMRef::GetIsolateNameServer()),
settings_(settings),
vm->GetSettings().log_tag,
vm->GetSettings().unhandled_exception_callback,
vm->GetIsolateNameServer()),
vm_(vm),
isolate_snapshot_(std::move(isolate_snapshot)),
shared_snapshot_(std::move(shared_snapshot)),
child_isolate_preparer_(std::move(child_isolate_preparer)) {
FML_DCHECK(isolate_snapshot_) << "Must contain a valid isolate snapshot.";
if (vm_ == nullptr) {
return;
}
phase_ = Phase::Uninitialized;
}
DartIsolate::~DartIsolate() = default;
const Settings& DartIsolate::GetSettings() const {
return settings_;
}
DartIsolate::Phase DartIsolate::GetPhase() const {
return phase_;
}
DartVM* DartIsolate::GetDartVM() const {
return vm_;
}
bool DartIsolate::Initialize(Dart_Isolate dart_isolate, bool is_root_isolate) {
TRACE_EVENT0("flutter", "DartIsolate::Initialize");
if (phase_ != Phase::Uninitialized) {
......@@ -489,16 +493,16 @@ Dart_Isolate DartIsolate::DartCreateAndStartServiceIsolate(
const char* package_config,
Dart_IsolateFlags* flags,
char** error) {
auto vm_data = DartVMRef::GetVMData();
auto vm = DartVM::ForProcessIfInitialized();
if (!vm_data) {
if (!vm) {
*error = strdup(
"Could not access VM data to initialize isolates. This may be because "
"the VM has initialized shutdown on another thread already.");
"Could not resolve the VM when attempting to create the service "
"isolate.");
return nullptr;
}
const auto& settings = vm_data->GetSettings();
const auto& settings = vm->GetSettings();
if (!settings.enable_observatory) {
FML_DLOG(INFO) << "Observatory is disabled.";
......@@ -511,26 +515,21 @@ Dart_Isolate DartIsolate::DartCreateAndStartServiceIsolate(
flags->load_vmservice_library = true;
if (advisory_script_uri == nullptr) {
advisory_script_uri = "";
}
if (advisory_script_entrypoint == nullptr) {
advisory_script_entrypoint = "";
}
std::weak_ptr<DartIsolate> weak_service_isolate =
DartIsolate::CreateRootIsolate(
vm_data->GetSettings(), // settings
vm_data->GetIsolateSnapshot(), // service isolate snapshot
vm_data->GetSharedSnapshot(), // shared snapshot
null_task_runners, // service isolate task runners
nullptr, // window
{}, // snapshot delegate
{}, // IO Manager
advisory_script_uri, // script uri
advisory_script_entrypoint, // script entrypoint
flags // flags
vm.get(), // vm
vm->GetIsolateSnapshot(), // isolate snapshot
vm->GetSharedSnapshot(), // shared snapshot
null_task_runners, // task runners
nullptr, // window
{}, // snapshot delegate
{}, // IO Manager
advisory_script_uri == nullptr ? ""
: advisory_script_uri, // script uri
advisory_script_entrypoint == nullptr
? ""
: advisory_script_entrypoint, // script entrypoint
flags // flags
);
std::shared_ptr<DartIsolate> service_isolate = weak_service_isolate.lock();
......@@ -553,13 +552,7 @@ Dart_Isolate DartIsolate::DartCreateAndStartServiceIsolate(
return nullptr;
}
if (auto service_protocol = DartVMRef::GetServiceProtocol()) {
service_protocol->ToggleHooks(true);
} else {
FML_DLOG(ERROR)
<< "Could not acquire the service protocol handlers. This might be "
"because the VM has already begun teardown on another thread.";
}
vm->GetServiceProtocol().ToggleHooks(true);
return service_isolate->isolate();
}
......@@ -617,13 +610,16 @@ DartIsolate::CreateDartVMAndEmbedderObjectPair(
std::unique_ptr<std::shared_ptr<DartIsolate>> embedder_isolate(
p_parent_embedder_isolate);
if (embedder_isolate == nullptr) {
if (embedder_isolate == nullptr ||
(*embedder_isolate)->GetDartVM() == nullptr) {
*error =
strdup("Parent isolate did not have embedder specific callback data.");
FML_DLOG(ERROR) << *error;
return {nullptr, {}};
}
DartVM* const vm = (*embedder_isolate)->GetDartVM();
if (!is_root_isolate) {
auto* raw_embedder_isolate = embedder_isolate.release();
......@@ -632,7 +628,7 @@ DartIsolate::CreateDartVMAndEmbedderObjectPair(
embedder_isolate = std::make_unique<std::shared_ptr<DartIsolate>>(
std::make_shared<DartIsolate>(
(*raw_embedder_isolate)->GetSettings(), // settings
vm, // vm
(*raw_embedder_isolate)->GetIsolateSnapshot(), // isolate_snapshot
(*raw_embedder_isolate)->GetSharedSnapshot(), // shared_snapshot
null_task_runners, // task_runners
......@@ -705,11 +701,11 @@ void DartIsolate::DartIsolateCleanupCallback(
delete embedder_isolate;
}
fml::RefPtr<const DartSnapshot> DartIsolate::GetIsolateSnapshot() const {
fml::RefPtr<DartSnapshot> DartIsolate::GetIsolateSnapshot() const {
return isolate_snapshot_;
}
fml::RefPtr<const DartSnapshot> DartIsolate::GetSharedSnapshot() const {
fml::RefPtr<DartSnapshot> DartIsolate::GetSharedSnapshot() const {
return shared_snapshot_;
}
......
......@@ -41,9 +41,9 @@ class DartIsolate : public UIDartState {
// bindings. From the VM's perspective, this isolate is not special in any
// way.
static std::weak_ptr<DartIsolate> CreateRootIsolate(
const Settings& settings,
fml::RefPtr<const DartSnapshot> isolate_snapshot,
fml::RefPtr<const DartSnapshot> shared_snapshot,
DartVM* vm,
fml::RefPtr<DartSnapshot> isolate_snapshot,
fml::RefPtr<DartSnapshot> shared_snapshot,
TaskRunners task_runners,
std::unique_ptr<Window> window,
fml::WeakPtr<SnapshotDelegate> snapshot_delegate,
......@@ -52,9 +52,9 @@ class DartIsolate : public UIDartState {
std::string advisory_script_entrypoint,
Dart_IsolateFlags* flags = nullptr);
DartIsolate(const Settings& settings,
fml::RefPtr<const DartSnapshot> isolate_snapshot,
fml::RefPtr<const DartSnapshot> shared_snapshot,
DartIsolate(DartVM* vm,
fml::RefPtr<DartSnapshot> isolate_snapshot,
fml::RefPtr<DartSnapshot> shared_snapshot,
TaskRunners task_runners,
fml::WeakPtr<SnapshotDelegate> snapshot_delegate,
fml::WeakPtr<IOManager> io_manager,
......@@ -64,8 +64,6 @@ class DartIsolate : public UIDartState {
~DartIsolate() override;
const Settings& GetSettings() const;
Phase GetPhase() const;
FML_WARN_UNUSED_RESULT
......@@ -87,9 +85,11 @@ class DartIsolate : public UIDartState {
void AddIsolateShutdownCallback(fml::closure closure);
fml::RefPtr<const DartSnapshot> GetIsolateSnapshot() const;
DartVM* GetDartVM() const;
fml::RefPtr<DartSnapshot> GetIsolateSnapshot() const;
fml::RefPtr<const DartSnapshot> GetSharedSnapshot() const;
fml::RefPtr<DartSnapshot> GetSharedSnapshot() const;
std::weak_ptr<DartIsolate> GetWeakIsolatePtr();
......@@ -108,10 +108,10 @@ class DartIsolate : public UIDartState {
};
friend class DartVM;
DartVM* const vm_ = nullptr;
Phase phase_ = Phase::Unknown;
const Settings settings_;
const fml::RefPtr<const DartSnapshot> isolate_snapshot_;
const fml::RefPtr<const DartSnapshot> shared_snapshot_;
const fml::RefPtr<DartSnapshot> isolate_snapshot_;
const fml::RefPtr<DartSnapshot> shared_snapshot_;
std::vector<std::shared_ptr<const fml::Mapping>> kernel_buffers_;
std::vector<std::unique_ptr<AutoFireClosure>> shutdown_callbacks_;
ChildIsolatePreparer child_isolate_preparer_ = nullptr;
......
......@@ -7,11 +7,15 @@
#include "flutter/fml/thread.h"
#include "flutter/runtime/dart_isolate.h"
#include "flutter/runtime/dart_vm.h"
#include "flutter/runtime/dart_vm_lifecycle.h"
#include "flutter/testing/testing.h"
#include "flutter/testing/thread_test.h"
#include "third_party/tonic/scopes/dart_isolate_scope.h"
#define CURRENT_TEST_NAME \
std::string { \
::testing::UnitTest::GetInstance()->current_test_info()->name() \
}
namespace blink {
using DartIsolateTest = ::testing::ThreadTest;
......@@ -20,26 +24,24 @@ TEST_F(DartIsolateTest, RootIsolateCreationAndShutdown) {
Settings settings = {};
settings.task_observer_add = [](intptr_t, fml::closure) {};
settings.task_observer_remove = [](intptr_t) {};
auto vm = DartVMRef::Create(settings);
auto vm = DartVM::ForProcess(settings);
ASSERT_TRUE(vm);
auto vm_data = vm->GetVMData();
ASSERT_TRUE(vm_data);
TaskRunners task_runners(testing::GetCurrentTestName(), //
GetCurrentTaskRunner(), //
GetCurrentTaskRunner(), //
GetCurrentTaskRunner(), //
GetCurrentTaskRunner() //
TaskRunners task_runners(CURRENT_TEST_NAME, //
GetCurrentTaskRunner(), //
GetCurrentTaskRunner(), //
GetCurrentTaskRunner(), //
GetCurrentTaskRunner() //
);
auto weak_isolate = DartIsolate::CreateRootIsolate(
vm_data->GetSettings(), // settings
vm_data->GetIsolateSnapshot(), // isolate snapshot
vm_data->GetSharedSnapshot(), // shared snapshot
std::move(task_runners), // task runners
nullptr, // window
{}, // snapshot delegate
{}, // io manager
"main.dart", // advisory uri
"main" // advisory entrypoint
vm.get(), // vm
vm->GetIsolateSnapshot(), // isolate snapshot
vm->GetSharedSnapshot(), // shared snapshot
std::move(task_runners), // task runners
nullptr, // window
{}, // snapshot delegate
{}, // io manager
"main.dart", // advisory uri
"main" // advisory entrypoint
);
auto root_isolate = weak_isolate.lock();
ASSERT_TRUE(root_isolate);
......@@ -51,26 +53,24 @@ TEST_F(DartIsolateTest, IsolateShutdownCallbackIsInIsolateScope) {
Settings settings = {};
settings.task_observer_add = [](intptr_t, fml::closure) {};
settings.task_observer_remove = [](intptr_t) {};
auto vm = DartVMRef::Create(settings);
auto vm = DartVM::ForProcess(settings);
ASSERT_TRUE(vm);
auto vm_data = vm->GetVMData();
ASSERT_TRUE(vm_data);
TaskRunners task_runners(testing::GetCurrentTestName(), //
GetCurrentTaskRunner(), //
GetCurrentTaskRunner(), //
GetCurrentTaskRunner(), //
GetCurrentTaskRunner() //
TaskRunners task_runners(CURRENT_TEST_NAME, //
GetCurrentTaskRunner(), //
GetCurrentTaskRunner(), //
GetCurrentTaskRunner(), //
GetCurrentTaskRunner() //
);
auto weak_isolate = DartIsolate::CreateRootIsolate(
vm_data->GetSettings(), // settings
vm_data->GetIsolateSnapshot(), // isolate snapshot
vm_data->GetSharedSnapshot(), // shared snapshot
std::move(task_runners), // task runners
nullptr, // window
{}, // snapshot delegate
{}, // io manager
"main.dart", // advisory uri
"main" // advisory entrypoint
vm.get(), // vm
vm->GetIsolateSnapshot(), // isolate snapshot
vm->GetSharedSnapshot(), // shared snapshot
std::move(task_runners), // task runners
nullptr, // window
{}, // snapshot delegate
{}, // io manager
"main.dart", // advisory uri
"main" // advisory entrypoint
);
auto root_isolate = weak_isolate.lock();
ASSERT_TRUE(root_isolate);
......@@ -86,11 +86,8 @@ TEST_F(DartIsolateTest, IsolateShutdownCallbackIsInIsolateScope) {
class AutoIsolateShutdown {
public:
AutoIsolateShutdown(blink::DartVMRef vm,
std::shared_ptr<blink::DartIsolate> isolate)
: vm_(std::move(vm)), isolate_(std::move(isolate)) {
FML_CHECK(vm_);
}
AutoIsolateShutdown(std::shared_ptr<blink::DartIsolate> isolate)
: isolate_(std::move(isolate)) {}
~AutoIsolateShutdown() {
if (isolate_) {
......@@ -122,7 +119,6 @@ class AutoIsolateShutdown {
}
private:
blink::DartVMRef vm_;
std::shared_ptr<blink::DartIsolate> isolate_;
FML_DISALLOW_COPY_AND_ASSIGN(AutoIsolateShutdown);
......@@ -132,38 +128,35 @@ std::unique_ptr<AutoIsolateShutdown> RunDartCodeInIsolate(
fml::RefPtr<fml::TaskRunner> task_runner,
std::string entrypoint) {
Settings settings = {};
settings.enable_observatory = true;
settings.task_observer_add = [](intptr_t, fml::closure) {};
settings.task_observer_remove = [](intptr_t) {};
auto vm = DartVMRef::Create(settings);
auto vm = DartVM::ForProcess(settings);
if (!vm) {
return {};
}
auto vm_data = vm->GetVMData();
TaskRunners task_runners(testing::GetCurrentTestName(), //
task_runner, //
task_runner, //
task_runner, //
task_runner //
TaskRunners task_runners(CURRENT_TEST_NAME, //
task_runner, //
task_runner, //
task_runner, //
task_runner //
);
auto weak_isolate = DartIsolate::CreateRootIsolate(
vm_data->GetSettings(), // settings
vm_data->GetIsolateSnapshot(), // isolate snapshot
vm_data->GetSharedSnapshot(), // shared snapshot
std::move(task_runners), // task runners
nullptr, // window
{}, // snapshot delegate
{}, // io manager
"main.dart", // advisory uri
"main" // advisory entrypoint
vm.get(), // vm
vm->GetIsolateSnapshot(), // isolate snapshot
vm->GetSharedSnapshot(), // shared snapshot
std::move(task_runners), // task runners
nullptr, // window
{}, // snapshot delegate
{}, // io manager
"main.dart", // advisory uri
"main" // advisory entrypoint
);
auto root_isolate =
std::make_unique<AutoIsolateShutdown>(std::move(vm), weak_isolate.lock());
std::make_unique<AutoIsolateShutdown>(weak_isolate.lock());
if (!root_isolate->IsValid()) {
FML_LOG(ERROR) << "Could not create isolate.";
......
......@@ -15,7 +15,6 @@
#include "flutter/fml/file.h"
#include "flutter/fml/logging.h"
#include "flutter/fml/mapping.h"
#include "flutter/fml/synchronization/thread_annotations.h"
#include "flutter/fml/time/time_delta.h"
#include "flutter/fml/trace_event.h"
#include "flutter/lib/io/dart_io.h"
......@@ -240,48 +239,66 @@ static void EmbedderInformationCallback(Dart_EmbedderInformation* info) {
info->name = "Flutter";
}
std::shared_ptr<DartVM> DartVM::Create(
fml::RefPtr<DartVM> DartVM::ForProcess(Settings settings) {
return ForProcess(settings, nullptr, nullptr, nullptr);
}
static std::once_flag gVMInitialization;
static std::mutex gVMMutex;
static fml::RefPtr<DartVM> gVM;
fml::RefPtr<DartVM> DartVM::ForProcess(
Settings settings,
fml::RefPtr<DartSnapshot> vm_snapshot,
fml::RefPtr<DartSnapshot> isolate_snapshot,
fml::RefPtr<DartSnapshot> shared_snapshot,
std::shared_ptr<IsolateNameServer> isolate_name_server) {
auto vm_data = DartVMData::Create(settings, //
std::move(vm_snapshot), //
std::move(isolate_snapshot), //
std::move(shared_snapshot) //
);
if (!vm_data) {
FML_LOG(ERROR) << "Could not setup VM data to bootstrap the VM from.";
return {};
}
// Note: std::make_shared unviable due to hidden constructor.
return std::shared_ptr<DartVM>(
new DartVM(std::move(vm_data), std::move(isolate_name_server)));
fml::RefPtr<DartSnapshot> shared_snapshot) {
std::lock_guard<std::mutex> lock(gVMMutex);
std::call_once(gVMInitialization, [settings, //
vm_snapshot, //
isolate_snapshot, //
shared_snapshot //
]() mutable {
if (!vm_snapshot) {
vm_snapshot = DartSnapshot::VMSnapshotFromSettings(settings);
}
if (!(vm_snapshot && vm_snapshot->IsValid())) {
FML_LOG(ERROR) << "VM snapshot must be valid.";
return;
}
if (!isolate_snapshot) {
isolate_snapshot = DartSnapshot::IsolateSnapshotFromSettings(settings);
}
if (!(isolate_snapshot && isolate_snapshot->IsValid())) {
FML_LOG(ERROR) << "Isolate snapshot must be valid.";
return;
}
if (!shared_snapshot) {
shared_snapshot = DartSnapshot::Empty();
}
gVM = fml::MakeRefCounted<DartVM>(settings, //
std::move(vm_snapshot), //
std::move(isolate_snapshot), //
std::move(shared_snapshot) //
);
});
return gVM;
}
static std::atomic_size_t gVMLaunchCount;
size_t DartVM::GetVMLaunchCount() {
return gVMLaunchCount;
fml::RefPtr<DartVM> DartVM::ForProcessIfInitialized() {
std::lock_guard<std::mutex> lock(gVMMutex);
return gVM;
}
DartVM::DartVM(std::shared_ptr<const DartVMData> vm_data,
std::shared_ptr<IsolateNameServer> isolate_name_server)
: settings_(vm_data->GetSettings()),
vm_data_(vm_data),
isolate_name_server_(std::move(isolate_name_server)),
service_protocol_(std::make_shared<ServiceProtocol>()) {
DartVM::DartVM(const Settings& settings,
fml::RefPtr<DartSnapshot> vm_snapshot,
fml::RefPtr<DartSnapshot> isolate_snapshot,
fml::RefPtr<DartSnapshot> shared_snapshot)
: settings_(settings),
vm_snapshot_(std::move(vm_snapshot)),
isolate_snapshot_(std::move(isolate_snapshot)),
shared_snapshot_(std::move(shared_snapshot)),
weak_factory_(this) {
TRACE_EVENT0("flutter", "DartVMInitializer");
gVMLaunchCount++;
FML_DCHECK(vm_data_);
FML_DCHECK(isolate_name_server_);
FML_DCHECK(service_protocol_);
FML_DLOG(INFO) << "Attempting Dart VM launch for mode: "
<< (IsRunningPrecompiledCode() ? "AOT" : "Interpreter");
......@@ -289,8 +306,8 @@ DartVM::DartVM(std::shared_ptr<const DartVMData> vm_data,
TRACE_EVENT0("flutter", "dart::bin::BootstrapDartIo");
dart::bin::BootstrapDartIo();
if (!settings_.temp_directory_path.empty()) {
dart::bin::SetSystemTempDirectory(settings_.temp_directory_path.c_str());
if (!settings.temp_directory_path.empty()) {
dart::bin::SetSystemTempDirectory(settings.temp_directory_path.c_str());
}
}
......@@ -303,7 +320,7 @@ DartVM::DartVM(std::shared_ptr<const DartVMData> vm_data,
args.push_back("--ignore-unrecognized-flags");
for (auto* const profiler_flag :
ProfilingFlags(settings_.enable_dart_profiling)) {
ProfilingFlags(settings.enable_dart_profiling)) {
args.push_back(profiler_flag);
}
......@@ -316,7 +333,7 @@ DartVM::DartVM(std::shared_ptr<const DartVMData> vm_data,
// Enable Dart assertions if we are not running precompiled code. We run non-
// precompiled code only in the debug product mode.
bool enable_asserts = !settings_.disable_dart_asserts;
bool enable_asserts = !settings.disable_dart_asserts;
#if FLUTTER_RUNTIME_MODE == FLUTTER_RUNTIME_MODE_DYNAMIC_PROFILE || \
FLUTTER_RUNTIME_MODE == FLUTTER_RUNTIME_MODE_DYNAMIC_RELEASE
......@@ -340,24 +357,24 @@ DartVM::DartVM(std::shared_ptr<const DartVMData> vm_data,
PushBackAll(&args, kDartAssertArgs, arraysize(kDartAssertArgs));
}
if (settings_.start_paused) {
if (settings.start_paused) {
PushBackAll(&args, kDartStartPausedArgs, arraysize(kDartStartPausedArgs));
}
if (settings_.endless_trace_buffer || settings_.trace_startup) {
if (settings.endless_trace_buffer || settings.trace_startup) {
// If we are tracing startup, make sure the trace buffer is endless so we
// don't lose early traces.
PushBackAll(&args, kDartEndlessTraceBufferArgs,
arraysize(kDartEndlessTraceBufferArgs));
}
if (settings_.trace_systrace) {
if (settings.trace_systrace) {
PushBackAll(&args, kDartSystraceTraceBufferArgs,
arraysize(kDartSystraceTraceBufferArgs));
PushBackAll(&args, kDartTraceStreamsArgs, arraysize(kDartTraceStreamsArgs));
}
if (settings_.trace_startup) {
if (settings.trace_startup) {
PushBackAll(&args, kDartTraceStartupArgs, arraysize(kDartTraceStartupArgs));
}
......@@ -366,8 +383,8 @@ DartVM::DartVM(std::shared_ptr<const DartVMData> vm_data,
PushBackAll(&args, kDartTraceStreamsArgs, arraysize(kDartTraceStreamsArgs));
#endif
for (size_t i = 0; i < settings_.dart_flags.size(); i++)
args.push_back(settings_.dart_flags[i].c_str());
for (size_t i = 0; i < settings.dart_flags.size(); i++)
args.push_back(settings.dart_flags[i].c_str());
char* flags_error = Dart_SetVMFlags(args.size(), args.data());
if (flags_error) {
......@@ -377,14 +394,14 @@ DartVM::DartVM(std::shared_ptr<const DartVMData> vm_data,
DartUI::InitForGlobal();
Dart_SetFileModifiedCallback(&DartFileModifiedCallback);
{
TRACE_EVENT0("flutter", "Dart_Initialize");
Dart_InitializeParams params = {};
params.version = DART_INITIALIZE_PARAMS_CURRENT_VERSION;
params.vm_snapshot_data =
vm_data_->GetVMSnapshot().GetData()->GetSnapshotPointer();
params.vm_snapshot_instructions =
vm_data_->GetVMSnapshot().GetInstructionsIfPresent();
params.vm_snapshot_data = vm_snapshot_->GetData()->GetSnapshotPointer();
params.vm_snapshot_instructions = vm_snapshot_->GetInstructionsIfPresent();
params.create = reinterpret_cast<decltype(params.create)>(
DartIsolate::DartIsolateCreateCallback);
params.shutdown = reinterpret_cast<decltype(params.shutdown)>(
......@@ -416,50 +433,51 @@ DartVM::DartVM(std::shared_ptr<const DartVMData> vm_data,
}
}
Dart_SetFileModifiedCallback(&DartFileModifiedCallback);
// Allow streaming of stdout and stderr by the Dart vm.
Dart_SetServiceStreamCallbacks(&ServiceStreamListenCallback,
&ServiceStreamCancelCallback);
Dart_SetEmbedderInformationCallback(&EmbedderInformationCallback);
FML_DLOG(INFO) << "New Dart VM instance created. Instance count: "
<< gVMLaunchCount;
}
DartVM::~DartVM() {
if (Dart_CurrentIsolate() != nullptr) {
Dart_ExitIsolate();
}
char* result = Dart_Cleanup();
if (result != nullptr) {
FML_LOG(ERROR) << "Could not cleanly shut down the Dart VM. Message: \""
<< result << "\".";
free(result);
}
}
dart::bin::CleanupDartIo();
const Settings& DartVM::GetSettings() const {
return settings_;
}
FML_CHECK(result == nullptr)
<< "Could not cleanly shut down the Dart VM. Error: \"" << result
<< "\".";
free(result);
const DartSnapshot& DartVM::GetVMSnapshot() const {
return *vm_snapshot_.get();
}
FML_DLOG(INFO) << "Dart VM instance destroyed. Instance count: "
<< gVMLaunchCount;
IsolateNameServer* DartVM::GetIsolateNameServer() {
return &isolate_name_server_;
}
std::shared_ptr<const DartVMData> DartVM::GetVMData() const {
return vm_data_;
fml::RefPtr<DartSnapshot> DartVM::GetIsolateSnapshot() const {
return isolate_snapshot_;
}
const Settings& DartVM::GetSettings() const {
return settings_;
fml::RefPtr<DartSnapshot> DartVM::GetSharedSnapshot() const {
return shared_snapshot_;
}
std::shared_ptr<ServiceProtocol> DartVM::GetServiceProtocol() const {
ServiceProtocol& DartVM::GetServiceProtocol() {
return service_protocol_;
}
std::shared_ptr<IsolateNameServer> DartVM::GetIsolateNameServer() const {
return isolate_name_server_;
fml::WeakPtr<DartVM> DartVM::GetWeakPtr() {
return weak_factory_.GetWeakPtr();
}
} // namespace blink
......@@ -5,8 +5,9 @@
#ifndef FLUTTER_RUNTIME_DART_VM_H_
#define FLUTTER_RUNTIME_DART_VM_H_
#include <memory>
#include <functional>
#include <string>
#include <vector>
#include "flutter/common/settings.h"
#include "flutter/fml/build_config.h"
......@@ -18,48 +19,59 @@
#include "flutter/lib/ui/isolate_name_server/isolate_name_server.h"
#include "flutter/runtime/dart_isolate.h"
#include "flutter/runtime/dart_snapshot.h"
#include "flutter/runtime/dart_vm_data.h"
#include "flutter/runtime/service_protocol.h"
#include "third_party/dart/runtime/include/dart_api.h"
namespace blink {
class DartVM {
class DartVM : public fml::RefCountedThreadSafe<DartVM> {
public:
~DartVM();
static fml::RefPtr<DartVM> ForProcess(Settings settings);
static fml::RefPtr<DartVM> ForProcess(
Settings settings,
fml::RefPtr<DartSnapshot> vm_snapshot,
fml::RefPtr<DartSnapshot> isolate_snapshot,
fml::RefPtr<DartSnapshot> shared_snapshot);
static fml::RefPtr<DartVM> ForProcessIfInitialized();
static bool IsRunningPrecompiledCode();
static bool IsKernelMapping(const fml::FileMapping* mapping);
static size_t GetVMLaunchCount();
const Settings& GetSettings() const;
std::shared_ptr<const DartVMData> GetVMData() const;
const DartSnapshot& GetVMSnapshot() const;
std::shared_ptr<ServiceProtocol> GetServiceProtocol() const;
IsolateNameServer* GetIsolateNameServer();
std::shared_ptr<IsolateNameServer> GetIsolateNameServer() const;
fml::RefPtr<DartSnapshot> GetIsolateSnapshot() const;
private:
const Settings settings_;
std::shared_ptr<const DartVMData> vm_data_;
const std::shared_ptr<IsolateNameServer> isolate_name_server_;
const std::shared_ptr<ServiceProtocol> service_protocol_;
fml::RefPtr<DartSnapshot> GetSharedSnapshot() const;
friend class DartVMRef;
fml::WeakPtr<DartVM> GetWeakPtr();
static std::shared_ptr<DartVM> Create(
Settings settings,
fml::RefPtr<DartSnapshot> vm_snapshot,
fml::RefPtr<DartSnapshot> isolate_snapshot,
fml::RefPtr<DartSnapshot> shared_snapshot,
std::shared_ptr<IsolateNameServer> isolate_name_server);
ServiceProtocol& GetServiceProtocol();
DartVM(std::shared_ptr<const DartVMData> data,
std::shared_ptr<IsolateNameServer> isolate_name_server);
private:
const Settings settings_;
const fml::RefPtr<DartSnapshot> vm_snapshot_;
IsolateNameServer isolate_name_server_;
const fml::RefPtr<DartSnapshot> isolate_snapshot_;
const fml::RefPtr<DartSnapshot> shared_snapshot_;
ServiceProtocol service_protocol_;
fml::WeakPtrFactory<DartVM> weak_factory_;
DartVM(const Settings& settings,
fml::RefPtr<DartSnapshot> vm_snapshot,
fml::RefPtr<DartSnapshot> isolate_snapshot,
fml::RefPtr<DartSnapshot> shared_snapshot);
~DartVM();
FML_FRIEND_REF_COUNTED_THREAD_SAFE(DartVM);
FML_FRIEND_MAKE_REF_COUNTED(DartVM);
FML_DISALLOW_COPY_AND_ASSIGN(DartVM);
};
......
// 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/runtime/dart_vm_data.h"
namespace blink {
std::shared_ptr<const DartVMData> DartVMData::Create(
Settings settings,
fml::RefPtr<DartSnapshot> vm_snapshot,
fml::RefPtr<DartSnapshot> isolate_snapshot,
fml::RefPtr<DartSnapshot> shared_snapshot) {
if (!vm_snapshot || !vm_snapshot->IsValid()) {
// Caller did not provide a valid VM snapshot. Attempt to infer one
// from the settings.
vm_snapshot = DartSnapshot::VMSnapshotFromSettings(settings);
if (!vm_snapshot) {
FML_LOG(ERROR)
<< "VM snapshot invalid and could not be inferred from settings.";
return {};
}
}
if (!isolate_snapshot || !isolate_snapshot->IsValid()) {
// Caller did not provide a valid isolate snapshot. Attempt to infer one
// from the settings.
isolate_snapshot = DartSnapshot::IsolateSnapshotFromSettings(settings);
if (!isolate_snapshot) {
FML_LOG(ERROR) << "Isolate snapshot invalid and could not be inferred "
"from settings.";
return {};
}
}
if (!shared_snapshot || !shared_snapshot->IsValid()) {
shared_snapshot = DartSnapshot::Empty();
if (!shared_snapshot) {
FML_LOG(ERROR) << "Shared snapshot invalid.";
return {};
}
}
return std::shared_ptr<const DartVMData>(new DartVMData(
std::move(settings), //
std::move(vm_snapshot), //
std::move(isolate_snapshot), //
std::move(shared_snapshot) //
));
}
DartVMData::DartVMData(Settings settings,
fml::RefPtr<const DartSnapshot> vm_snapshot,
fml::RefPtr<const DartSnapshot> isolate_snapshot,
fml::RefPtr<const DartSnapshot> shared_snapshot)
: settings_(settings),
vm_snapshot_(vm_snapshot),
isolate_snapshot_(isolate_snapshot),
shared_snapshot_(shared_snapshot) {}
DartVMData::~DartVMData() = default;
const Settings& DartVMData::GetSettings() const {
return settings_;
}
const DartSnapshot& DartVMData::GetVMSnapshot() const {
return *vm_snapshot_;
}
fml::RefPtr<const DartSnapshot> DartVMData::GetIsolateSnapshot() const {
return isolate_snapshot_;
}
fml::RefPtr<const DartSnapshot> DartVMData::GetSharedSnapshot() const {
return shared_snapshot_;
}
} // namespace blink
// 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_RUNTIME_DART_VM_DATA_H_
#define FLUTTER_RUNTIME_DART_VM_DATA_H_
#include "flutter/fml/macros.h"
#include "flutter/runtime/dart_snapshot.h"
namespace blink {
class DartVMData {
public:
static std::shared_ptr<const DartVMData> Create(
Settings settings,
fml::RefPtr<DartSnapshot> vm_snapshot,
fml::RefPtr<DartSnapshot> isolate_snapshot,
fml::RefPtr<DartSnapshot> shared_snapshot);
~DartVMData();
const Settings& GetSettings() const;
const DartSnapshot& GetVMSnapshot() const;
fml::RefPtr<const DartSnapshot> GetIsolateSnapshot() const;
fml::RefPtr<const DartSnapshot> GetSharedSnapshot() const;
private:
const Settings settings_;
const fml::RefPtr<const DartSnapshot> vm_snapshot_;
const fml::RefPtr<const DartSnapshot> isolate_snapshot_;
const fml::RefPtr<const DartSnapshot> shared_snapshot_;
DartVMData(Settings settings,
fml::RefPtr<const DartSnapshot> vm_snapshot,
fml::RefPtr<const DartSnapshot> isolate_snapshot,
fml::RefPtr<const DartSnapshot> shared_snapshot);
FML_DISALLOW_COPY_AND_ASSIGN(DartVMData);
};
} // namespace blink
#endif // FLUTTER_RUNTIME_DART_VM_DATA_H_
// 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/runtime/dart_vm_lifecycle.h"
#include <mutex>
namespace blink {
// We need to explicitly put the constructor and destructor of the DartVM in the
// critical section. All accesses (not just const members) to the global VM
// object weak pointer are behind this mutex.
static std::mutex gVMMutex;
static std::weak_ptr<DartVM> gVM FML_GUARDED_BY(gVMMutex);
// We are going to be modifying more than just the control blocks of the
// following weak pointers (in the |Create| case where an old VM could not be
// reused). Ideally, we would use |std::atomic<std::weak_ptr<T>>| specialization
// but that is only available since C++20. We don't expect contention on these
// locks so we just use one mutex for all.
static std::mutex gVMDependentsMutex;
static std::weak_ptr<const DartVMData> gVMData
FML_GUARDED_BY(gVMDependentsMutex);
static std::weak_ptr<ServiceProtocol> gVMServiceProtocol
FML_GUARDED_BY(gVMDependentsMutex);
static std::weak_ptr<IsolateNameServer> gVMIsolateNameServer
FML_GUARDED_BY(gVMDependentsMutex);
DartVMRef::DartVMRef(std::shared_ptr<DartVM> vm) : vm_(vm) {}
DartVMRef::DartVMRef(DartVMRef&& other) = default;
DartVMRef::~DartVMRef() {
if (!vm_) {
// If there is no valid VM (possible via a move), there is no way that the
// decrement on the shared pointer can cause a collection. Avoid acquiring
// the lifecycle lock in this case. This is just working around a
// pessimization and not required for correctness.
return;
}
std::lock_guard<std::mutex> lifecycle_lock(gVMMutex);
vm_.reset();
}
DartVMRef DartVMRef::Create(Settings settings,
fml::RefPtr<DartSnapshot> vm_snapshot,
fml::RefPtr<DartSnapshot> isolate_snapshot,
fml::RefPtr<DartSnapshot> shared_snapshot) {
std::lock_guard<std::mutex> lifecycle_lock(gVMMutex);
// If there is already a running VM in the process, grab a strong reference to
// it.
if (auto vm = gVM.lock()) {
FML_DLOG(WARNING) << "Attempted to create a VM in a process where one was "
"already running. Ignoring arguments for current VM "
"create call and reusing the old VM.";
// There was already a running VM in the process,
return DartVMRef{std::move(vm)};
}
std::lock_guard<std::mutex> dependents_lock(gVMDependentsMutex);
gVMData.reset();
gVMServiceProtocol.reset();
gVMIsolateNameServer.reset();
gVM.reset();
// If there is no VM in the process. Initialize one, hold the weak reference
// and pass a strong reference to the caller.
auto isolate_name_server = std::make_shared<IsolateNameServer>();
auto vm = DartVM::Create(std::move(settings), //
std::move(vm_snapshot), //
std::move(isolate_snapshot), //
std::move(shared_snapshot), //
isolate_name_server //
);
if (!vm) {
FML_LOG(ERROR) << "Could not create Dart VM instance.";
return {nullptr};
}
gVMData = vm->GetVMData();
gVMServiceProtocol = vm->GetServiceProtocol();
gVMIsolateNameServer = isolate_name_server;
gVM = vm;
return DartVMRef{std::move(vm)};
}
bool DartVMRef::IsInstanceRunning() {
std::lock_guard<std::mutex> lock(gVMMutex);
return !gVM.expired();
}
std::shared_ptr<const DartVMData> DartVMRef::GetVMData() {
std::lock_guard<std::mutex> lock(gVMDependentsMutex);
return gVMData.lock();
}
std::shared_ptr<ServiceProtocol> DartVMRef::GetServiceProtocol() {
std::lock_guard<std::mutex> lock(gVMDependentsMutex);
return gVMServiceProtocol.lock();
}
std::shared_ptr<IsolateNameServer> DartVMRef::GetIsolateNameServer() {
std::lock_guard<std::mutex> lock(gVMDependentsMutex);
return gVMIsolateNameServer.lock();
}
} // namespace blink
// 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_RUNTIME_DART_VM_LIFECYCLE_H_
#define FLUTTER_RUNTIME_DART_VM_LIFECYCLE_H_
#include <memory>
#include "flutter/fml/macros.h"
#include "flutter/lib/ui/isolate_name_server/isolate_name_server.h"
#include "flutter/runtime/dart_vm.h"
#include "flutter/runtime/service_protocol.h"
namespace blink {
// A strong reference to the Dart VM. There can only be one VM running in the
// process at any given time. A reference to the VM may only be obtained via the
// |Create| method. In case there is already a running instance of the VM in the
// process, a strong reference to that VM is obtained and the arguments to the
// |Create| call ignored. If there is no VM already running in the process, a VM
// is initialized in a thread safe manner and returned to the caller. The VM
// will shutdown only when all callers relinquish their references (by
// collecting their instances of this class).
//
// DartVMRef instances may be created on any thread.
class DartVMRef {
public:
FML_WARN_UNUSED_RESULT
static DartVMRef Create(Settings settings,
fml::RefPtr<DartSnapshot> vm_snapshot = nullptr,
fml::RefPtr<DartSnapshot> isolate_snapshot = nullptr,
fml::RefPtr<DartSnapshot> shared_snapshot = nullptr);
DartVMRef(DartVMRef&&);
~DartVMRef();
// This is an inherently racy way to check if a VM instance is running and
// should not be used outside of unit-tests where there is a known threading
// model.
static bool IsInstanceRunning();
static std::shared_ptr<const DartVMData> GetVMData();
static std::shared_ptr<ServiceProtocol> GetServiceProtocol();
static std::shared_ptr<IsolateNameServer> GetIsolateNameServer();
operator bool() const { return static_cast<bool>(vm_); }
DartVM* operator->() {
FML_DCHECK(vm_);
return vm_.get();
}
DartVM* operator&() {
FML_DCHECK(vm_);
return vm_.get();
}
private:
std::shared_ptr<DartVM> vm_;
DartVMRef(std::shared_ptr<DartVM> vm);
FML_DISALLOW_COPY_AND_ASSIGN(DartVMRef);
};
} // namespace blink
#endif // FLUTTER_RUNTIME_DART_VM_LIFECYCLE_H_
......@@ -3,36 +3,25 @@
// found in the LICENSE file.
#include "flutter/runtime/dart_vm.h"
#include "flutter/runtime/dart_vm_lifecycle.h"
#include "flutter/shell/common/thread_host.h"
#include "flutter/testing/testing.h"
#include "flutter/testing/thread_test.h"
#include "gtest/gtest.h"
namespace blink {
static Settings GetTestSettings() {
Settings settings;
settings.verbose_logging = true;
TEST(DartVM, SimpleInitialization) {
Settings settings = {};
settings.task_observer_add = [](intptr_t, fml::closure) {};
settings.task_observer_remove = [](intptr_t) {};
return settings;
}
TEST(DartVM, SimpleInitialization) {
auto vm1 = DartVMRef::Create(GetTestSettings());
ASSERT_TRUE(vm1);
// Multiple initializations should return the same VM.
auto vm2 = DartVMRef::Create(GetTestSettings());
ASSERT_TRUE(vm2);
ASSERT_EQ(&vm1, &vm2);
auto vm = DartVM::ForProcess(settings);
ASSERT_TRUE(vm);
ASSERT_EQ(vm, DartVM::ForProcess(settings));
ASSERT_FALSE(DartVM::IsRunningPrecompiledCode());
}
TEST(DartVM, SimpleIsolateNameServer) {
auto vm = DartVMRef::Create(GetTestSettings());
Settings settings = {};
settings.task_observer_add = [](intptr_t, fml::closure) {};
settings.task_observer_remove = [](intptr_t) {};
auto vm = DartVM::ForProcess(settings);
auto ns = vm->GetIsolateNameServer();
ASSERT_EQ(ns->LookupIsolatePortByName("foobar"), ILLEGAL_PORT);
ASSERT_FALSE(ns->RemoveIsolateNameMapping("foobar"));
......@@ -42,79 +31,4 @@ TEST(DartVM, SimpleIsolateNameServer) {
ASSERT_TRUE(ns->RemoveIsolateNameMapping("foobar"));
}
TEST(DartVM, CanReinitializeVMOverAndOver) {
size_t vm_launch_count = DartVM::GetVMLaunchCount();
for (size_t i = 0; i < 1000; ++i) {
FML_LOG(INFO) << "Run " << i + 1;
// VM should not already be running.
ASSERT_FALSE(DartVMRef::IsInstanceRunning());
auto vm = DartVMRef::Create(GetTestSettings());
ASSERT_TRUE(vm);
size_t new_vm_launch_count = DartVM::GetVMLaunchCount();
ASSERT_EQ(vm_launch_count + 1, new_vm_launch_count);
vm_launch_count = new_vm_launch_count;
// VM should now be running
ASSERT_TRUE(DartVMRef::IsInstanceRunning());
}
}
using DartVMThreadTest = ::testing::ThreadTest;
TEST_F(DartVMThreadTest, CanRunIsolatesInANewVM) {
for (size_t i = 0; i < 1000; ++i) {
FML_LOG(INFO) << "Run " << i + 1;
size_t vm_launch_count = DartVM::GetVMLaunchCount();
// VM should not already be running.
ASSERT_FALSE(DartVMRef::IsInstanceRunning());
auto vm = DartVMRef::Create(GetTestSettings());
ASSERT_TRUE(vm);
// VM should not already be running.
ASSERT_TRUE(DartVMRef::IsInstanceRunning());
size_t new_vm_launch_count = DartVM::GetVMLaunchCount();
ASSERT_EQ(vm_launch_count + 1, new_vm_launch_count);
Settings settings = {};
settings.task_observer_add = [](intptr_t, fml::closure) {};
settings.task_observer_remove = [](intptr_t) {};
auto labels = testing::GetCurrentTestName() + std::to_string(i);
shell::ThreadHost host(labels, shell::ThreadHost::Type::UI |
shell::ThreadHost::Type::GPU |
shell::ThreadHost::Type::IO);
TaskRunners task_runners(
labels, // task runner labels
GetCurrentTaskRunner(), // platform task runner
host.gpu_thread->GetTaskRunner(), // GPU task runner
host.ui_thread->GetTaskRunner(), // UI task runner
host.io_thread->GetTaskRunner() // IO task runner
);
auto weak_isolate = DartIsolate::CreateRootIsolate(
vm->GetVMData()->GetSettings(), // settings
vm->GetVMData()->GetIsolateSnapshot(), // isolate snapshot
vm->GetVMData()->GetSharedSnapshot(), // shared snapshot
std::move(task_runners), // task runners
nullptr, // window
{}, // snapshot delegate
{}, // io manager
"main.dart", // advisory uri
"main" // advisory entrypoint
);
auto root_isolate = weak_isolate.lock();
ASSERT_TRUE(root_isolate);
ASSERT_EQ(root_isolate->GetPhase(), DartIsolate::Phase::LibrariesSetup);
ASSERT_TRUE(root_isolate->Shutdown());
}
}
} // namespace blink
......@@ -17,8 +17,8 @@ namespace blink {
RuntimeController::RuntimeController(
RuntimeDelegate& p_client,
DartVM* p_vm,
fml::RefPtr<const DartSnapshot> p_isolate_snapshot,
fml::RefPtr<const DartSnapshot> p_shared_snapshot,
fml::RefPtr<DartSnapshot> p_isolate_snapshot,
fml::RefPtr<DartSnapshot> p_shared_snapshot,
TaskRunners p_task_runners,
fml::WeakPtr<SnapshotDelegate> p_snapshot_delegate,
fml::WeakPtr<IOManager> p_io_manager,
......@@ -40,8 +40,8 @@ RuntimeController::RuntimeController(
RuntimeController::RuntimeController(
RuntimeDelegate& p_client,
DartVM* p_vm,
fml::RefPtr<const DartSnapshot> p_isolate_snapshot,
fml::RefPtr<const DartSnapshot> p_shared_snapshot,
fml::RefPtr<DartSnapshot> p_isolate_snapshot,
fml::RefPtr<DartSnapshot> p_shared_snapshot,
TaskRunners p_task_runners,
fml::WeakPtr<SnapshotDelegate> p_snapshot_delegate,
fml::WeakPtr<IOManager> p_io_manager,
......@@ -61,7 +61,7 @@ RuntimeController::RuntimeController(
idle_notification_callback_(idle_notification_callback),
window_data_(std::move(p_window_data)),
root_isolate_(
DartIsolate::CreateRootIsolate(vm_->GetVMData()->GetSettings(),
DartIsolate::CreateRootIsolate(vm_,
isolate_snapshot_,
shared_snapshot_,
task_runners_,
......
......@@ -30,8 +30,8 @@ class RuntimeController final : public WindowClient {
public:
RuntimeController(RuntimeDelegate& client,
DartVM* vm,
fml::RefPtr<const DartSnapshot> isolate_snapshot,
fml::RefPtr<const DartSnapshot> shared_snapshot,
fml::RefPtr<DartSnapshot> isolate_snapshot,
fml::RefPtr<DartSnapshot> shared_snapshot,
TaskRunners task_runners,
fml::WeakPtr<SnapshotDelegate> snapshot_delegate,
fml::WeakPtr<IOManager> io_manager,
......@@ -118,8 +118,8 @@ class RuntimeController final : public WindowClient {
RuntimeDelegate& client_;
DartVM* const vm_;
fml::RefPtr<const DartSnapshot> isolate_snapshot_;
fml::RefPtr<const DartSnapshot> shared_snapshot_;
fml::RefPtr<DartSnapshot> isolate_snapshot_;
fml::RefPtr<DartSnapshot> shared_snapshot_;
TaskRunners task_runners_;
fml::WeakPtr<SnapshotDelegate> snapshot_delegate_;
fml::WeakPtr<IOManager> io_manager_;
......@@ -132,8 +132,8 @@ class RuntimeController final : public WindowClient {
RuntimeController(RuntimeDelegate& client,
DartVM* vm,
fml::RefPtr<const DartSnapshot> isolate_snapshot,
fml::RefPtr<const DartSnapshot> shared_snapshot,
fml::RefPtr<DartSnapshot> isolate_snapshot,
fml::RefPtr<DartSnapshot> shared_snapshot,
TaskRunners task_runners,
fml::WeakPtr<SnapshotDelegate> snapshot_delegate,
fml::WeakPtr<IOManager> io_manager,
......
......@@ -37,8 +37,8 @@ static constexpr char kSettingsChannel[] = "flutter/settings";
Engine::Engine(Delegate& delegate,
blink::DartVM& vm,
fml::RefPtr<const blink::DartSnapshot> isolate_snapshot,
fml::RefPtr<const blink::DartSnapshot> shared_snapshot,
fml::RefPtr<blink::DartSnapshot> isolate_snapshot,
fml::RefPtr<blink::DartSnapshot> shared_snapshot,
blink::TaskRunners task_runners,
blink::Settings settings,
std::unique_ptr<Animator> animator,
......
......@@ -56,8 +56,8 @@ class Engine final : public blink::RuntimeDelegate {
Engine(Delegate& delegate,
blink::DartVM& vm,
fml::RefPtr<const blink::DartSnapshot> isolate_snapshot,
fml::RefPtr<const blink::DartSnapshot> shared_snapshot,
fml::RefPtr<blink::DartSnapshot> isolate_snapshot,
fml::RefPtr<blink::DartSnapshot> shared_snapshot,
blink::TaskRunners task_runners,
blink::Settings settings,
std::unique_ptr<Animator> animator,
......
......@@ -36,20 +36,17 @@ namespace shell {
constexpr char kSkiaChannel[] = "flutter/skia";
std::unique_ptr<Shell> Shell::CreateShellOnPlatformThread(
blink::DartVMRef vm,
blink::TaskRunners task_runners,
blink::Settings settings,
fml::RefPtr<const blink::DartSnapshot> isolate_snapshot,
fml::RefPtr<const blink::DartSnapshot> shared_snapshot,
fml::RefPtr<blink::DartSnapshot> isolate_snapshot,
fml::RefPtr<blink::DartSnapshot> shared_snapshot,
Shell::CreateCallback<PlatformView> on_create_platform_view,
Shell::CreateCallback<Rasterizer> on_create_rasterizer) {
if (!task_runners.IsValid()) {
FML_LOG(ERROR) << "Task runners to run the shell were invalid.";
return nullptr;
}
auto shell =
std::unique_ptr<Shell>(new Shell(std::move(vm), task_runners, settings));
auto shell = std::unique_ptr<Shell>(new Shell(task_runners, settings));
// Create the platform view on the platform thread (this thread).
auto platform_view = on_create_platform_view(*shell.get());
......@@ -78,7 +75,6 @@ std::unique_ptr<Shell> Shell::CreateShellOnPlatformThread(
&platform_view, //
io_task_runner //
]() {
TRACE_EVENT0("flutter", "ShellSetupIOSubsystem");
io_manager = std::make_unique<IOManager>(
platform_view->CreateResourceContext(), io_task_runner);
io_latch.Signal();
......@@ -96,7 +92,6 @@ std::unique_ptr<Shell> Shell::CreateShellOnPlatformThread(
shell = shell.get(), //
&snapshot_delegate //
]() {
TRACE_EVENT0("flutter", "ShellSetupGPUSubsystem");
if (auto new_rasterizer = on_create_rasterizer(*shell)) {
rasterizer = std::move(new_rasterizer);
snapshot_delegate = rasterizer->GetSnapshotDelegate();
......@@ -120,7 +115,6 @@ std::unique_ptr<Shell> Shell::CreateShellOnPlatformThread(
snapshot_delegate = std::move(snapshot_delegate), //
io_manager = io_manager->GetWeakPtr() //
]() mutable {
TRACE_EVENT0("flutter", "ShellSetupUISubsystem");
const auto& task_runners = shell->GetTaskRunners();
// The animator is owned by the UI thread but it gets its vsync pulses
......@@ -129,7 +123,7 @@ std::unique_ptr<Shell> Shell::CreateShellOnPlatformThread(
std::move(vsync_waiter));
engine = std::make_unique<Engine>(*shell, //
*shell->GetDartVM(), //
shell->GetDartVM(), //
std::move(isolate_snapshot), //
std::move(shared_snapshot), //
task_runners, //
......@@ -210,35 +204,26 @@ std::unique_ptr<Shell> Shell::Create(
Shell::CreateCallback<Rasterizer> on_create_rasterizer) {
PerformInitializationTasks(settings);
TRACE_EVENT0("flutter", "Shell::Create");
auto vm = blink::DartVMRef::Create(settings);
auto vm = blink::DartVM::ForProcess(settings);
FML_CHECK(vm) << "Must be able to initialize the VM.";
auto vm_data = vm->GetVMData();
return Shell::Create(std::move(task_runners), //
std::move(settings), //
vm_data->GetIsolateSnapshot(), // isolate snapshot
blink::DartSnapshot::Empty(), // shared snapshot
vm->GetIsolateSnapshot(), //
blink::DartSnapshot::Empty(), //
std::move(on_create_platform_view), //
std::move(on_create_rasterizer), //
std::move(vm) //
std::move(on_create_rasterizer) //
);
}
std::unique_ptr<Shell> Shell::Create(
blink::TaskRunners task_runners,
blink::Settings settings,
fml::RefPtr<const blink::DartSnapshot> isolate_snapshot,
fml::RefPtr<const blink::DartSnapshot> shared_snapshot,
fml::RefPtr<blink::DartSnapshot> isolate_snapshot,
fml::RefPtr<blink::DartSnapshot> shared_snapshot,
Shell::CreateCallback<PlatformView> on_create_platform_view,
Shell::CreateCallback<Rasterizer> on_create_rasterizer,
blink::DartVMRef vm) {
Shell::CreateCallback<Rasterizer> on_create_rasterizer) {
PerformInitializationTasks(settings);
TRACE_EVENT0("flutter", "Shell::CreateWithSnapshots");
if (!task_runners.IsValid() || !on_create_platform_view ||
!on_create_rasterizer) {
return nullptr;
......@@ -248,18 +233,16 @@ std::unique_ptr<Shell> Shell::Create(
std::unique_ptr<Shell> shell;
fml::TaskRunner::RunNowOrPostTask(
task_runners.GetPlatformTaskRunner(),
fml::MakeCopyable([&latch, //
vm = std::move(vm), //
&shell, //
task_runners = std::move(task_runners), //
settings, //
isolate_snapshot = std::move(isolate_snapshot), //
shared_snapshot = std::move(shared_snapshot), //
on_create_platform_view, //
on_create_rasterizer //
]() mutable {
shell = CreateShellOnPlatformThread(std::move(vm),
std::move(task_runners), //
[&latch, //
&shell, //
task_runners = std::move(task_runners), //
settings, //
isolate_snapshot = std::move(isolate_snapshot), //
shared_snapshot = std::move(shared_snapshot), //
on_create_platform_view, //
on_create_rasterizer //
]() {
shell = CreateShellOnPlatformThread(std::move(task_runners), //
settings, //
std::move(isolate_snapshot), //
std::move(shared_snapshot), //
......@@ -267,18 +250,15 @@ std::unique_ptr<Shell> Shell::Create(
on_create_rasterizer //
);
latch.Signal();
}));
});
latch.Wait();
return shell;
}
Shell::Shell(blink::DartVMRef vm,
blink::TaskRunners task_runners,
blink::Settings settings)
Shell::Shell(blink::TaskRunners task_runners, blink::Settings settings)
: task_runners_(std::move(task_runners)),
settings_(std::move(settings)),
vm_(std::move(vm)) {
FML_CHECK(vm_) << "Must have access to VM to create a shell.";
vm_(blink::DartVM::ForProcess(settings_)) {
FML_DCHECK(task_runners_.IsValid());
FML_DCHECK(task_runners_.GetPlatformTaskRunner()->RunsTasksOnCurrentThread());
......@@ -320,7 +300,9 @@ Shell::~Shell() {
PersistentCache::GetCacheForProcess()->RemoveWorkerTaskRunner(
task_runners_.GetIOTaskRunner());
vm_->GetServiceProtocol()->RemoveHandler(this);
if (auto vm = blink::DartVM::ForProcessIfInitialized()) {
vm->GetServiceProtocol().RemoveHandler(this);
}
fml::AutoResetWaitableEvent ui_latch, gpu_latch, platform_latch, io_latch;
......@@ -391,7 +373,9 @@ bool Shell::Setup(std::unique_ptr<PlatformView> platform_view,
is_setup_ = true;
vm_->GetServiceProtocol()->AddHandler(this, GetServiceProtocolDescription());
if (auto vm = blink::DartVM::ForProcessIfInitialized()) {
vm->GetServiceProtocol().AddHandler(this, GetServiceProtocolDescription());
}
PersistentCache::GetCacheForProcess()->AddWorkerTaskRunner(
task_runners_.GetIOTaskRunner());
......@@ -422,13 +406,12 @@ fml::WeakPtr<PlatformView> Shell::GetPlatformView() {
return platform_view_->GetWeakPtr();
}
blink::DartVM* Shell::GetDartVM() {
return &vm_;
blink::DartVM& Shell::GetDartVM() const {
return *vm_;
}
// |shell::PlatformView::Delegate|
void Shell::OnPlatformViewCreated(std::unique_ptr<Surface> surface) {
TRACE_EVENT0("flutter", "Shell::OnPlatformViewCreated");
FML_DCHECK(is_setup_);
FML_DCHECK(task_runners_.GetPlatformTaskRunner()->RunsTasksOnCurrentThread());
......@@ -486,7 +469,6 @@ void Shell::OnPlatformViewCreated(std::unique_ptr<Surface> surface) {
// |shell::PlatformView::Delegate|
void Shell::OnPlatformViewDestroyed() {
TRACE_EVENT0("flutter", "Shell::OnPlatformViewDestroyed");
FML_DCHECK(is_setup_);
FML_DCHECK(task_runners_.GetPlatformTaskRunner()->RunsTasksOnCurrentThread());
......@@ -822,8 +804,10 @@ void Shell::OnPreEngineRestart() {
// |shell::Engine::Delegate|
void Shell::UpdateIsolateDescription(const std::string isolate_name,
int64_t isolate_port) {
Handler::Description description(isolate_port, isolate_name);
vm_->GetServiceProtocol()->SetHandlerDescription(this, description);
if (auto vm = blink::DartVM::ForProcessIfInitialized()) {
Handler::Description description(isolate_port, isolate_name);
vm->GetServiceProtocol().SetHandlerDescription(this, description);
}
}
// |blink::ServiceProtocol::Handler|
......
......@@ -23,7 +23,6 @@
#include "flutter/lib/ui/semantics/custom_accessibility_action.h"
#include "flutter/lib/ui/semantics/semantics_node.h"
#include "flutter/lib/ui/window/platform_message.h"
#include "flutter/runtime/dart_vm_lifecycle.h"
#include "flutter/runtime/service_protocol.h"
#include "flutter/shell/common/animator.h"
#include "flutter/shell/common/engine.h"
......@@ -55,11 +54,10 @@ class Shell final : public PlatformView::Delegate,
static std::unique_ptr<Shell> Create(
blink::TaskRunners task_runners,
blink::Settings settings,
fml::RefPtr<const blink::DartSnapshot> isolate_snapshot,
fml::RefPtr<const blink::DartSnapshot> shared_snapshot,
fml::RefPtr<blink::DartSnapshot> isolate_snapshot,
fml::RefPtr<blink::DartSnapshot> shared_snapshot,
CreateCallback<PlatformView> on_create_platform_view,
CreateCallback<Rasterizer> on_create_rasterizer,
blink::DartVMRef vm);
CreateCallback<Rasterizer> on_create_rasterizer);
~Shell();
......@@ -73,7 +71,7 @@ class Shell final : public PlatformView::Delegate,
fml::WeakPtr<PlatformView> GetPlatformView();
blink::DartVM* GetDartVM();
blink::DartVM& GetDartVM() const;
bool IsSetup() const;
......@@ -87,7 +85,7 @@ class Shell final : public PlatformView::Delegate,
const blink::TaskRunners task_runners_;
const blink::Settings settings_;
blink::DartVMRef vm_;
fml::RefPtr<blink::DartVM> vm_;
std::unique_ptr<PlatformView> platform_view_; // on platform task runner
std::unique_ptr<Engine> engine_; // on UI task runner
std::unique_ptr<Rasterizer> rasterizer_; // on GPU task runner
......@@ -100,19 +98,16 @@ class Shell final : public PlatformView::Delegate,
>
service_protocol_handlers_;
bool is_setup_ = false;
uint64_t next_pointer_flow_id_ = 0;
Shell(blink::TaskRunners task_runners, blink::Settings settings);
Shell(blink::DartVMRef vm,
blink::TaskRunners task_runners,
blink::Settings settings);
static std::unique_ptr<Shell> CreateShellOnPlatformThread(
blink::DartVMRef vm,
blink::TaskRunners task_runners,
blink::Settings settings,
fml::RefPtr<const blink::DartSnapshot> isolate_snapshot,
fml::RefPtr<const blink::DartSnapshot> shared_snapshot,
fml::RefPtr<blink::DartSnapshot> isolate_snapshot,
fml::RefPtr<blink::DartSnapshot> shared_snapshot,
Shell::CreateCallback<PlatformView> on_create_platform_view,
Shell::CreateCallback<Rasterizer> on_create_rasterizer);
......
......@@ -6,8 +6,6 @@
namespace testing {
std::string GetCurrentTestName() {
return UnitTest::GetInstance()->current_test_info()->name();
}
//
} // namespace testing
......@@ -5,8 +5,6 @@
#ifndef TESTING_TESTING_H_
#define TESTING_TESTING_H_
#include <string>
#include "gtest/gtest.h"
namespace testing {
......@@ -16,8 +14,6 @@ namespace testing {
// error.
const char* GetFixturesPath();
std::string GetCurrentTestName();
} // namespace testing
#endif // TESTING_TESTING_H_
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册