diff options
author | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2017-07-17 13:57:45 +0200 |
---|---|---|
committer | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2017-07-19 13:44:40 +0000 |
commit | 6ec7b8da05d21a3878bd21c691b41e675d74bb1c (patch) | |
tree | b87f250bc19413750b9bb9cdbf2da20ef5014820 /chromium/gin | |
parent | ec02ee4181c49b61fce1c8fb99292dbb8139cc90 (diff) | |
download | qtwebengine-chromium-6ec7b8da05d21a3878bd21c691b41e675d74bb1c.tar.gz |
BASELINE: Update Chromium to 60.0.3112.70
Change-Id: I9911c2280a014d4632f254857876a395d4baed2d
Reviewed-by: Alexandru Croitor <alexandru.croitor@qt.io>
Diffstat (limited to 'chromium/gin')
-rw-r--r-- | chromium/gin/BUILD.gn | 6 | ||||
-rw-r--r-- | chromium/gin/OWNERS | 3 | ||||
-rw-r--r-- | chromium/gin/README.md (renamed from chromium/gin/README) | 8 | ||||
-rw-r--r-- | chromium/gin/arguments.cc | 13 | ||||
-rw-r--r-- | chromium/gin/arguments.h | 5 | ||||
-rw-r--r-- | chromium/gin/arguments_unittest.cc | 63 | ||||
-rw-r--r-- | chromium/gin/data_object_builder.cc | 14 | ||||
-rw-r--r-- | chromium/gin/data_object_builder.h | 69 | ||||
-rw-r--r-- | chromium/gin/data_object_builder_unittest.cc | 119 | ||||
-rw-r--r-- | chromium/gin/isolate_holder.cc | 1 | ||||
-rw-r--r-- | chromium/gin/modules/module_registry.cc | 3 | ||||
-rw-r--r-- | chromium/gin/modules/timer.cc | 9 | ||||
-rw-r--r-- | chromium/gin/modules/timer_unittest.cc | 30 | ||||
-rw-r--r-- | chromium/gin/shell/gin_main.cc | 52 | ||||
-rw-r--r-- | chromium/gin/shell_runner_unittest.cc | 4 | ||||
-rw-r--r-- | chromium/gin/v8_platform.cc | 27 |
16 files changed, 362 insertions, 64 deletions
diff --git a/chromium/gin/BUILD.gn b/chromium/gin/BUILD.gn index 427d2a03f8c..f386fb6b222 100644 --- a/chromium/gin/BUILD.gn +++ b/chromium/gin/BUILD.gn @@ -32,6 +32,8 @@ component("gin") { "context_holder.cc", "converter.cc", "converter.h", + "data_object_builder.cc", + "data_object_builder.h", "debug_impl.cc", "debug_impl.h", "dictionary.cc", @@ -120,7 +122,7 @@ executable("gin_shell") { ":gin", "//base", "//base:i18n", - "//build/config/sanitizers:deps", + "//build/config:exe_and_shlib_deps", "//build/win:default_exe_manifest", "//v8", ] @@ -151,6 +153,7 @@ source_set("gin_test") { "//testing/gtest", ] deps = [ + "//base/test:test_support", "//v8", ] @@ -161,6 +164,7 @@ test("gin_unittests") { sources = [ "arguments_unittest.cc", "converter_unittest.cc", + "data_object_builder_unittest.cc", "interceptor_unittest.cc", "modules/module_registry_unittest.cc", "modules/timer_unittest.cc", diff --git a/chromium/gin/OWNERS b/chromium/gin/OWNERS index d691287b2d5..ae52483ef1c 100644 --- a/chromium/gin/OWNERS +++ b/chromium/gin/OWNERS @@ -1 +1,4 @@ jochen@chromium.org + +# TEAM: blink-reviews-bindings@chromium.org +# COMPONENT: Blink>Bindings diff --git a/chromium/gin/README b/chromium/gin/README.md index fc2d92e0f78..99a7a35fa54 100644 --- a/chromium/gin/README +++ b/chromium/gin/README.md @@ -5,13 +5,13 @@ This directory contains Gin, a set of utilities to make working with V8 easier. Here are some of the key bits: -* converter.h: Templatized JS<->C++ conversion routines for many common C++ +* converter.h: Templatized JS ↔ C++ conversion routines for many common C++ types. You can define your own by specializing Converter. -* function_template.h: Create JavaScript functions that dispatch to any C++ +* function\_template.h: Create JavaScript functions that dispatch to any C++ function, member function pointer, or base::Callback. -* object_template_builder.h: A handy utility for creation of v8::ObjectTemplate. +* object\_template\_builder.h: A handy utility for creation of v8::ObjectTemplate. * wrappable.h: Base class for C++ classes that want to be owned by the V8 GC. Wrappable objects are automatically deleted when GC discovers that nothing in @@ -20,5 +20,5 @@ Here are some of the key bits: * runner.h: Create script contexts and run code in them. -* module_runner_delegate.h: A delegate for runner that implements a subset of +* module\_runner\_delegate.h: A delegate for runner that implements a subset of the AMD module specification. Also see modules/ with some example modules. diff --git a/chromium/gin/arguments.cc b/chromium/gin/arguments.cc index 600a811f848..4d01c0e44d9 100644 --- a/chromium/gin/arguments.cc +++ b/chromium/gin/arguments.cc @@ -32,6 +32,19 @@ v8::Local<v8::Value> Arguments::PeekNext() const { return (*info_)[next_]; } +std::vector<v8::Local<v8::Value>> Arguments::GetAll() const { + std::vector<v8::Local<v8::Value>> result; + int length = info_->Length(); + if (length == 0) + return result; + + result.reserve(length); + for (int i = 0; i < length; ++i) + result.push_back((*info_)[i]); + + return result; +} + v8::Local<v8::Context> Arguments::GetHolderCreationContext() { return info_->Holder()->CreationContext(); } diff --git a/chromium/gin/arguments.h b/chromium/gin/arguments.h index 99a5d16db21..c0a7bc2171d 100644 --- a/chromium/gin/arguments.h +++ b/chromium/gin/arguments.h @@ -81,6 +81,11 @@ class GIN_EXPORT Arguments { // dereferencing the handle. v8::Local<v8::Value> PeekNext() const; + // Returns all arguments. Since this doesn't require any conversion, it + // cannot fail. This does not rely on or modify the current position in the + // array used by Get/PeekNext(). + std::vector<v8::Local<v8::Value>> GetAll() const; + void ThrowError() const; void ThrowTypeError(const std::string& message) const; diff --git a/chromium/gin/arguments_unittest.cc b/chromium/gin/arguments_unittest.cc index d2b51361995..3a262c7818d 100644 --- a/chromium/gin/arguments_unittest.cc +++ b/chromium/gin/arguments_unittest.cc @@ -64,4 +64,67 @@ TEST_F(ArgumentsTest, TestArgumentsHolderCreationContext) { } } +TEST_F(ArgumentsTest, TestGetAll) { + v8::Isolate* isolate = instance_->isolate(); + v8::HandleScope handle_scope(isolate); + v8::Local<v8::Context> context = context_.Get(instance_->isolate()); + + using V8List = std::vector<v8::Local<v8::Value>>; + + V8List list1 = { + gin::ConvertToV8(isolate, 1), gin::StringToV8(isolate, "some string"), + gin::ConvertToV8(context, std::vector<double>({2.0, 3.0})) + .ToLocalChecked(), + }; + bool called1 = false; + + V8List list2 = { + gin::StringToV8(isolate, "some other string"), + gin::ConvertToV8(isolate, 42), + }; + bool called2 = false; + + V8List list3; // Empty list. + bool called3 = false; + + auto check_arguments = [](V8List* expected, bool* called, + gin::Arguments* arguments) { + *called = true; + V8List actual = arguments->GetAll(); + ASSERT_EQ(expected->size(), actual.size()); + for (size_t i = 0; i < expected->size(); ++i) + EXPECT_EQ(expected->at(i), actual[i]) << i; + }; + + // Create an object that will compare GetHolderCreationContext() with + // |creation_context|. + v8::Local<v8::ObjectTemplate> object_template = + ObjectTemplateBuilder(isolate) + .SetMethod("check1", base::Bind(check_arguments, &list1, &called1)) + .SetMethod("check2", base::Bind(check_arguments, &list2, &called2)) + .SetMethod("check3", base::Bind(check_arguments, &list3, &called3)) + .Build(); + + v8::Local<v8::Object> object = + object_template->NewInstance(context).ToLocalChecked(); + + auto do_check = [object, context](V8List& args, base::StringPiece key) { + v8::Local<v8::Value> val; + ASSERT_TRUE( + object->Get(context, gin::StringToSymbol(context->GetIsolate(), key)) + .ToLocal(&val)); + ASSERT_TRUE(val->IsFunction()); + val.As<v8::Function>() + ->Call(context, object, static_cast<int>(args.size()), args.data()) + .ToLocalChecked(); + }; + + do_check(list1, "check1"); + EXPECT_TRUE(called1); + do_check(list2, "check2"); + EXPECT_TRUE(called2); + do_check(list3, "check3"); + EXPECT_TRUE(called3); +} + } // namespace gin diff --git a/chromium/gin/data_object_builder.cc b/chromium/gin/data_object_builder.cc new file mode 100644 index 00000000000..243c7efc5ff --- /dev/null +++ b/chromium/gin/data_object_builder.cc @@ -0,0 +1,14 @@ +// Copyright 2017 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. + +#include "gin/data_object_builder.h" + +namespace gin { + +DataObjectBuilder::DataObjectBuilder(v8::Isolate* isolate) + : isolate_(isolate), + context_(isolate->GetCurrentContext()), + object_(v8::Object::New(isolate)) {} + +} // namespace gin diff --git a/chromium/gin/data_object_builder.h b/chromium/gin/data_object_builder.h new file mode 100644 index 00000000000..8d75dfd2356 --- /dev/null +++ b/chromium/gin/data_object_builder.h @@ -0,0 +1,69 @@ +// Copyright 2017 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_DATA_OBJECT_BUILDER_H_ +#define GIN_DATA_OBJECT_BUILDER_H_ + +#include <utility> + +#include "base/logging.h" +#include "base/macros.h" +#include "base/strings/string_piece.h" +#include "gin/converter.h" +#include "gin/gin_export.h" +#include "v8/include/v8.h" + +namespace gin { + +// Constructs a JavaScript object with a series of data properties. +// (As with default data properties in JavaScript, these properties are +// configurable, writable and enumerable.) +// +// Values are automatically converted using gin::Converter, though if +// using a type where the conversion may fail, callers must convert ahead of +// time. +// +// This class avoids the pitfall of using v8::Object::Set, which may invoke +// setters on the object prototype. +// +// Expected usage: +// v8::Local<v8::Object> object = gin::DataObjectBuilder(isolate) +// .Set("boolean", true) +// .Set("integer", 42) +// .Build(); +// +// Because this builder class contains local handles, callers must ensure it +// does not outlive the scope in which it is created. +class GIN_EXPORT DataObjectBuilder { + public: + explicit DataObjectBuilder(v8::Isolate* isolate); + + template <typename T> + DataObjectBuilder& Set(base::StringPiece key, T&& value) { + DCHECK(!object_.IsEmpty()); + v8::Local<v8::String> v8_key = StringToSymbol(isolate_, key); + v8::Local<v8::Value> v8_value = + ConvertToV8(isolate_, std::forward<T>(value)); + CHECK(object_->CreateDataProperty(context_, v8_key, v8_value).ToChecked()); + return *this; + } + + v8::Local<v8::Object> Build() { + DCHECK(!object_.IsEmpty()); + v8::Local<v8::Object> result = object_; + object_.Clear(); + return result; + } + + private: + v8::Isolate* isolate_; + v8::Local<v8::Context> context_; + v8::Local<v8::Object> object_; + + DISALLOW_COPY_AND_ASSIGN(DataObjectBuilder); +}; + +} // namespace gin + +#endif // GIN_DATA_OBJECT_BUILDER_H_ diff --git a/chromium/gin/data_object_builder_unittest.cc b/chromium/gin/data_object_builder_unittest.cc new file mode 100644 index 00000000000..1629cdf596d --- /dev/null +++ b/chromium/gin/data_object_builder_unittest.cc @@ -0,0 +1,119 @@ +// Copyright 2017 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. + +#include "gin/data_object_builder.h" + +#include "base/bind.h" +#include "gin/dictionary.h" +#include "gin/public/isolate_holder.h" +#include "gin/test/v8_test.h" + +namespace gin { +namespace { + +using DataObjectBuilderTest = V8Test; + +// It should create ordinary data properties. +TEST_F(DataObjectBuilderTest, CreatesDataProperties) { + v8::Isolate* isolate = instance_->isolate(); + v8::HandleScope handle_scope(isolate); + v8::Local<v8::Context> context = context_.Get(isolate); + + v8::Local<v8::Object> object = + DataObjectBuilder(isolate).Set("key", 42).Build(); + ASSERT_TRUE(object->HasOwnProperty(context, StringToSymbol(isolate, "key")) + .ToChecked()); + + v8::Local<v8::Value> descriptor_object; + ASSERT_TRUE( + object->GetOwnPropertyDescriptor(context, StringToSymbol(isolate, "key")) + .ToLocal(&descriptor_object)); + gin::Dictionary descriptor(isolate, descriptor_object.As<v8::Object>()); + + int32_t value = 0; + ASSERT_TRUE(descriptor.Get("value", &value)); + EXPECT_EQ(42, value); + + bool writable = false; + ASSERT_TRUE(descriptor.Get("writable", &writable)); + EXPECT_TRUE(writable); + + bool enumerable = false; + ASSERT_TRUE(descriptor.Get("enumerable", &enumerable)); + EXPECT_TRUE(enumerable); + + bool configurable = false; + ASSERT_TRUE(descriptor.Get("configurable", &configurable)); + EXPECT_TRUE(configurable); +} + +// It should not invoke setters on the prototype chain. +TEST_F(DataObjectBuilderTest, DoesNotInvokeSetters) { + v8::Isolate* isolate = instance_->isolate(); + v8::HandleScope handle_scope(isolate); + v8::Local<v8::Context> context = context_.Get(isolate); + + // Install a setter on the object prototype. + v8::Local<v8::Value> object_constructor; + ASSERT_TRUE(context->Global() + ->Get(context, StringToSymbol(isolate, "Object")) + .ToLocal(&object_constructor)); + v8::Local<v8::Value> object_prototype; + ASSERT_TRUE(object_constructor.As<v8::Function>() + ->Get(context, StringToSymbol(isolate, "prototype")) + .ToLocal(&object_prototype)); + ASSERT_TRUE( + object_prototype.As<v8::Object>() + ->SetAccessor(context, StringToSymbol(isolate, "key"), + [](v8::Local<v8::Name>, + const v8::PropertyCallbackInfo<v8::Value>&) {}, + [](v8::Local<v8::Name>, v8::Local<v8::Value>, + const v8::PropertyCallbackInfo<void>&) { + ADD_FAILURE() << "setter should not be invoked"; + }) + .ToChecked()); + + // Create an object. + DataObjectBuilder(isolate).Set("key", 42).Build(); +} + +// The internal handle is cleared when the builder is finished. +// This makes the class harder to abuse, so that its methods cannot be used +// after something may have modified the object in unexpected ways. +#if DCHECK_IS_ON() +TEST_F(DataObjectBuilderTest, UnusableAfterBuild) { + v8::Isolate* isolate = instance_->isolate(); + v8::HandleScope handle_scope(isolate); + + DataObjectBuilder builder(isolate); + EXPECT_FALSE(builder.Build().IsEmpty()); + + bool has_dcheck_failure = false; + logging::ScopedLogAssertHandler handler(base::Bind( + [](bool* flag, const char* file, int line, base::StringPiece message, + base::StringPiece stack_trace) { *flag = true; }, + base::Unretained(&has_dcheck_failure))); + builder.Build(); + EXPECT_TRUE(has_dcheck_failure); +} +#endif // DCHECK_IS_ON() + +// As is the normal behaviour of CreateDataProperty, new data properties should +// replace existing ones. Since no non-configurable ones are present, nor should +// the object be non-extensible, this should work. +TEST_F(DataObjectBuilderTest, ReplacesExistingProperties) { + v8::Isolate* isolate = instance_->isolate(); + v8::HandleScope handle_scope(isolate); + + v8::Local<v8::Object> object = + DataObjectBuilder(isolate).Set("value", 42).Set("value", 55).Build(); + + gin::Dictionary dictionary(isolate, object); + int32_t value; + ASSERT_TRUE(dictionary.Get("value", &value)); + EXPECT_EQ(55, value); +} + +} // namespace +} // namespace gin diff --git a/chromium/gin/isolate_holder.cc b/chromium/gin/isolate_holder.cc index caea27e7a56..2e707359ca7 100644 --- a/chromium/gin/isolate_holder.cc +++ b/chromium/gin/isolate_holder.cc @@ -13,6 +13,7 @@ #include "base/logging.h" #include "base/message_loop/message_loop.h" +#include "base/single_thread_task_runner.h" #include "base/sys_info.h" #include "gin/debug_impl.h" #include "gin/function_template.h" diff --git a/chromium/gin/modules/module_registry.cc b/chromium/gin/modules/module_registry.cc index 3e8b4759760..99783d37920 100644 --- a/chromium/gin/modules/module_registry.cc +++ b/chromium/gin/modules/module_registry.cc @@ -11,6 +11,7 @@ #include <vector> #include "base/logging.h" +#include "base/memory/ptr_util.h" #include "gin/arguments.h" #include "gin/converter.h" #include "gin/modules/module_registry_observer.h" @@ -139,7 +140,7 @@ ModuleRegistry* ModuleRegistry::From(v8::Local<Context> context) { // PerContextData takes ownership of ModuleRegistryData. registry_data = new ModuleRegistryData; registry_data->registry.reset(new ModuleRegistry(context->GetIsolate())); - data->SetUserData(kModuleRegistryKey, registry_data); + data->SetUserData(kModuleRegistryKey, base::WrapUnique(registry_data)); } return registry_data->registry.get(); } diff --git a/chromium/gin/modules/timer.cc b/chromium/gin/modules/timer.cc index 9e5a26c8ea9..e1deeaad8f5 100644 --- a/chromium/gin/modules/timer.cc +++ b/chromium/gin/modules/timer.cc @@ -67,9 +67,14 @@ void Timer::OnTimerFired() { Runner::Scope scope(runner_.get()); v8::Isolate* isolate = runner_->GetContextHolder()->isolate(); + + v8::Local<v8::Object> wrapper; + if (!GetWrapper(isolate).ToLocal(&wrapper)) { + return; + } + v8::Local<v8::Function> function = v8::Local<v8::Function>::Cast( - GetWrapper(isolate) - .ToLocalChecked() + wrapper ->GetPrivate(runner_->GetContextHolder()->context(), GetHiddenPropertyName(isolate)) .ToLocalChecked()); diff --git a/chromium/gin/modules/timer_unittest.cc b/chromium/gin/modules/timer_unittest.cc index bd4b3450f0a..665ea4e788d 100644 --- a/chromium/gin/modules/timer_unittest.cc +++ b/chromium/gin/modules/timer_unittest.cc @@ -67,12 +67,6 @@ struct TestHelper { result->GetWrapper(isolate).ToLocalChecked()); } - void QuitSoon(base::MessageLoop* message_loop) { - message_loop->task_runner()->PostDelayedTask( - FROM_HERE, base::MessageLoop::QuitWhenIdleClosure(), - base::TimeDelta::FromMilliseconds(0)); - } - ShellRunnerDelegate delegate; std::unique_ptr<ShellRunner> runner; Runner::Scope scope; @@ -94,8 +88,7 @@ TEST_F(TimerUnittest, OneShot) { helper.runner->Run(source, "script"); EXPECT_EQ(0, helper.result->count()); - helper.QuitSoon(&message_loop_); - base::RunLoop().Run(); + base::RunLoop().RunUntilIdle(); EXPECT_EQ(1, helper.result->count()); } @@ -110,8 +103,7 @@ TEST_F(TimerUnittest, OneShotCancel) { helper.runner->Run(source, "script"); EXPECT_EQ(0, helper.result->count()); - helper.QuitSoon(&message_loop_); - base::RunLoop().Run(); + base::RunLoop().RunUntilIdle(); EXPECT_EQ(0, helper.result->count()); } @@ -121,12 +113,15 @@ TEST_F(TimerUnittest, Repeating) { // TODO(aa): Cannot do: if (++result.count == 3) because of v8 bug. Create // test case and report. std::string source = - "timer.createRepeating(0, function() {" - " result.count++;" - " if (result.count == 3) {" - " result.quit();" - " }" - "});"; + "var t = timer.createRepeating(0, function() {" + " result.count++;" + " if (result.count == 3) {" + " /* Cancel the timer to prevent a hang when ScopedTaskEnvironment " + " flushes main thread tasks. */" + " t.cancel();" + " result.quit();" + " }" + "});"; helper.runner->Run(source, "script"); EXPECT_EQ(0, helper.result->count()); @@ -146,9 +141,8 @@ TEST_F(TimerUnittest, TimerCallbackToDestroyedRunner) { EXPECT_EQ(0, helper.result->count()); // Destroy runner, which should destroy the timer object we created. - helper.QuitSoon(&message_loop_); helper.runner.reset(NULL); - base::RunLoop().Run(); + base::RunLoop().RunUntilIdle(); // Timer should not have run because it was deleted. EXPECT_EQ(0, helper.result->count()); diff --git a/chromium/gin/shell/gin_main.cc b/chromium/gin/shell/gin_main.cc index c7cf598756d..0b8f8b8597e 100644 --- a/chromium/gin/shell/gin_main.cc +++ b/chromium/gin/shell/gin_main.cc @@ -14,6 +14,7 @@ #include "base/message_loop/message_loop.h" #include "base/run_loop.h" #include "base/single_thread_task_runner.h" +#include "base/task_scheduler/task_scheduler.h" #include "base/threading/thread_task_runner_handle.h" #include "gin/array_buffer.h" #include "gin/modules/console.h" @@ -73,34 +74,43 @@ int main(int argc, char** argv) { #endif base::MessageLoop message_loop; + base::TaskScheduler::CreateAndStartWithDefaultParams("gin"); // Initialize the base::FeatureList since IsolateHolder can depend on it. base::FeatureList::SetInstance(base::WrapUnique(new base::FeatureList)); - gin::IsolateHolder::Initialize(gin::IsolateHolder::kStrictMode, - gin::IsolateHolder::kStableV8Extras, - gin::ArrayBufferAllocator::SharedInstance()); - gin::IsolateHolder instance(base::ThreadTaskRunnerHandle::Get()); - - gin::GinShellRunnerDelegate delegate; - gin::ShellRunner runner(&delegate, instance.isolate()); - { - gin::Runner::Scope scope(&runner); - runner.GetContextHolder() - ->isolate() - ->SetCaptureStackTraceForUncaughtExceptions(true); + gin::IsolateHolder::Initialize(gin::IsolateHolder::kStrictMode, + gin::IsolateHolder::kStableV8Extras, + gin::ArrayBufferAllocator::SharedInstance()); + gin::IsolateHolder instance(base::ThreadTaskRunnerHandle::Get()); + + gin::GinShellRunnerDelegate delegate; + gin::ShellRunner runner(&delegate, instance.isolate()); + + { + gin::Runner::Scope scope(&runner); + runner.GetContextHolder() + ->isolate() + ->SetCaptureStackTraceForUncaughtExceptions(true); + } + + base::CommandLine::StringVector args = + base::CommandLine::ForCurrentProcess()->GetArgs(); + for (base::CommandLine::StringVector::const_iterator it = args.begin(); + it != args.end(); ++it) { + base::ThreadTaskRunnerHandle::Get()->PostTask( + FROM_HERE, + base::Bind(gin::Run, runner.GetWeakPtr(), base::FilePath(*it))); + } + + base::RunLoop().RunUntilIdle(); } - base::CommandLine::StringVector args = - base::CommandLine::ForCurrentProcess()->GetArgs(); - for (base::CommandLine::StringVector::const_iterator it = args.begin(); - it != args.end(); ++it) { - base::ThreadTaskRunnerHandle::Get()->PostTask( - FROM_HERE, - base::Bind(gin::Run, runner.GetWeakPtr(), base::FilePath(*it))); - } + // gin::IsolateHolder waits for tasks running in TaskScheduler in its + // destructor and thus must be destroyed before TaskScheduler starts skipping + // CONTINUE_ON_SHUTDOWN tasks. + base::TaskScheduler::GetInstance()->Shutdown(); - base::RunLoop().RunUntilIdle(); return 0; } diff --git a/chromium/gin/shell_runner_unittest.cc b/chromium/gin/shell_runner_unittest.cc index 0743ededb62..02e6835abcf 100644 --- a/chromium/gin/shell_runner_unittest.cc +++ b/chromium/gin/shell_runner_unittest.cc @@ -5,7 +5,7 @@ #include "gin/shell_runner.h" #include "base/compiler_specific.h" -#include "base/message_loop/message_loop.h" +#include "base/test/scoped_task_environment.h" #include "base/threading/thread_task_runner_handle.h" #include "gin/array_buffer.h" #include "gin/converter.h" @@ -25,7 +25,7 @@ using v8::String; namespace gin { TEST(RunnerTest, Run) { - base::MessageLoop message_loop; + base::test::ScopedTaskEnvironment scoped_task_environment; std::string source = "this.result = 'PASS';\n"; #ifdef V8_USE_EXTERNAL_STARTUP_DATA diff --git a/chromium/gin/v8_platform.cc b/chromium/gin/v8_platform.cc index dc887c43c3e..1bfa2f66e8e 100644 --- a/chromium/gin/v8_platform.cc +++ b/chromium/gin/v8_platform.cc @@ -4,11 +4,14 @@ #include "gin/public/v8_platform.h" +#include <algorithm> + #include "base/bind.h" #include "base/debug/stack_trace.h" #include "base/location.h" #include "base/sys_info.h" -#include "base/threading/worker_pool.h" +#include "base/task_scheduler/post_task.h" +#include "base/task_scheduler/task_scheduler.h" #include "base/trace_event/trace_event.h" #include "gin/per_isolate_data.h" @@ -16,6 +19,9 @@ namespace gin { namespace { +constexpr base::TaskTraits kBackgroundThreadTaskTraits = { + base::TaskPriority::USER_VISIBLE}; + base::LazyInstance<V8Platform>::Leaky g_v8_platform = LAZY_INSTANCE_INITIALIZER; void RunWithLocker(v8::Isolate* isolate, v8::Task* task) { @@ -58,25 +64,16 @@ V8Platform::V8Platform() {} V8Platform::~V8Platform() {} size_t V8Platform::NumberOfAvailableBackgroundThreads() { - // WorkerPool will currently always create additional threads for posted - // background tasks, unless there are threads sitting idle (on posix). - // Indicate that V8 should create no more than the number of cores available, - // reserving one core for the main thread. - const size_t available_cores = - static_cast<size_t>(base::SysInfo::NumberOfProcessors()); - if (available_cores > 1) { - return available_cores - 1; - } - return 1; + return std::max(1, base::TaskScheduler::GetInstance() + ->GetMaxConcurrentTasksWithTraitsDeprecated( + kBackgroundThreadTaskTraits)); } void V8Platform::CallOnBackgroundThread( v8::Task* task, v8::Platform::ExpectedRuntime expected_runtime) { - base::WorkerPool::PostTask( - FROM_HERE, - base::Bind(&v8::Task::Run, base::Owned(task)), - expected_runtime == v8::Platform::kLongRunningTask); + base::PostTaskWithTraits(FROM_HERE, kBackgroundThreadTaskTraits, + base::Bind(&v8::Task::Run, base::Owned(task))); } void V8Platform::CallOnForegroundThread(v8::Isolate* isolate, v8::Task* task) { |