Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
Classes | Public Types | Public Member Functions | Static Public Member Functions | Friends | List of all members
flutter::DartIsolate Class Reference

Represents an instance of a live isolate. An isolate is a separate Dart execution context. Different Dart isolates don't share memory and can be scheduled concurrently by the Dart VM on one of the Dart VM managed worker pool threads. More...

#include <dart_isolate.h>

Inheritance diagram for flutter::DartIsolate:
flutter::UIDartState tonic::DartState

Classes

class  Flags
 

Public Types

enum class  Phase {
  Unknown , Uninitialized , Initialized , LibrariesSetup ,
  Ready , Running , Shutdown
}
 The engine represents all dart isolates as being in one of the known phases. By invoking various methods on the Dart isolate, the engine transition the Dart isolate from one phase to the next. The Dart isolate will only move from one phase to the next in the order specified in the DartIsolate::Phase enum. That is, once the isolate has moved out of a particular phase, it can never transition back to that phase in the future. There is no error recovery mechanism and callers that find their isolates in an undesirable phase must discard the isolate and start over. More...
 

Public Member Functions

 ~DartIsolate () override
 
Phase GetPhase () const
 The current phase of the isolate. The engine represents all dart isolates as being in one of the known phases. By invoking various methods on the Dart isolate, the engine transitions the Dart isolate from one phase to the next. The Dart isolate will only move from one phase to the next in the order specified in the DartIsolate::Phase enum. That is, the once the isolate has moved out of a particular phase, it can never transition back to that phase in the future. There is no error recovery mechanism and callers that find their isolates in an undesirable phase must discard the isolate and start over.
 
std::string GetServiceId ()
 Returns the ID for an isolate which is used to query the service protocol.
 
bool PrepareForRunningFromPrecompiledCode ()
 Prepare the isolate for running for a precompiled code bundle. The Dart VM must be configured for running precompiled code.
 
bool PrepareForRunningFromKernel (const std::shared_ptr< const fml::Mapping > &kernel, bool child_isolate, bool last_piece)
 Prepare the isolate for running for a a list of kernel files.
 
bool PrepareForRunningFromKernels (std::vector< std::shared_ptr< const fml::Mapping > > kernels)
 Prepare the isolate for running for a a list of kernel files.
 
bool PrepareForRunningFromKernels (std::vector< std::unique_ptr< const fml::Mapping > > kernels)
 Prepare the isolate for running for a a list of kernel files.
 
bool RunFromLibrary (std::optional< std::string > library_name, std::optional< std::string > entrypoint, const std::vector< std::string > &args)
 Transition the root isolate to the Phase::Running phase and invoke the main entrypoint (the "main" method) in the specified library. The isolate must already be in the Phase::Ready phase.
 
bool Shutdown ()
 Transition the isolate to the Phase::Shutdown phase. The only thing left to do is to collect the isolate.
 
void AddIsolateShutdownCallback (const fml::closure &closure)
 Registers a callback that will be invoked in isolate scope just before the isolate transitions to the Phase::Shutdown phase.
 
std::weak_ptr< DartIsolateGetWeakIsolatePtr ()
 A weak pointer to the Dart isolate instance. This instance may only be used on the task runner that created the root isolate.
 
fml::RefPtr< fml::TaskRunnerGetMessageHandlingTaskRunner () const
 The task runner on which the Dart code for the root isolate is running. For the root isolate, this is the UI task runner for the shell that owns the root isolate.
 
Dart_Isolate CreatePlatformIsolate (Dart_Handle entry_point, char **error) override
 Creates a new isolate in the same group as this isolate, which runs on the platform thread. This method can only be invoked on the root isolate.
 
bool LoadLoadingUnit (intptr_t loading_unit_id, std::unique_ptr< const fml::Mapping > snapshot_data, std::unique_ptr< const fml::Mapping > snapshot_instructions)
 
void LoadLoadingUnitError (intptr_t loading_unit_id, const std::string &error_message, bool transient)
 
DartIsolateGroupDataGetIsolateGroupData ()
 
const DartIsolateGroupDataGetIsolateGroupData () const
 
- Public Member Functions inherited from flutter::UIDartState
Dart_Port main_port () const
 
bool IsRootIsolate () const
 
void SetDebugName (const std::string &name)
 
const std::string & debug_name () const
 
const std::string & logger_prefix () const
 
PlatformConfigurationplatform_configuration () const
 
void SetPlatformMessageHandler (std::weak_ptr< PlatformMessageHandler > handler)
 
Dart_Handle HandlePlatformMessage (std::unique_ptr< PlatformMessage > message)
 
const TaskRunnersGetTaskRunners () const
 
void ScheduleMicrotask (Dart_Handle handle)
 
void FlushMicrotasksNow ()
 
fml::WeakPtr< IOManagerGetIOManager () const
 
fml::RefPtr< flutter::SkiaUnrefQueueGetSkiaUnrefQueue () const
 
std::shared_ptr< VolatilePathTrackerGetVolatilePathTracker () const
 
std::shared_ptr< fml::ConcurrentTaskRunnerGetConcurrentTaskRunner () const
 
fml::TaskRunnerAffineWeakPtr< SnapshotDelegateGetSnapshotDelegate () const
 
fml::WeakPtr< ImageDecoderGetImageDecoder () const
 
fml::WeakPtr< ImageGeneratorRegistryGetImageGeneratorRegistry () const
 
std::shared_ptr< IsolateNameServerGetIsolateNameServer () const
 
tonic::DartErrorHandleType GetLastError ()
 
void LogMessage (const std::string &tag, const std::string &message) const
 
UnhandledExceptionCallback unhandled_exception_callback () const
 
int64_t GetRootIsolateToken () const
 
bool IsImpellerEnabled () const
 Whether Impeller is enabled for this application.
 
impeller::RuntimeStageBackend GetRuntimeStageBackend () const
 The expected type for runtime stage shaders.
 
- Public Member Functions inherited from tonic::DartState
 DartState (int dirfd=-1, std::function< void(Dart_Handle)> message_epilogue=nullptr)
 
virtual ~DartState ()
 
std::weak_ptr< DartStateGetWeakPtr ()
 
Dart_Isolate isolate ()
 
void SetIsolate (Dart_Isolate isolate)
 
Dart_PersistentHandle private_constructor_name ()
 
DartClassLibraryclass_library ()
 
DartMessageHandlermessage_handler ()
 
FileLoaderfile_loader ()
 
void MessageEpilogue (Dart_Handle message_result)
 
void SetReturnCode (uint32_t return_code)
 
void SetReturnCodeCallback (std::function< void(uint32_t)> callback)
 
bool has_set_return_code () const
 
void SetIsShuttingDown ()
 
bool IsShuttingDown ()
 

Static Public Member Functions

static std::weak_ptr< DartIsolateCreateRunningRootIsolate (const Settings &settings, const fml::RefPtr< const DartSnapshot > &isolate_snapshot, std::unique_ptr< PlatformConfiguration > platform_configuration, Flags flags, const fml::closure &root_isolate_create_callback, const fml::closure &isolate_create_callback, const fml::closure &isolate_shutdown_callback, std::optional< std::string > dart_entrypoint, std::optional< std::string > dart_entrypoint_library, const std::vector< std::string > &dart_entrypoint_args, std::unique_ptr< IsolateConfiguration > isolate_configuration, const UIDartState::Context &context, const DartIsolate *spawning_isolate=nullptr)
 Creates an instance of a root isolate and returns a weak pointer to the same. The isolate instance may only be used safely on the engine thread on which it was created. In the shell, this is the UI thread and task runner. Using the isolate on any other thread is user error.
 
static Dart_Handle LoadLibraryFromKernel (const std::shared_ptr< const fml::Mapping > &mapping)
 
- Static Public Member Functions inherited from flutter::UIDartState
static UIDartStateCurrent ()
 
static void ThrowIfUIOperationsProhibited ()
 
- Static Public Member Functions inherited from tonic::DartState
static DartStateFrom (Dart_Isolate isolate)
 
static DartStateCurrent ()
 
static Dart_Handle HandleLibraryTag (Dart_LibraryTag tag, Dart_Handle library, Dart_Handle url)
 

Friends

class IsolateConfiguration
 
class DartVM
 

Additional Inherited Members

- Protected Member Functions inherited from flutter::UIDartState
 UIDartState (TaskObserverAdd add_callback, TaskObserverRemove remove_callback, std::string logger_prefix, UnhandledExceptionCallback unhandled_exception_callback, LogMessageCallback log_message_callback, std::shared_ptr< IsolateNameServer > isolate_name_server, bool is_root_isolate_, const UIDartState::Context &context)
 
 ~UIDartState () override
 
void SetPlatformConfiguration (std::unique_ptr< PlatformConfiguration > platform_configuration)
 
const std::string & GetAdvisoryScriptURI () const
 
- Protected Member Functions inherited from tonic::DartState
Dart_Isolate isolate () const
 
 TONIC_DISALLOW_COPY_AND_ASSIGN (DartState)
 

Detailed Description

Represents an instance of a live isolate. An isolate is a separate Dart execution context. Different Dart isolates don't share memory and can be scheduled concurrently by the Dart VM on one of the Dart VM managed worker pool threads.

The entire lifecycle of a Dart isolate is controlled by the Dart VM. Because of this, the engine never holds a strong pointer to the Dart VM for extended periods of time. This allows the VM (or the isolates themselves) to terminate Dart execution without consulting the engine.

The isolate that the engine creates to act as the host for the Flutter application code with UI bindings is called the root isolate.

The root isolate is special in the following ways:

Definition at line 63 of file dart_isolate.h.

Member Enumeration Documentation

◆ Phase

enum class flutter::DartIsolate::Phase
strong

The engine represents all dart isolates as being in one of the known phases. By invoking various methods on the Dart isolate, the engine transition the Dart isolate from one phase to the next. The Dart isolate will only move from one phase to the next in the order specified in the DartIsolate::Phase enum. That is, once the isolate has moved out of a particular phase, it can never transition back to that phase in the future. There is no error recovery mechanism and callers that find their isolates in an undesirable phase must discard the isolate and start over.

Enumerator
Unknown 

The initial phase of all Dart isolates. This is an internal phase and callers can never get a reference to a Dart isolate in this phase.

Uninitialized 

The Dart isolate has been created but none of the library tag or message handers have been set yet. The is an internal phase and callers can never get a reference to a Dart isolate in this phase.

Initialized 

The Dart isolate has been fully initialized but none of the libraries referenced by that isolate have been loaded yet. This is an internal phase and callers can never get a reference to a Dart isolate in this phase.

LibrariesSetup 

The isolate has been fully initialized and is waiting for the caller to associate isolate snapshots with the same. The isolate will only be ready to execute Dart code once one of the Prepare calls are successfully made.

Ready 

The isolate is fully ready to start running Dart code. Callers can transition the isolate to the next state by calling the Run or RunFromLibrary methods.

Running 

The isolate is currently running Dart code.

Shutdown 

The isolate is no longer running Dart code and is in the middle of being collected. This is in internal phase and callers can never get a reference to a Dart isolate in this phase.

Definition at line 94 of file dart_isolate.h.

94 {
95 // NOLINTBEGIN(readability-identifier-naming)
96 //--------------------------------------------------------------------------
97 /// The initial phase of all Dart isolates. This is an internal phase and
98 /// callers can never get a reference to a Dart isolate in this phase.
99 ///
100 Unknown,
101 //--------------------------------------------------------------------------
102 /// The Dart isolate has been created but none of the library tag or message
103 /// handers have been set yet. The is an internal phase and callers can
104 /// never get a reference to a Dart isolate in this phase.
105 ///
107 //--------------------------------------------------------------------------
108 /// The Dart isolate has been fully initialized but none of the
109 /// libraries referenced by that isolate have been loaded yet. This is an
110 /// internal phase and callers can never get a reference to a Dart isolate
111 /// in this phase.
112 ///
114 //--------------------------------------------------------------------------
115 /// The isolate has been fully initialized and is waiting for the caller to
116 /// associate isolate snapshots with the same. The isolate will only be
117 /// ready to execute Dart code once one of the `Prepare` calls are
118 /// successfully made.
119 ///
121 //--------------------------------------------------------------------------
122 /// The isolate is fully ready to start running Dart code. Callers can
123 /// transition the isolate to the next state by calling the `Run` or
124 /// `RunFromLibrary` methods.
125 ///
126 Ready,
127 //--------------------------------------------------------------------------
128 /// The isolate is currently running Dart code.
129 ///
130 Running,
131 //--------------------------------------------------------------------------
132 /// The isolate is no longer running Dart code and is in the middle of being
133 /// collected. This is in internal phase and callers can never get a
134 /// reference to a Dart isolate in this phase.
135 ///
136 Shutdown,
137 // NOLINTEND(readability-identifier-naming)
138 };
bool Shutdown()
Transition the isolate to the Phase::Shutdown phase. The only thing left to do is to collect the isol...

Constructor & Destructor Documentation

◆ ~DartIsolate()

flutter::DartIsolate::~DartIsolate ( )
override

Definition at line 470 of file dart_isolate.cc.

470 {
472 FML_DCHECK(GetMessageHandlingTaskRunner()->RunsTasksOnCurrentThread());
473 }
474}
fml::RefPtr< fml::TaskRunner > GetMessageHandlingTaskRunner() const
The task runner on which the Dart code for the root isolate is running. For the root isolate,...
bool IsRootIsolate() const
#define FML_DCHECK(condition)
Definition logging.h:103

Member Function Documentation

◆ AddIsolateShutdownCallback()

void flutter::DartIsolate::AddIsolateShutdownCallback ( const fml::closure closure)

Registers a callback that will be invoked in isolate scope just before the isolate transitions to the Phase::Shutdown phase.

Parameters
[in]closureThe callback to invoke on isolate shutdown.

Definition at line 1277 of file dart_isolate.cc.

1277 {
1278 shutdown_callbacks_.emplace_back(std::make_unique<AutoFireClosure>(closure));
1279}

◆ CreatePlatformIsolate()

Dart_Isolate flutter::DartIsolate::CreatePlatformIsolate ( Dart_Handle  entry_point,
char **  error 
)
overridevirtual

Creates a new isolate in the same group as this isolate, which runs on the platform thread. This method can only be invoked on the root isolate.

Parameters
[in]entry_pointThe entrypoint to invoke once the isolate is spawned. Will be run on the platform thread.
[out]errorIf spawning fails inside the Dart VM, this is set to the error string. The error should be reported to the user. Otherwise it is set to null. It's possible for spawning to fail, but this error still be null. In that case the failure should not be reported to the user.
Returns
The newly created isolate, or null if spawning failed.

Reimplemented from flutter::UIDartState.

Definition at line 285 of file dart_isolate.cc.

286 {
287 *error = nullptr;
288 PlatformConfiguration* platform_config = platform_configuration();
289 FML_DCHECK(platform_config != nullptr);
290 std::shared_ptr<PlatformIsolateManager> platform_isolate_manager =
291 platform_config->client()->GetPlatformIsolateManager();
292 std::weak_ptr<PlatformIsolateManager> weak_platform_isolate_manager =
293 platform_isolate_manager;
294 if (platform_isolate_manager->HasShutdownMaybeFalseNegative()) {
295 // Don't set the error string. We want to silently ignore this error,
296 // because the engine is shutting down.
297 FML_LOG(INFO) << "CreatePlatformIsolate called after shutdown";
298 return nullptr;
299 }
300
301 Dart_Isolate parent_isolate = isolate();
302 Dart_ExitIsolate(); // Exit parent_isolate.
303
304 const TaskRunners& task_runners = GetTaskRunners();
305 fml::RefPtr<fml::TaskRunner> platform_task_runner =
306 task_runners.GetPlatformTaskRunner();
307 FML_DCHECK(platform_task_runner);
308
309 auto isolate_group_data = std::shared_ptr<DartIsolateGroupData>(
310 *static_cast<std::shared_ptr<DartIsolateGroupData>*>(
311 Dart_IsolateGroupData(parent_isolate)));
312
313 Settings settings(isolate_group_data->GetSettings());
314
315 // PlatformIsolate.spawn should behave like Isolate.spawn when unhandled
316 // exceptions happen (log the exception, but don't terminate the app). But the
317 // default unhandled_exception_callback may terminate the app, because it is
318 // only called for the root isolate (child isolates are managed by the VM and
319 // have a different error code path). So override it to simply log the error.
320 settings.unhandled_exception_callback = [](const std::string& error,
321 const std::string& stack_trace) {
322 FML_LOG(ERROR) << "Unhandled exception:\n" << error << "\n" << stack_trace;
323 return true;
324 };
325
326 // The platform isolate task observer must be added on the platform thread. So
327 // schedule the add function on the platform task runner.
328 TaskObserverAdd old_task_observer_add = settings.task_observer_add;
329 settings.task_observer_add = [old_task_observer_add, platform_task_runner,
330 weak_platform_isolate_manager](
331 intptr_t key, const fml::closure& callback) {
332 platform_task_runner->PostTask([old_task_observer_add,
333 weak_platform_isolate_manager, key,
334 callback]() {
335 std::shared_ptr<PlatformIsolateManager> platform_isolate_manager =
336 weak_platform_isolate_manager.lock();
337 if (platform_isolate_manager == nullptr ||
338 platform_isolate_manager->HasShutdown()) {
339 // Shutdown happened in between this task being posted, and it running.
340 // platform_isolate has already been shut down. Do nothing.
341 FML_LOG(INFO) << "Shutdown before platform isolate task observer added";
342 return;
343 }
344 old_task_observer_add(key, callback);
345 });
346 };
347
348 UIDartState::Context context(task_runners);
349 context.advisory_script_uri = isolate_group_data->GetAdvisoryScriptURI();
350 context.advisory_script_entrypoint =
351 isolate_group_data->GetAdvisoryScriptEntrypoint();
352 auto isolate_data = std::make_unique<std::shared_ptr<DartIsolate>>(
353 std::shared_ptr<DartIsolate>(
354 new DartIsolate(settings, context, platform_isolate_manager)));
355
356 IsolateMaker isolate_maker =
357 [parent_isolate](
358 std::shared_ptr<DartIsolateGroupData>* unused_isolate_group_data,
359 std::shared_ptr<DartIsolate>* isolate_data, Dart_IsolateFlags* flags,
360 char** error) {
362 /*group_member=*/parent_isolate,
363 /*name=*/"PlatformIsolate",
364 /*shutdown_callback=*/
365 reinterpret_cast<Dart_IsolateShutdownCallback>(
366 DartIsolate::SpawnIsolateShutdownCallback),
367 /*cleanup_callback=*/
368 reinterpret_cast<Dart_IsolateCleanupCallback>(
369 DartIsolateCleanupCallback),
370 /*child_isolate_data=*/isolate_data,
371 /*error=*/error);
372 };
373 Dart_Isolate platform_isolate = CreateDartIsolateGroup(
374 nullptr, std::move(isolate_data), nullptr, error, isolate_maker);
375
376 Dart_EnterIsolate(parent_isolate);
377
378 if (*error) {
379 return nullptr;
380 }
381
382 if (!platform_isolate_manager->RegisterPlatformIsolate(platform_isolate)) {
383 // The PlatformIsolateManager was shutdown while we were creating the
384 // isolate. This means that we're shutting down the engine. We need to
385 // shutdown the platform isolate.
386 FML_LOG(INFO) << "Shutdown during platform isolate creation";
387 tonic::DartIsolateScope isolate_scope(platform_isolate);
389 return nullptr;
390 }
391
392 tonic::DartApiScope api_scope;
393 Dart_PersistentHandle entry_point_handle =
394 Dart_NewPersistentHandle(entry_point);
395
396 platform_task_runner->PostTask([entry_point_handle, platform_isolate,
397 weak_platform_isolate_manager]() {
398 std::shared_ptr<PlatformIsolateManager> platform_isolate_manager =
399 weak_platform_isolate_manager.lock();
400 if (platform_isolate_manager == nullptr ||
401 platform_isolate_manager->HasShutdown()) {
402 // Shutdown happened in between this task being posted, and it running.
403 // platform_isolate has already been shut down. Do nothing.
404 FML_LOG(INFO) << "Shutdown before platform isolate entry point";
405 return;
406 }
407
408 tonic::DartIsolateScope isolate_scope(platform_isolate);
409 tonic::DartApiScope api_scope;
410 Dart_Handle entry_point = Dart_HandleFromPersistent(entry_point_handle);
411 Dart_DeletePersistentHandle(entry_point_handle);
412
413 // Disable Isolate.exit().
414 Dart_Handle isolate_lib = Dart_LookupLibrary(tonic::ToDart("dart:isolate"));
417 isolate_lib, tonic::ToDart("Isolate"), 0, nullptr);
420 Dart_SetField(isolate_type, tonic::ToDart("_mayExit"), Dart_False());
422
423 tonic::DartInvokeVoid(entry_point);
424 });
425
426 return platform_isolate;
427}
PlatformConfiguration * platform_configuration() const
const TaskRunners & GetTaskRunners() const
Dart_Isolate isolate()
Definition dart_state.h:51
DART_EXPORT Dart_Handle Dart_HandleFromPersistent(Dart_PersistentHandle object)
DART_EXPORT Dart_Handle Dart_GetNonNullableType(Dart_Handle library, Dart_Handle class_name, intptr_t number_of_type_arguments, Dart_Handle *type_arguments)
void(* Dart_IsolateCleanupCallback)(void *isolate_group_data, void *isolate_data)
Definition dart_api.h:728
DART_EXPORT void Dart_ShutdownIsolate(void)
struct _Dart_Handle * Dart_Handle
Definition dart_api.h:258
DART_EXPORT Dart_PersistentHandle Dart_NewPersistentHandle(Dart_Handle object)
DART_EXPORT Dart_Isolate Dart_CreateIsolateInGroup(Dart_Isolate group_member, const char *name, Dart_IsolateShutdownCallback shutdown_callback, Dart_IsolateCleanupCallback cleanup_callback, void *child_isolate_data, char **error)
struct _Dart_Isolate * Dart_Isolate
Definition dart_api.h:88
DART_EXPORT Dart_Handle Dart_LookupLibrary(Dart_Handle url)
DART_EXPORT DART_WARN_UNUSED_RESULT Dart_Handle Dart_SetField(Dart_Handle container, Dart_Handle name, Dart_Handle value)
Dart_Handle Dart_PersistentHandle
Definition dart_api.h:259
DART_EXPORT Dart_Handle Dart_False(void)
void(* Dart_IsolateShutdownCallback)(void *isolate_group_data, void *isolate_data)
Definition dart_api.h:710
DART_EXPORT void * Dart_IsolateGroupData(Dart_Isolate isolate)
DART_EXPORT void Dart_EnterIsolate(Dart_Isolate isolate)
DART_EXPORT void Dart_ExitIsolate(void)
DART_EXPORT void Dart_DeletePersistentHandle(Dart_PersistentHandle object)
FlutterSemanticsFlag flags
FlKeyEvent uint64_t FlKeyResponderAsyncCallback callback
const uint8_t uint32_t uint32_t GError ** error
GAsyncResult * result
#define FML_LOG(severity)
Definition logging.h:82
#define FML_CHECK(condition)
Definition logging.h:85
std::function< void(intptr_t, fml::closure)> TaskObserverAdd
Definition settings.h:82
std::function< void()> closure
Definition closure.h:14
Dart_Handle ToDart(const T &object)
Dart_Handle DartInvokeVoid(Dart_Handle closure)
bool CheckAndHandleError(Dart_Handle handle)
Definition dart_error.cc:33
#define ERROR(message)

◆ CreateRunningRootIsolate()

std::weak_ptr< DartIsolate > flutter::DartIsolate::CreateRunningRootIsolate ( const Settings settings,
const fml::RefPtr< const DartSnapshot > &  isolate_snapshot,
std::unique_ptr< PlatformConfiguration platform_configuration,
Flags  flags,
const fml::closure root_isolate_create_callback,
const fml::closure isolate_create_callback,
const fml::closure isolate_shutdown_callback,
std::optional< std::string >  dart_entrypoint,
std::optional< std::string >  dart_entrypoint_library,
const std::vector< std::string > &  dart_entrypoint_args,
std::unique_ptr< IsolateConfiguration isolate_configuration,
const UIDartState::Context context,
const DartIsolate spawning_isolate = nullptr 
)
static

Creates an instance of a root isolate and returns a weak pointer to the same. The isolate instance may only be used safely on the engine thread on which it was created. In the shell, this is the UI thread and task runner. Using the isolate on any other thread is user error.

The isolate that the engine creates to act as the host for the Flutter application code with UI bindings is called the root isolate.

The root isolate is special in the following ways:

  • The root isolate forms a new isolate group. Child isolates are added to their parents groups. When the root isolate dies, all isolates in its group are terminated.
  • Only root isolates get UI bindings.
  • Root isolates execute their code on engine managed threads. All other isolates run their Dart code on Dart VM managed thread pool workers that the engine has no control over.
  • Since the engine does not know the thread on which non-root isolates are run, the engine has no opportunity to get a reference to non-root isolates. Such isolates can only be terminated if they terminate themselves or their isolate group is torn down.
Parameters
[in]settingsThe settings used to create the isolate.
[in]platform_configurationThe platform configuration for handling communication with the framework.
[in]flagsThe Dart isolate flags for this isolate instance.
[in]dart_entrypointThe name of the dart entrypoint function to invoke.
[in]dart_entrypoint_libraryThe name of the dart library containing the entrypoint.
[in]dart_entrypoint_argsArguments passed as a List<String> to Dart's entrypoint function.
[in]isolate_configurationThe isolate configuration used to configure the isolate before invoking the entrypoint.
[in]root_isolate_create_callbackA callback called after the root isolate is created, without isolate scope. This gives the caller a chance to finish any setup before running the Dart program, and after any embedder callbacks in the settings object.
[in]isolate_create_callbackThe isolate create callback. This will be called when the before the main Dart entrypoint is invoked in the root isolate. The isolate is already in the running state at this point and an isolate scope is current.
[in]isolate_shutdown_callbackThe isolate shutdown callback. This will be called before the isolate is about to transition into the Shutdown phase. The isolate is still running at this point and an isolate scope is current.
[in]contextEngine-owned state which is accessed by the root dart isolate.
[in]spawning_isolateThe isolate that is spawning the new isolate.
Returns
A weak pointer to the root Dart isolate. The caller must ensure that the isolate is not referenced for long periods of time as it prevents isolate collection when the isolate terminates itself. The caller may also only use the isolate on the thread on which the isolate was created.

Definition at line 89 of file dart_isolate.cc.

102 {
103 if (!isolate_snapshot) {
104 FML_LOG(ERROR) << "Invalid isolate snapshot.";
105 return {};
106 }
107
108 if (!isolate_configuration) {
109 FML_LOG(ERROR) << "Invalid isolate configuration.";
110 return {};
111 }
112
113 isolate_flags.SetNullSafetyEnabled(
114 isolate_configuration->IsNullSafetyEnabled(*isolate_snapshot));
115 isolate_flags.SetIsDontNeedSafe(isolate_snapshot->IsDontNeedSafe());
116
117 auto isolate = CreateRootIsolate(settings, //
118 isolate_snapshot, //
119 std::move(platform_configuration), //
120 isolate_flags, //
121 isolate_create_callback, //
122 isolate_shutdown_callback, //
123 context, //
124 spawning_isolate //
125 )
126 .lock();
127
128 if (!isolate) {
129 FML_LOG(ERROR) << "Could not create root isolate.";
130 return {};
131 }
132
133 fml::ScopedCleanupClosure shutdown_on_error([isolate]() {
134 if (!isolate->Shutdown()) {
135 FML_DLOG(ERROR) << "Could not shutdown transient isolate.";
136 }
137 });
138
139 if (isolate->GetPhase() != DartIsolate::Phase::LibrariesSetup) {
140 FML_LOG(ERROR) << "Root isolate was created in an incorrect phase: "
141 << static_cast<int>(isolate->GetPhase());
142 return {};
143 }
144
145 if (!isolate_configuration->PrepareIsolate(*isolate.get())) {
146 FML_LOG(ERROR) << "Could not prepare isolate.";
147 return {};
148 }
149
150 if (isolate->GetPhase() != DartIsolate::Phase::Ready) {
151 FML_LOG(ERROR) << "Root isolate not in the ready phase for Dart entrypoint "
152 "invocation.";
153 return {};
154 }
155
156 if (settings.root_isolate_create_callback) {
157 // Isolate callbacks always occur in isolate scope and before user code has
158 // had a chance to run.
159 tonic::DartState::Scope scope(isolate.get());
160 settings.root_isolate_create_callback(*isolate.get());
161 }
162
163 if (root_isolate_create_callback) {
164 root_isolate_create_callback();
165 }
166
167 if (!isolate->RunFromLibrary(std::move(dart_entrypoint_library), //
168 std::move(dart_entrypoint), //
169 dart_entrypoint_args)) {
170 FML_LOG(ERROR) << "Could not run the run main Dart entrypoint.";
171 return {};
172 }
173
174 if (settings.root_isolate_shutdown_callback) {
175 isolate->AddIsolateShutdownCallback(
176 settings.root_isolate_shutdown_callback);
177 }
178
179 shutdown_on_error.Release();
180
181 return isolate;
182}
Wraps a closure that is invoked in the destructor unless released by the caller.
Definition closure.h:32

◆ GetIsolateGroupData() [1/2]

DartIsolateGroupData & flutter::DartIsolate::GetIsolateGroupData ( )

Definition at line 1027 of file dart_isolate.cc.

1027 {
1028 std::shared_ptr<DartIsolateGroupData>* isolate_group_data =
1029 static_cast<std::shared_ptr<DartIsolateGroupData>*>(
1031 return **isolate_group_data;
1032}

◆ GetIsolateGroupData() [2/2]

const DartIsolateGroupData & flutter::DartIsolate::GetIsolateGroupData ( ) const

Definition at line 1034 of file dart_isolate.cc.

1034 {
1035 DartIsolate* non_const_this = const_cast<DartIsolate*>(this);
1036 return non_const_this->GetIsolateGroupData();
1037}

◆ GetMessageHandlingTaskRunner()

fml::RefPtr< fml::TaskRunner > flutter::DartIsolate::GetMessageHandlingTaskRunner ( ) const

The task runner on which the Dart code for the root isolate is running. For the root isolate, this is the UI task runner for the shell that owns the root isolate.

Returns
The message handling task runner.

Definition at line 532 of file dart_isolate.cc.

532 {
533 return message_handling_task_runner_;
534}

◆ GetPhase()

DartIsolate::Phase flutter::DartIsolate::GetPhase ( ) const

The current phase of the isolate. The engine represents all dart isolates as being in one of the known phases. By invoking various methods on the Dart isolate, the engine transitions the Dart isolate from one phase to the next. The Dart isolate will only move from one phase to the next in the order specified in the DartIsolate::Phase enum. That is, the once the isolate has moved out of a particular phase, it can never transition back to that phase in the future. There is no error recovery mechanism and callers that find their isolates in an undesirable phase must discard the isolate and start over.

Returns
The current isolate phase.

Definition at line 476 of file dart_isolate.cc.

476 {
477 return phase_;
478}

◆ GetServiceId()

std::string flutter::DartIsolate::GetServiceId ( )

Returns the ID for an isolate which is used to query the service protocol.

Returns
The service identifier for this isolate.

Definition at line 480 of file dart_isolate.cc.

480 {
481 const char* service_id_buf = Dart_IsolateServiceId(isolate());
482 std::string service_id(service_id_buf);
483 free(const_cast<char*>(service_id_buf));
484 return service_id;
485}
DART_EXPORT const char * Dart_IsolateServiceId(Dart_Isolate isolate)

◆ GetWeakIsolatePtr()

std::weak_ptr< DartIsolate > flutter::DartIsolate::GetWeakIsolatePtr ( )

A weak pointer to the Dart isolate instance. This instance may only be used on the task runner that created the root isolate.

Returns
The weak isolate pointer.

Definition at line 1273 of file dart_isolate.cc.

1273 {
1274 return std::static_pointer_cast<DartIsolate>(shared_from_this());
1275}

◆ LoadLibraryFromKernel()

Dart_Handle flutter::DartIsolate::LoadLibraryFromKernel ( const std::shared_ptr< const fml::Mapping > &  mapping)
static

Returns the "main" entrypoint of the library contained in the kernel data in mapping.

Definition at line 1323 of file dart_isolate.cc.

1324 {
1326 return Dart_Null();
1327 }
1328
1329 auto* isolate_group_data =
1330 static_cast<std::shared_ptr<DartIsolateGroupData>*>(
1332 // Mapping must be retained until isolate shutdown.
1333 (*isolate_group_data)->AddKernelBuffer(mapping);
1334
1335 auto lib =
1336 Dart_LoadLibraryFromKernel(mapping->GetMapping(), mapping->GetSize());
1337 if (tonic::CheckAndHandleError(lib)) {
1338 return Dart_Null();
1339 }
1340 auto result = Dart_FinalizeLoading(false);
1341 if (Dart_IsError(result)) {
1342 return result;
1343 }
1344 return Dart_GetField(lib, Dart_NewStringFromCString("main"));
1345}
static bool IsRunningPrecompiledCode()
Checks if VM instances in the process can run precompiled code. This call can be made at any time and...
Definition dart_vm.cc:205
DART_EXPORT DART_WARN_UNUSED_RESULT Dart_Handle Dart_LoadLibraryFromKernel(const uint8_t *kernel_buffer, intptr_t kernel_buffer_size)
DART_EXPORT DART_WARN_UNUSED_RESULT Dart_Handle Dart_FinalizeLoading(bool complete_futures)
DART_EXPORT Dart_Handle Dart_Null(void)
DART_EXPORT Dart_Handle Dart_NewStringFromCString(const char *str)
DART_EXPORT DART_WARN_UNUSED_RESULT Dart_Handle Dart_GetField(Dart_Handle container, Dart_Handle name)
DART_EXPORT bool Dart_IsError(Dart_Handle handle)
DART_EXPORT void * Dart_CurrentIsolateGroupData(void)

◆ LoadLoadingUnit()

bool flutter::DartIsolate::LoadLoadingUnit ( intptr_t  loading_unit_id,
std::unique_ptr< const fml::Mapping snapshot_data,
std::unique_ptr< const fml::Mapping snapshot_instructions 
)

Definition at line 536 of file dart_isolate.cc.

539 {
540 tonic::DartState::Scope scope(this);
541
542 fml::RefPtr<DartSnapshot> dart_snapshot =
544 std::move(snapshot_data), std::move(snapshot_instructions));
545
547 loading_unit_id, dart_snapshot->GetDataMapping(),
548 dart_snapshot->GetInstructionsMapping());
550 LoadLoadingUnitError(loading_unit_id, Dart_GetError(result),
551 /*transient*/ true);
552 return false;
553 }
554 loading_unit_snapshots_.insert(dart_snapshot);
555 return true;
556}
void LoadLoadingUnitError(intptr_t loading_unit_id, const std::string &error_message, bool transient)
static fml::RefPtr< DartSnapshot > IsolateSnapshotFromMappings(const std::shared_ptr< const fml::Mapping > &snapshot_data, const std::shared_ptr< const fml::Mapping > &snapshot_instructions)
Create an isolate snapshot from existing fml::Mappings.
DART_EXPORT DART_WARN_UNUSED_RESULT Dart_Handle Dart_DeferredLoadComplete(intptr_t loading_unit_id, const uint8_t *snapshot_data, const uint8_t *snapshot_instructions)
DART_EXPORT const char * Dart_GetError(Dart_Handle handle)

◆ LoadLoadingUnitError()

void flutter::DartIsolate::LoadLoadingUnitError ( intptr_t  loading_unit_id,
const std::string &  error_message,
bool  transient 
)

Definition at line 558 of file dart_isolate.cc.

560 {
561 tonic::DartState::Scope scope(this);
563 loading_unit_id, error_message.c_str(), transient);
565}
DART_EXPORT DART_WARN_UNUSED_RESULT Dart_Handle Dart_DeferredLoadCompleteError(intptr_t loading_unit_id, const char *error_message, bool transient)

◆ PrepareForRunningFromKernel()

bool flutter::DartIsolate::PrepareForRunningFromKernel ( const std::shared_ptr< const fml::Mapping > &  kernel,
bool  child_isolate,
bool  last_piece 
)

Prepare the isolate for running for a a list of kernel files.

        The Dart VM must be configured for running from kernel
        snapshots.

        The isolate must already be in the `Phase::LibrariesSetup`
        phase. This call can be made multiple times. After a series of
        successful calls to this method, the caller can specify the
        last kernel file mapping by specifying `last_piece` to `true`.
        On success, the isolate will transition to the `Phase::Ready`
        phase.
Parameters
[in]kernelThe kernel mapping.
[in]last_pieceIndicates if this is the last kernel mapping expected. After this point, the isolate will attempt a transition to the Phase::Ready phase.
Returns
If the kernel mapping supplied was successfully used to prepare the isolate.

Definition at line 730 of file dart_isolate.cc.

733 {
734 TRACE_EVENT0("flutter", "DartIsolate::PrepareForRunningFromKernel");
735 if (phase_ != Phase::LibrariesSetup) {
736 return false;
737 }
738
740 return false;
741 }
742
743 tonic::DartState::Scope scope(this);
744
745 if (!child_isolate && !is_spawning_in_group_) {
746 if (!mapping || mapping->GetSize() == 0) {
747 return false;
748 }
749
750 // Use root library provided by kernel in favor of one provided by snapshot.
752
753 if (!LoadKernel(mapping, last_piece)) {
754 return false;
755 }
756 }
757
758 if (!last_piece) {
759 // More to come.
760 return true;
761 }
762
764 return false;
765 }
766
767 if (!MarkIsolateRunnable()) {
768 return false;
769 }
770
771 // Child isolate shares root isolate embedder_isolate (lines 691 and 693
772 // below). Re-initializing child_isolate_preparer_ lambda while it is being
773 // executed leads to crashes.
774 if (GetIsolateGroupData().GetChildIsolatePreparer() == nullptr) {
776 [buffers =
777 GetIsolateGroupData().GetKernelBuffers()](DartIsolate* isolate) {
778 for (uint64_t i = 0; i < buffers.size(); i++) {
779 bool last_piece = i + 1 == buffers.size();
780 const std::shared_ptr<const fml::Mapping>& buffer = buffers.at(i);
781 if (!isolate->PrepareForRunningFromKernel(buffer,
782 /*child_isolate=*/true,
783 last_piece)) {
784 return false;
785 }
786 }
787 return true;
788 });
789 }
790
791 const fml::closure& isolate_create_callback =
793 if (isolate_create_callback) {
794 isolate_create_callback();
795 }
796
797 phase_ = Phase::Ready;
798
799 return true;
800}
void SetChildIsolatePreparer(const ChildIsolatePreparer &value)
const fml::closure & GetIsolateCreateCallback() const
DartIsolateGroupData & GetIsolateGroupData()
DART_EXPORT bool Dart_IsNull(Dart_Handle object)
DART_EXPORT Dart_Handle Dart_RootLibrary(void)
DART_EXPORT Dart_Handle Dart_SetRootLibrary(Dart_Handle library)
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot The VM snapshot data that will be memory mapped as read only SnapshotAssetPath must be present isolate snapshot The isolate snapshot data that will be memory mapped as read only SnapshotAssetPath must be present cache dir Path to the cache directory This is different from the persistent_cache_path in embedder which is used for Skia shader cache icu native lib Path to the library file that exports the ICU data vm service The hostname IP address on which the Dart VM Service should be served If not defaults to or::depending on whether ipv6 is specified vm service A custom Dart VM Service port The default is to pick a randomly available open port disable vm Disable the Dart VM Service The Dart VM Service is never available in release mode disable vm service Disable mDNS Dart VM Service publication Bind to the IPv6 localhost address for the Dart VM Service Ignored if vm service host is set endless trace buffer
Definition switches.h:126
#define TRACE_EVENT0(category_group, name)

◆ PrepareForRunningFromKernels() [1/2]

bool flutter::DartIsolate::PrepareForRunningFromKernels ( std::vector< std::shared_ptr< const fml::Mapping > >  kernels)

Prepare the isolate for running for a a list of kernel files.

        The Dart VM must be configured for running from kernel
        snapshots.

        The isolate must already be in the `Phase::LibrariesSetup`
        phase. After a successful call to this method, the isolate
        will transition to the `Phase::Ready` phase.
Parameters
[in]kernelsThe kernels
Returns
If the kernel mappings supplied were successfully used to prepare the isolate.

Definition at line 802 of file dart_isolate.cc.

803 {
804 const auto count = kernels.size();
805 if (count == 0) {
806 return false;
807 }
808
809 for (size_t i = 0; i < count; ++i) {
810 bool last = (i == (count - 1));
811 if (!PrepareForRunningFromKernel(kernels[i], /*child_isolate=*/false,
812 last)) {
813 return false;
814 }
815 }
816
817 return true;
818}
int count
bool PrepareForRunningFromKernel(const std::shared_ptr< const fml::Mapping > &kernel, bool child_isolate, bool last_piece)
Prepare the isolate for running for a a list of kernel files.

◆ PrepareForRunningFromKernels() [2/2]

bool flutter::DartIsolate::PrepareForRunningFromKernels ( std::vector< std::unique_ptr< const fml::Mapping > >  kernels)

Prepare the isolate for running for a a list of kernel files.

        The Dart VM must be configured for running from kernel
        snapshots.

        The isolate must already be in the `Phase::LibrariesSetup`
        phase. After a successful call to this method, the isolate
        will transition to the `Phase::Ready` phase.
Parameters
[in]kernelsThe kernels
Returns
If the kernel mappings supplied were successfully used to prepare the isolate.

Definition at line 820 of file dart_isolate.cc.

821 {
822 std::vector<std::shared_ptr<const fml::Mapping>> shared_kernels;
823 shared_kernels.reserve(kernels.size());
824 for (auto& kernel : kernels) {
825 shared_kernels.emplace_back(std::move(kernel));
826 }
827 return PrepareForRunningFromKernels(shared_kernels);
828}
bool PrepareForRunningFromKernels(std::vector< std::shared_ptr< const fml::Mapping > > kernels)
Prepare the isolate for running for a a list of kernel files.

◆ PrepareForRunningFromPrecompiledCode()

bool flutter::DartIsolate::PrepareForRunningFromPrecompiledCode ( )

Prepare the isolate for running for a precompiled code bundle. The Dart VM must be configured for running precompiled code.

The isolate must already be in the Phase::LibrariesSetup phase. After a successful call to this method, the isolate will transition to the Phase::Ready phase.

Returns
Whether the isolate was prepared and the described phase transition made.

Definition at line 671 of file dart_isolate.cc.

671 {
672 TRACE_EVENT0("flutter", "DartIsolate::PrepareForRunningFromPrecompiledCode");
673 if (phase_ != Phase::LibrariesSetup) {
674 return false;
675 }
676
677 tonic::DartState::Scope scope(this);
678
680 return false;
681 }
682
683 if (!MarkIsolateRunnable()) {
684 return false;
685 }
686
687 if (GetIsolateGroupData().GetChildIsolatePreparer() == nullptr) {
689 return isolate->PrepareForRunningFromPrecompiledCode();
690 });
691 }
692
693 const fml::closure& isolate_create_callback =
695 if (isolate_create_callback) {
696 isolate_create_callback();
697 }
698
699 phase_ = Phase::Ready;
700 return true;
701}

◆ RunFromLibrary()

bool flutter::DartIsolate::RunFromLibrary ( std::optional< std::string >  library_name,
std::optional< std::string >  entrypoint,
const std::vector< std::string > &  args 
)

Transition the root isolate to the Phase::Running phase and invoke the main entrypoint (the "main" method) in the specified library. The isolate must already be in the Phase::Ready phase.

Parameters
[in]library_nameThe name of the library in which to invoke the supplied entrypoint.
[in]entrypointThe entrypoint in library_name
[in]argsA list of string arguments to the entrypoint.
Returns
If the isolate successfully transitioned to the running phase and the main entrypoint was invoked.

Definition at line 884 of file dart_isolate.cc.

886 {
887 TRACE_EVENT0("flutter", "DartIsolate::RunFromLibrary");
888 if (phase_ != Phase::Ready) {
889 return false;
890 }
891
892 tonic::DartState::Scope scope(this);
893
894 auto library_handle =
895 library_name.has_value() && !library_name.value().empty()
896 ? ::Dart_LookupLibrary(tonic::ToDart(library_name.value().c_str()))
897 : ::Dart_RootLibrary();
898 auto entrypoint_handle = entrypoint.has_value() && !entrypoint.value().empty()
899 ? tonic::ToDart(entrypoint.value().c_str())
900 : tonic::ToDart("main");
901
903 // TODO(gaaclarke): Remove once the framework PR lands that uses `--source`
904 // to compile the Dart Plugin Registrant
905 // (https://github.com/flutter/flutter/pull/100572).
907 }
908
909 auto user_entrypoint_function =
910 ::Dart_GetField(library_handle, entrypoint_handle);
911
912 auto entrypoint_args = tonic::ToDart(args);
913
914 if (!InvokeMainEntrypoint(user_entrypoint_function, entrypoint_args)) {
915 return false;
916 }
917
918 phase_ = Phase::Running;
919
920 return true;
921}
G_BEGIN_DECLS G_MODULE_EXPORT FlValue * args
bool InvokeDartPluginRegistrantIfAvailable(Dart_Handle library_handle)
bool FindAndInvokeDartPluginRegistrant()
static bool InvokeMainEntrypoint(Dart_Handle user_entrypoint_function, Dart_Handle args)

◆ Shutdown()

bool flutter::DartIsolate::Shutdown ( )

Transition the isolate to the Phase::Shutdown phase. The only thing left to do is to collect the isolate.

Returns
If the isolate successfully transitioned to the shutdown phase.

Definition at line 923 of file dart_isolate.cc.

923 {
924 TRACE_EVENT0("flutter", "DartIsolate::Shutdown");
925 // This call may be re-entrant since Dart_ShutdownIsolate can invoke the
926 // cleanup callback which deletes the embedder side object of the dart isolate
927 // (a.k.a. this).
928 if (phase_ == Phase::Shutdown) {
929 return false;
930 }
931 phase_ = Phase::Shutdown;
932 Dart_Isolate vm_isolate = isolate();
933 // The isolate can be nullptr if this instance is the stub isolate data used
934 // during root isolate creation.
935 if (vm_isolate != nullptr) {
936 // We need to enter the isolate because Dart_ShutdownIsolate does not take
937 // the isolate to shutdown as a parameter.
938 FML_DCHECK(Dart_CurrentIsolate() == nullptr);
939 Dart_EnterIsolate(vm_isolate);
941 FML_DCHECK(Dart_CurrentIsolate() == nullptr);
942 }
943 return true;
944}
DART_EXPORT Dart_Isolate Dart_CurrentIsolate(void)

Friends And Related Symbol Documentation

◆ DartVM

friend class DartVM
friend

Definition at line 431 of file dart_isolate.h.

◆ IsolateConfiguration

friend class IsolateConfiguration
friend

Definition at line 420 of file dart_isolate.h.


The documentation for this class was generated from the following files: