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

 ~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 last_piece=true)
 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...
 
- 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
 
fml::WeakPtr< SnapshotDelegateGetSnapshotDelegate () const
 
fml::WeakPtr< HintFreedDelegateGetHintFreedDelegate () const
 
fml::WeakPtr< GrDirectContext > GetResourceContext () const
 
fml::WeakPtr< ImageDecoderGetImageDecoder () const
 
std::shared_ptr< IsolateNameServerGetIsolateNameServer () const
 
tonic::DartErrorHandleType GetLastError ()
 
void ReportUnhandledException (const std::string &error, const std::string &stack_trace)
 
- 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
 

Static Public Member Functions

static std::weak_ptr< DartIsolateCreateRunningRootIsolate (const Settings &settings, fml::RefPtr< const DartSnapshot > isolate_snapshot, TaskRunners task_runners, std::unique_ptr< PlatformConfiguration > platform_configuration, fml::WeakPtr< SnapshotDelegate > snapshot_delegate, fml::WeakPtr< HintFreedDelegate > hint_freed_delegate, fml::WeakPtr< IOManager > io_manager, fml::RefPtr< SkiaUnrefQueue > skia_unref_queue, fml::WeakPtr< ImageDecoder > image_decoder, 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)
 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 (TaskRunners task_runners, TaskObserverAdd add_callback, TaskObserverRemove remove_callback, fml::WeakPtr< SnapshotDelegate > snapshot_delegate, fml::WeakPtr< HintFreedDelegate > hint_freed_delegate, fml::WeakPtr< IOManager > io_manager, fml::RefPtr< SkiaUnrefQueue > skia_unref_queue, fml::WeakPtr< ImageDecoder > image_decoder, std::string advisory_script_uri, std::string advisory_script_entrypoint, std::string logger_prefix, UnhandledExceptionCallback unhandled_exception_callback, std::shared_ptr< IsolateNameServer > isolate_name_server, bool is_root_isolate_)
 
 ~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
 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 274 of file dart_isolate.cc.

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

274  {
276  FML_DCHECK(GetMessageHandlingTaskRunner()->RunsTasksOnCurrentThread());
277  }
278 }
#define FML_DCHECK(condition)
Definition: logging.h:86
bool IsRootIsolate() const
Definition: ui_dart_state.h:39
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 979 of file dart_isolate.cc.

References FML_LOG.

979  {
980  shutdown_callbacks_.emplace_back(std::make_unique<AutoFireClosure>(closure));
981 }
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,
TaskRunners  task_runners,
std::unique_ptr< PlatformConfiguration platform_configuration,
fml::WeakPtr< SnapshotDelegate snapshot_delegate,
fml::WeakPtr< HintFreedDelegate hint_freed_delegate,
fml::WeakPtr< IOManager io_manager,
fml::RefPtr< SkiaUnrefQueue skia_unref_queue,
fml::WeakPtr< ImageDecoder image_decoder,
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 
)
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]isolate_snapshotThe isolate snapshot. This is usually obtained from the DartVMData associated with the running Dart VM instance.
[in]task_runnersThe task runners used by the isolate. Via UI bindings, the isolate will use the IO task runner to scheduled texture decompression jobs and post tasks back to the UI task runner.
[in]windowThe weak pointer to the window associated with this root isolate.
[in]io_managerThe i/o manager.
[in]unref_queueThe Skia unref queue.
[in]image_decoderThe image decoder.
[in]advisory_script_uriThe advisory script uri. This is only used in instrumentation.
[in]advisory_script_entrypointThe advisory script entrypoint. This is only used in instrumentation. Notably, this is NOT the main entrypoint of Dart code in the isolate. That is specified when making one of the Run calls.
[in]flagsThe Dart isolate flags for this isolate instance.
[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. This callback is made for all isolate launches (including the children of the root isolate).
[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. This callback is made for all isolate shutdowns (including the children of the root 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 76 of file dart_isolate.cc.

References flutter::Settings::dart_entrypoint_args, flutter::Settings::domain_network_policy, error, flutter::flags, FML_DLOG, FML_LOG, flutter::DartIsolate::Flags::Get(), flutter::DartVMRef::GetIsolateNameServer(), tonic::DartState::isolate(), LibrariesSetup, 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(), and flutter::testing::TEST_F().

93  {
94  if (!isolate_snapshot) {
95  FML_LOG(ERROR) << "Invalid isolate snapshot.";
96  return {};
97  }
98 
99  if (!isolate_configration) {
100  FML_LOG(ERROR) << "Invalid isolate configuration.";
101  return {};
102  }
103 
104  isolate_flags.SetNullSafetyEnabled(
105  isolate_configration->IsNullSafetyEnabled(*isolate_snapshot));
106 
107  auto isolate = CreateRootIsolate(settings, //
108  isolate_snapshot, //
109  task_runners, //
110  std::move(platform_configuration), //
111  snapshot_delegate, //
112  hint_freed_delegate, //
113  io_manager, //
114  skia_unref_queue, //
115  image_decoder, //
116  advisory_script_uri, //
117  advisory_script_entrypoint, //
118  isolate_flags, //
119  isolate_create_callback, //
120  isolate_shutdown_callback //
121  )
122  .lock();
123 
124  if (!isolate) {
125  FML_LOG(ERROR) << "Could not create root isolate.";
126  return {};
127  }
128 
129  fml::ScopedCleanupClosure shutdown_on_error([isolate]() {
130  if (!isolate->Shutdown()) {
131  FML_DLOG(ERROR) << "Could not shutdown transient isolate.";
132  }
133  });
134 
135  if (isolate->GetPhase() != DartIsolate::Phase::LibrariesSetup) {
136  FML_LOG(ERROR) << "Root isolate was created in an incorrect phase.";
137  return {};
138  }
139 
140  if (!isolate_configration->PrepareIsolate(*isolate.get())) {
141  FML_LOG(ERROR) << "Could not prepare isolate.";
142  return {};
143  }
144 
145  if (isolate->GetPhase() != DartIsolate::Phase::Ready) {
146  FML_LOG(ERROR) << "Root isolate not in the ready phase for Dart entrypoint "
147  "invocation.";
148  return {};
149  }
150 
151  if (settings.root_isolate_create_callback) {
152  // Isolate callbacks always occur in isolate scope and before user code has
153  // had a chance to run.
154  tonic::DartState::Scope scope(isolate.get());
155  settings.root_isolate_create_callback(*isolate.get());
156  }
157 
158  if (!isolate->RunFromLibrary(dart_entrypoint_library, //
159  dart_entrypoint, //
160  settings.dart_entrypoint_args //
161  )) {
162  FML_LOG(ERROR) << "Could not run the run main Dart entrypoint.";
163  return {};
164  }
165 
166  if (settings.root_isolate_shutdown_callback) {
167  isolate->AddIsolateShutdownCallback(
168  settings.root_isolate_shutdown_callback);
169  }
170 
171  shutdown_on_error.Release();
172 
173  return isolate;
174 }
Dart_Isolate isolate()
Definition: dart_state.h:49
#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
Definition: ui_dart_state.h:48
#define FML_DLOG(severity)
Definition: logging.h:85

◆ GetMessageHandlingTaskRunner()

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

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

280  {
281  return phase_;
282 }

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

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

284  {
285  const char* service_id_buf = Dart_IsolateServiceId(isolate());
286  std::string service_id(service_id_buf);
287  free(const_cast<char*>(service_id_buf));
288  return service_id;
289 }
Dart_Isolate isolate()
Definition: dart_state.h:49

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

975  {
976  return std::static_pointer_cast<DartIsolate>(shared_from_this());
977 }

◆ PrepareForRunningFromKernel()

bool flutter::DartIsolate::PrepareForRunningFromKernel ( std::shared_ptr< const fml::Mapping kernel,
bool  last_piece = true 
)

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

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

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

474  {
475  TRACE_EVENT0("flutter", "DartIsolate::PrepareForRunningFromKernel");
476  if (phase_ != Phase::LibrariesSetup) {
477  return false;
478  }
479 
481  return false;
482  }
483 
484  if (!mapping || mapping->GetSize() == 0) {
485  return false;
486  }
487 
488  tonic::DartState::Scope scope(this);
489 
490  // Use root library provided by kernel in favor of one provided by snapshot.
491  Dart_SetRootLibrary(Dart_Null());
492 
493  if (!LoadKernel(mapping, last_piece)) {
494  return false;
495  }
496 
497  if (!last_piece) {
498  // More to come.
499  return true;
500  }
501 
502  if (Dart_IsNull(Dart_RootLibrary())) {
503  return false;
504  }
505 
506  if (!MarkIsolateRunnable()) {
507  return false;
508  }
509 
510  // Child isolate shares root isolate embedder_isolate (lines 691 and 693
511  // below). Re-initializing child_isolate_preparer_ lambda while it is being
512  // executed leads to crashes.
513  if (GetIsolateGroupData().GetChildIsolatePreparer() == nullptr) {
514  GetIsolateGroupData().SetChildIsolatePreparer(
515  [buffers = kernel_buffers_](DartIsolate* isolate) {
516  for (uint64_t i = 0; i < buffers.size(); i++) {
517  bool last_piece = i + 1 == buffers.size();
518  const std::shared_ptr<const fml::Mapping>& buffer = buffers.at(i);
519  if (!isolate->PrepareForRunningFromKernel(buffer, last_piece)) {
520  return false;
521  }
522  }
523  return true;
524  });
525  }
526 
527  const fml::closure& isolate_create_callback =
528  GetIsolateGroupData().GetIsolateCreateCallback();
529  if (isolate_create_callback) {
530  isolate_create_callback();
531  }
532 
533  phase_ = Phase::Ready;
534 
535  return true;
536 }
void SetChildIsolatePreparer(const ChildIsolatePreparer &value)
Dart_Isolate isolate()
Definition: dart_state.h:49
#define TRACE_EVENT0(category_group, name)
Definition: trace_event.h:75
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:199
const fml::closure & GetIsolateCreateCallback() const

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

References PrepareForRunningFromKernel().

Referenced by PrepareForRunningFromKernels().

539  {
540  const auto count = kernels.size();
541  if (count == 0) {
542  return false;
543  }
544 
545  for (size_t i = 0; i < count; ++i) {
546  bool last = (i == (count - 1));
547  if (!PrepareForRunningFromKernel(kernels[i], last)) {
548  return false;
549  }
550  }
551 
552  return true;
553 }
bool PrepareForRunningFromKernel(std::shared_ptr< const fml::Mapping > kernel, bool last_piece=true)
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 555 of file dart_isolate.cc.

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

556  {
557  std::vector<std::shared_ptr<const fml::Mapping>> shared_kernels;
558  for (auto& kernel : kernels) {
559  shared_kernels.emplace_back(std::move(kernel));
560  }
561  return PrepareForRunningFromKernels(shared_kernels);
562 }
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 413 of file dart_isolate.cc.

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

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

413  {
414  TRACE_EVENT0("flutter", "DartIsolate::PrepareForRunningFromPrecompiledCode");
415  if (phase_ != Phase::LibrariesSetup) {
416  return false;
417  }
418 
419  tonic::DartState::Scope scope(this);
420 
421  if (Dart_IsNull(Dart_RootLibrary())) {
422  return false;
423  }
424 
425  if (!MarkIsolateRunnable()) {
426  return false;
427  }
428 
429  if (GetIsolateGroupData().GetChildIsolatePreparer() == nullptr) {
430  GetIsolateGroupData().SetChildIsolatePreparer([](DartIsolate* isolate) {
431  return isolate->PrepareForRunningFromPrecompiledCode();
432  });
433  }
434 
435  const fml::closure& isolate_create_callback =
436  GetIsolateGroupData().GetIsolateCreateCallback();
437  if (isolate_create_callback) {
438  isolate_create_callback();
439  }
440 
441  phase_ = Phase::Ready;
442  return true;
443 }
void SetChildIsolatePreparer(const ChildIsolatePreparer &value)
Dart_Isolate isolate()
Definition: dart_state.h:49
#define TRACE_EVENT0(category_group, name)
Definition: trace_event.h:75
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 618 of file dart_isolate.cc.

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

620  {
621  TRACE_EVENT0("flutter", "DartIsolate::RunFromLibrary");
622  if (phase_ != Phase::Ready) {
623  return false;
624  }
625 
626  tonic::DartState::Scope scope(this);
627 
628  auto library_handle =
629  library_name.has_value() && !library_name.value().empty()
630  ? ::Dart_LookupLibrary(tonic::ToDart(library_name.value().c_str()))
631  : ::Dart_RootLibrary();
632  auto entrypoint_handle = entrypoint.has_value() && !entrypoint.value().empty()
633  ? tonic::ToDart(entrypoint.value().c_str())
634  : tonic::ToDart("main");
635  auto user_entrypoint_function =
636  ::Dart_GetField(library_handle, entrypoint_handle);
637 
638  auto entrypoint_args = tonic::ToDart(args);
639 
640  if (!InvokeMainEntrypoint(user_entrypoint_function, entrypoint_args)) {
641  return false;
642  }
643 
644  phase_ = Phase::Running;
645 
646  return true;
647 }
G_BEGIN_DECLS FlValue * args
#define TRACE_EVENT0(category_group, name)
Definition: trace_event.h:75
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 succesfully transitioned to the shutdown phase.

Definition at line 649 of file dart_isolate.cc.

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

649  {
650  TRACE_EVENT0("flutter", "DartIsolate::Shutdown");
651  // This call may be re-entrant since Dart_ShutdownIsolate can invoke the
652  // cleanup callback which deletes the embedder side object of the dart isolate
653  // (a.k.a. this).
654  if (phase_ == Phase::Shutdown) {
655  return false;
656  }
657  phase_ = Phase::Shutdown;
658  Dart_Isolate vm_isolate = isolate();
659  // The isolate can be nullptr if this instance is the stub isolate data used
660  // during root isolate creation.
661  if (vm_isolate != nullptr) {
662  // We need to enter the isolate because Dart_ShutdownIsolate does not take
663  // the isolate to shutdown as a parameter.
664  FML_DCHECK(Dart_CurrentIsolate() == nullptr);
665  Dart_EnterIsolate(vm_isolate);
666  Dart_ShutdownIsolate();
667  FML_DCHECK(Dart_CurrentIsolate() == nullptr);
668  }
669  return true;
670 }
Dart_Isolate isolate()
Definition: dart_state.h:49
#define TRACE_EVENT0(category_group, name)
Definition: trace_event.h:75
#define FML_DCHECK(condition)
Definition: logging.h:86

Friends And Related Function Documentation

◆ DartVM

friend class DartVM
friend

Definition at line 399 of file dart_isolate.h.

◆ IsolateConfiguration

friend class IsolateConfiguration
friend

Definition at line 388 of file dart_isolate.h.


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