Flutter Engine
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  Phase {
  Phase::Unknown,
  Phase::Uninitialized,
  Phase::Initialized,
  Phase::LibrariesSetup,
  Phase::Ready,
  Phase::Running,
  Phase::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

std::weak_ptr< DartIsolateSpawnIsolate (const Settings &settings, std::unique_ptr< PlatformConfiguration > platform_configuration, fml::WeakPtr< SnapshotDelegate > snapshot_delegate, std::string advisory_script_uri, std::string advisory_script_entrypoint, Flags flags, 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, std::unique_ptr< IsolateConfiguration > isolate_configration) const
 Creates a running DartIsolate who shares as many resources as possible with the caller DartIsolate. This allows them to occupy less memory together and to be created faster. More...
 
 ~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. More...
 
std::string GetServiceId ()
 Returns the ID for an isolate which is used to query the service protocol. More...
 
bool PrepareForRunningFromPrecompiledCode ()
 Prepare the isolate for running for a precompiled code bundle. The Dart VM must be configured for running precompiled code. More...
 
bool PrepareForRunningFromKernel (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. More...
 
bool PrepareForRunningFromKernels (std::vector< std::shared_ptr< const fml::Mapping >> kernels)
 Prepare the isolate for running for a a list of kernel files. More...
 
bool PrepareForRunningFromKernels (std::vector< std::unique_ptr< const fml::Mapping >> kernels)
 Prepare the isolate for running for a a list of kernel files. More...
 
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. More...
 
bool Shutdown ()
 Transition the isolate to the Phase::Shutdown phase. The only thing left to do is to collect the isolate. More...
 
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. More...
 
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. More...
 
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. More...
 
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)
 
- 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
 
const TaskRunnersGetTaskRunners () const
 
void ScheduleMicrotask (Dart_Handle handle)
 
void FlushMicrotasksNow ()
 
fml::WeakPtr< IOManagerGetIOManager () const
 
fml::RefPtr< flutter::SkiaUnrefQueueGetSkiaUnrefQueue () const
 
std::shared_ptr< VolatilePathTrackerGetVolatilePathTracker () const
 
fml::WeakPtr< SnapshotDelegateGetSnapshotDelegate () const
 
fml::WeakPtr< GrDirectContext > GetResourceContext () const
 
fml::WeakPtr< ImageDecoderGetImageDecoder () const
 
fml::WeakPtr< ImageGeneratorRegistryGetImageGeneratorRegistry () const
 
std::shared_ptr< IsolateNameServerGetIsolateNameServer () const
 
tonic::DartErrorHandleType GetLastError ()
 
void ReportUnhandledException (const std::string &error, const std::string &stack_trace)
 
void LogMessage (const std::string &tag, const std::string &message) const
 
bool enable_skparagraph () const
 
bool enable_display_list () const
 
- 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, fml::RefPtr< const DartSnapshot > isolate_snapshot, std::unique_ptr< PlatformConfiguration > platform_configuration, Flags flags, 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, std::unique_ptr< IsolateConfiguration > isolate_configration, 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. More...
 
- Static Public Member Functions inherited from flutter::UIDartState
static UIDartStateCurrent ()
 
static void ThrowIfUIOperationsProhibited ()
 
template<class T >
static flutter::SkiaGPUObject< T > CreateGPUObject (sk_sp< T > object)
 
- 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_, bool enable_skparagraph, bool enable_display_list, const UIDartState::Context &context)
 
 ~UIDartState () override
 
void SetPlatformConfiguration (std::unique_ptr< PlatformConfiguration > platform_configuration)
 
const std::string & GetAdvisoryScriptURI () const
 
const std::string & GetAdvisoryScriptEntrypoint () 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:

  • 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.

Definition at line 62 of file dart_isolate.h.

Member Enumeration Documentation

◆ Phase

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 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 92 of file dart_isolate.h.

92  {
93  //--------------------------------------------------------------------------
94  /// The initial phase of all Dart isolates. This is an internal phase and
95  /// callers can never get a reference to a Dart isolate in this phase.
96  ///
97  Unknown,
98  //--------------------------------------------------------------------------
99  /// The Dart isolate has been created but none of the library tag or message
100  /// handers have been set yet. The is an internal phase and callers can
101  /// never get a reference to a Dart isolate in this phase.
102  ///
103  Uninitialized,
104  //--------------------------------------------------------------------------
105  /// The Dart isolate has been been fully initialized but none of the
106  /// libraries referenced by that isolate have been loaded yet. This is an
107  /// internal phase and callers can never get a reference to a Dart isolate
108  /// in this phase.
109  ///
110  Initialized,
111  //--------------------------------------------------------------------------
112  /// The isolate has been fully initialized and is waiting for the caller to
113  /// associate isolate snapshots with the same. The isolate will only be
114  /// ready to execute Dart code once one of the `Prepare` calls are
115  /// successfully made.
116  ///
117  LibrariesSetup,
118  //--------------------------------------------------------------------------
119  /// The isolate is fully ready to start running Dart code. Callers can
120  /// transition the isolate to the next state by calling the `Run` or
121  /// `RunFromLibrary` methods.
122  ///
123  Ready,
124  //--------------------------------------------------------------------------
125  /// The isolate is currently running Dart code.
126  ///
127  Running,
128  //--------------------------------------------------------------------------
129  /// The isolate is no longer running Dart code and is in the middle of being
130  /// collected. This is in internal phase and callers can never get a
131  /// reference to a Dart isolate in this phase.
132  ///
133  Shutdown,
134  };
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 328 of file dart_isolate.cc.

References FML_DCHECK, GetMessageHandlingTaskRunner(), and flutter::UIDartState::IsRootIsolate().

328  {
330  FML_DCHECK(GetMessageHandlingTaskRunner()->RunsTasksOnCurrentThread());
331  }
332 }
#define FML_DCHECK(condition)
Definition: logging.h:86
bool IsRootIsolate() const
Definition: ui_dart_state.h:96
fml::RefPtr< fml::TaskRunner > GetMessageHandlingTaskRunner() const
The task runner on which the Dart code for the root isolate is running. For the root isolate...

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 1130 of file dart_isolate.cc.

References flutter::PlatformConfiguration::client(), flutter::UIDartState::Current(), tonic::DartState::Current(), FML_LOG, flutter::UIDartState::platform_configuration(), flutter::PlatformConfigurationClient::RequestDartDeferredLibrary(), tonic::DartState::SetIsShuttingDown(), and state.

1130  {
1131  shutdown_callbacks_.emplace_back(std::make_unique<AutoFireClosure>(closure));
1132 }
std::function< void()> closure
Definition: closure.h:14

◆ CreateRunningRootIsolate()

std::weak_ptr< DartIsolate > flutter::DartIsolate::CreateRunningRootIsolate ( const Settings settings,
fml::RefPtr< const DartSnapshot isolate_snapshot,
std::unique_ptr< PlatformConfiguration platform_configuration,
Flags  flags,
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,
std::unique_ptr< IsolateConfiguration isolate_configration,
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]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. See also DartIsolate::SpawnIsolate.
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 117 of file dart_isolate.cc.

References flutter::UIDartState::Context::advisory_script_entrypoint, flutter::UIDartState::Context::advisory_script_uri, flutter::Settings::dart_entrypoint_args, flutter::Settings::domain_network_policy, flutter::Settings::enable_display_list, flutter::Settings::enable_skparagraph, error, flutter::flags, FML_DLOG, FML_LOG, flutter::DartIsolate::Flags::Get(), flutter::DartVMRef::GetIsolateNameServer(), tonic::DartState::isolate(), flutter::DartVM::IsRunningPrecompiledCode(), LibrariesSetup, flutter::Settings::log_message_callback, flutter::Settings::log_tag, flutter::Settings::may_insecurely_connect_to_all_domains, flutter::UIDartState::platform_configuration(), Ready, flutter::Settings::root_isolate_create_callback, flutter::Settings::root_isolate_shutdown_callback, flutter::DartIsolate::Flags::SetNullSafetyEnabled(), flutter::Settings::task_observer_add, flutter::Settings::task_observer_remove, TRACE_EVENT0, flutter::UIDartState::UIDartState(), flutter::Settings::unhandled_exception_callback, and Uninitialized.

Referenced by flutter::testing::CreateAndRunRootIsolate(), flutter::RuntimeController::LaunchRootIsolate(), flutter::testing::RunDartCodeInIsolateOnUITaskRunner(), SpawnIsolate(), and flutter::testing::TEST_F().

129  {
130  if (!isolate_snapshot) {
131  FML_LOG(ERROR) << "Invalid isolate snapshot.";
132  return {};
133  }
134 
135  if (!isolate_configration) {
136  FML_LOG(ERROR) << "Invalid isolate configuration.";
137  return {};
138  }
139 
140  isolate_flags.SetNullSafetyEnabled(
141  isolate_configration->IsNullSafetyEnabled(*isolate_snapshot));
142 
143  auto isolate = CreateRootIsolate(settings, //
144  isolate_snapshot, //
145  std::move(platform_configuration), //
146  isolate_flags, //
147  isolate_create_callback, //
148  isolate_shutdown_callback, //
149  context, //
150  spawning_isolate //
151  )
152  .lock();
153 
154  if (!isolate) {
155  FML_LOG(ERROR) << "Could not create root isolate.";
156  return {};
157  }
158 
159  fml::ScopedCleanupClosure shutdown_on_error([isolate]() {
160  if (!isolate->Shutdown()) {
161  FML_DLOG(ERROR) << "Could not shutdown transient isolate.";
162  }
163  });
164 
165  if (isolate->GetPhase() != DartIsolate::Phase::LibrariesSetup) {
166  FML_LOG(ERROR) << "Root isolate was created in an incorrect phase: "
167  << static_cast<int>(isolate->GetPhase());
168  return {};
169  }
170 
171  if (!isolate_configration->PrepareIsolate(*isolate.get())) {
172  FML_LOG(ERROR) << "Could not prepare isolate.";
173  return {};
174  }
175 
176  if (isolate->GetPhase() != DartIsolate::Phase::Ready) {
177  FML_LOG(ERROR) << "Root isolate not in the ready phase for Dart entrypoint "
178  "invocation.";
179  return {};
180  }
181 
182  if (settings.root_isolate_create_callback) {
183  // Isolate callbacks always occur in isolate scope and before user code has
184  // had a chance to run.
185  tonic::DartState::Scope scope(isolate.get());
186  settings.root_isolate_create_callback(*isolate.get());
187  }
188 
189  if (root_isolate_create_callback) {
190  root_isolate_create_callback();
191  }
192 
193  if (!isolate->RunFromLibrary(dart_entrypoint_library, //
194  dart_entrypoint, //
195  settings.dart_entrypoint_args //
196  )) {
197  FML_LOG(ERROR) << "Could not run the run main Dart entrypoint.";
198  return {};
199  }
200 
201  if (settings.root_isolate_shutdown_callback) {
202  isolate->AddIsolateShutdownCallback(
203  settings.root_isolate_shutdown_callback);
204  }
205 
206  shutdown_on_error.Release();
207 
208  return isolate;
209 }
Dart_Isolate isolate()
Definition: dart_state.h:50
#define FML_LOG(severity)
Definition: logging.h:65
Wraps a closure that is invoked in the destructor unless released by the caller.
Definition: closure.h:32
PlatformConfiguration * platform_configuration() const
#define FML_DLOG(severity)
Definition: logging.h:85

◆ 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 397 of file dart_isolate.cc.

Referenced by ~DartIsolate().

397  {
398  return message_handling_task_runner_;
399 }

◆ 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 334 of file dart_isolate.cc.

Referenced by flutter::IsolateConfiguration::PrepareIsolate().

334  {
335  return phase_;
336 }

◆ 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 338 of file dart_isolate.cc.

References flutter::UIDartState::GetTaskRunners(), tonic::DartState::HandleLibraryTag(), Initialized, tonic::DartState::isolate(), flutter::UIDartState::IsRootIsolate(), tonic::LogIfError(), tonic::DartState::SetIsolate(), TRACE_EVENT0, and Uninitialized.

338  {
339  const char* service_id_buf = Dart_IsolateServiceId(isolate());
340  std::string service_id(service_id_buf);
341  free(const_cast<char*>(service_id_buf));
342  return service_id;
343 }
Dart_Isolate isolate()
Definition: dart_state.h:50

◆ 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 1126 of file dart_isolate.cc.

1126  {
1127  return std::static_pointer_cast<DartIsolate>(shared_from_this());
1128 }

◆ 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 401 of file dart_isolate.cc.

References flutter::DartSnapshot::IsolateSnapshotFromMappings(), LoadLoadingUnitError(), tonic::LogIfError(), and result.

404  {
405  tonic::DartState::Scope scope(this);
406 
407  fml::RefPtr<DartSnapshot> dart_snapshot =
409  std::move(snapshot_data), std::move(snapshot_instructions));
410 
411  Dart_Handle result = Dart_DeferredLoadComplete(
412  loading_unit_id, dart_snapshot->GetDataMapping(),
413  dart_snapshot->GetInstructionsMapping());
414  if (tonic::LogIfError(result)) {
415  LoadLoadingUnitError(loading_unit_id, Dart_GetError(result),
416  /*transient*/ true);
417  return false;
418  }
419  loading_unit_snapshots_.insert(dart_snapshot);
420  return true;
421 }
GAsyncResult * result
bool LogIfError(Dart_Handle handle)
Definition: dart_error.cc:15
static fml::RefPtr< DartSnapshot > IsolateSnapshotFromMappings(std::shared_ptr< const fml::Mapping > snapshot_data, std::shared_ptr< const fml::Mapping > snapshot_instructions)
Create an isolate snapshot from existing fml::Mappings.
void LoadLoadingUnitError(intptr_t loading_unit_id, const std::string error_message, bool transient)

◆ LoadLoadingUnitError()

◆ PrepareForRunningFromKernel()

bool flutter::DartIsolate::PrepareForRunningFromKernel ( 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 584 of file dart_isolate.cc.

References buffer, tonic::DartState::isolate(), flutter::DartVM::IsRunningPrecompiledCode(), LibrariesSetup, PrepareForRunningFromKernel(), Ready, and TRACE_EVENT0.

Referenced by flutter::KernelIsolateConfiguration::DoPrepareIsolate(), flutter::KernelListIsolateConfiguration::DoPrepareIsolate(), PrepareForRunningFromKernel(), and PrepareForRunningFromKernels().

587  {
588  TRACE_EVENT0("flutter", "DartIsolate::PrepareForRunningFromKernel");
589  if (phase_ != Phase::LibrariesSetup) {
590  return false;
591  }
592 
594  return false;
595  }
596 
597  if (!mapping || mapping->GetSize() == 0) {
598  return false;
599  }
600 
601  tonic::DartState::Scope scope(this);
602 
603  if (!child_isolate || !Dart_IsVMFlagSet("--enable-isolate-groups")) {
604  // Use root library provided by kernel in favor of one provided by snapshot.
605  Dart_SetRootLibrary(Dart_Null());
606 
607  if (!LoadKernel(mapping, last_piece)) {
608  return false;
609  }
610  }
611 
612  if (!last_piece) {
613  // More to come.
614  return true;
615  }
616 
617  if (Dart_IsNull(Dart_RootLibrary())) {
618  return false;
619  }
620 
621  if (!MarkIsolateRunnable()) {
622  return false;
623  }
624 
625  // Child isolate shares root isolate embedder_isolate (lines 691 and 693
626  // below). Re-initializing child_isolate_preparer_ lambda while it is being
627  // executed leads to crashes.
628  if (GetIsolateGroupData().GetChildIsolatePreparer() == nullptr) {
629  GetIsolateGroupData().SetChildIsolatePreparer(
630  [buffers = kernel_buffers_](DartIsolate* isolate) {
631  for (uint64_t i = 0; i < buffers.size(); i++) {
632  bool last_piece = i + 1 == buffers.size();
633  const std::shared_ptr<const fml::Mapping>& buffer = buffers.at(i);
634  if (!isolate->PrepareForRunningFromKernel(buffer,
635  /*child_isolate=*/true,
636  last_piece)) {
637  return false;
638  }
639  }
640  return true;
641  });
642  }
643 
644  const fml::closure& isolate_create_callback =
645  GetIsolateGroupData().GetIsolateCreateCallback();
646  if (isolate_create_callback) {
647  isolate_create_callback();
648  }
649 
650  phase_ = Phase::Ready;
651 
652  return true;
653 }
void SetChildIsolatePreparer(const ChildIsolatePreparer &value)
Dart_Isolate isolate()
Definition: dart_state.h:50
#define TRACE_EVENT0(category_group, name)
Definition: trace_event.h:90
std::function< void()> closure
Definition: closure.h:14
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:202
const fml::closure & GetIsolateCreateCallback() const
static const uint8_t buffer[]

◆ 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 655 of file dart_isolate.cc.

References PrepareForRunningFromKernel().

Referenced by PrepareForRunningFromKernels().

656  {
657  const auto count = kernels.size();
658  if (count == 0) {
659  return false;
660  }
661 
662  for (size_t i = 0; i < count; ++i) {
663  bool last = (i == (count - 1));
664  if (!PrepareForRunningFromKernel(kernels[i], /*child_isolate=*/false,
665  last)) {
666  return false;
667  }
668  }
669 
670  return true;
671 }
bool PrepareForRunningFromKernel(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 673 of file dart_isolate.cc.

References error, FML_DLOG, tonic::DartState::isolate(), LibrariesSetup, PrepareForRunningFromKernels(), and TRACE_EVENT0.

674  {
675  std::vector<std::shared_ptr<const fml::Mapping>> shared_kernels;
676  for (auto& kernel : kernels) {
677  shared_kernels.emplace_back(std::move(kernel));
678  }
679  return PrepareForRunningFromKernels(shared_kernels);
680 }
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 525 of file dart_isolate.cc.

References tonic::DartState::isolate(), LibrariesSetup, tonic::LogIfError(), PrepareForRunningFromPrecompiledCode(), Ready, and TRACE_EVENT0.

Referenced by flutter::AppSnapshotIsolateConfiguration::DoPrepareIsolate(), and PrepareForRunningFromPrecompiledCode().

525  {
526  TRACE_EVENT0("flutter", "DartIsolate::PrepareForRunningFromPrecompiledCode");
527  if (phase_ != Phase::LibrariesSetup) {
528  return false;
529  }
530 
531  tonic::DartState::Scope scope(this);
532 
533  if (Dart_IsNull(Dart_RootLibrary())) {
534  return false;
535  }
536 
537  if (!MarkIsolateRunnable()) {
538  return false;
539  }
540 
541  if (GetIsolateGroupData().GetChildIsolatePreparer() == nullptr) {
542  GetIsolateGroupData().SetChildIsolatePreparer([](DartIsolate* isolate) {
543  return isolate->PrepareForRunningFromPrecompiledCode();
544  });
545  }
546 
547  const fml::closure& isolate_create_callback =
548  GetIsolateGroupData().GetIsolateCreateCallback();
549  if (isolate_create_callback) {
550  isolate_create_callback();
551  }
552 
553  phase_ = Phase::Ready;
554  return true;
555 }
void SetChildIsolatePreparer(const ChildIsolatePreparer &value)
Dart_Isolate isolate()
Definition: dart_state.h:50
#define TRACE_EVENT0(category_group, name)
Definition: trace_event.h:90
std::function< void()> closure
Definition: closure.h:14
const fml::closure & GetIsolateCreateCallback() const

◆ 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 758 of file dart_isolate.cc.

References flutter::InvokeDartPluginRegistrantIfAvailable(), flutter::InvokeMainEntrypoint(), Ready, Running, tonic::ToDart(), and TRACE_EVENT0.

760  {
761  TRACE_EVENT0("flutter", "DartIsolate::RunFromLibrary");
762  if (phase_ != Phase::Ready) {
763  return false;
764  }
765 
766  tonic::DartState::Scope scope(this);
767 
768  auto library_handle =
769  library_name.has_value() && !library_name.value().empty()
770  ? ::Dart_LookupLibrary(tonic::ToDart(library_name.value().c_str()))
771  : ::Dart_RootLibrary();
772  auto entrypoint_handle = entrypoint.has_value() && !entrypoint.value().empty()
773  ? tonic::ToDart(entrypoint.value().c_str())
774  : tonic::ToDart("main");
775 
777 
778  auto user_entrypoint_function =
779  ::Dart_GetField(library_handle, entrypoint_handle);
780 
781  auto entrypoint_args = tonic::ToDart(args);
782 
783  if (!InvokeMainEntrypoint(user_entrypoint_function, entrypoint_args)) {
784  return false;
785  }
786 
787  phase_ = Phase::Running;
788 
789  return true;
790 }
G_BEGIN_DECLS FlValue * args
#define TRACE_EVENT0(category_group, name)
Definition: trace_event.h:90
static void InvokeDartPluginRegistrantIfAvailable(Dart_Handle library_handle)
static bool InvokeMainEntrypoint(Dart_Handle user_entrypoint_function, Dart_Handle args)
Dart_Handle ToDart(const T &object)

◆ 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 792 of file dart_isolate.cc.

References flutter::UIDartState::Context::advisory_script_entrypoint, flutter::UIDartState::Context::advisory_script_uri, callback, flutter::Settings::disable_service_auth_codes, flutter::Settings::enable_observatory, flutter::Settings::enable_service_port_fallback, error, flutter::flags, FML_DCHECK, FML_DLOG, FML_LOG, flutter::DartIsolateGroupData::GetChildIsolatePreparer(), flutter::DartIsolateGroupData::GetIsolateCreateCallback(), flutter::DartIsolateGroupData::GetIsolateShutdownCallback(), flutter::DartIsolateGroupData::GetIsolateSnapshot(), flutter::DartVMRef::GetServiceProtocol(), flutter::DartIsolateGroupData::GetSettings(), flutter::DartVMRef::GetVMData(), tonic::DartState::HandleLibraryTag(), tonic::DartState::isolate(), flutter::Settings::observatory_host, flutter::Settings::observatory_port, Shutdown, flutter::DartServiceIsolate::Startup(), fml::strdup(), and TRACE_EVENT0.

792  {
793  TRACE_EVENT0("flutter", "DartIsolate::Shutdown");
794  // This call may be re-entrant since Dart_ShutdownIsolate can invoke the
795  // cleanup callback which deletes the embedder side object of the dart isolate
796  // (a.k.a. this).
797  if (phase_ == Phase::Shutdown) {
798  return false;
799  }
800  phase_ = Phase::Shutdown;
801  Dart_Isolate vm_isolate = isolate();
802  // The isolate can be nullptr if this instance is the stub isolate data used
803  // during root isolate creation.
804  if (vm_isolate != nullptr) {
805  // We need to enter the isolate because Dart_ShutdownIsolate does not take
806  // the isolate to shutdown as a parameter.
807  FML_DCHECK(Dart_CurrentIsolate() == nullptr);
808  Dart_EnterIsolate(vm_isolate);
809  Dart_ShutdownIsolate();
810  FML_DCHECK(Dart_CurrentIsolate() == nullptr);
811  }
812  return true;
813 }
Dart_Isolate isolate()
Definition: dart_state.h:50
#define TRACE_EVENT0(category_group, name)
Definition: trace_event.h:90
#define FML_DCHECK(condition)
Definition: logging.h:86

◆ SpawnIsolate()

std::weak_ptr< DartIsolate > flutter::DartIsolate::SpawnIsolate ( const Settings settings,
std::unique_ptr< PlatformConfiguration platform_configuration,
fml::WeakPtr< SnapshotDelegate snapshot_delegate,
std::string  advisory_script_uri,
std::string  advisory_script_entrypoint,
Flags  flags,
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,
std::unique_ptr< IsolateConfiguration isolate_configration 
) const

Creates a running DartIsolate who shares as many resources as possible with the caller DartIsolate. This allows them to occupy less memory together and to be created faster.

Shared components will be destroyed when the last live DartIsolate is destroyed. SpawnIsolate can only be used to create DartIsolates whose executable code is shared with the calling DartIsolate.

Attention
Only certain setups can take advantage of the most savings currently, AOT specifically.
Returns
A weak pointer to a new running DartIsolate. 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 81 of file dart_isolate.cc.

References CreateRunningRootIsolate(), flutter::UIDartState::GetImageDecoder(), flutter::UIDartState::GetImageGeneratorRegistry(), flutter::UIDartState::GetIOManager(), flutter::UIDartState::GetSkiaUnrefQueue(), flutter::UIDartState::GetTaskRunners(), and flutter::UIDartState::GetVolatilePathTracker().

92  {
94  settings, //
95  GetIsolateGroupData().GetIsolateSnapshot(), //
96  std::move(platform_configuration), //
97  flags, //
98  nullptr, //
99  isolate_create_callback, //
100  isolate_shutdown_callback, //
101  dart_entrypoint, //
102  dart_entrypoint_library, //
103  std::move(isolate_configration), //
104  UIDartState::Context{GetTaskRunners(), //
105  snapshot_delegate, //
106  GetIOManager(), //
107  GetSkiaUnrefQueue(), //
108  GetImageDecoder(), //
110  advisory_script_uri, //
111  advisory_script_entrypoint, //
113  this //
114  );
115 }
fml::WeakPtr< ImageGeneratorRegistry > GetImageGeneratorRegistry() const
PlatformConfiguration * platform_configuration() const
fml::RefPtr< flutter::SkiaUnrefQueue > GetSkiaUnrefQueue() const
static std::weak_ptr< DartIsolate > CreateRunningRootIsolate(const Settings &settings, fml::RefPtr< const DartSnapshot > isolate_snapshot, std::unique_ptr< PlatformConfiguration > platform_configuration, Flags flags, 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, std::unique_ptr< IsolateConfiguration > isolate_configration, 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 ma...
fml::WeakPtr< ImageDecoder > GetImageDecoder() const
fml::WeakPtr< IOManager > GetIOManager() const
const TaskRunners & GetTaskRunners() const
DEF_SWITCHES_START snapshot asset Path to the directory containing the four files specified by VmSnapshotInstructions and IsolateSnapshotInstructions vm snapshot The VM instructions snapshot that will be memory mapped as read and executable SnapshotAssetPath must be present isolate snapshot The isolate instructions snapshot that will be memory mapped as read and executable SnapshotAssetPath must be present icu symbol Prefix for the symbols representing ICU data linked into the Flutter library dart flags
Definition: switches.h:66
std::shared_ptr< VolatilePathTracker > GetVolatilePathTracker() const

Friends And Related Function Documentation

◆ DartVM

friend class DartVM
friend

Definition at line 425 of file dart_isolate.h.

◆ IsolateConfiguration

friend class IsolateConfiguration
friend

Definition at line 414 of file dart_isolate.h.


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