提交 d6ff8e90 编写于 作者: C Chinmay Garde

Switch to using precompiled snapshots on iOS

上级 db8dc933
......@@ -25,7 +25,7 @@ vars = {
# Note: When updating the Dart revision, ensure that all entries that are
# dependencies of dart are also updated
'dart_revision': '6aab1cecb25f8e04087320f2082336073628afb4',
'dart_revision': '2da9b9ce0a786c9dc7742a1045ed5b326c73076d',
'dart_observatory_packages_revision': '5c199c5954146747f75ed127871207718dc87786',
'dart_root_certificates_revision': 'c3a41df63afacec62fcb8135196177e35fe72f71',
......
......@@ -67,7 +67,7 @@ declare_args() {
# depending on the application type, may be unnecessary. If the type of
# architecture is known beforehand, setting that as the active arch will
# greatly reduce build times and reduce binary sizes.
ios_active_arch = "armv7"
ios_active_arch = "arm64"
}
# default_include_dirs ---------------------------------------------------------
......
......@@ -10,7 +10,6 @@ group("sky") {
"//sky/engine/wtf:unittests($host_toolchain)",
"//examples",
"//sky/tools/imagediff($host_toolchain)",
"//sky/tools/sky_snapshot($host_toolchain)",
":sky_dev",
]
......
......@@ -36,6 +36,11 @@ template("flx") {
"--output-file", rebase_path(bundle, root_build_dir),
]
if(is_ios) {
# This makes the tools bypass the script snapshot compiler
args += [ "--precompiled" ]
}
if (defined(invoker.manifest)) {
inputs += [ invoker.manifest ]
args += [
......
......@@ -95,6 +95,7 @@ template("sky_app") {
} else if (is_ios && defined(invoker.info_plist)) {
import("//build/config/ios/rules.gni")
import("//build/config/ios/ios_sdk.gni")
import("//sky/engine/bindings/bindings.gni")
ios_app(target_name) {
app_name = target_name + "_app"
......@@ -124,10 +125,17 @@ template("sky_app") {
deps = [ ":app" ]
}
precompiled_gen_target = target_name + "_precompiled"
dart_precompile(precompiled_gen_target) {
dart_package_root = rebase_path("packages", root_build_dir)
dart_script = invoker.main_dart
}
deps = [
"//sky/shell:ios_scaffolding",
":$resources_gen_target_name",
":$flx_target_name",
":$precompiled_gen_target",
]
if (defined(invoker.deps)) {
......
......@@ -27,7 +27,7 @@ copy("sky_shell") {
deps = [
"//sky/shell",
]
} else if (is_ios || is_mac) {
} else if (is_mac) {
sources = [
"$root_build_dir/SkyShell.app",
]
......@@ -35,7 +35,7 @@ copy("sky_shell") {
deps = [
"//sky/shell:shell_struct",
]
} else {
} else if(!is_ios) {
sources = [
"$root_build_dir/sky_shell",
"$root_build_dir/icudtl.dat",
......@@ -45,6 +45,9 @@ copy("sky_shell") {
"//sky/shell",
"//third_party/icu:icudata",
]
} else {
sources = []
deps = []
}
sky_snapshot_dir =
......
......@@ -41,9 +41,18 @@ source_set("bindings") {
"//sky/engine/tonic",
"//sky/engine/wtf",
":generated_bindings",
":snapshot_cc",
":updater_snapshot_cc",
]
# On iOS, precompiled snapshots contain the instruction buffer. Generation
# of the same requires all application specific script code to be specified
# up front. In such cases, there can be no updater or generic snapshotter
if (!is_ios) {
deps += [
":snapshot_cc",
":updater_snapshot_cc",
]
}
include_dirs = [
"..",
"$root_build_dir",
......
......@@ -48,3 +48,118 @@ idl_compiler_files = [
"scripts/v8_types.py",
"scripts/v8_utilities.py",
]
template("dart_precompile") {
assert(defined(invoker.dart_package_root),
"The dart package root must be defined")
assert(defined(invoker.dart_script),
"The dart script must be specified")
vm_isolate_snapshot_name = target_name + "_vm_isolate.bin"
vm_isolate_snapshot = "$target_gen_dir/$vm_isolate_snapshot_name"
isolate_snapshot_name = target_name + "_isolate.bin"
isolate_snapshot = "$target_gen_dir/$isolate_snapshot_name"
assembly_path =
"$target_gen_dir/" + target_name + "_instructions.S"
instructions_gen_target_name = target_name + "_instructions"
action(instructions_gen_target_name) {
deps = [
"//dart/runtime/bin:gen_snapshot($host_toolchain)",
]
embedder_entry_points_manifest =
"//sky/engine/bindings/dart_vm_entry_points.txt"
inputs = [
"//dart/runtime/tools/create_snapshot_bin.py",
"//mojo/public/dart/mojo/sdk_ext/internal.dart",
"//mojo/public/dart/mojo/sdk_ext/src/handle_watcher.dart",
"//mojo/public/dart/mojo/sdk_ext/src/natives.dart",
"//mojo/public/dart/mojo/sdk_ext/src/timer_queue.dart",
"//sky/engine/bindings/internals.dart",
embedder_entry_points_manifest,
]
outputs = [
vm_isolate_snapshot,
isolate_snapshot,
assembly_path
]
dart_mojo_internal_path =
rebase_path("//mojo/public/dart/mojo/sdk_ext/internal.dart")
dart_ui_internals_path =
rebase_path("//sky/engine/bindings/internals.dart")
dart_ui_path =
rebase_path("$root_build_dir/clang_x64/gen/sky/bindings/dart_ui.dart")
gen_snapshot_dir =
get_label_info("//dart/runtime/bin:gen_snapshot($host_toolchain)",
"root_out_dir")
script = "//dart/runtime/tools/create_snapshot_bin.py"
args = [
"--executable",
rebase_path("$gen_snapshot_dir/gen_snapshot"),
"--package_root",
rebase_path(invoker.dart_package_root, root_build_dir),
"--script",
rebase_path(invoker.dart_script, root_build_dir),
"--vm_output_bin",
rebase_path(vm_isolate_snapshot, root_build_dir),
"--output_bin",
rebase_path(isolate_snapshot, root_build_dir),
"--instructions_bin",
rebase_path(assembly_path, root_build_dir),
"--embedder_entry_points_manifest",
rebase_path(embedder_entry_points_manifest, root_build_dir),
"--target_os",
target_os,
"--url_mapping=dart:mojo.internal,$dart_mojo_internal_path",
"--url_mapping=dart:ui,$dart_ui_path",
"--url_mapping=dart:ui_internals,$dart_ui_internals_path",
]
}
snapshot_cc = "$target_gen_dir/" + target_name + "_precompiled_snapshot.cc"
snapshot_cc_gen_target_name = target_name + "_snapshot_cc"
action(snapshot_cc_gen_target_name) {
deps = [
":$instructions_gen_target_name",
]
template_file = "//sky/engine/bindings/snapshot.cc.tmpl"
inputs = [
template_file,
vm_isolate_snapshot,
isolate_snapshot,
]
outputs = [
snapshot_cc,
]
script = "//dart/runtime/tools/create_snapshot_file.py"
args = [
"--vm_input_bin",
rebase_path(vm_isolate_snapshot, root_build_dir),
"--input_bin",
rebase_path(isolate_snapshot, root_build_dir),
"--input_cc",
rebase_path(template_file, root_build_dir),
"--output",
rebase_path(snapshot_cc),
]
}
source_set(target_name) {
sources = [
assembly_path,
snapshot_cc,
]
deps = [
":$instructions_gen_target_name",
":$snapshot_cc_gen_target_name",
]
}
}
......@@ -118,9 +118,11 @@ static void InitDartInternal(Dart_Handle builtin_library,
} else {
CHECK(isolate_type == DartNatives::DartIOIsolate);
Dart_Handle io_lib = DartBuiltin::LookupLibrary("dart:io");
DART_CHECK_VALID(io_lib);
Dart_Handle setup_hooks = Dart_NewStringFromCString("_setupHooks");
DART_CHECK_VALID(Dart_Invoke(io_lib, setup_hooks, 0, NULL));
Dart_Handle isolate_lib = DartBuiltin::LookupLibrary("dart:isolate");
DART_CHECK_VALID(isolate_lib);
DART_CHECK_VALID(Dart_Invoke(isolate_lib, setup_hooks, 0, NULL));
}
}
......
dart:io,::,_setupHooks
dart:mojo.internal,MojoHandleWatcher,_start
dart:ui,::,_getCreateTimerClosure
dart:ui,::,_getGetBaseURLClosure
dart:ui,::,_getMainClosure
dart:ui,::,_getPrintClosure
dart:ui,::,_getScheduleMicrotaskClosure
dart:ui,Canvas,Canvas.
dart:ui,CharacterData,CharacterData.
dart:ui,ClientRect,ClientRect.
dart:ui,ClientRectList,ClientRectList.
dart:ui,CSSStyleDeclaration,CSSStyleDeclaration.
dart:ui,Document,Document.
dart:ui,DocumentFragment,DocumentFragment.
dart:ui,DOMError,DOMError.
dart:ui,DOMException,DOMException.
dart:ui,Drawable,Drawable.
dart:ui,DrawLooper,DrawLooper.
dart:ui,DrawLooperLayerInfo,DrawLooperLayerInfo.
dart:ui,Element,Element.
dart:ui,Event,Event.
dart:ui,Event,Event.
dart:ui,GestureVelocity,GestureVelocity.
dart:ui,HTMLElement,HTMLElement.
dart:ui,Image,Image.
dart:ui,ImageData,ImageData.
dart:ui,ImageShader,ImageShader.
dart:ui,KeyboardEvent,KeyboardEvent.
dart:ui,KeyboardEvent,KeyboardEvent.
dart:ui,LayerDrawLooperBuilder,LayerDrawLooperBuilder.
dart:ui,LayoutRoot,LayoutRoot.
dart:ui,Node,Node.
dart:ui,Paragraph,Paragraph.
dart:ui,ParagraphBuilder,ParagraphBuilder.
dart:ui,ParagraphStyle,ParagraphStyle.
dart:ui,ParentNode,ParentNode.
dart:ui,Path,Path.
dart:ui,Picture,Picture.
dart:ui,PictureRecorder,PictureRecorder.
dart:ui,PointerEvent,PointerEvent.
dart:ui,PointerEvent,PointerEvent.
dart:ui,Range,Range.
dart:ui,RRect,RRect.
dart:ui,Scene,Scene.
dart:ui,SceneBuilder,SceneBuilder.
dart:ui,Shader,Shader.
dart:ui,Text,Text.
dart:ui,TextMetrics,TextMetrics.
dart:ui,TextStyle,TextStyle.
dart:ui,Tracing,Tracing.
dart:ui,VelocityTracker,VelocityTracker.
dart:ui,View,View.
dart:ui,WheelEvent,WheelEvent.
dart:ui,WheelEvent,WheelEvent.
dart:ui_internals,::,takeRootBundleHandle
dart:ui_internals,::,takeServiceRegistry
dart:ui_internals,::,takeServicesProvidedByEmbedder
dart:ui_internals,::,takeServicesProvidedToEmbedder
dart:ui_internals,::,takeShellProxyHandle
......@@ -10,7 +10,6 @@ import 'dart:io';
import 'dart:isolate';
import 'dart:math';
import 'dart:mojo.internal';
import 'dart:mirrors';
import 'dart:ui';
import 'dart:ui_internals';
import 'dart:typed_data';
......@@ -53,3 +53,10 @@ _getPrintClosure() => _print;
_getScheduleMicrotaskClosure() => _scheduleMicrotask;
_getGetBaseURLClosure() =>_getBaseURL;
_getCreateTimerClosure() => _createTimer;
// Though the "main" symbol is not included in any of the libraries imported
// above, the builtin library will be included manually during VM setup. This
// symbol is only necessary for precompilation. It is marked as a stanalone
// entry point into the VM. This prevents the precompiler from tree shaking
// away "main"
_getMainClosure() => main;
......@@ -95,11 +95,14 @@ void DartController::DidLoadSnapshot() {
DartApiScope dart_api_scope;
Dart_Handle library = Dart_RootLibrary();
if (LogIfError(library))
return;
DART_CHECK_VALID(library);
DartInvokeAppField(library, ToDart("main"), 0, nullptr);
}
void DartController::RunFromPrecompiledSnapshot() {
DidLoadSnapshot();
}
void DartController::RunFromSnapshot(
mojo::ScopedDataPipeConsumerHandle snapshot) {
snapshot_loader_ = adoptPtr(new DartSnapshotLoader(dart_state()));
......
......@@ -33,6 +33,7 @@ class DartController {
void RunFromLibrary(const String& name,
DartLibraryProvider* library_provider);
void RunFromPrecompiledSnapshot();
void RunFromSnapshot(mojo::ScopedDataPipeConsumerHandle snapshot);
void RunFromSnapshotBuffer(const uint8_t* buffer, size_t size);
......
......@@ -4,6 +4,8 @@
#include "sky/engine/core/script/dart_init.h"
#include <dlfcn.h>
#include "base/bind.h"
#include "base/logging.h"
#include "base/single_thread_task_runner.h"
......@@ -76,10 +78,16 @@ void CreateEmptyRootLibraryIfNeeded() {
static const char* kDartArgs[] = {
"--enable_mirrors=false",
#if WTF_OS_IOS || WTF_OS_MACOSX
"--no-profile"
"--no-profile",
#endif
};
static const char* kInstructionsSnapshotSymbolName = "kInstructionsSnapshot";
static const char* kDartPrecompilationArgs[] {
"--precompilation",
};
static const char* kDartCheckedModeArgs[] = {
"--enable_asserts",
"--enable_type_checks",
......@@ -100,6 +108,16 @@ bool IsServiceIsolateURL(const char* url_name) {
String(url_name) == DART_VM_SERVICE_ISOLATE_NAME;
}
static const uint8_t* PrecompiledInstructionsSymbolIfPresent() {
dlerror(); // clear previous errors on thread
void * sym = dlsym(RTLD_SELF, kInstructionsSnapshotSymbolName);
return (dlerror() != nullptr) ? nullptr : reinterpret_cast<uint8_t * >(sym);
}
static bool IsRunningPrecompiledCode() {
return PrecompiledInstructionsSymbolIfPresent() != nullptr;
}
// TODO(rafaelw): Right now this only supports the creation of the handle
// watcher isolate and the service isolate. Presumably, we'll want application
// isolates to spawn their own isolates.
......@@ -129,7 +147,8 @@ Dart_Isolate IsolateCreateCallback(const char* script_uri,
// Start the handle watcher from the service isolate so it isn't available
// for debugging or general Observatory interaction.
EnsureHandleWatcherStarted();
if (RuntimeEnabledFeatures::observatoryEnabled()) {
if (!IsRunningPrecompiledCode() &&
RuntimeEnabledFeatures::observatoryEnabled()) {
std::string ip = "127.0.0.1";
const intptr_t port = 8181;
const bool service_isolate_booted =
......@@ -181,6 +200,10 @@ void InitDartVM() {
Vector<const char*> args;
args.append(kDartArgs, arraysize(kDartArgs));
if (IsRunningPrecompiledCode())
args.append(kDartPrecompilationArgs, arraysize(kDartPrecompilationArgs));
if (enable_checked_mode)
args.append(kDartCheckedModeArgs, arraysize(kDartCheckedModeArgs));
......@@ -189,7 +212,7 @@ void InitDartVM() {
DartDebugger::InitDebugger();
CHECK(Dart_Initialize(
kDartVmIsolateSnapshotBuffer,
nullptr,
PrecompiledInstructionsSymbolIfPresent(),
IsolateCreateCallback,
nullptr, // Isolate interrupt callback.
UnhandledExceptionCallback, IsolateShutdownCallback,
......
......@@ -59,6 +59,11 @@ void SkyView::RunFromLibrary(const WebString& name,
dart_controller_->RunFromLibrary(name, library_provider);
}
void SkyView::RunFromPrecompiledSnapshot() {
DCHECK(view_);
dart_controller_->RunFromPrecompiledSnapshot();
}
void SkyView::RunFromSnapshot(const WebString& name,
mojo::ScopedDataPipeConsumerHandle snapshot) {
DCHECK(view_);
......
......@@ -42,6 +42,7 @@ class SkyView {
void RunFromLibrary(const WebString& name,
DartLibraryProvider* library_provider);
void RunFromPrecompiledSnapshot();
void RunFromSnapshot(const WebString& name,
mojo::ScopedDataPipeConsumerHandle snapshot);
......
......@@ -27,6 +27,7 @@ interface SkyEngine {
RunFromNetwork(string url);
RunFromFile(string main, string package_root);
RunFromPrecompiledSnapshot();
RunFromSnapshot(string path);
RunFromBundle(string path);
};
......@@ -221,21 +221,9 @@ if (is_android) {
]
}
ios_app("shell") {
app_name = "SkyShell"
info_plist = "ios/Info.plist"
entitlements_path = "ios/Entitlements.xcent"
code_signing_identity = ios_code_signing_identity
resource_copy_ios("sky_resources") {
resources = [ "//third_party/icu/android/icudtl.dat" ]
bundle_directory = "."
}
deps = [
":ios_scaffolding",
":sky_resources",
]
group("shell") {
# iOS only supports application bundles with a precompiled instruction
# buffer. There is not Shell target for the same.
}
} else if (is_linux) {
executable("shell") {
......
......@@ -17,10 +17,6 @@
#include "sky/shell/ui_delegate.h"
#include <strings.h>
#ifndef NDEBUG
#include "document_watcher.h"
#endif
enum MapperPhase {
Accessed,
Added,
......@@ -92,10 +88,6 @@ class TouchMapper {
sky::SkyEnginePtr _sky_engine;
scoped_ptr<sky::shell::ShellView> _shell_view;
TouchMapper _touch_mapper;
#ifndef NDEBUG
DocumentWatcher *_document_watcher;
#endif
}
static std::string SkPictureTracingPath() {
......@@ -104,7 +96,7 @@ static std::string SkPictureTracingPath() {
return [paths.firstObject UTF8String];
}
-(instancetype) initWithShellView:(sky::shell::ShellView *) shellView {
- (instancetype)initWithShellView:(sky::shell::ShellView*)shellView {
self = [super init];
if (self) {
base::FilePath pictureTracingPath =
......@@ -140,7 +132,9 @@ static std::string SkPictureTracingPath() {
metrics->padding_top =
[UIApplication sharedApplication].statusBarFrame.size.height;
[[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleLightContent animated:NO];
[[UIApplication sharedApplication]
setStatusBarStyle:UIStatusBarStyleLightContent
animated:NO];
_sky_engine->OnViewportMetricsChanged(metrics.Pass());
}
......@@ -175,85 +169,16 @@ static std::string SkPictureTracingPath() {
self.platformView->SurfaceCreated(self.acceleratedWidget);
}
- (NSString*)skyInitialLoadURL {
NSUserDefaults *standardDefaults = [NSUserDefaults standardUserDefaults];
NSString *target = [standardDefaults stringForKey:@"target"];
NSString *server = [standardDefaults stringForKey:@"server"];
if (server && target) {
return [NSString stringWithFormat:@"http://%@/%@", server, target];
}
return [NSBundle mainBundle].infoDictionary[@"org.domokit.sky.load_url"];
}
- (NSString*)skyInitialBundleURL {
NSString *flxBundlePath = [[NSBundle mainBundle] pathForResource:@"app" ofType:@"flx"];
#ifndef NDEBUG
NSFileManager *fileManager = [NSFileManager defaultManager];
NSError *error = nil;
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *flxDocsPath = [documentsDirectory stringByAppendingPathComponent:@"app.flx"];
// Write an empty file to help identify the correct simulator app by its bundle id. See sky_tool for its use.
NSString *bundleIDPath = [documentsDirectory stringByAppendingPathComponent:[[NSBundle mainBundle] bundleIdentifier]];
NSData *data = [[NSData alloc] initWithBytes:"" length:0];
if (![data writeToFile:bundleIDPath options:NSDataWritingAtomic error:&error]) {
NSLog(@"Couldn't write the bundle id file %@: auto reloading on the iOS simulator won't work\n%@", bundleIDPath, error);
}
if (flxBundlePath != nil && [fileManager fileExistsAtPath:flxDocsPath] == NO) {
if ([fileManager copyItemAtPath:flxBundlePath toPath:flxDocsPath error:&error]) {
return flxDocsPath;
}
NSLog(@"Error encountered copying app.flx from the Bundle to the Documents directory. Dynamic reloading will not be possible. %@", error);
return flxBundlePath;
}
return flxDocsPath;
#endif
return flxBundlePath;
}
- (void)connectToEngineAndLoad {
auto interface_request = mojo::GetProxy(&_sky_engine);
self.platformView->ConnectToEngine(interface_request.Pass());
NSString *endpoint = self.skyInitialBundleURL;
if (endpoint.length > 0) {
#ifndef NDEBUG
_document_watcher = [[DocumentWatcher alloc] initWithDocumentPath:endpoint callbackBlock:^{
mojo::String string(endpoint.UTF8String);
_sky_engine->RunFromBundle(string);
}];
#endif
// Load from bundle
mojo::String string(endpoint.UTF8String);
_sky_engine->RunFromBundle(string);
return;
}
endpoint = self.skyInitialLoadURL;
if (endpoint.length > 0) {
// Load from URL
mojo::String string(endpoint.UTF8String);
_sky_engine->RunFromNetwork(string);
return;
}
_sky_engine->RunFromPrecompiledSnapshot();
}
- (void)notifySurfaceDestruction {
self.platformView->SurfaceDestroyed();
}
#ifndef NDEBUG
- (void)didMoveToWindow {
if (self.window == nil) {
[_document_watcher cancel];
[_document_watcher release];
_document_watcher = nil;
}
}
#endif
#pragma mark - UIResponder overrides for raw touches
- (void)dispatchTouches:(NSSet*)touches phase:(UITouchPhase)phase {
......
......@@ -181,6 +181,13 @@ void Engine::RunFromSnapshotStream(
sky_view_->SetDisplayMetrics(display_metrics_);
}
void Engine::RunFromPrecompiledSnapshot() {
sky_view_ = blink::SkyView::Create(this);
sky_view_->CreateView("Sky");
sky_view_->RunFromPrecompiledSnapshot();
sky_view_->SetDisplayMetrics(display_metrics_);
}
void Engine::RunFromNetwork(const mojo::String& url) {
dart_library_provider_.reset(
new DartLibraryProviderNetwork(network_service_.get()));
......
......@@ -74,6 +74,7 @@ class Engine : public UIDelegate,
void RunFromNetwork(const mojo::String& url) override;
void RunFromFile(const mojo::String& main,
const mojo::String& package_root) override;
void RunFromPrecompiledSnapshot() override;
void RunFromSnapshot(const mojo::String& path) override;
void RunFromBundle(const mojo::String& path) override;
......
......@@ -48,6 +48,7 @@ def to_gn_args(args):
if args.simulator:
gn_args['use_libjpeg_turbo'] = False
gn_args['use_ios_simulator'] = args.simulator
gn_args['dart_target_arch'] = "arm64"
else:
gn_args['use_aura'] = False
gn_args['use_glib'] = False
......
......@@ -22,6 +22,9 @@ def main():
parser.add_argument('--output-file', type=str)
parser.add_argument('--package-root', type=str)
parser.add_argument('--snapshot', type=str)
parser.add_argument('--precompiled', dest='precompiled', action='store_true')
parser.set_defaults(precompiled=False)
args = parser.parse_args()
command = [
......@@ -36,6 +39,11 @@ def main():
'--private-key', os.path.abspath(os.path.join(args.package_root, '..', 'privatekey.der')),
]
if args.precompiled:
command += [
'--precompiled'
]
if args.manifest:
command += ['--manifest', os.path.abspath(args.manifest)]
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册