diff options
author | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2022-02-04 17:20:24 +0100 |
---|---|---|
committer | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2022-02-12 08:15:25 +0000 |
commit | 8fa0776f1f79e91fc9c0b9c1ba11a0a29c05196b (patch) | |
tree | 788d8d7549712682703a0310ca4a0f0860d4802b /chromium/gin | |
parent | 606d85f2a5386472314d39923da28c70c60dc8e7 (diff) | |
download | qtwebengine-chromium-8fa0776f1f79e91fc9c0b9c1ba11a0a29c05196b.tar.gz |
BASELINE: Update Chromium to 98.0.4758.90
Change-Id: Ib7c41539bf8a8e0376bd639f27d68294de90f3c8
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
Diffstat (limited to 'chromium/gin')
32 files changed, 290 insertions, 106 deletions
diff --git a/chromium/gin/BUILD.gn b/chromium/gin/BUILD.gn index 18af92cf184..93d501cfb63 100644 --- a/chromium/gin/BUILD.gn +++ b/chromium/gin/BUILD.gn @@ -81,6 +81,7 @@ component("gin") { if (v8_use_external_startup_data) { data = [ "$root_out_dir/snapshot_blob.bin" ] + sources += [ "public/v8_snapshot_file_type.h" ] } defines = [ "GIN_IMPLEMENTATION" ] @@ -90,7 +91,10 @@ component("gin") { "//base/allocator:buildflags", "//v8", ] - deps = [ "//base/third_party/dynamic_annotations" ] + deps = [ + "//base/third_party/dynamic_annotations", + "//third_party/abseil-cpp:absl", + ] if (is_mac) { frameworks = [ "CoreFoundation.framework" ] diff --git a/chromium/gin/arguments.h b/chromium/gin/arguments.h index eaded13e299..307108c19d8 100644 --- a/chromium/gin/arguments.h +++ b/chromium/gin/arguments.h @@ -5,6 +5,7 @@ #ifndef GIN_ARGUMENTS_H_ #define GIN_ARGUMENTS_H_ +#include "base/memory/raw_ptr.h" #include "gin/converter.h" #include "gin/gin_export.h" @@ -109,7 +110,7 @@ class GIN_EXPORT Arguments { bool IsConstructCall() const; private: - v8::Isolate* isolate_; + raw_ptr<v8::Isolate> isolate_; union { const v8::FunctionCallbackInfo<v8::Value>* info_for_function_; const v8::PropertyCallbackInfo<v8::Value>* info_for_property_; diff --git a/chromium/gin/data_object_builder.cc b/chromium/gin/data_object_builder.cc index 243c7efc5ff..bdc1c8410b7 100644 --- a/chromium/gin/data_object_builder.cc +++ b/chromium/gin/data_object_builder.cc @@ -11,4 +11,6 @@ DataObjectBuilder::DataObjectBuilder(v8::Isolate* isolate) context_(isolate->GetCurrentContext()), object_(v8::Object::New(isolate)) {} +DataObjectBuilder::~DataObjectBuilder() = default; + } // namespace gin diff --git a/chromium/gin/data_object_builder.h b/chromium/gin/data_object_builder.h index 47d2d7a8913..b735963f45a 100644 --- a/chromium/gin/data_object_builder.h +++ b/chromium/gin/data_object_builder.h @@ -8,6 +8,7 @@ #include <utility> #include "base/check.h" +#include "base/memory/raw_ptr.h" #include "base/strings/string_piece.h" #include "gin/converter.h" #include "gin/gin_export.h" @@ -41,6 +42,8 @@ class GIN_EXPORT DataObjectBuilder { DataObjectBuilder(const DataObjectBuilder&) = delete; DataObjectBuilder& operator=(const DataObjectBuilder&) = delete; + ~DataObjectBuilder(); + template <typename T> DataObjectBuilder& Set(base::StringPiece key, T&& value) { DCHECK(!object_.IsEmpty()); @@ -68,7 +71,7 @@ class GIN_EXPORT DataObjectBuilder { } private: - v8::Isolate* isolate_; + raw_ptr<v8::Isolate> isolate_; v8::Local<v8::Context> context_; v8::Local<v8::Object> object_; }; diff --git a/chromium/gin/dictionary.h b/chromium/gin/dictionary.h index 2645d328b4c..947694b7d4a 100644 --- a/chromium/gin/dictionary.h +++ b/chromium/gin/dictionary.h @@ -5,6 +5,7 @@ #ifndef GIN_DICTIONARY_H_ #define GIN_DICTIONARY_H_ +#include "base/memory/raw_ptr.h" #include "gin/converter.h" #include "gin/gin_export.h" @@ -15,7 +16,7 @@ namespace gin { // arbitrary JavaScript object as a result. For example, Dictionary is useful // when you might use the |dictionary| type in WebIDL: // -// http://heycam.github.io/webidl/#idl-dictionaries +// https://webidl.spec.whatwg.org/#idl-dictionaries // // WARNING: You cannot retain a Dictionary object in the heap. The underlying // storage for Dictionary is tied to the closest enclosing @@ -58,7 +59,7 @@ class GIN_EXPORT Dictionary { friend struct Converter<Dictionary>; // TODO(aa): Remove this. Instead, get via FromV8(), Set(), and Get(). - v8::Isolate* isolate_; + raw_ptr<v8::Isolate> isolate_; v8::Local<v8::Object> object_; }; diff --git a/chromium/gin/function_template.h b/chromium/gin/function_template.h index db630d26942..61b2064ba01 100644 --- a/chromium/gin/function_template.h +++ b/chromium/gin/function_template.h @@ -10,6 +10,7 @@ #include "base/callback.h" #include "base/check.h" +#include "base/memory/raw_ptr.h" #include "base/strings/strcat.h" #include "gin/arguments.h" #include "gin/converter.h" @@ -187,7 +188,7 @@ class Invoker<std::index_sequence<indices...>, ArgTypes...> return arg1 && And(args...); } - Arguments* args_; + raw_ptr<Arguments> args_; }; // DispatchToCallback converts all the JavaScript arguments to C++ types and diff --git a/chromium/gin/gin_features.cc b/chromium/gin/gin_features.cc index 3f1949547b0..ab83bb99fb3 100644 --- a/chromium/gin/gin_features.cc +++ b/chromium/gin/gin_features.cc @@ -7,6 +7,14 @@ namespace features { +// Enable code space compaction when finalizing a full GC with stack +const base::Feature kV8CompactCodeSpaceWithStack{ + "V8CompactCodeSpaceWithStack", base::FEATURE_ENABLED_BY_DEFAULT}; + +// Enable compaction when finalizing a full GC with stack. +const base::Feature kV8CompactWithStack{"V8CompactWithStack", + base::FEATURE_ENABLED_BY_DEFAULT}; + // Enables optimization of JavaScript in V8. const base::Feature kV8OptimizeJavascript{"V8OptimizeJavascript", base::FEATURE_ENABLED_BY_DEFAULT}; @@ -66,6 +74,12 @@ const base::Feature kV8Turboprop{"V8Turboprop", const base::Feature kV8Sparkplug{"V8Sparkplug", base::FEATURE_ENABLED_BY_DEFAULT}; +// Enables the concurrent Sparkplug compiler. +const base::Feature kV8ConcurrentSparkplug{"V8ConcurrentSparkplug", + base::FEATURE_DISABLED_BY_DEFAULT}; +const base::FeatureParam<int> kV8ConcurrentSparkplugMaxThreads{ + &kV8ConcurrentSparkplug, "V8ConcurrentSparkplugMaxThreads", 0}; + // Makes sure the experimental Sparkplug compiler is only enabled if short // builtin calls are enabled too. const base::Feature kV8SparkplugNeedsShortBuiltinCalls{ @@ -95,6 +109,9 @@ const base::Feature kV8SlowHistograms{"V8SlowHistograms", base::FEATURE_DISABLED_BY_DEFAULT}; // Multiple finch experiments might use slow-histograms. We introduce // separate feature flags to circumvent finch limitations. +const base::Feature kV8SlowHistogramsCodeMemoryWriteProtection{ + "V8SlowHistogramsCodeMemoryWriteProtection", + base::FEATURE_DISABLED_BY_DEFAULT}; const base::Feature kV8SlowHistogramsSparkplug{ "V8SlowHistogramsSparkplug", base::FEATURE_DISABLED_BY_DEFAULT}; const base::Feature kV8SlowHistogramsSparkplugAndroid{ diff --git a/chromium/gin/gin_features.h b/chromium/gin/gin_features.h index 5aa231d63ba..834d9a0b934 100644 --- a/chromium/gin/gin_features.h +++ b/chromium/gin/gin_features.h @@ -11,7 +11,12 @@ namespace features { +GIN_EXPORT extern const base::Feature kV8CompactCodeSpaceWithStack; +GIN_EXPORT extern const base::Feature kV8CompactWithStack; GIN_EXPORT extern const base::Feature kV8ConcurrentInlining; +GIN_EXPORT extern const base::Feature kV8ConcurrentSparkplug; +GIN_EXPORT extern const base::FeatureParam<int> + kV8ConcurrentSparkplugMaxThreads; GIN_EXPORT extern const base::Feature kV8ExperimentalRegexpEngine; GIN_EXPORT extern const base::Feature kV8FlushBytecode; GIN_EXPORT extern const base::Feature kV8FlushBaselineCode; @@ -29,6 +34,8 @@ GIN_EXPORT extern const base::FeatureParam<int> kV8ScriptDelayMs; GIN_EXPORT extern const base::FeatureParam<int> kV8ScriptDelayOnceMs; GIN_EXPORT extern const base::Feature kV8ShortBuiltinCalls; GIN_EXPORT extern const base::Feature kV8SlowHistograms; +GIN_EXPORT extern const base::Feature + kV8SlowHistogramsCodeMemoryWriteProtection; GIN_EXPORT extern const base::Feature kV8SlowHistogramsSparkplug; GIN_EXPORT extern const base::Feature kV8SlowHistogramsSparkplugAndroid; GIN_EXPORT extern const base::Feature kV8SlowHistogramsScriptAblation; diff --git a/chromium/gin/handle.h b/chromium/gin/handle.h index 8a27f91e002..2be9ac6e1b5 100644 --- a/chromium/gin/handle.h +++ b/chromium/gin/handle.h @@ -5,6 +5,7 @@ #ifndef GIN_HANDLE_H_ #define GIN_HANDLE_H_ +#include "base/memory/raw_ptr.h" #include "gin/converter.h" namespace gin { @@ -36,7 +37,7 @@ class Handle { private: v8::Local<v8::Value> wrapper_; - T* object_; + raw_ptr<T> object_; }; template<typename T> diff --git a/chromium/gin/interceptor.h b/chromium/gin/interceptor.h index ff6dcc32384..73560e47850 100644 --- a/chromium/gin/interceptor.h +++ b/chromium/gin/interceptor.h @@ -10,6 +10,7 @@ #include <string> #include <vector> +#include "base/memory/raw_ptr.h" #include "gin/gin_export.h" #include "v8/include/v8-forward.h" @@ -36,8 +37,8 @@ class GIN_EXPORT NamedPropertyInterceptor { v8::Isolate* isolate); private: - v8::Isolate* isolate_; - WrappableBase* base_; + raw_ptr<v8::Isolate> isolate_; + raw_ptr<WrappableBase> base_; }; class GIN_EXPORT IndexedPropertyInterceptor { @@ -58,8 +59,8 @@ class GIN_EXPORT IndexedPropertyInterceptor { v8::Isolate* isolate); private: - v8::Isolate* isolate_; - WrappableBase* base_; + raw_ptr<v8::Isolate> isolate_; + raw_ptr<WrappableBase> base_; }; } // namespace gin diff --git a/chromium/gin/isolate_holder.cc b/chromium/gin/isolate_holder.cc index e9382446381..6305d03e231 100644 --- a/chromium/gin/isolate_holder.cc +++ b/chromium/gin/isolate_holder.cc @@ -12,9 +12,9 @@ #include <utility> #include "base/check_op.h" -#include "base/single_thread_task_runner.h" #include "base/system/sys_info.h" #include "base/task/current_thread.h" +#include "base/task/single_thread_task_runner.h" #include "base/threading/thread_task_runner_handle.h" #include "build/build_config.h" #include "gin/debug_impl.h" @@ -55,7 +55,9 @@ IsolateHolder::IsolateHolder( AccessMode access_mode, AllowAtomicsWaitMode atomics_wait_mode, IsolateType isolate_type, - IsolateCreationMode isolate_creation_mode) + IsolateCreationMode isolate_creation_mode, + v8::CreateHistogramCallback create_histogram_callback, + v8::AddHistogramSampleCallback add_histogram_sample_callback) : access_mode_(access_mode), isolate_type_(isolate_type) { CHECK(Initialized()) << "You need to invoke gin::IsolateHolder::Initialize first"; @@ -88,6 +90,8 @@ IsolateHolder::IsolateHolder( params.only_terminate_in_safe_scope = true; params.embedder_wrapper_type_index = kWrapperInfoIndex; params.embedder_wrapper_object_index = kEncodedValueIndex; + params.create_histogram_callback = create_histogram_callback; + params.add_histogram_sample_callback = add_histogram_sample_callback; v8::Isolate::Initialize(isolate_, params); } @@ -110,9 +114,10 @@ IsolateHolder::~IsolateHolder() { // static void IsolateHolder::Initialize(ScriptMode mode, v8::ArrayBuffer::Allocator* allocator, - const intptr_t* reference_table) { + const intptr_t* reference_table, + const std::string js_command_line_flags) { CHECK(allocator); - V8Initializer::Initialize(mode); + V8Initializer::Initialize(mode, js_command_line_flags); g_array_buffer_allocator = allocator; g_reference_table = reference_table; } diff --git a/chromium/gin/object_template_builder.h b/chromium/gin/object_template_builder.h index 33bfd24ffee..60265ea6d73 100644 --- a/chromium/gin/object_template_builder.h +++ b/chromium/gin/object_template_builder.h @@ -11,6 +11,7 @@ #include "base/bind.h" #include "base/callback.h" +#include "base/memory/raw_ptr.h" #include "base/strings/string_piece.h" #include "gin/converter.h" #include "gin/function_template.h" @@ -129,7 +130,7 @@ class GIN_EXPORT ObjectTemplateBuilder { v8::AccessorNameGetterCallback callback, v8::Local<v8::Value> data); - v8::Isolate* isolate_; + raw_ptr<v8::Isolate> isolate_; // If provided, |type_name_| will be used to give a user-friendly error // message if a member function is invoked on the wrong type of object. diff --git a/chromium/gin/per_context_data.h b/chromium/gin/per_context_data.h index 4ce53d80fc8..33968322a0e 100644 --- a/chromium/gin/per_context_data.h +++ b/chromium/gin/per_context_data.h @@ -5,6 +5,7 @@ #ifndef GIN_PER_CONTEXT_DATA_H_ #define GIN_PER_CONTEXT_DATA_H_ +#include "base/memory/raw_ptr.h" #include "base/supports_user_data.h" #include "gin/gin_export.h" #include "v8/include/v8-forward.h" @@ -38,8 +39,8 @@ class GIN_EXPORT PerContextData : public base::SupportsUserData { ContextHolder* context_holder() { return context_holder_; } private: - ContextHolder* context_holder_; - Runner* runner_; + raw_ptr<ContextHolder> context_holder_; + raw_ptr<Runner> runner_; }; } // namespace gin diff --git a/chromium/gin/per_isolate_data.cc b/chromium/gin/per_isolate_data.cc index 014830e69e9..888b984fb8b 100644 --- a/chromium/gin/per_isolate_data.cc +++ b/chromium/gin/per_isolate_data.cc @@ -8,7 +8,7 @@ #include "base/check.h" #include "base/notreached.h" -#include "base/single_thread_task_runner.h" +#include "base/task/single_thread_task_runner.h" #include "base/threading/thread_task_runner_handle.h" #include "gin/public/gin_embedders.h" #include "gin/v8_foreground_task_runner.h" diff --git a/chromium/gin/per_isolate_data.h b/chromium/gin/per_isolate_data.h index f792533c229..8d7c725a31d 100644 --- a/chromium/gin/per_isolate_data.h +++ b/chromium/gin/per_isolate_data.h @@ -8,8 +8,9 @@ #include <map> #include <memory> +#include "base/memory/raw_ptr.h" #include "base/memory/ref_counted.h" -#include "base/single_thread_task_runner.h" +#include "base/task/single_thread_task_runner.h" #include "gin/gin_export.h" #include "gin/public/isolate_holder.h" #include "gin/public/wrapper_info.h" @@ -87,8 +88,8 @@ class GIN_EXPORT PerIsolateData { // PerIsolateData doesn't actually own |isolate_|. Instead, the isolate is // owned by the IsolateHolder, which also owns the PerIsolateData. - v8::Isolate* isolate_; - v8::ArrayBuffer::Allocator* allocator_; + raw_ptr<v8::Isolate> isolate_; + raw_ptr<v8::ArrayBuffer::Allocator> allocator_; ObjectTemplateMap object_templates_; FunctionTemplateMap function_templates_; IndexedPropertyInterceptorMap indexed_interceptors_; diff --git a/chromium/gin/public/context_holder.h b/chromium/gin/public/context_holder.h index b71e4954dc4..3d403c05e86 100644 --- a/chromium/gin/public/context_holder.h +++ b/chromium/gin/public/context_holder.h @@ -8,6 +8,7 @@ #include <list> #include <memory> +#include "base/memory/raw_ptr.h" #include "gin/gin_export.h" #include "v8/include/v8-context.h" #include "v8/include/v8-forward.h" @@ -43,7 +44,7 @@ class GIN_EXPORT ContextHolder { void SetContext(v8::Local<v8::Context> context); private: - v8::Isolate* isolate_; + raw_ptr<v8::Isolate> isolate_; v8::UniquePersistent<v8::Context> context_; std::unique_ptr<PerContextData> data_; }; diff --git a/chromium/gin/public/isolate_holder.h b/chromium/gin/public/isolate_holder.h index f0a7d0c05fa..78133f9b343 100644 --- a/chromium/gin/public/isolate_holder.h +++ b/chromium/gin/public/isolate_holder.h @@ -7,10 +7,12 @@ #include <memory> +#include "base/memory/raw_ptr.h" #include "base/memory/ref_counted.h" #include "gin/gin_export.h" #include "gin/public/v8_idle_task_runner.h" #include "v8/include/v8-array-buffer.h" +#include "v8/include/v8-callbacks.h" #include "v8/include/v8-forward.h" namespace base { @@ -68,9 +70,8 @@ class GIN_EXPORT IsolateHolder { kUtility }; - explicit IsolateHolder( - scoped_refptr<base::SingleThreadTaskRunner> task_runner, - IsolateType isolate_type); + IsolateHolder(scoped_refptr<base::SingleThreadTaskRunner> task_runner, + IsolateType isolate_type); IsolateHolder(scoped_refptr<base::SingleThreadTaskRunner> task_runner, AccessMode access_mode, IsolateType isolate_type); @@ -79,7 +80,9 @@ class GIN_EXPORT IsolateHolder { AccessMode access_mode, AllowAtomicsWaitMode atomics_wait_mode, IsolateType isolate_type, - IsolateCreationMode isolate_creation_mode = IsolateCreationMode::kNormal); + IsolateCreationMode isolate_creation_mode = IsolateCreationMode::kNormal, + v8::CreateHistogramCallback create_histogram_callback = nullptr, + v8::AddHistogramSampleCallback add_histogram_sample_callback = nullptr); IsolateHolder(const IsolateHolder&) = delete; IsolateHolder& operator=(const IsolateHolder&) = delete; ~IsolateHolder(); @@ -89,12 +92,15 @@ class GIN_EXPORT IsolateHolder { // defined and the snapshot file is available, it should be loaded (by calling // V8Initializer::LoadV8SnapshotFromFD or // V8Initializer::LoadV8Snapshot) before calling this method. + // |js_command_line_flags| can contain a comma-separed command line flags + // that are passed to V8. // If the snapshot file contains customised contexts which have static // external references, |reference_table| needs to point an array of those // reference pointers. Otherwise, it can be nullptr. static void Initialize(ScriptMode mode, v8::ArrayBuffer::Allocator* allocator, - const intptr_t* reference_table = nullptr); + const intptr_t* reference_table = nullptr, + const std::string js_command_line_flags = {}); // Returns whether `Initialize` has already been invoked in the process. // Initialization is a one-way operation (i.e., this method cannot return @@ -125,7 +131,7 @@ class GIN_EXPORT IsolateHolder { void SetUp(scoped_refptr<base::SingleThreadTaskRunner> task_runner); std::unique_ptr<v8::SnapshotCreator> snapshot_creator_; - v8::Isolate* isolate_; + raw_ptr<v8::Isolate> isolate_; std::unique_ptr<PerIsolateData> isolate_data_; std::unique_ptr<V8IsolateMemoryDumpProvider> isolate_memory_dump_provider_; AccessMode access_mode_; diff --git a/chromium/gin/public/v8_snapshot_file_type.h b/chromium/gin/public/v8_snapshot_file_type.h new file mode 100644 index 00000000000..ad8b6a4c4f4 --- /dev/null +++ b/chromium/gin/public/v8_snapshot_file_type.h @@ -0,0 +1,32 @@ +// Copyright 2021 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. + +#ifndef GIN_PUBLIC_V8_SNAPSHOT_FILE_TYPE_H_ +#define GIN_PUBLIC_V8_SNAPSHOT_FILE_TYPE_H_ + +#if !defined(V8_USE_EXTERNAL_STARTUP_DATA) +#error Don't include this header unless v8_external_startup_data is true. +#endif + +#include "gin/gin_export.h" + +namespace gin { + +// Indicates which file to load as a snapshot blob image. +enum class V8SnapshotFileType { + kDefault, + + // Snapshot augmented with customized contexts, which can be deserialized + // using v8::Context::FromSnapshot. + kWithAdditionalContext, +}; + +// Returns the V8SnapshotFileType used when loading the snapshot. This must +// be called after loading the snapshot. +// NOTE: this is implemented in v8_initializer.cc +GIN_EXPORT V8SnapshotFileType GetLoadedSnapshotFileType(); + +} // namespace gin + +#endif // GIN_PUBLIC_V8_SNAPSHOT_FILE_TYPE_H_ diff --git a/chromium/gin/shell/gin_main.cc b/chromium/gin/shell/gin_main.cc index 25d8edebb59..7df858e5865 100644 --- a/chromium/gin/shell/gin_main.cc +++ b/chromium/gin/shell/gin_main.cc @@ -12,8 +12,8 @@ #include "base/logging.h" #include "base/memory/ptr_util.h" #include "base/run_loop.h" -#include "base/single_thread_task_runner.h" #include "base/task/single_thread_task_executor.h" +#include "base/task/single_thread_task_runner.h" #include "base/task/thread_pool/thread_pool_instance.h" #include "base/threading/thread_task_runner_handle.h" #include "gin/array_buffer.h" diff --git a/chromium/gin/shell_runner.h b/chromium/gin/shell_runner.h index 82d72a3642a..95ddd2629eb 100644 --- a/chromium/gin/shell_runner.h +++ b/chromium/gin/shell_runner.h @@ -7,6 +7,7 @@ #include <memory> +#include "base/memory/raw_ptr.h" #include "gin/runner.h" namespace gin { @@ -56,7 +57,7 @@ class GIN_EXPORT ShellRunner : public Runner { void Run(v8::Local<v8::Script> script); - ShellRunnerDelegate* delegate_; + raw_ptr<ShellRunnerDelegate> delegate_; std::unique_ptr<ContextHolder> context_holder_; }; diff --git a/chromium/gin/shell_runner_unittest.cc b/chromium/gin/shell_runner_unittest.cc index b4c8e1894fb..41c2622d076 100644 --- a/chromium/gin/shell_runner_unittest.cc +++ b/chromium/gin/shell_runner_unittest.cc @@ -25,7 +25,9 @@ using v8::String; namespace gin { TEST(RunnerTest, Run) { - base::test::SingleThreadTaskEnvironment task_environment; + // V8 is generally multi threaded and may use tasks for arbitrary reasons, + // such as GC and off-thread compilation. + base::test::TaskEnvironment task_environment; std::string source = "this.result = 'PASS';\n"; #ifdef V8_USE_EXTERNAL_STARTUP_DATA diff --git a/chromium/gin/try_catch.h b/chromium/gin/try_catch.h index 4f0656cb653..edacbec82cd 100644 --- a/chromium/gin/try_catch.h +++ b/chromium/gin/try_catch.h @@ -7,6 +7,7 @@ #include <string> +#include "base/memory/raw_ptr.h" #include "gin/gin_export.h" #include "v8/include/v8-exception.h" @@ -24,7 +25,7 @@ class GIN_EXPORT TryCatch { std::string GetStackTrace(); private: - v8::Isolate* isolate_; + raw_ptr<v8::Isolate> isolate_; v8::TryCatch try_catch_; }; diff --git a/chromium/gin/v8_foreground_task_runner.cc b/chromium/gin/v8_foreground_task_runner.cc index 0a40b8e0176..53500d1a873 100644 --- a/chromium/gin/v8_foreground_task_runner.cc +++ b/chromium/gin/v8_foreground_task_runner.cc @@ -6,7 +6,7 @@ #include "base/bind.h" #include "base/callback_helpers.h" -#include "base/single_thread_task_runner.h" +#include "base/task/single_thread_task_runner.h" #include "base/threading/thread_task_runner_handle.h" namespace gin { diff --git a/chromium/gin/v8_foreground_task_runner_with_locker.cc b/chromium/gin/v8_foreground_task_runner_with_locker.cc index a769c81328b..4451bfc98bf 100644 --- a/chromium/gin/v8_foreground_task_runner_with_locker.cc +++ b/chromium/gin/v8_foreground_task_runner_with_locker.cc @@ -6,7 +6,8 @@ #include "base/bind.h" #include "base/callback_helpers.h" -#include "base/single_thread_task_runner.h" +#include "base/memory/raw_ptr.h" +#include "base/task/single_thread_task_runner.h" #include "base/threading/thread_task_runner_handle.h" #include "v8/include/v8-locker.h" @@ -43,7 +44,7 @@ class IdleTaskWithLocker : public v8::IdleTask { } private: - v8::Isolate* isolate_; + raw_ptr<v8::Isolate> isolate_; std::unique_ptr<v8::IdleTask> task_; }; diff --git a/chromium/gin/v8_foreground_task_runner_with_locker.h b/chromium/gin/v8_foreground_task_runner_with_locker.h index 9d1ebbdf68d..78c81a2cddf 100644 --- a/chromium/gin/v8_foreground_task_runner_with_locker.h +++ b/chromium/gin/v8_foreground_task_runner_with_locker.h @@ -5,6 +5,7 @@ #ifndef GIN_V8_FOREGROUND_TASK_RUNNER_WITH_LOCKER_H_ #define GIN_V8_FOREGROUND_TASK_RUNNER_WITH_LOCKER_H_ +#include "base/memory/raw_ptr.h" #include "base/memory/ref_counted.h" #include "gin/v8_foreground_task_runner_base.h" @@ -35,7 +36,7 @@ class V8ForegroundTaskRunnerWithLocker : public V8ForegroundTaskRunnerBase { bool NonNestableTasksEnabled() const override; private: - v8::Isolate* isolate_; + raw_ptr<v8::Isolate> isolate_; scoped_refptr<base::SingleThreadTaskRunner> task_runner_; }; diff --git a/chromium/gin/v8_initializer.cc b/chromium/gin/v8_initializer.cc index 3d8d99cc584..f576fc909ee 100644 --- a/chromium/gin/v8_initializer.cc +++ b/chromium/gin/v8_initializer.cc @@ -24,13 +24,17 @@ #include "base/notreached.h" #include "base/path_service.h" #include "base/rand_util.h" +#include "base/strings/string_piece.h" +#include "base/strings/string_split.h" #include "base/strings/string_util.h" #include "base/strings/sys_string_conversions.h" #include "base/system/sys_info.h" #include "base/threading/platform_thread.h" #include "base/time/time.h" +#include "base/win/windows_version.h" #include "build/build_config.h" #include "gin/gin_features.h" +#include "third_party/abseil-cpp/absl/types/optional.h" #include "v8/include/v8-initialization.h" #include "v8/include/v8-snapshot.h" @@ -49,6 +53,10 @@ namespace { // This global is never freed nor closed. base::MemoryMappedFile* g_mapped_snapshot = nullptr; +#if defined(V8_USE_EXTERNAL_STARTUP_DATA) +absl::optional<gin::V8SnapshotFileType> g_snapshot_file_type; +#endif + bool GenerateEntropy(unsigned char* buffer, size_t amount) { base::RandBytes(buffer, amount); return true; @@ -88,12 +96,11 @@ const char kV8ContextSnapshotFileName[] = V8_CONTEXT_SNAPSHOT_FILENAME; const char kSnapshotFileName[] = "snapshot_blob.bin"; #endif // defined(OS_ANDROID) -const char* GetSnapshotFileName( - const V8Initializer::V8SnapshotFileType file_type) { +const char* GetSnapshotFileName(const V8SnapshotFileType file_type) { switch (file_type) { - case V8Initializer::V8SnapshotFileType::kDefault: + case V8SnapshotFileType::kDefault: return kSnapshotFileName; - case V8Initializer::V8SnapshotFileType::kWithAdditionalContext: + case V8SnapshotFileType::kWithAdditionalContext: #if defined(USE_V8_CONTEXT_SNAPSHOT) return kV8ContextSnapshotFileName; #else @@ -223,44 +230,15 @@ void SetV8FlagsIfOverridden(const base::Feature& feature, } } -} // namespace - -// static -void V8Initializer::Initialize(IsolateHolder::ScriptMode mode) { - static bool v8_is_initialized = false; - if (v8_is_initialized) - return; - - v8::V8::InitializePlatform(V8Platform::Get()); - -#if defined(V8_VIRTUAL_MEMORY_CAGE) - static_assert(ARCH_CPU_64_BITS, - "V8 virtual memory cage can only work in 64-bit builds"); - // For now, creating the virtual memory cage is optional, and we only do it - // if the correpsonding feature is enabled. In the future, it will be - // mandatory when compiling with V8_VIRTUAL_MEMORY_CAGE. - bool v8_cage_is_initialized = false; - if (base::FeatureList::IsEnabled(features::kV8VirtualMemoryCage)) { - v8_cage_is_initialized = v8::V8::InitializeVirtualMemoryCage(); - - // Record the size of the virtual memory cage, in GB. The size will always - // be a power of two, so we use a sparse histogram to capture it. - // If the initialization failed, this API will return zero. - // The main reason for capturing this histogram here instead of having V8 - // do it is that there are no Isolates available yet, which are required - // for recording histograms in V8. - size_t size = v8::V8::GetVirtualMemoryCageSizeInBytes(); - int sizeInGB = size >> 30; - DCHECK(base::bits::IsPowerOfTwo(size)); - DCHECK(size == 0 || sizeInGB > 0); - base::UmaHistogramSparse("V8.VirtualMemoryCageSizeGB", sizeInGB); - } -#endif - +void SetFlags(IsolateHolder::ScriptMode mode, + const std::string js_command_line_flags) { // We assume that all feature flag defaults correspond to the default - // values of the coresponding V8 flags. - // TODO(cbruni): Fix flag priorities to let --js-flags override feature - // flags. + // values of the corresponding V8 flags. + SetV8FlagsIfOverridden(features::kV8CompactCodeSpaceWithStack, + "--compact-code-space-with-stack", + "--no-compact-code-space-with-stack"); + SetV8FlagsIfOverridden(features::kV8CompactWithStack, "--compact-with-stack", + "--no-compact-with-stack"); SetV8FlagsIfOverridden(features::kV8OptimizeJavascript, "--opt", "--no-opt"); SetV8FlagsIfOverridden(features::kV8FlushBytecode, "--flush-bytecode", "--no-flush-bytecode"); @@ -296,6 +274,8 @@ void V8Initializer::Initialize(IsolateHolder::ScriptMode mode) { "--no-turboprop"); SetV8FlagsIfOverridden(features::kV8Sparkplug, "--sparkplug", "--no-sparkplug"); + SetV8FlagsIfOverridden(features::kV8ConcurrentSparkplug, + "--concurrent-sparkplug", "--no-concurrent-sparkplug"); SetV8FlagsIfOverridden(features::kV8SparkplugNeedsShortBuiltinCalls, "--sparkplug-needs-short-builtins", "--no-sparkplug-needs-short-builtins"); @@ -307,6 +287,12 @@ void V8Initializer::Initialize(IsolateHolder::ScriptMode mode) { SetV8FlagsIfOverridden(features::kV8SlowHistograms, "--slow-histograms", "--no-slow-histograms"); + if (base::FeatureList::IsEnabled(features::kV8ConcurrentSparkplug)) { + if (int max_threads = features::kV8ConcurrentSparkplugMaxThreads.Get()) { + SetV8FlagsFormatted("--concurrent-sparkplug-max-threads=%i", max_threads); + } + } + if (base::FeatureList::IsEnabled(features::kV8ScriptAblation)) { if (int delay = features::kV8ScriptDelayMs.Get()) { SetV8FlagsFormatted("--script-delay=%i", delay); @@ -322,9 +308,11 @@ void V8Initializer::Initialize(IsolateHolder::ScriptMode mode) { // Make sure aliases of kV8SlowHistograms only enable the feature to // avoid contradicting settings between multiple finch experiments. bool any_slow_histograms_alias = - base::FeatureList::IsEnabled(features::kV8SlowHistogramsSparkplug) | base::FeatureList::IsEnabled( - features::kV8SlowHistogramsSparkplugAndroid) | + features::kV8SlowHistogramsCodeMemoryWriteProtection) || + base::FeatureList::IsEnabled(features::kV8SlowHistogramsSparkplug) || + base::FeatureList::IsEnabled( + features::kV8SlowHistogramsSparkplugAndroid) || base::FeatureList::IsEnabled(features::kV8SlowHistogramsScriptAblation); if (any_slow_histograms_alias) { SetV8Flags("--slow-histograms"); @@ -337,6 +325,59 @@ void V8Initializer::Initialize(IsolateHolder::ScriptMode mode) { SetV8Flags("--use_strict"); } + if (js_command_line_flags.empty()) + return; + + // Allow the --js-flags switch to override existing flags: + std::vector<base::StringPiece> flag_list = + base::SplitStringPiece(js_command_line_flags, ",", base::TRIM_WHITESPACE, + base::SPLIT_WANT_NONEMPTY); + for (const auto& flag : flag_list) { + v8::V8::SetFlagsFromString(std::string(flag).c_str(), flag.size()); + } +} + +} // namespace + +// static +void V8Initializer::Initialize(IsolateHolder::ScriptMode mode, + const std::string js_command_line_flags) { + static bool v8_is_initialized = false; + if (v8_is_initialized) + return; + + v8::V8::InitializePlatform(V8Platform::Get()); + + // Set this early on as some initialization steps, such as the initialization + // of the virtual memory cage, already use V8's random number generator. + v8::V8::SetEntropySource(&GenerateEntropy); + +#if defined(V8_VIRTUAL_MEMORY_CAGE) + static_assert(ARCH_CPU_64_BITS, + "V8 virtual memory cage can only work in 64-bit builds"); + // For now, creating the virtual memory cage is optional, and we only do it + // if the correpsonding feature is enabled. In the future, it will be + // mandatory when compiling with V8_VIRTUAL_MEMORY_CAGE. + bool v8_cage_is_initialized = false; + if (base::FeatureList::IsEnabled(features::kV8VirtualMemoryCage)) { + v8_cage_is_initialized = v8::V8::InitializeVirtualMemoryCage(); + + // Record the size of the virtual memory cage, in GB. The size will always + // be a power of two, so we use a sparse histogram to capture it. + // If the initialization failed, this API will return zero. + // The main reason for capturing this histogram here instead of having V8 + // do it is that there are no Isolates available yet, which are required + // for recording histograms in V8. + size_t size = v8::V8::GetVirtualMemoryCageSizeInBytes(); + int sizeInGB = size >> 30; + DCHECK(base::bits::IsPowerOfTwo(size)); + DCHECK(size == 0 || sizeInGB > 0); + base::UmaHistogramSparse("V8.VirtualMemoryCageSizeGB", sizeInGB); + } +#endif + + SetFlags(mode, js_command_line_flags); + #if defined(V8_USE_EXTERNAL_STARTUP_DATA) if (g_mapped_snapshot) { v8::StartupData snapshot; @@ -345,27 +386,67 @@ void V8Initializer::Initialize(IsolateHolder::ScriptMode mode) { } #endif // V8_USE_EXTERNAL_STARTUP_DATA - v8::V8::SetEntropySource(&GenerateEntropy); v8::V8::Initialize(); v8_is_initialized = true; #if defined(V8_VIRTUAL_MEMORY_CAGE) if (v8_cage_is_initialized) { + // These values are persisted to logs. Entries should not be renumbered and + // numeric values should never be reused. This should match enum + // V8VirtualMemoryCageMode in \tools\metrics\histograms\enums.xml + enum class VirtualMemoryCageMode { + kSecure = 0, + kInsecure = 1, + kMaxValue = kInsecure, + }; + base::UmaHistogramEnumeration("V8.VirtualMemoryCageMode", + v8::V8::IsUsingSecureVirtualMemoryCage() + ? VirtualMemoryCageMode::kSecure + : VirtualMemoryCageMode::kInsecure); + // When the virtual memory cage is enabled, ArrayBuffers must be located // inside the cage. To achieve that, PA's ConfigurablePool is created inside // the cage and Blink will create the ArrayBuffer partition inside that // Pool if it is enabled. v8::PageAllocator* cage_page_allocator = v8::V8::GetVirtualMemoryCagePageAllocator(); - size_t pool_size = base::internal::PartitionAddressSpace:: - ConfigurablePoolReservationSize(); - void* pool_base = cage_page_allocator->AllocatePages( - nullptr, pool_size, pool_size, v8::PageAllocator::kNoAccess); - // The V8 cage is guaranteed to be large enough to host the Pool. + const size_t max_pool_size = + base::internal::PartitionAddressSpace::ConfigurablePoolMaxSize(); + const size_t min_pool_size = + base::internal::PartitionAddressSpace::ConfigurablePoolMinSize(); + size_t pool_size = max_pool_size; +#if defined(OS_WIN) + // On Windows prior to 8.1 we allocate a smaller Pool since reserving + // virtual memory is expensive on these OSes. + if (base::win::GetVersion() < base::win::Version::WIN8_1) { + // The size chosen here should be synchronized with the size of the + // virtual memory reservation for the V8 cage on these platforms. + // Currently, that is 8GB, of which 4GB are used for V8's pointer + // compression region. + // TODO(saelo) give this constant a proper name and maybe move it + // somewhere else. + constexpr size_t kGB = 1ULL << 30; + pool_size = 4ULL * kGB; + DCHECK_LE(pool_size, max_pool_size); + DCHECK_GE(pool_size, min_pool_size); + } +#endif + // Try to reserve the maximum size of the pool at first, then keep halving + // the size on failure until it succeeds. + void* pool_base = nullptr; + while (!pool_base && pool_size >= min_pool_size) { + pool_base = cage_page_allocator->AllocatePages( + nullptr, pool_size, pool_size, v8::PageAllocator::kNoAccess); + if (!pool_base) { + pool_size /= 2; + } + } + // The V8 cage is guaranteed to be large enough to host the pool. CHECK(pool_base); base::internal::PartitionAddressSpace::InitConfigurablePool(pool_base, pool_size); + // TODO(saelo) maybe record the size of the Pool into UMA. } #endif } @@ -413,6 +494,7 @@ void V8Initializer::LoadV8SnapshotFromFile( return; } + g_snapshot_file_type = snapshot_file_type; base::MemoryMappedFile::Region region = base::MemoryMappedFile::Region::kWholeFile; if (snapshot_file_region) { @@ -433,10 +515,10 @@ base::FilePath V8Initializer::GetSnapshotFilePath( base::FilePath path; const char* filename = nullptr; switch (snapshot_file_type) { - case V8Initializer::V8SnapshotFileType::kDefault: + case V8SnapshotFileType::kDefault: filename = abi_32_bit ? kSnapshotFileName32 : kSnapshotFileName64; break; - case V8Initializer::V8SnapshotFileType::kWithAdditionalContext: + case V8SnapshotFileType::kWithAdditionalContext: filename = abi_32_bit ? kV8ContextSnapshotFileName32 : kV8ContextSnapshotFileName64; break; @@ -447,6 +529,12 @@ base::FilePath V8Initializer::GetSnapshotFilePath( return path; } #endif // defined(OS_ANDROID) + +V8SnapshotFileType GetLoadedSnapshotFileType() { + DCHECK(g_snapshot_file_type.has_value()); + return *g_snapshot_file_type; +} + #endif // defined(V8_USE_EXTERNAL_STARTUP_DATA) } // namespace gin diff --git a/chromium/gin/v8_initializer.h b/chromium/gin/v8_initializer.h index 955be10e118..de650aa85dd 100644 --- a/chromium/gin/v8_initializer.h +++ b/chromium/gin/v8_initializer.h @@ -15,6 +15,10 @@ #include "gin/public/isolate_holder.h" #include "gin/public/v8_platform.h" +#if defined(V8_USE_EXTERNAL_STARTUP_DATA) +#include "gin/public/v8_snapshot_file_type.h" +#endif + namespace v8 { class StartupData; } @@ -24,7 +28,8 @@ namespace gin { class GIN_EXPORT V8Initializer { public: // This should be called by IsolateHolder::Initialize(). - static void Initialize(IsolateHolder::ScriptMode mode); + static void Initialize(IsolateHolder::ScriptMode mode, + const std::string js_command_line_flags = {}); // Get address and size information for currently loaded snapshot. // If no snapshot is loaded, the return values are null for addresses @@ -34,15 +39,6 @@ class GIN_EXPORT V8Initializer { int* snapshot_size_out); #if defined(V8_USE_EXTERNAL_STARTUP_DATA) - // Indicates which file to load as a snapshot blob image. - enum class V8SnapshotFileType { - kDefault, - - // Snapshot augmented with customized contexts, which can be deserialized - // using v8::Context::FromSnapshot. - kWithAdditionalContext, - }; - // Load V8 snapshot from default resources, if they are available. static void LoadV8Snapshot( V8SnapshotFileType snapshot_file_type = V8SnapshotFileType::kDefault); diff --git a/chromium/gin/v8_isolate_memory_dump_provider.cc b/chromium/gin/v8_isolate_memory_dump_provider.cc index d0de05893dc..fcc8659daff 100644 --- a/chromium/gin/v8_isolate_memory_dump_provider.cc +++ b/chromium/gin/v8_isolate_memory_dump_provider.cc @@ -82,6 +82,9 @@ void DumpCodeStatistics(base::trace_event::MemoryAllocatorDump* dump, dump->AddScalar("external_script_source_size", base::trace_event::MemoryAllocatorDump::kUnitsBytes, code_statistics.external_script_source_size()); + dump->AddScalar("cpu_profiler_metadata_size", + base::trace_event::MemoryAllocatorDump::kUnitsBytes, + code_statistics.cpu_profiler_metadata_size()); } // Dump the number of native and detached contexts. @@ -154,7 +157,7 @@ bool CanHaveMultipleIsolates(IsolateHolder::IsolateType isolate_type) { LOG(FATAL) << "Unreachable code"; } -} // namespace anonymous +} // namespace void V8IsolateMemoryDumpProvider::DumpHeapStatistics( const base::trace_event::MemoryDumpArgs& args, diff --git a/chromium/gin/v8_isolate_memory_dump_provider.h b/chromium/gin/v8_isolate_memory_dump_provider.h index 2cd6346b2d1..b3ca74a6827 100644 --- a/chromium/gin/v8_isolate_memory_dump_provider.h +++ b/chromium/gin/v8_isolate_memory_dump_provider.h @@ -5,7 +5,8 @@ #ifndef GIN_V8_ISOLATE_MEMORY_DUMP_PROVIDER_H_ #define GIN_V8_ISOLATE_MEMORY_DUMP_PROVIDER_H_ -#include "base/single_thread_task_runner.h" +#include "base/memory/raw_ptr.h" +#include "base/task/single_thread_task_runner.h" #include "base/trace_event/memory_dump_provider.h" #include "gin/gin_export.h" @@ -36,7 +37,7 @@ class V8IsolateMemoryDumpProvider const base::trace_event::MemoryDumpArgs& args, base::trace_event::ProcessMemoryDump* process_memory_dump); - IsolateHolder* isolate_holder_; // Not owned. + raw_ptr<IsolateHolder> isolate_holder_; // Not owned. }; } // namespace gin diff --git a/chromium/gin/v8_isolate_memory_dump_provider_unittest.cc b/chromium/gin/v8_isolate_memory_dump_provider_unittest.cc index ec4002c702a..cbc02c2a33b 100644 --- a/chromium/gin/v8_isolate_memory_dump_provider_unittest.cc +++ b/chromium/gin/v8_isolate_memory_dump_provider_unittest.cc @@ -159,6 +159,7 @@ TEST_F(V8MemoryDumpProviderTest, DumpCodeStatistics) { bool did_dump_bytecode_size = false; bool did_dump_code_size = false; bool did_dump_external_scripts_size = false; + bool did_dump_cpu_profiler_metadata_size = false; for (const auto& name_dump : allocator_dumps) { const std::string& name = name_dump.first; @@ -171,6 +172,8 @@ TEST_F(V8MemoryDumpProviderTest, DumpCodeStatistics) { did_dump_code_size = true; } else if (entry.name == "external_script_source_size") { did_dump_external_scripts_size = true; + } else if (entry.name == "cpu_profiler_metadata_size") { + did_dump_cpu_profiler_metadata_size = true; } } } @@ -180,6 +183,7 @@ TEST_F(V8MemoryDumpProviderTest, DumpCodeStatistics) { ASSERT_TRUE(did_dump_bytecode_size); ASSERT_TRUE(did_dump_code_size); ASSERT_TRUE(did_dump_external_scripts_size); + ASSERT_TRUE(did_dump_cpu_profiler_metadata_size); } // Tests that a deterministic memory dump request performs a GC. diff --git a/chromium/gin/v8_platform.cc b/chromium/gin/v8_platform.cc index 563888e117d..0ccafbde90f 100644 --- a/chromium/gin/v8_platform.cc +++ b/chromium/gin/v8_platform.cc @@ -13,6 +13,7 @@ #include "base/debug/stack_trace.h" #include "base/location.h" #include "base/memory/nonscannable_memory.h" +#include "base/memory/raw_ptr.h" #include "base/rand_util.h" #include "base/system/sys_info.h" #include "base/task/post_job.h" @@ -23,7 +24,6 @@ #include "base/trace_event/trace_event.h" #include "base/tracing_buildflags.h" #include "build/build_config.h" - #include "gin/per_isolate_data.h" #include "v8_platform_page_allocator.h" @@ -210,7 +210,7 @@ class JobDelegateImpl : public v8::JobDelegate { bool IsJoiningThread() const override { return delegate_->IsJoiningThread(); } private: - base::JobDelegate* delegate_; + raw_ptr<base::JobDelegate> delegate_; }; class JobHandleImpl : public v8::JobHandle { diff --git a/chromium/gin/v8_platform_unittest.cc b/chromium/gin/v8_platform_unittest.cc index 332e0f7995c..fc748795370 100644 --- a/chromium/gin/v8_platform_unittest.cc +++ b/chromium/gin/v8_platform_unittest.cc @@ -7,6 +7,7 @@ #include <atomic> #include "base/barrier_closure.h" +#include "base/memory/raw_ptr.h" #include "base/test/task_environment.h" #include "base/test/test_waitable_event.h" #include "base/trace_event/trace_event.h" @@ -81,7 +82,7 @@ TEST(V8PlatformTest, PostJobSimple) { return *num_tasks_to_run; } - std::atomic_size_t* num_tasks_to_run; + raw_ptr<std::atomic_size_t> num_tasks_to_run; }; auto handle = V8Platform::Get()->PostJob(v8::TaskPriority::kUserVisible, @@ -126,9 +127,9 @@ TEST(V8PlatformTest, PostJobLifetime) { return *num_tasks_to_run_; } - std::atomic_size_t* num_tasks_to_run_; + raw_ptr<std::atomic_size_t> num_tasks_to_run_; base::RepeatingClosure threads_running_barrier_; - base::TestWaitableEvent* threads_continue_; + raw_ptr<base::TestWaitableEvent> threads_continue_; }; base::test::TaskEnvironment task_environment; |