diff --git a/runtime/BUILD.gn b/runtime/BUILD.gn index 5e41f19f031e2..edd3f8198bcbf 100644 --- a/runtime/BUILD.gn +++ b/runtime/BUILD.gn @@ -46,6 +46,8 @@ source_set("runtime") { sources = [ "dart_isolate.cc", "dart_isolate.h", + "dart_isolate_group_data.cc", + "dart_isolate_group_data.h", "dart_service_isolate.cc", "dart_service_isolate.h", "dart_snapshot.cc", diff --git a/runtime/dart_isolate.cc b/runtime/dart_isolate.cc index 9fe676aca7b5b..97f55a2507961 100644 --- a/runtime/dart_isolate.cc +++ b/runtime/dart_isolate.cc @@ -12,6 +12,7 @@ #include "flutter/lib/io/dart_io.h" #include "flutter/lib/ui/dart_runtime_hooks.h" #include "flutter/lib/ui/dart_ui.h" +#include "flutter/runtime/dart_isolate_group_data.h" #include "flutter/runtime/dart_service_isolate.h" #include "flutter/runtime/dart_vm.h" #include "flutter/runtime/dart_vm_lifecycle.h" @@ -29,6 +30,27 @@ namespace flutter { +namespace { + +class DartErrorString { + public: + DartErrorString() : str_(nullptr) {} + ~DartErrorString() { + if (str_) { + ::free(str_); + } + } + char** error() { return &str_; } + const char* str() const { return str_; } + operator bool() const { return str_ != nullptr; } + + private: + FML_DISALLOW_COPY_AND_ASSIGN(DartErrorString); + char* str_; +}; + +} // anonymous namespace + std::weak_ptr DartIsolate::CreateRootIsolate( const Settings& settings, fml::RefPtr isolate_snapshot, @@ -44,21 +66,24 @@ std::weak_ptr DartIsolate::CreateRootIsolate( const fml::closure& isolate_create_callback, const fml::closure& isolate_shutdown_callback) { TRACE_EVENT0("flutter", "DartIsolate::CreateRootIsolate"); - Dart_Isolate vm_isolate = nullptr; - std::weak_ptr embedder_isolate; - - char* error = nullptr; - // Since this is the root isolate, we fake a parent embedder data object. We - // cannot use unique_ptr here because the destructor is private (since the - // isolate lifecycle is entirely managed by the VM). - // // The child isolate preparer is null but will be set when the isolate is // being prepared to run. - auto root_embedder_data = std::make_unique>( + auto isolate_group_data = + std::make_unique>( + std::shared_ptr(new DartIsolateGroupData( + settings, // settings + std::move(isolate_snapshot), // isolate snapshot + advisory_script_uri, // advisory URI + advisory_script_entrypoint, // advisory entrypoint + nullptr, // child isolate preparer + isolate_create_callback, // isolate create callback + isolate_shutdown_callback // isolate shutdown callback + ))); + + auto isolate_data = std::make_unique>( std::shared_ptr(new DartIsolate( settings, // settings - std::move(isolate_snapshot), // isolate snapshot task_runners, // task runners std::move(snapshot_delegate), // snapshot delegate std::move(io_manager), // IO manager @@ -66,46 +91,31 @@ std::weak_ptr DartIsolate::CreateRootIsolate( std::move(image_decoder), // Image Decoder advisory_script_uri, // advisory URI advisory_script_entrypoint, // advisory entrypoint - nullptr, // child isolate preparer - isolate_create_callback, // isolate create callback - isolate_shutdown_callback, // isolate shutdown callback - true, // is_root_isolate - true // is_group_root_isolate + true // is_root_isolate ))); - std::tie(vm_isolate, embedder_isolate) = CreateDartVMAndEmbedderObjectPair( - advisory_script_uri.c_str(), // advisory script URI - advisory_script_entrypoint.c_str(), // advisory script entrypoint - nullptr, // package root - nullptr, // package config - flags, // flags - root_embedder_data.get(), // parent embedder data - true, // is root isolate - &error // error (out) - ); + DartErrorString error; + Dart_Isolate vm_isolate = + CreateDartIsolateGroup(std::move(isolate_group_data), + std::move(isolate_data), flags, error.error()); - if (error != nullptr) { - free(error); + if (error) { + FML_LOG(ERROR) << "CreateDartIsolateGroup failed: " << error.str(); } if (vm_isolate == nullptr) { return {}; } - std::shared_ptr shared_embedder_isolate = - embedder_isolate.lock(); - if (shared_embedder_isolate) { - // Only root isolates can interact with windows. - shared_embedder_isolate->SetWindow(std::move(window)); - } + std::shared_ptr* root_isolate_data = + static_cast*>(Dart_IsolateData(vm_isolate)); - root_embedder_data.release(); + (*root_isolate_data)->SetWindow(std::move(window)); - return embedder_isolate; + return (*root_isolate_data)->GetWeakIsolatePtr(); } DartIsolate::DartIsolate(const Settings& settings, - fml::RefPtr isolate_snapshot, TaskRunners task_runners, fml::WeakPtr snapshot_delegate, fml::WeakPtr io_manager, @@ -113,11 +123,7 @@ DartIsolate::DartIsolate(const Settings& settings, fml::WeakPtr image_decoder, std::string advisory_script_uri, std::string advisory_script_entrypoint, - const ChildIsolatePreparer& child_isolate_preparer, - const fml::closure& isolate_create_callback, - const fml::closure& isolate_shutdown_callback, - bool is_root_isolate, - bool is_group_root_isolate) + bool is_root_isolate) : UIDartState(std::move(task_runners), settings.task_observer_add, settings.task_observer_remove, @@ -130,21 +136,14 @@ DartIsolate::DartIsolate(const Settings& settings, settings.log_tag, settings.unhandled_exception_callback, DartVMRef::GetIsolateNameServer()), - settings_(settings), - isolate_snapshot_(std::move(isolate_snapshot)), - child_isolate_preparer_(std::move(child_isolate_preparer)), - isolate_create_callback_(isolate_create_callback), - isolate_shutdown_callback_(isolate_shutdown_callback), - is_root_isolate_(is_root_isolate), - is_group_root_isolate_(is_group_root_isolate) { - FML_DCHECK(isolate_snapshot_) << "Must contain a valid isolate snapshot."; + is_root_isolate_(is_root_isolate) { phase_ = Phase::Uninitialized; } -DartIsolate::~DartIsolate() = default; - -const Settings& DartIsolate::GetSettings() const { - return settings_; +DartIsolate::~DartIsolate() { + if (IsRootIsolate() && GetMessageHandlingTaskRunner()) { + FML_DCHECK(GetMessageHandlingTaskRunner()->RunsTasksOnCurrentThread()); + } } DartIsolate::Phase DartIsolate::GetPhase() const { @@ -295,12 +294,14 @@ bool DartIsolate::PrepareForRunningFromPrecompiledCode() { return false; } - child_isolate_preparer_ = [](DartIsolate* isolate) { + GetIsolateGroupData().SetChildIsolatePreparer([](DartIsolate* isolate) { return isolate->PrepareForRunningFromPrecompiledCode(); - }; + }); - if (isolate_create_callback_) { - isolate_create_callback_(); + const fml::closure& isolate_create_callback = + GetIsolateGroupData().GetIsolateCreateCallback(); + if (isolate_create_callback) { + isolate_create_callback(); } phase_ = Phase::Ready; @@ -376,22 +377,24 @@ bool DartIsolate::PrepareForRunningFromKernel( // Child isolate shares root isolate embedder_isolate (lines 691 and 693 // below). Re-initializing child_isolate_preparer_ lambda while it is being // executed leads to crashes. - if (child_isolate_preparer_ == nullptr) { - child_isolate_preparer_ = [buffers = - kernel_buffers_](DartIsolate* isolate) { - for (unsigned long i = 0; i < buffers.size(); i++) { - bool last_piece = i + 1 == buffers.size(); - const std::shared_ptr& buffer = buffers.at(i); - if (!isolate->PrepareForRunningFromKernel(buffer, last_piece)) { - return false; - } - } - return true; - }; + if (GetIsolateGroupData().GetChildIsolatePreparer() == nullptr) { + GetIsolateGroupData().SetChildIsolatePreparer( + [buffers = kernel_buffers_](DartIsolate* isolate) { + for (unsigned long i = 0; i < buffers.size(); i++) { + bool last_piece = i + 1 == buffers.size(); + const std::shared_ptr& buffer = buffers.at(i); + if (!isolate->PrepareForRunningFromKernel(buffer, last_piece)) { + return false; + } + } + return true; + }); } - if (isolate_create_callback_) { - isolate_create_callback_(); + const fml::closure& isolate_create_callback = + GetIsolateGroupData().GetIsolateCreateCallback(); + if (isolate_create_callback) { + isolate_create_callback(); } phase_ = Phase::Ready; @@ -641,6 +644,13 @@ Dart_Isolate DartIsolate::DartCreateAndStartServiceIsolate( return service_isolate->isolate(); } +DartIsolateGroupData& DartIsolate::GetIsolateGroupData() { + std::shared_ptr* isolate_group_data = + static_cast*>( + Dart_IsolateGroupData(isolate())); + return **isolate_group_data; +} + // |Dart_IsolateGroupCreateCallback| Dart_Isolate DartIsolate::DartIsolateGroupCreateCallback( const char* advisory_script_uri, @@ -648,10 +658,10 @@ Dart_Isolate DartIsolate::DartIsolateGroupCreateCallback( const char* package_root, const char* package_config, Dart_IsolateFlags* flags, - std::shared_ptr* parent_embedder_isolate, + std::shared_ptr* parent_isolate_data, char** error) { TRACE_EVENT0("flutter", "DartIsolate::DartIsolateGroupCreateCallback"); - if (parent_embedder_isolate == nullptr && + if (parent_isolate_data == nullptr && strcmp(advisory_script_uri, DART_VM_SERVICE_ISOLATE_NAME) == 0) { // The VM attempts to start the VM service for us on |Dart_Initialize|. In // such a case, the callback data will be null and the script URI will be @@ -665,17 +675,44 @@ Dart_Isolate DartIsolate::DartIsolateGroupCreateCallback( ); } - return CreateDartVMAndEmbedderObjectPair( - advisory_script_uri, // URI - advisory_script_entrypoint, // entrypoint - package_root, // package root - package_config, // package config - flags, // isolate flags - parent_embedder_isolate, // embedder data - false, // is root isolate - error // error - ) - .first; + DartIsolateGroupData& parent_group_data = + (*parent_isolate_data)->GetIsolateGroupData(); + + auto isolate_group_data = + std::make_unique>( + std::shared_ptr(new DartIsolateGroupData( + parent_group_data.GetSettings(), + parent_group_data.GetIsolateSnapshot(), advisory_script_uri, + advisory_script_entrypoint, + parent_group_data.GetChildIsolatePreparer(), + parent_group_data.GetIsolateCreateCallback(), + parent_group_data.GetIsolateShutdownCallback()))); + + TaskRunners null_task_runners(advisory_script_uri, + /* platform= */ nullptr, /* gpu= */ nullptr, + /* ui= */ nullptr, + /* io= */ nullptr); + + auto isolate_data = std::make_unique>( + std::shared_ptr(new DartIsolate( + (*isolate_group_data)->GetSettings(), // settings + null_task_runners, // task_runners + fml::WeakPtr{}, // snapshot_delegate + fml::WeakPtr{}, // io_manager + fml::RefPtr{}, // unref_queue + fml::WeakPtr{}, // image_decoder + advisory_script_uri, // advisory_script_uri + advisory_script_entrypoint, // advisory_script_entrypoint + false))); // is_root_isolate + + Dart_Isolate vm_isolate = CreateDartIsolateGroup( + std::move(isolate_group_data), std::move(isolate_data), flags, error); + + if (*error) { + FML_LOG(ERROR) << "CreateDartIsolateGroup failed: " << error; + } + + return vm_isolate; } // |Dart_IsolateInitializeCallback| @@ -689,36 +726,29 @@ bool DartIsolate::DartIsolateInitializeCallback(void** child_callback_data, return false; } - auto* root_embedder_isolate = static_cast*>( - Dart_CurrentIsolateGroupData()); + auto* isolate_group_data = + static_cast*>( + Dart_CurrentIsolateGroupData()); - TaskRunners null_task_runners( - (*root_embedder_isolate)->GetAdvisoryScriptURI(), - /* platform= */ nullptr, /* gpu= */ nullptr, - /* ui= */ nullptr, - /* io= */ nullptr); + TaskRunners null_task_runners((*isolate_group_data)->GetAdvisoryScriptURI(), + /* platform= */ nullptr, /* gpu= */ nullptr, + /* ui= */ nullptr, + /* io= */ nullptr); auto embedder_isolate = std::make_unique>( std::shared_ptr(new DartIsolate( - (*root_embedder_isolate)->GetSettings(), // settings - (*root_embedder_isolate)->GetIsolateSnapshot(), // isolate_snapshot - null_task_runners, // task_runners - fml::WeakPtr{}, // snapshot_delegate - fml::WeakPtr{}, // io_manager - fml::RefPtr{}, // unref_queue - fml::WeakPtr{}, // image_decoder - (*root_embedder_isolate) - ->GetAdvisoryScriptURI(), // advisory_script_uri - (*root_embedder_isolate) + (*isolate_group_data)->GetSettings(), // settings + null_task_runners, // task_runners + fml::WeakPtr{}, // snapshot_delegate + fml::WeakPtr{}, // io_manager + fml::RefPtr{}, // unref_queue + fml::WeakPtr{}, // image_decoder + (*isolate_group_data)->GetAdvisoryScriptURI(), // advisory_script_uri + (*isolate_group_data) ->GetAdvisoryScriptEntrypoint(), // advisory_script_entrypoint - (*root_embedder_isolate)->child_isolate_preparer_, // preparer - (*root_embedder_isolate)->isolate_create_callback_, // on create - (*root_embedder_isolate)->isolate_shutdown_callback_, // on shutdown - false, // is_root_isolate - false))); // is_group_root_isolate - - // root isolate should have been created via CreateRootIsolate and - // CreateDartVMAndEmbedderObjectPair + false))); // is_root_isolate + + // root isolate should have been created via CreateRootIsolate if (!InitializeIsolate(*embedder_isolate, isolate, error)) { return false; } @@ -731,84 +761,35 @@ bool DartIsolate::DartIsolateInitializeCallback(void** child_callback_data, return true; } -std::pair> -DartIsolate::CreateDartVMAndEmbedderObjectPair( - const char* advisory_script_uri, - const char* advisory_script_entrypoint, - const char* package_root, - const char* package_config, +Dart_Isolate DartIsolate::CreateDartIsolateGroup( + std::unique_ptr> isolate_group_data, + std::unique_ptr> isolate_data, Dart_IsolateFlags* flags, - std::shared_ptr* p_parent_embedder_isolate, - bool is_root_isolate, char** error) { - TRACE_EVENT0("flutter", "DartIsolate::CreateDartVMAndEmbedderObjectPair"); - - std::unique_ptr> embedder_isolate( - p_parent_embedder_isolate); - - if (embedder_isolate == nullptr) { - *error = - strdup("Parent isolate did not have embedder specific callback data."); - FML_DLOG(ERROR) << *error; - return {nullptr, {}}; - } - - if (!is_root_isolate) { - auto* raw_embedder_isolate = embedder_isolate.release(); - - TaskRunners null_task_runners(advisory_script_uri, nullptr, nullptr, - nullptr, nullptr); - - // Copy most fields from the parent to the child. - embedder_isolate = std::make_unique>( - std::shared_ptr(new DartIsolate( - (*raw_embedder_isolate)->GetSettings(), // settings - (*raw_embedder_isolate)->GetIsolateSnapshot(), // isolate_snapshot - null_task_runners, // task_runners - fml::WeakPtr{}, // snapshot_delegate - fml::WeakPtr{}, // io_manager - fml::RefPtr{}, // unref_queue - fml::WeakPtr{}, // image_decoder - advisory_script_uri, // advisory_script_uri - advisory_script_entrypoint, // advisory_script_entrypoint - (*raw_embedder_isolate)->child_isolate_preparer_, // preparer - (*raw_embedder_isolate)->isolate_create_callback_, // on create - (*raw_embedder_isolate)->isolate_shutdown_callback_, // on shutdown - is_root_isolate, - true)) // is_root_group_isolate - ); - } + TRACE_EVENT0("flutter", "DartIsolate::CreateDartIsolateGroup"); // Create the Dart VM isolate and give it the embedder object as the baton. Dart_Isolate isolate = Dart_CreateIsolateGroup( - advisory_script_uri, // - advisory_script_entrypoint, // - (*embedder_isolate)->GetIsolateSnapshot()->GetDataMapping(), - (*embedder_isolate)->GetIsolateSnapshot()->GetInstructionsMapping(), - flags, - embedder_isolate.get(), // isolate_group_data - embedder_isolate.get(), // isolate_group - error); + (*isolate_group_data)->GetAdvisoryScriptURI().c_str(), + (*isolate_group_data)->GetAdvisoryScriptEntrypoint().c_str(), + (*isolate_group_data)->GetIsolateSnapshot()->GetDataMapping(), + (*isolate_group_data)->GetIsolateSnapshot()->GetInstructionsMapping(), + flags, isolate_group_data.get(), isolate_data.get(), error); if (isolate == nullptr) { - FML_DLOG(ERROR) << *error; - return {nullptr, {}}; - } - - if (!InitializeIsolate(*embedder_isolate, isolate, error)) { - return {nullptr, {}}; + return nullptr; } - auto* isolate_data = static_cast*>( - Dart_IsolateGroupData(isolate)); - FML_DCHECK(isolate_data->get() == embedder_isolate->get()); + // Ownership of the isolate data objects has been transferred to the Dart VM. + std::shared_ptr embedder_isolate(*isolate_data); + isolate_group_data.release(); + isolate_data.release(); - auto weak_embedder_isolate = (*embedder_isolate)->GetWeakIsolatePtr(); + if (!InitializeIsolate(std::move(embedder_isolate), isolate, error)) { + return nullptr; + } - // The ownership of the embedder object is controlled by the Dart VM. So the - // only reference returned to the caller is weak. - embedder_isolate.release(); - return {isolate, weak_embedder_isolate}; + return isolate; } bool DartIsolate::InitializeIsolate( @@ -833,8 +814,10 @@ bool DartIsolate::InitializeIsolate( // also a root isolate) by the utility routines in the VM. However, secondary // isolates will be run by the VM if they are marked as runnable. if (!embedder_isolate->IsRootIsolate()) { - FML_DCHECK(embedder_isolate->child_isolate_preparer_); - if (!embedder_isolate->child_isolate_preparer_(embedder_isolate.get())) { + const ChildIsolatePreparer& child_isolate_preparer = + embedder_isolate->GetIsolateGroupData().GetChildIsolatePreparer(); + FML_DCHECK(child_isolate_preparer); + if (!child_isolate_preparer(embedder_isolate.get())) { *error = strdup("Could not prepare the child isolate to run."); FML_DLOG(ERROR) << *error; return false; @@ -846,7 +829,7 @@ bool DartIsolate::InitializeIsolate( // |Dart_IsolateShutdownCallback| void DartIsolate::DartIsolateShutdownCallback( - std::shared_ptr* isolate_group_data, + std::shared_ptr* isolate_group_data, std::shared_ptr* isolate_data) { TRACE_EVENT0("flutter", "DartIsolate::DartIsolateShutdownCallback"); FML_DLOG(INFO) << "DartIsolateShutdownCallback" @@ -857,7 +840,7 @@ void DartIsolate::DartIsolateShutdownCallback( // |Dart_IsolateGroupCleanupCallback| void DartIsolate::DartIsolateGroupCleanupCallback( - std::shared_ptr* isolate_data) { + std::shared_ptr* isolate_data) { TRACE_EVENT0("flutter", "DartIsolate::DartIsolateGroupCleanupCallback"); FML_DLOG(INFO) << "DartIsolateGroupCleanupCallback isolate_data " << isolate_data; @@ -867,38 +850,15 @@ void DartIsolate::DartIsolateGroupCleanupCallback( // |Dart_IsolateCleanupCallback| void DartIsolate::DartIsolateCleanupCallback( - std::shared_ptr* isolate_group_data, + std::shared_ptr* isolate_group_data, std::shared_ptr* isolate_data) { TRACE_EVENT0("flutter", "DartIsolate::DartIsolateCleanupCallback"); - if ((*isolate_data)->IsRootIsolate()) { - // isolate_data will be cleaned up as part of IsolateGroup cleanup - FML_DLOG(INFO) - << "DartIsolateCleanupCallback no-op for root isolate isolate_data " - << isolate_data; - return; - } - if ((*isolate_data)->IsGroupRootIsolate()) { - // Even if isolate was not a root isolate(i.e. was spawned), - // it might have IsolateGroup created for it (when - // --no-enable-isolate-groups dart vm flag is used). - // Then its isolate_data will be cleaned up as part of IsolateGroup - // cleanup as well. - FML_DLOG(INFO) << "DartIsolateCleanupCallback no-op for group root isolate " - "isolate_data " - << isolate_data; - return; - } - FML_DLOG(INFO) << "DartIsolateCleanupCallback cleaned up isolate_data " << isolate_data; delete isolate_data; } -fml::RefPtr DartIsolate::GetIsolateSnapshot() const { - return isolate_snapshot_; -} - std::weak_ptr DartIsolate::GetWeakIsolatePtr() { return std::static_pointer_cast(shared_from_this()); } @@ -917,8 +877,11 @@ void DartIsolate::OnShutdownCallback() { } shutdown_callbacks_.clear(); - if (isolate_shutdown_callback_) { - isolate_shutdown_callback_(); + + const fml::closure& isolate_shutdown_callback = + GetIsolateGroupData().GetIsolateShutdownCallback(); + if (isolate_shutdown_callback) { + isolate_shutdown_callback(); } } diff --git a/runtime/dart_isolate.h b/runtime/dart_isolate.h index 100a16fea9f6a..efbc6bde21755 100644 --- a/runtime/dart_isolate.h +++ b/runtime/dart_isolate.h @@ -24,6 +24,7 @@ namespace flutter { class DartVM; +class DartIsolateGroupData; //------------------------------------------------------------------------------ /// @brief Represents an instance of a live isolate. An isolate is a @@ -205,13 +206,6 @@ class DartIsolate : public UIDartState { // |UIDartState| ~DartIsolate() override; - //---------------------------------------------------------------------------- - /// @brief Get the settings used to create this isolate instance. - /// - /// @return The settings used in the `CreateRootIsolate` call. - /// - const Settings& GetSettings() const; - //---------------------------------------------------------------------------- /// @brief The current phase of the isolate. The engine represents all /// dart isolates as being in one of the known phases. By invoking @@ -376,14 +370,6 @@ class DartIsolate : public UIDartState { /// void AddIsolateShutdownCallback(const fml::closure& closure); - //---------------------------------------------------------------------------- - /// @brief The snapshot used to launch this isolate. This is referenced - /// by any child isolates launched by the root isolate. - /// - /// @return The isolate snapshot. - /// - fml::RefPtr GetIsolateSnapshot() const; - //---------------------------------------------------------------------------- /// @brief A weak pointer to the Dart isolate instance. This instance may /// only be used on the task runner that created the root isolate. @@ -403,14 +389,8 @@ class DartIsolate : public UIDartState { // Root isolate of the VM application bool IsRootIsolate() const { return is_root_isolate_; } - // Isolate that owns IsolateGroup it lives in. - // When --no-enable-isolate-groups dart vm flag is set, - // all child isolates will have their own IsolateGroups. - bool IsGroupRootIsolate() const { return is_group_root_isolate_; } private: - using ChildIsolatePreparer = std::function; - class AutoFireClosure { public: AutoFireClosure(const fml::closure& closure); @@ -424,19 +404,12 @@ class DartIsolate : public UIDartState { friend class DartVM; Phase phase_ = Phase::Unknown; - const Settings settings_; - const fml::RefPtr isolate_snapshot_; std::vector> kernel_buffers_; std::vector> shutdown_callbacks_; - ChildIsolatePreparer child_isolate_preparer_ = nullptr; fml::RefPtr message_handling_task_runner_; - const fml::closure isolate_create_callback_; - const fml::closure isolate_shutdown_callback_; const bool is_root_isolate_; - const bool is_group_root_isolate_; DartIsolate(const Settings& settings, - fml::RefPtr isolate_snapshot, TaskRunners task_runners, fml::WeakPtr snapshot_delegate, fml::WeakPtr io_manager, @@ -444,11 +417,7 @@ class DartIsolate : public UIDartState { fml::WeakPtr image_decoder, std::string advisory_script_uri, std::string advisory_script_entrypoint, - const ChildIsolatePreparer& child_isolate_preparer, - const fml::closure& isolate_create_callback, - const fml::closure& isolate_shutdown_callback, - bool is_root_isolate, - bool is_group_root_isolate); + bool is_root_isolate); FML_WARN_UNUSED_RESULT bool Initialize(Dart_Isolate isolate); void SetMessageHandlingTaskRunner(fml::RefPtr runner); @@ -465,6 +434,8 @@ class DartIsolate : public UIDartState { void OnShutdownCallback(); + DartIsolateGroupData& GetIsolateGroupData(); + // |Dart_IsolateGroupCreateCallback| static Dart_Isolate DartIsolateGroupCreateCallback( const char* advisory_script_uri, @@ -472,7 +443,7 @@ class DartIsolate : public UIDartState { const char* package_root, const char* package_config, Dart_IsolateFlags* flags, - std::shared_ptr* embedder_isolate, + std::shared_ptr* parent_isolate_group, char** error); // |Dart_IsolateInitializeCallback| @@ -485,16 +456,10 @@ class DartIsolate : public UIDartState { Dart_IsolateFlags* flags, char** error); - static std::pair /* embedder */> - CreateDartVMAndEmbedderObjectPair( - const char* advisory_script_uri, - const char* advisory_script_entrypoint, - const char* package_root, - const char* package_config, + static Dart_Isolate CreateDartIsolateGroup( + std::unique_ptr> isolate_group_data, + std::unique_ptr> isolate_data, Dart_IsolateFlags* flags, - std::shared_ptr* parent_embedder_isolate, - bool is_root_isolate, char** error); static bool InitializeIsolate(std::shared_ptr embedder_isolate, @@ -503,17 +468,17 @@ class DartIsolate : public UIDartState { // |Dart_IsolateShutdownCallback| static void DartIsolateShutdownCallback( - std::shared_ptr* isolate_group_data, + std::shared_ptr* isolate_group_data, std::shared_ptr* isolate_data); // |Dart_IsolateCleanupCallback| static void DartIsolateCleanupCallback( - std::shared_ptr* isolate_group_data, + std::shared_ptr* isolate_group_data, std::shared_ptr* isolate_data); // |Dart_IsolateGroupCleanupCallback| static void DartIsolateGroupCleanupCallback( - std::shared_ptr* isolate_group_data); + std::shared_ptr* isolate_group_data); FML_DISALLOW_COPY_AND_ASSIGN(DartIsolate); }; diff --git a/runtime/dart_isolate_group_data.cc b/runtime/dart_isolate_group_data.cc new file mode 100644 index 0000000000000..20a61894ff680 --- /dev/null +++ b/runtime/dart_isolate_group_data.cc @@ -0,0 +1,65 @@ +// 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_isolate_group_data.h" +#include "flutter/runtime/dart_snapshot.h" + +namespace flutter { + +DartIsolateGroupData::DartIsolateGroupData( + const Settings& settings, + fml::RefPtr isolate_snapshot, + std::string advisory_script_uri, + std::string advisory_script_entrypoint, + const ChildIsolatePreparer& child_isolate_preparer, + const fml::closure& isolate_create_callback, + const fml::closure& isolate_shutdown_callback) + : settings_(settings), + isolate_snapshot_(isolate_snapshot), + advisory_script_uri_(advisory_script_uri), + advisory_script_entrypoint_(advisory_script_entrypoint), + child_isolate_preparer_(child_isolate_preparer), + isolate_create_callback_(isolate_create_callback), + isolate_shutdown_callback_(isolate_shutdown_callback) { + FML_DCHECK(isolate_snapshot_) << "Must contain a valid isolate snapshot."; +} + +DartIsolateGroupData::~DartIsolateGroupData() = default; + +const Settings& DartIsolateGroupData::GetSettings() const { + return settings_; +} + +fml::RefPtr DartIsolateGroupData::GetIsolateSnapshot() + const { + return isolate_snapshot_; +} + +const std::string& DartIsolateGroupData::GetAdvisoryScriptURI() const { + return advisory_script_uri_; +} + +const std::string& DartIsolateGroupData::GetAdvisoryScriptEntrypoint() const { + return advisory_script_entrypoint_; +} + +const ChildIsolatePreparer& DartIsolateGroupData::GetChildIsolatePreparer() + const { + return child_isolate_preparer_; +} + +const fml::closure& DartIsolateGroupData::GetIsolateCreateCallback() const { + return isolate_create_callback_; +} + +const fml::closure& DartIsolateGroupData::GetIsolateShutdownCallback() const { + return isolate_shutdown_callback_; +} + +void DartIsolateGroupData::SetChildIsolatePreparer( + const ChildIsolatePreparer& value) { + child_isolate_preparer_ = value; +} + +} // namespace flutter diff --git a/runtime/dart_isolate_group_data.h b/runtime/dart_isolate_group_data.h new file mode 100644 index 0000000000000..400831aee5ec8 --- /dev/null +++ b/runtime/dart_isolate_group_data.h @@ -0,0 +1,63 @@ +// 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_ISOLATE_GROUP_DATA_H_ +#define FLUTTER_RUNTIME_DART_ISOLATE_GROUP_DATA_H_ + +#include + +#include "flutter/common/settings.h" +#include "flutter/fml/closure.h" +#include "flutter/fml/memory/ref_ptr.h" + +namespace flutter { + +class DartIsolate; +class DartSnapshot; + +using ChildIsolatePreparer = std::function; + +// Object holding state associated with a Dart isolate group. An instance of +// this class will be provided to Dart_CreateIsolateGroup as the +// isolate_group_data. +// +// This object must be thread safe because the Dart VM can invoke the isolate +// group cleanup callback on any thread. +class DartIsolateGroupData { + public: + DartIsolateGroupData(const Settings& settings, + fml::RefPtr isolate_snapshot, + std::string advisory_script_uri, + std::string advisory_script_entrypoint, + const ChildIsolatePreparer& child_isolate_preparer, + const fml::closure& isolate_create_callback, + const fml::closure& isolate_shutdown_callback); + + ~DartIsolateGroupData(); + + const Settings& GetSettings() const; + fml::RefPtr GetIsolateSnapshot() const; + const std::string& GetAdvisoryScriptURI() const; + const std::string& GetAdvisoryScriptEntrypoint() const; + const ChildIsolatePreparer& GetChildIsolatePreparer() const; + const fml::closure& GetIsolateCreateCallback() const; + const fml::closure& GetIsolateShutdownCallback() const; + + void SetChildIsolatePreparer(const ChildIsolatePreparer& value); + + private: + FML_DISALLOW_COPY_AND_ASSIGN(DartIsolateGroupData); + + const Settings settings_; + const fml::RefPtr isolate_snapshot_; + const std::string advisory_script_uri_; + const std::string advisory_script_entrypoint_; + ChildIsolatePreparer child_isolate_preparer_; + const fml::closure isolate_create_callback_; + const fml::closure isolate_shutdown_callback_; +}; + +} // namespace flutter + +#endif // FLUTTER_RUNTIME_DART_ISOLATE_GROUP_DATA_H_