1 // Copyright 2013 The Flutter Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef FLUTTER_SHELL_COMMON_ISOLATE_CONFIGURATION_H_ 6 #define FLUTTER_SHELL_COMMON_ISOLATE_CONFIGURATION_H_ 7 8 #include <future> 9 #include <memory> 10 #include <string> 11 12 #include "flutter/assets/asset_manager.h" 13 #include "flutter/assets/asset_resolver.h" 14 #include "flutter/common/settings.h" 15 #include "flutter/fml/macros.h" 16 #include "flutter/fml/mapping.h" 17 #include "flutter/fml/memory/weak_ptr.h" 18 #include "flutter/runtime/dart_isolate.h" 19 20 namespace flutter { 21 22 //------------------------------------------------------------------------------ 23 /// @brief An isolate configuration is a collection of snapshots and asset 24 /// managers that the engine will use to configure the isolate 25 /// before invoking its root entrypoint. The set of snapshots must 26 /// be sufficient for the engine to move the isolate from the 27 /// |DartIsolate::Phase::LibrariesSetup| phase to the 28 /// |DartIsolate::Phase::Ready| phase. Note that the isolate 29 /// configuration will not be collected till the isolate tied to the 30 /// configuration as well as any and all child isolates of that 31 /// isolate are collected. The engine may ask the configuration to 32 /// prepare multiple isolates. All subclasses of this class must be 33 /// thread safe as the configuration may be created, collected and 34 /// used on multiple threads. Usually these threads are engine or VM 35 /// managed so care must be taken to ensure that subclasses do not 36 /// reference any thread local state. 37 /// 38 class IsolateConfiguration { 39 public: 40 //---------------------------------------------------------------------------- 41 /// @brief Attempts to infer the isolate configuration from the 42 /// `Settings` object. If the VM is configured for AOT mode, 43 /// snapshot resolution is attempted with predefined symbols 44 /// present in the currently loaded process. In JIT mode, Dart 45 /// kernel file resolution is attempted in the assets directory. 46 /// If an IO worker is specified, snapshot resolution may be 47 /// attempted on the serial worker task runner. The worker task 48 /// runner thread must remain valid and running till after the 49 /// shell associated with the engine used to launch the isolate 50 /// for which this run configuration is used is collected. 51 /// 52 /// @param[in] settings The settings 53 /// @param[in] asset_manager The asset manager 54 /// @param[in] io_worker An optional IO worker. Specify `nullptr` is a 55 /// worker should not be used or one is not 56 /// available. 57 /// 58 /// @return An isolate configuration if one can be inferred from the 59 /// settings. If not, returns `nullptr`. 60 /// 61 static std::unique_ptr<IsolateConfiguration> InferFromSettings( 62 const Settings& settings, 63 std::shared_ptr<AssetManager> asset_manager, 64 fml::RefPtr<fml::TaskRunner> io_worker); 65 66 //---------------------------------------------------------------------------- 67 /// @brief Creates an AOT isolate configuration using snapshot symbols 68 /// present in the currently loaded process. These symbols need to 69 /// be given to the Dart VM on bootstrap and hence have already 70 /// been resolved. 71 /// 72 /// @return An AOT isolate configuration. 73 /// 74 static std::unique_ptr<IsolateConfiguration> CreateForAppSnapshot(); 75 76 //---------------------------------------------------------------------------- 77 /// @brief Creates a JIT isolate configuration using a list of futures to 78 /// snapshots defining the ready isolate state. In environments 79 /// where snapshot resolution is extremely expensive, embedders 80 /// attempt to resolve snapshots on worker thread(s) and return 81 /// the future of the promise of snapshot resolution to this 82 /// method. That way, snapshot resolution begins well before 83 /// isolate launch is attempted by the engine. 84 /// 85 /// @param[in] kernel_pieces The list of futures to Dart kernel snapshots. 86 /// 87 /// @return A JIT isolate configuration. 88 /// 89 static std::unique_ptr<IsolateConfiguration> CreateForKernelList( 90 std::vector<std::future<std::unique_ptr<const fml::Mapping>>> 91 kernel_pieces); 92 93 //---------------------------------------------------------------------------- 94 /// @brief Creates a JIT isolate configuration using the specified 95 /// snapshot. This is a convenience method for the 96 /// `CreateForKernelList` method that takes a list of futures to 97 /// Dart kernel snapshots. 98 /// 99 /// @see CreateForKernelList() 100 /// 101 /// @param[in] kernel The kernel snapshot. 102 /// 103 /// @return A JIT isolate configuration. 104 /// 105 static std::unique_ptr<IsolateConfiguration> CreateForKernel( 106 std::unique_ptr<const fml::Mapping> kernel); 107 108 //---------------------------------------------------------------------------- 109 /// @brief Creates a JIT isolate configuration using the specified 110 /// snapshots. This is a convenience method for the 111 /// `CreateForKernelList` method that takes a list of futures to 112 /// Dart kernel snapshots. 113 /// 114 /// @see CreateForKernelList() 115 /// 116 /// @param[in] kernel_pieces The kernel pieces 117 /// 118 /// @return { description_of_the_return_value } 119 /// 120 static std::unique_ptr<IsolateConfiguration> CreateForKernelList( 121 std::vector<std::unique_ptr<const fml::Mapping>> kernel_pieces); 122 123 //---------------------------------------------------------------------------- 124 /// @brief Create an isolate configuration. This has no threading 125 /// restrictions. 126 /// 127 IsolateConfiguration(); 128 129 //---------------------------------------------------------------------------- 130 /// @brief Destroys an isolate configuration. This has no threading 131 /// restrictions and may be collection of configurations may occur 132 /// on any thread (and usually happens on an internal VM managed 133 /// thread pool thread). 134 /// 135 virtual ~IsolateConfiguration(); 136 137 //---------------------------------------------------------------------------- 138 /// @brief When an isolate is created and sufficiently initialized to 139 /// move it into the `DartIsolate::Phase::LibrariesSetup` phase, 140 /// this method is invoked on the isolate to then move the isolate 141 /// into the `DartIsolate::Phase::Ready` phase. Then isolate's 142 /// main entrypoint is then invoked to move it into the 143 /// `DartIsolate::Phase::Running` phase. This method will be 144 /// called each time the root isolate is launched (which may be 145 /// multiple times in cold-restart scenarios) as well as one each 146 /// for any child isolates referenced by that isolate. 147 /// 148 /// @param isolate The isolate which is already in the 149 /// `DartIsolate::Phase::LibrariesSetup` phase. 150 /// 151 /// @return Returns true if the isolate could be configured. Unless this 152 /// returns true, the engine will not move the isolate to the 153 /// `DartIsolate::Phase::Ready` phase for subsequent run. 154 /// 155 bool PrepareIsolate(DartIsolate& isolate); 156 157 protected: 158 virtual bool DoPrepareIsolate(DartIsolate& isolate) = 0; 159 160 private: 161 FML_DISALLOW_COPY_AND_ASSIGN(IsolateConfiguration); 162 }; 163 164 } // namespace flutter 165 166 #endif // FLUTTER_SHELL_COMMON_ISOLATE_CONFIGURATION_H_ 167