blob: e837e4f5d92f152545a699bc36dcbd80bf26c35c [file] [log] [blame]
[email protected]fd911dd2012-01-27 01:57:101// Copyright (c) 2012 The Chromium Authors. All rights reserved.
license.botbf09a502008-08-24 00:55:552// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
initial.commit09911bf2008-07-26 23:55:294
[email protected]d353541f2012-05-03 22:45:415#include "content/renderer/render_process_impl.h"
6
[email protected]037fce02009-01-22 01:42:157#include "build/build_config.h"
8
[email protected]037fce02009-01-22 01:42:159#if defined(OS_WIN)
initial.commit09911bf2008-07-26 23:55:2910#include <windows.h>
11#include <objidl.h>
12#include <mlang.h>
[email protected]037fce02009-01-22 01:42:1513#endif
initial.commit09911bf2008-07-26 23:55:2914
fdorayd2233a72016-12-13 17:18:2115#include <stddef.h>
16
17#include <vector>
18
19#include "base/bind.h"
initial.commit09911bf2008-07-26 23:55:2920#include "base/command_line.h"
[email protected]037fce02009-01-22 01:42:1521#include "base/compiler_specific.h"
georgesak80353b52017-01-10 21:18:5122#include "base/debug/crash_logging.h"
ishell75fddc12016-04-12 14:03:1423#include "base/feature_list.h"
[email protected]35b4f0c2014-06-26 16:55:2724#include "base/sys_info.h"
fdorayd2233a72016-12-13 17:18:2125#include "base/task_scheduler/initialization_util.h"
26#include "base/task_scheduler/scheduler_worker_pool_params.h"
27#include "base/task_scheduler/task_scheduler.h"
28#include "base/task_scheduler/task_traits.h"
29#include "base/threading/platform_thread.h"
30#include "base/time/time.h"
nicke7cd12a2015-06-17 06:48:3831#include "content/child/site_isolation_stats_gatherer.h"
fdorayd2233a72016-12-13 17:18:2132#include "content/public/common/content_client.h"
bradnelsonc79f5a6f2016-10-10 18:31:1433#include "content/public/common/content_features.h"
[email protected]c08950d22011-10-13 22:20:2934#include "content/public/common/content_switches.h"
[email protected]d344114c2011-10-01 01:24:3435#include "content/public/renderer/content_renderer_client.h"
[email protected]6bd867b2013-07-24 22:10:2036#include "third_party/WebKit/public/web/WebFrame.h"
[email protected]067f5192014-01-29 05:22:0937#include "v8/include/v8.h"
initial.commit09911bf2008-07-26 23:55:2938
georgesak80353b52017-01-10 21:18:5139#if defined(OS_WIN)
40#include "base/win/win_util.h"
41#endif
42
ishell75fddc12016-04-12 14:03:1443namespace {
44
fdorayd2233a72016-12-13 17:18:2145enum WorkerPoolType : size_t {
46 BACKGROUND = 0,
47 BACKGROUND_FILE_IO,
48 FOREGROUND,
49 FOREGROUND_FILE_IO,
50 WORKER_POOL_COUNT // Always last.
51};
52
ishell75fddc12016-04-12 14:03:1453const base::Feature kV8_ES2015_TailCalls_Feature {
54 "V8_ES2015_TailCalls", base::FEATURE_DISABLED_BY_DEFAULT
55};
56
ishell73f577b2016-04-14 11:59:3957const base::Feature kV8_ES2016_ExplicitTailCalls_Feature{
58 "V8_ES2016_ExplicitTailCalls", base::FEATURE_DISABLED_BY_DEFAULT};
59
ishell75fddc12016-04-12 14:03:1460const base::Feature kV8SerializeEagerFeature{"V8_Serialize_Eager",
61 base::FEATURE_DISABLED_BY_DEFAULT};
62
63const base::Feature kV8SerializeAgeCodeFeature{
64 "V8_Serialize_Age_Code", base::FEATURE_DISABLED_BY_DEFAULT};
65
66void SetV8FlagIfFeature(const base::Feature& feature, const char* v8_flag) {
67 if (base::FeatureList::IsEnabled(feature)) {
68 v8::V8::SetFlagsFromString(v8_flag, strlen(v8_flag));
69 }
70}
71
72void SetV8FlagIfHasSwitch(const char* switch_name, const char* v8_flag) {
73 if (base::CommandLine::ForCurrentProcess()->HasSwitch(switch_name)) {
74 v8::V8::SetFlagsFromString(v8_flag, strlen(v8_flag));
75 }
76}
77
fdorayd2233a72016-12-13 17:18:2178std::vector<base::SchedulerWorkerPoolParams>
79GetDefaultSchedulerWorkerPoolParams() {
80 using StandbyThreadPolicy =
81 base::SchedulerWorkerPoolParams::StandbyThreadPolicy;
82 using ThreadPriority = base::ThreadPriority;
83 constexpr size_t kMaxNumThreadsInBackgroundPool = 1;
84 constexpr size_t kMaxNumThreadsInBackgroundFileIOPool = 1;
85 constexpr int kMaxNumThreadsInForegroundPoolLowerBound = 2;
86 constexpr int kMaxNumThreadsInForegroundPoolUpperBound = 4;
87 constexpr double kMaxNumThreadsInForegroundPoolCoresMultiplier = 1;
88 constexpr int kMaxNumThreadsInForegroundPoolOffset = 0;
89 constexpr size_t kMaxNumThreadsInForegroundFileIOPool = 1;
90 constexpr auto kSuggestedReclaimTime = base::TimeDelta::FromSeconds(30);
91
92 std::vector<base::SchedulerWorkerPoolParams> params_vector;
93 params_vector.emplace_back("RendererBackground", ThreadPriority::BACKGROUND,
94 StandbyThreadPolicy::LAZY,
95 kMaxNumThreadsInBackgroundPool,
96 kSuggestedReclaimTime);
97 params_vector.emplace_back(
98 "RendererBackgroundFileIO", ThreadPriority::BACKGROUND,
99 StandbyThreadPolicy::LAZY, kMaxNumThreadsInBackgroundFileIOPool,
100 kSuggestedReclaimTime);
101 params_vector.emplace_back("RendererForeground", ThreadPriority::NORMAL,
102 StandbyThreadPolicy::LAZY,
103 base::RecommendedMaxNumberOfThreadsInPool(
104 kMaxNumThreadsInForegroundPoolLowerBound,
105 kMaxNumThreadsInForegroundPoolUpperBound,
106 kMaxNumThreadsInForegroundPoolCoresMultiplier,
107 kMaxNumThreadsInForegroundPoolOffset),
108 kSuggestedReclaimTime);
109 params_vector.emplace_back("RendererForegroundFileIO", ThreadPriority::NORMAL,
110 StandbyThreadPolicy::LAZY,
111 kMaxNumThreadsInForegroundFileIOPool,
112 kSuggestedReclaimTime);
113 DCHECK_EQ(WORKER_POOL_COUNT, params_vector.size());
114 return params_vector;
115}
116
117// Returns the worker pool index for |traits| defaulting to FOREGROUND or
118// FOREGROUND_FILE_IO on any other priorities based off of worker pools defined
119// in GetDefaultSchedulerWorkerPoolParams().
120size_t DefaultRendererWorkerPoolIndexForTraits(const base::TaskTraits& traits) {
121 const bool is_background =
122 traits.priority() == base::TaskPriority::BACKGROUND;
123 if (traits.with_file_io())
124 return is_background ? BACKGROUND_FILE_IO : FOREGROUND_FILE_IO;
125
126 return is_background ? BACKGROUND : FOREGROUND;
127}
128
129void InitializeTaskScheduler() {
130 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
131 switches::kSingleProcess)) {
132 // There should already be a TaskScheduler when the renderer runs inside the
133 // browser process.
134 DCHECK(base::TaskScheduler::GetInstance());
135 return;
136 }
137 DCHECK(!base::TaskScheduler::GetInstance());
138
139 std::vector<base::SchedulerWorkerPoolParams> params_vector;
140 base::TaskScheduler::WorkerPoolIndexForTraitsCallback
141 index_to_traits_callback;
142 content::GetContentClient()->renderer()->GetTaskSchedulerInitializationParams(
143 &params_vector, &index_to_traits_callback);
144
145 if (params_vector.empty()) {
146 params_vector = GetDefaultSchedulerWorkerPoolParams();
147 index_to_traits_callback =
148 base::Bind(&DefaultRendererWorkerPoolIndexForTraits);
149 }
150 DCHECK(index_to_traits_callback);
151
152 base::TaskScheduler::CreateAndSetDefaultTaskScheduler(
153 params_vector, index_to_traits_callback);
154}
155
ishell75fddc12016-04-12 14:03:14156} // namespace
157
[email protected]eb398192012-10-22 20:16:19158namespace content {
159
[email protected]396c3a462010-03-03 05:03:22160RenderProcessImpl::RenderProcessImpl()
[email protected]1cf03f7f2014-04-24 03:09:49161 : enabled_bindings_(0) {
[email protected]396c3a462010-03-03 05:03:22162#if defined(OS_WIN)
georgesak80353b52017-01-10 21:18:51163 // Record whether the machine is domain joined in a crash key. This will be
164 // used to better identify whether crashes are from enterprise users.
165 // Note that this is done very early on so that crashes have the highest
166 // chance of getting tagged.
167 base::debug::SetCrashKeyValue("enrolled-to-domain",
168 base::win::IsEnrolledToDomain() ? "yes" : "no");
169
[email protected]396c3a462010-03-03 05:03:22170 // HACK: See http://b/issue?id=1024307 for rationale.
171 if (GetModuleHandle(L"LPK.DLL") == NULL) {
172 // Makes sure lpk.dll is loaded by gdi32 to make sure ExtTextOut() works
173 // when buffering into a EMF buffer for printing.
174 typedef BOOL (__stdcall *GdiInitializeLanguagePack)(int LoadedShapingDLLs);
175 GdiInitializeLanguagePack gdi_init_lpk =
176 reinterpret_cast<GdiInitializeLanguagePack>(GetProcAddress(
177 GetModuleHandle(L"GDI32.DLL"),
178 "GdiInitializeLanguagePack"));
179 DCHECK(gdi_init_lpk);
[email protected]00c39612010-03-06 02:53:28180 if (gdi_init_lpk) {
[email protected]396c3a462010-03-03 05:03:22181 gdi_init_lpk(0);
[email protected]00c39612010-03-06 02:53:28182 }
[email protected]396c3a462010-03-03 05:03:22183 }
[email protected]e68e62fa2009-02-20 02:00:04184#endif
185
[email protected]35b4f0c2014-06-26 16:55:27186 if (base::SysInfo::IsLowEndDevice()) {
[email protected]067f5192014-01-29 05:22:09187 std::string optimize_flag("--optimize-for-size");
188 v8::V8::SetFlagsFromString(optimize_flag.c_str(),
189 static_cast<int>(optimize_flag.size()));
190 }
[email protected]987422f2013-10-01 10:33:31191
ishell75fddc12016-04-12 14:03:14192 SetV8FlagIfFeature(kV8_ES2015_TailCalls_Feature, "--harmony-tailcalls");
ishell73f577b2016-04-14 11:59:39193 SetV8FlagIfFeature(kV8_ES2016_ExplicitTailCalls_Feature,
194 "--harmony-explicit-tailcalls");
ishell75fddc12016-04-12 14:03:14195 SetV8FlagIfFeature(kV8SerializeEagerFeature, "--serialize_eager");
196 SetV8FlagIfFeature(kV8SerializeAgeCodeFeature, "--serialize_age_code");
197 SetV8FlagIfHasSwitch(switches::kDisableJavaScriptHarmonyShipping,
198 "--noharmony-shipping");
199 SetV8FlagIfHasSwitch(switches::kJavaScriptHarmony, "--harmony");
bradnelsonc79f5a6f2016-10-10 18:31:14200 SetV8FlagIfFeature(features::kAsmJsToWebAssembly, "--validate-asm");
201 SetV8FlagIfFeature(features::kWebAssembly, "--expose-wasm");
bradnelsonf5cb1b62016-10-12 18:21:08202 SetV8FlagIfFeature(features::kSharedArrayBuffer,
203 "--harmony-sharedarraybuffer");
ishell75fddc12016-04-12 14:03:14204
avi83883c82014-12-23 00:08:49205 const base::CommandLine& command_line =
206 *base::CommandLine::ForCurrentProcess();
ishell75fddc12016-04-12 14:03:14207
[email protected]396c3a462010-03-03 05:03:22208 if (command_line.HasSwitch(switches::kJavaScriptFlags)) {
[email protected]067f5192014-01-29 05:22:09209 std::string flags(
[email protected]95edc392010-07-30 22:00:38210 command_line.GetSwitchValueASCII(switches::kJavaScriptFlags));
[email protected]067f5192014-01-29 05:22:09211 v8::V8::SetFlagsFromString(flags.c_str(), static_cast<int>(flags.size()));
[email protected]396c3a462010-03-03 05:03:22212 }
[email protected]55dd9332013-09-04 17:17:50213
nick88299ba2015-06-16 23:57:41214 SiteIsolationStatsGatherer::SetEnabled(
215 GetContentClient()->renderer()->ShouldGatherSiteIsolationStats());
fdorayd2233a72016-12-13 17:18:21216
217 InitializeTaskScheduler();
[email protected]e68e62fa2009-02-20 02:00:04218}
219
[email protected]396c3a462010-03-03 05:03:22220RenderProcessImpl::~RenderProcessImpl() {
[email protected]396c3a462010-03-03 05:03:22221#ifndef NDEBUG
[email protected]180ef242013-11-07 06:50:46222 int count = blink::WebFrame::instanceCount();
[email protected]6bd867b2013-07-24 22:10:20223 if (count)
224 DLOG(ERROR) << "WebFrame LEAKED " << count << " TIMES";
[email protected]396c3a462010-03-03 05:03:22225#endif
[email protected]e68e62fa2009-02-20 02:00:04226
fdorayd2233a72016-12-13 17:18:21227 if (!base::CommandLine::ForCurrentProcess()->HasSwitch(
228 switches::kSingleProcess)) {
229 DCHECK(base::TaskScheduler::GetInstance());
230 base::TaskScheduler::GetInstance()->Shutdown();
231 }
232
[email protected]396c3a462010-03-03 05:03:22233 GetShutDownEvent()->Signal();
[email protected]396c3a462010-03-03 05:03:22234}
[email protected]e68e62fa2009-02-20 02:00:04235
[email protected]744c2a22012-03-15 18:42:04236void RenderProcessImpl::AddBindings(int bindings) {
237 enabled_bindings_ |= bindings;
238}
239
240int RenderProcessImpl::GetEnabledBindings() const {
241 return enabled_bindings_;
242}
243
[email protected]eb398192012-10-22 20:16:19244} // namespace content