Update from https://crrev.com/311076 Includes updating DCHECK_IS_ON to a function-style macro and removing various dead skia-overriding code from Sky. Review URL: https://codereview.chromium.org/851503003
diff --git a/gin/BUILD.gn b/gin/BUILD.gn index b352c3a..d389b84 100644 --- a/gin/BUILD.gn +++ b/gin/BUILD.gn
@@ -2,6 +2,8 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. +import("//build/module_args/v8.gni") + component("gin") { sources = [ "arguments.cc", @@ -68,6 +70,40 @@ deps = [ "//base/third_party/dynamic_annotations", ] + if (v8_use_external_startup_data && is_win) { + deps += [ + ":gin_v8_snapshot_fingerprint", + "//crypto:crypto", + ] + sources += [ "$target_gen_dir/v8_snapshot_fingerprint.cc" ] + defines += [ "V8_VERIFY_EXTERNAL_STARTUP_DATA" ] + } +} + +if (v8_use_external_startup_data) { + action("gin_v8_snapshot_fingerprint") { + script = "//gin/fingerprint/fingerprint_v8_snapshot.py" + + snapshot_file = "$root_build_dir/snapshot_blob.bin" + natives_file = "$root_build_dir/natives_blob.bin" + output_file = "$target_gen_dir/v8_snapshot_fingerprint.cc" + + args = [ + "--snapshot_file", + rebase_path(snapshot_file, root_build_dir), + "--natives_file", + rebase_path(natives_file, root_build_dir), + "--output_file", + rebase_path(output_file, root_build_dir), + ] + inputs = [ + snapshot_file, + natives_file, + ] + outputs = [ + output_file, + ] + } } executable("gin_shell") {
diff --git a/gin/DEPS b/gin/DEPS index 4e3f30a..d4cc2ba 100644 --- a/gin/DEPS +++ b/gin/DEPS
@@ -1,4 +1,5 @@ include_rules = [ "+base", + "+crypto", "+v8", ]
diff --git a/gin/fingerprint/fingerprint_v8_snapshot.gypi b/gin/fingerprint/fingerprint_v8_snapshot.gypi new file mode 100644 index 0000000..ede0de3 --- /dev/null +++ b/gin/fingerprint/fingerprint_v8_snapshot.gypi
@@ -0,0 +1,47 @@ +# Copyright 2015 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +# This file is meant to be included into a target to provide a rule that +# fingerprints the v8 snapshot and generates a .cc file which includes this +# fingerprint. +# +# To use this, create a gyp target with the following form: +# { +# 'target_name': 'gin_v8_snapshot_fingerprint', +# 'type': 'none', +# 'variables': { +# 'snapshot_file': 'snapshot blob file to be fingerprinted', +# 'natives_file': 'natives blob file to be fingerprinted', +# 'output_file': 'output .cc file to generate with fingerprints', +# }, +# 'includes': [ '../gin/fingerprint/fingerprint_v8_snapshot.gypi' ], +# }, +# + +{ + 'conditions': [ + ['v8_use_external_startup_data==1', { + 'actions': [ + { + 'action_name': 'Generate V8 snapshot fingerprint', + 'message': 'Generating V8 snapshot fingerprint', + 'inputs': [ + '<(DEPTH)/gin/fingerprint/fingerprint_v8_snapshot.py', + '<(snapshot_file)', + '<(natives_file)', + ], + 'outputs': [ + '<(output_file)', + ], + 'action': [ + 'python', '<(DEPTH)/gin/fingerprint/fingerprint_v8_snapshot.py', + '--snapshot_file=<(snapshot_file)', + '--natives_file=<(natives_file)', + '--output_file=<(output_file)', + ], + } + ], + }], + ], +} \ No newline at end of file
diff --git a/gin/fingerprint/fingerprint_v8_snapshot.py b/gin/fingerprint/fingerprint_v8_snapshot.py new file mode 100755 index 0000000..d1f7092 --- /dev/null +++ b/gin/fingerprint/fingerprint_v8_snapshot.py
@@ -0,0 +1,86 @@ +#!/usr/bin/env python +# +# Copyright 2015 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +"""Fingerprints the V8 snapshot blob files. + +Constructs a SHA256 fingerprint of the V8 natives and snapshot blob files and +creates a .cc file which includes these fingerprint as variables. +""" + +import hashlib +import optparse +import os +import sys + +_HEADER = """// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// This file was generated by fingerprint_v8_snapshot.py. + +namespace gin { +""" + +_FOOTER = """ +} // namespace gin +""" + + +def FingerprintFile(file_path): + input_file = open(file_path, 'rb') + sha256 = hashlib.sha256() + while True: + block = input_file.read(sha256.block_size) + if not block: + break + sha256.update(block) + return sha256.digest() + + +def WriteFingerprint(output_file, variable_name, fingerprint): + output_file.write('\nextern const unsigned char %s[] = { ' % variable_name) + for byte in fingerprint: + output_file.write(str(ord(byte)) + ', ') + output_file.write('};\n') + + +def WriteOutputFile(natives_fingerprint, + snapshot_fingerprint, + output_file_path): + output_dir_path = os.path.dirname(output_file_path) + if not os.path.exists(output_dir_path): + os.makedirs(output_dir_path) + output_file = open(output_file_path, 'w') + + output_file.write(_HEADER) + WriteFingerprint(output_file, 'g_natives_fingerprint', natives_fingerprint) + output_file.write('\n') + WriteFingerprint(output_file, 'g_snapshot_fingerprint', snapshot_fingerprint) + output_file.write(_FOOTER) + + +def main(): + parser = optparse.OptionParser() + + parser.add_option('--snapshot_file', + help='The input V8 snapshot blob file path.') + parser.add_option('--natives_file', + help='The input V8 natives blob file path.') + parser.add_option('--output_file', + help='The path for the output cc file which will be write.') + + options, _ = parser.parse_args() + + natives_fingerprint = FingerprintFile(options.natives_file) + snapshot_fingerprint = FingerprintFile(options.snapshot_file) + WriteOutputFile( + natives_fingerprint, snapshot_fingerprint, options.output_file) + + return 0 + + +if __name__ == '__main__': + sys.exit(main())
diff --git a/gin/gin.gyp b/gin/gin.gyp index b38dc85..096c120 100644 --- a/gin/gin.gyp +++ b/gin/gin.gyp
@@ -5,6 +5,7 @@ { 'variables': { 'chromium_code': 1, + 'gin_gen_path': '<(SHARED_INTERMEDIATE_DIR)/gin/', }, 'targets': [ { @@ -14,7 +15,6 @@ '../base/base.gyp:base', '../base/third_party/dynamic_annotations/dynamic_annotations.gyp:dynamic_annotations', '../v8/tools/gyp/v8.gyp:v8', - ], 'export_dependent_settings': [ '../base/base.gyp:base', @@ -78,6 +78,30 @@ 'wrappable.h', 'wrapper_info.cc', ], + 'conditions': [ + ['v8_use_external_startup_data==1 and OS=="win"', { + 'dependencies': [ + 'gin_v8_snapshot_fingerprint', + '../crypto/crypto.gyp:crypto', + ], + 'sources': [ + '<(gin_gen_path)/v8_snapshot_fingerprint.cc', + ], + 'defines': [ + 'V8_VERIFY_EXTERNAL_STARTUP_DATA', + ] + }], + ], + }, + { + 'target_name': 'gin_v8_snapshot_fingerprint', + 'type': 'none', + 'variables': { + 'snapshot_file': '<(PRODUCT_DIR)/snapshot_blob.bin', + 'natives_file': '<(PRODUCT_DIR)/natives_blob.bin', + 'output_file': '<(gin_gen_path)/v8_snapshot_fingerprint.cc', + }, + 'includes': [ '../gin/fingerprint/fingerprint_v8_snapshot.gypi' ], }, { 'target_name': 'gin_shell',
diff --git a/gin/isolate_holder.cc b/gin/isolate_holder.cc index 2b6d64b..c666e29 100644 --- a/gin/isolate_holder.cc +++ b/gin/isolate_holder.cc
@@ -11,7 +11,9 @@ #include "base/logging.h" #include "base/message_loop/message_loop.h" #include "base/rand_util.h" +#include "base/strings/sys_string_conversions.h" #include "base/sys_info.h" +#include "crypto/sha2.h" #include "gin/array_buffer.h" #include "gin/debug_impl.h" #include "gin/function_template.h" @@ -19,8 +21,8 @@ #include "gin/public/v8_platform.h" #include "gin/run_microtasks_observer.h" -#ifdef V8_USE_EXTERNAL_STARTUP_DATA -#ifdef OS_MACOSX +#if defined(V8_USE_EXTERNAL_STARTUP_DATA) +#if defined(OS_MACOSX) #include "base/mac/foundation_util.h" #endif // OS_MACOSX #include "base/path_service.h" @@ -40,16 +42,29 @@ base::MemoryMappedFile* g_mapped_natives = NULL; base::MemoryMappedFile* g_mapped_snapshot = NULL; -#ifdef V8_USE_EXTERNAL_STARTUP_DATA -bool MapV8Files(base::FilePath* natives_path, base::FilePath* snapshot_path, - int natives_fd = -1, int snapshot_fd = -1) { +#if defined(V8_USE_EXTERNAL_STARTUP_DATA) +bool MapV8Files(base::FilePath* natives_path, + base::FilePath* snapshot_path, + int natives_fd = -1, + int snapshot_fd = -1, + base::MemoryMappedFile::Region natives_region = + base::MemoryMappedFile::Region::kWholeFile, + base::MemoryMappedFile::Region snapshot_region = + base::MemoryMappedFile::Region::kWholeFile) { int flags = base::File::FLAG_OPEN | base::File::FLAG_READ; g_mapped_natives = new base::MemoryMappedFile; if (!g_mapped_natives->IsValid()) { +#if !defined(OS_WIN) if (natives_fd == -1 - ? !g_mapped_natives->Initialize(base::File(*natives_path, flags)) - : !g_mapped_natives->Initialize(base::File(natives_fd))) { + ? !g_mapped_natives->Initialize(base::File(*natives_path, flags), + natives_region) + : !g_mapped_natives->Initialize(base::File(natives_fd), + natives_region)) { +#else + if (!g_mapped_natives->Initialize(base::File(*natives_path, flags), + natives_region)) { +#endif // !OS_WIN delete g_mapped_natives; g_mapped_natives = NULL; LOG(FATAL) << "Couldn't mmap v8 natives data file"; @@ -59,9 +74,16 @@ g_mapped_snapshot = new base::MemoryMappedFile; if (!g_mapped_snapshot->IsValid()) { +#if !defined(OS_WIN) if (snapshot_fd == -1 - ? !g_mapped_snapshot->Initialize(base::File(*snapshot_path, flags)) - : !g_mapped_snapshot->Initialize(base::File(snapshot_fd))) { + ? !g_mapped_snapshot->Initialize(base::File(*snapshot_path, flags), + snapshot_region) + : !g_mapped_snapshot->Initialize(base::File(snapshot_fd), + snapshot_region)) { +#else + if (!g_mapped_snapshot->Initialize(base::File(*snapshot_path, flags), + snapshot_region)) { +#endif // !OS_WIN delete g_mapped_snapshot; g_mapped_snapshot = NULL; LOG(ERROR) << "Couldn't mmap v8 snapshot data file"; @@ -72,21 +94,44 @@ return true; } +#if defined(V8_VERIFY_EXTERNAL_STARTUP_DATA) +bool VerifyV8SnapshotFile(base::MemoryMappedFile* snapshot_file, + const unsigned char* fingerprint) { + unsigned char output[crypto::kSHA256Length]; + crypto::SHA256HashString( + base::StringPiece(reinterpret_cast<const char*>(snapshot_file->data()), + snapshot_file->length()), + output, sizeof(output)); + return !memcmp(fingerprint, output, sizeof(output)); +} +#endif // V8_VERIFY_EXTERNAL_STARTUP_DATA + #if !defined(OS_MACOSX) const int v8_snapshot_dir = #if defined(OS_ANDROID) base::DIR_ANDROID_APP_DATA; #elif defined(OS_POSIX) base::DIR_EXE; -#endif // defined(OS_ANDROID) -#endif // !defined(OS_MACOSX) +#elif defined(OS_WIN) + base::DIR_MODULE; +#endif // OS_ANDROID +#endif // !OS_MACOSX #endif // V8_USE_EXTERNAL_STARTUP_DATA } // namespace +#if defined(V8_USE_EXTERNAL_STARTUP_DATA) -#ifdef V8_USE_EXTERNAL_STARTUP_DATA +#if defined(V8_VERIFY_EXTERNAL_STARTUP_DATA) +// Defined in gen/gin/v8_snapshot_fingerprint.cc +extern const unsigned char g_natives_fingerprint[]; +extern const unsigned char g_snapshot_fingerprint[]; +#endif // V8_VERIFY_EXTERNAL_STARTUP_DATA + +const char IsolateHolder::kNativesFileName[] = "natives_blob.bin"; +const char IsolateHolder::kSnapshotFileName[] = "snapshot_blob.bin"; + // static bool IsolateHolder::LoadV8Snapshot() { if (g_mapped_natives && g_mapped_snapshot) @@ -97,26 +142,58 @@ PathService::Get(v8_snapshot_dir, &data_path); DCHECK(!data_path.empty()); - base::FilePath natives_path = data_path.AppendASCII("natives_blob.bin"); - base::FilePath snapshot_path = data_path.AppendASCII("snapshot_blob.bin"); + base::FilePath natives_path = data_path.AppendASCII(kNativesFileName); + base::FilePath snapshot_path = data_path.AppendASCII(kSnapshotFileName); #else // !defined(OS_MACOSX) + base::ScopedCFTypeRef<CFStringRef> natives_file_name( + base::SysUTF8ToCFStringRef(kNativesFileName)); base::FilePath natives_path = base::mac::PathForFrameworkBundleResource( - CFSTR("natives_blob.bin")); + natives_file_name); + base::ScopedCFTypeRef<CFStringRef> snapshot_file_name( + base::SysUTF8ToCFStringRef(kSnapshotFileName)); base::FilePath snapshot_path = base::mac::PathForFrameworkBundleResource( - CFSTR("snapshot_blob.bin")); + snapshot_file_name); DCHECK(!natives_path.empty()); DCHECK(!snapshot_path.empty()); #endif // !defined(OS_MACOSX) - return MapV8Files(&natives_path, &snapshot_path); + if (!MapV8Files(&natives_path, &snapshot_path)) + return false; + +#if defined(V8_VERIFY_EXTERNAL_STARTUP_DATA) + return VerifyV8SnapshotFile(g_mapped_natives, g_natives_fingerprint) && + VerifyV8SnapshotFile(g_mapped_snapshot, g_snapshot_fingerprint); +#else + return true; +#endif // V8_VERIFY_EXTERNAL_STARTUP_DATA } //static -bool IsolateHolder::LoadV8SnapshotFD(int natives_fd, int snapshot_fd) { +bool IsolateHolder::LoadV8SnapshotFd(int natives_fd, + int64 natives_offset, + int64 natives_size, + int snapshot_fd, + int64 snapshot_offset, + int64 snapshot_size) { if (g_mapped_natives && g_mapped_snapshot) return true; - return MapV8Files(NULL, NULL, natives_fd, snapshot_fd); + base::MemoryMappedFile::Region natives_region = + base::MemoryMappedFile::Region::kWholeFile; + if (natives_size != 0 || natives_offset != 0) { + natives_region = + base::MemoryMappedFile::Region(natives_offset, natives_size); + } + + base::MemoryMappedFile::Region snapshot_region = + base::MemoryMappedFile::Region::kWholeFile; + if (natives_size != 0 || natives_offset != 0) { + snapshot_region = + base::MemoryMappedFile::Region(snapshot_offset, snapshot_size); + } + + return MapV8Files( + NULL, NULL, natives_fd, snapshot_fd, natives_region, snapshot_region); } #endif // V8_USE_EXTERNAL_STARTUP_DATA @@ -193,7 +270,7 @@ v8::V8::SetFlagsFromString(v8_flags, sizeof(v8_flags) - 1); } v8::V8::SetEntropySource(&GenerateEntropy); -#ifdef V8_USE_EXTERNAL_STARTUP_DATA +#if defined(V8_USE_EXTERNAL_STARTUP_DATA) v8::StartupData natives; natives.data = reinterpret_cast<const char*>(g_mapped_natives->data()); natives.raw_size = static_cast<int>(g_mapped_natives->length());
diff --git a/gin/public/isolate_holder.h b/gin/public/isolate_holder.h index b12734c..44d1d89 100644 --- a/gin/public/isolate_holder.h +++ b/gin/public/isolate_holder.h
@@ -33,7 +33,7 @@ // Should be invoked once before creating IsolateHolder instances to // initialize V8 and Gin. In case V8_USE_EXTERNAL_STARTUP_DATA is defined, // V8's initial snapshot should be loaded (by calling LoadV8Snapshot or - // LoadV8SnapshotFD) before calling Initialize. + // LoadV8SnapshotFd) before calling Initialize. static void Initialize(ScriptMode mode, v8::ArrayBuffer::Allocator* allocator); @@ -51,8 +51,16 @@ // thread. void RemoveRunMicrotasksObserver(); -#ifdef V8_USE_EXTERNAL_STARTUP_DATA - static bool LoadV8SnapshotFD(int natives_fd, int snapshot_fd); +#if defined(V8_USE_EXTERNAL_STARTUP_DATA) + static const char kNativesFileName[]; + static const char kSnapshotFileName[]; + + static bool LoadV8SnapshotFd(int natives_fd, + int64 natives_offset, + int64 natives_size, + int snapshot_fd, + int64 snapshot_offset, + int64 snapshot_size); static bool LoadV8Snapshot(); #endif // V8_USE_EXTERNAL_STARTUP_DATA static void GetV8ExternalSnapshotData(const char** natives_data_out,