Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(68)

Side by Side Diff: chrome/renderer/chrome_render_process_observer.cc

Issue 1081323003: Convert renderer JS memory usage reporting to use Mojo. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@utility-process-report-js-memory
Patch Set: Rebase and fix tests. Created 5 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « chrome/renderer/chrome_render_process_observer.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/renderer/chrome_render_process_observer.h" 5 #include "chrome/renderer/chrome_render_process_observer.h"
6 6
7 #include <limits> 7 #include <limits>
8 #include <vector> 8 #include <vector>
9 9
10 #include "base/allocator/allocator_extension.h" 10 #include "base/allocator/allocator_extension.h"
11 #include "base/bind.h" 11 #include "base/bind.h"
12 #include "base/command_line.h" 12 #include "base/command_line.h"
13 #include "base/files/file_util.h" 13 #include "base/files/file_util.h"
14 #include "base/memory/weak_ptr.h" 14 #include "base/memory/weak_ptr.h"
15 #include "base/message_loop/message_loop.h" 15 #include "base/message_loop/message_loop.h"
16 #include "base/metrics/field_trial.h" 16 #include "base/metrics/field_trial.h"
17 #include "base/metrics/histogram.h" 17 #include "base/metrics/histogram.h"
18 #include "base/metrics/statistics_recorder.h" 18 #include "base/metrics/statistics_recorder.h"
19 #include "base/native_library.h" 19 #include "base/native_library.h"
20 #include "base/path_service.h" 20 #include "base/path_service.h"
21 #include "base/strings/utf_string_conversions.h" 21 #include "base/strings/utf_string_conversions.h"
22 #include "base/threading/platform_thread.h" 22 #include "base/threading/platform_thread.h"
23 #include "chrome/common/child_process_logging.h" 23 #include "chrome/common/child_process_logging.h"
24 #include "chrome/common/chrome_paths.h" 24 #include "chrome/common/chrome_paths.h"
25 #include "chrome/common/chrome_switches.h" 25 #include "chrome/common/chrome_switches.h"
26 #include "chrome/common/net/net_resource_provider.h" 26 #include "chrome/common/net/net_resource_provider.h"
27 #include "chrome/common/render_messages.h" 27 #include "chrome/common/render_messages.h"
28 #include "chrome/common/resource_usage_reporter.mojom.h"
28 #include "chrome/common/url_constants.h" 29 #include "chrome/common/url_constants.h"
29 #include "chrome/common/variations/variations_util.h" 30 #include "chrome/common/variations/variations_util.h"
30 #include "chrome/renderer/content_settings_observer.h" 31 #include "chrome/renderer/content_settings_observer.h"
31 #include "chrome/renderer/security_filter_peer.h" 32 #include "chrome/renderer/security_filter_peer.h"
32 #include "content/public/child/resource_dispatcher_delegate.h" 33 #include "content/public/child/resource_dispatcher_delegate.h"
34 #include "content/public/common/service_registry.h"
33 #include "content/public/renderer/render_thread.h" 35 #include "content/public/renderer/render_thread.h"
34 #include "content/public/renderer/render_view.h" 36 #include "content/public/renderer/render_view.h"
35 #include "content/public/renderer/render_view_visitor.h" 37 #include "content/public/renderer/render_view_visitor.h"
36 #include "crypto/nss_util.h" 38 #include "crypto/nss_util.h"
37 #include "net/base/net_errors.h" 39 #include "net/base/net_errors.h"
38 #include "net/base/net_module.h" 40 #include "net/base/net_module.h"
41 #include "third_party/mojo/src/mojo/public/cpp/bindings/strong_binding.h"
39 #include "third_party/WebKit/public/web/WebCache.h" 42 #include "third_party/WebKit/public/web/WebCache.h"
40 #include "third_party/WebKit/public/web/WebDocument.h" 43 #include "third_party/WebKit/public/web/WebDocument.h"
41 #include "third_party/WebKit/public/web/WebFrame.h" 44 #include "third_party/WebKit/public/web/WebFrame.h"
42 #include "third_party/WebKit/public/web/WebRuntimeFeatures.h" 45 #include "third_party/WebKit/public/web/WebRuntimeFeatures.h"
43 #include "third_party/WebKit/public/web/WebSecurityPolicy.h" 46 #include "third_party/WebKit/public/web/WebSecurityPolicy.h"
44 #include "third_party/WebKit/public/web/WebView.h" 47 #include "third_party/WebKit/public/web/WebView.h"
45 48
46 #if defined(ENABLE_EXTENSIONS) 49 #if defined(ENABLE_EXTENSIONS)
47 #include "chrome/renderer/extensions/extension_localization_peer.h" 50 #include "chrome/renderer/extensions/extension_localization_peer.h"
48 #endif 51 #endif
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
103 RenderThread::Get()->Send(new ChromeViewHostMsg_UpdatedCacheStats(stats)); 106 RenderThread::Get()->Send(new ChromeViewHostMsg_UpdatedCacheStats(stats));
104 } 107 }
105 108
106 base::WeakPtrFactory<RendererResourceDelegate> weak_factory_; 109 base::WeakPtrFactory<RendererResourceDelegate> weak_factory_;
107 110
108 DISALLOW_COPY_AND_ASSIGN(RendererResourceDelegate); 111 DISALLOW_COPY_AND_ASSIGN(RendererResourceDelegate);
109 }; 112 };
110 113
111 static const int kWaitForWorkersStatsTimeoutMS = 20; 114 static const int kWaitForWorkersStatsTimeoutMS = 20;
112 115
113 class HeapStatisticsCollector { 116 class ResourceUsageReporterImpl : public ResourceUsageReporter {
114 public: 117 public:
115 HeapStatisticsCollector() : round_id_(0) {} 118 explicit ResourceUsageReporterImpl(
116 119 mojo::InterfaceRequest<ResourceUsageReporter> req)
117 void InitiateCollection(); 120 : binding_(this, req.Pass()), weak_factory_(this) {}
118 static HeapStatisticsCollector* Instance(); 121 ~ResourceUsageReporterImpl() override {}
119 122
120 private: 123 private:
121 void CollectOnWorkerThread(scoped_refptr<base::TaskRunner> master, 124 static void CollectOnWorkerThread(
122 int round_id); 125 const scoped_refptr<base::TaskRunner>& master,
123 void ReceiveStats(int round_id, size_t total_size, size_t used_size); 126 base::WeakPtr<ResourceUsageReporterImpl> impl) {
124 void SendStatsToBrowser(int round_id); 127 size_t total_bytes = 0;
128 size_t used_bytes = 0;
129 v8::Isolate* isolate = v8::Isolate::GetCurrent();
130 if (isolate) {
131 v8::HeapStatistics heap_stats;
132 isolate->GetHeapStatistics(&heap_stats);
133 total_bytes = heap_stats.total_heap_size();
134 used_bytes = heap_stats.used_heap_size();
135 }
136 master->PostTask(FROM_HERE,
137 base::Bind(&ResourceUsageReporterImpl::ReceiveStats, impl,
138 total_bytes, used_bytes));
139 }
125 140
126 size_t total_bytes_; 141 void ReceiveStats(size_t total_bytes, size_t used_bytes) {
127 size_t used_bytes_; 142 usage_data_->v8_bytes_allocated += total_bytes;
143 usage_data_->v8_bytes_used += used_bytes;
144 workers_to_go_--;
145 if (!workers_to_go_)
146 SendResults();
147 }
148
149 void SendResults() {
150 if (!callback_.is_null())
151 callback_.Run(usage_data_.Pass());
152 callback_.reset();
153 weak_factory_.InvalidateWeakPtrs();
154 workers_to_go_ = 0;
155 }
156
157 void GetUsageData(
158 const mojo::Callback<void(ResourceUsageDataPtr)>& callback) override {
159 DCHECK(callback_.is_null());
160 weak_factory_.InvalidateWeakPtrs();
161 usage_data_ = ResourceUsageData::New();
162 usage_data_->reports_v8_stats = true;
163 callback_ = callback;
164
165 v8::HeapStatistics heap_stats;
166 v8::Isolate::GetCurrent()->GetHeapStatistics(&heap_stats);
167 usage_data_->v8_bytes_allocated = heap_stats.total_heap_size();
168 usage_data_->v8_bytes_used = heap_stats.used_heap_size();
169 base::Closure collect = base::Bind(
170 &ResourceUsageReporterImpl::CollectOnWorkerThread,
171 base::MessageLoopProxy::current(), weak_factory_.GetWeakPtr());
172 workers_to_go_ = RenderThread::Get()->PostTaskToAllWebWorkers(collect);
173 if (workers_to_go_) {
174 // The guard task to send out partial stats
175 // in case some workers are not responsive.
176 base::MessageLoopProxy::current()->PostDelayedTask(
177 FROM_HERE, base::Bind(&ResourceUsageReporterImpl::SendResults,
178 weak_factory_.GetWeakPtr()),
179 base::TimeDelta::FromMilliseconds(kWaitForWorkersStatsTimeoutMS));
180 } else {
181 // No worker threads so just send out the main thread data right away.
182 SendResults();
183 }
184 }
185
186 ResourceUsageDataPtr usage_data_;
187 mojo::Callback<void(ResourceUsageDataPtr)> callback_;
128 int workers_to_go_; 188 int workers_to_go_;
129 int round_id_; 189 mojo::StrongBinding<ResourceUsageReporter> binding_;
190
191 base::WeakPtrFactory<ResourceUsageReporterImpl> weak_factory_;
130 }; 192 };
131 193
132 HeapStatisticsCollector* HeapStatisticsCollector::Instance() { 194 void CreateResourceUsageReporter(
133 CR_DEFINE_STATIC_LOCAL(HeapStatisticsCollector, instance, ()); 195 mojo::InterfaceRequest<ResourceUsageReporter> request) {
134 return &instance; 196 new ResourceUsageReporterImpl(request.Pass());
135 }
136
137 void HeapStatisticsCollector::InitiateCollection() {
138 v8::HeapStatistics heap_stats;
139 v8::Isolate::GetCurrent()->GetHeapStatistics(&heap_stats);
140 total_bytes_ = heap_stats.total_heap_size();
141 used_bytes_ = heap_stats.used_heap_size();
142 base::Closure collect = base::Bind(
143 &HeapStatisticsCollector::CollectOnWorkerThread,
144 base::Unretained(this),
145 base::MessageLoopProxy::current(),
146 round_id_);
147 workers_to_go_ = RenderThread::Get()->PostTaskToAllWebWorkers(collect);
148 if (workers_to_go_) {
149 // The guard task to send out partial stats
150 // in case some workers are not responsive.
151 base::MessageLoopProxy::current()->PostDelayedTask(
152 FROM_HERE,
153 base::Bind(&HeapStatisticsCollector::SendStatsToBrowser,
154 base::Unretained(this),
155 round_id_),
156 base::TimeDelta::FromMilliseconds(kWaitForWorkersStatsTimeoutMS));
157 } else {
158 // No worker threads so just send out the main thread data right away.
159 SendStatsToBrowser(round_id_);
160 }
161 }
162
163 void HeapStatisticsCollector::CollectOnWorkerThread(
164 scoped_refptr<base::TaskRunner> master,
165 int round_id) {
166
167 size_t total_bytes = 0;
168 size_t used_bytes = 0;
169 v8::Isolate* isolate = v8::Isolate::GetCurrent();
170 if (isolate) {
171 v8::HeapStatistics heap_stats;
172 isolate->GetHeapStatistics(&heap_stats);
173 total_bytes = heap_stats.total_heap_size();
174 used_bytes = heap_stats.used_heap_size();
175 }
176 master->PostTask(
177 FROM_HERE,
178 base::Bind(&HeapStatisticsCollector::ReceiveStats,
179 base::Unretained(this),
180 round_id,
181 total_bytes,
182 used_bytes));
183 }
184
185 void HeapStatisticsCollector::ReceiveStats(int round_id,
186 size_t total_bytes,
187 size_t used_bytes) {
188 if (round_id != round_id_)
189 return;
190 total_bytes_ += total_bytes;
191 used_bytes_ += used_bytes;
192 if (!--workers_to_go_)
193 SendStatsToBrowser(round_id);
194 }
195
196 void HeapStatisticsCollector::SendStatsToBrowser(int round_id) {
197 if (round_id != round_id_)
198 return;
199 // TODO(alph): Do caching heap stats and use the cache if we haven't got
200 // reply from a worker.
201 // Currently a busy worker stats are not counted.
202 RenderThread::Get()->Send(new ChromeViewHostMsg_V8HeapStats(
203 total_bytes_, used_bytes_));
204 ++round_id_;
205 } 197 }
206 198
207 } // namespace 199 } // namespace
208 200
209 bool ChromeRenderProcessObserver::is_incognito_process_ = false; 201 bool ChromeRenderProcessObserver::is_incognito_process_ = false;
210 202
211 ChromeRenderProcessObserver::ChromeRenderProcessObserver() 203 ChromeRenderProcessObserver::ChromeRenderProcessObserver()
212 : webkit_initialized_(false) { 204 : webkit_initialized_(false) {
213 const base::CommandLine& command_line = 205 const base::CommandLine& command_line =
214 *base::CommandLine::ForCurrentProcess(); 206 *base::CommandLine::ForCurrentProcess();
215 207
216 #if defined(ENABLE_AUTOFILL_DIALOG) 208 #if defined(ENABLE_AUTOFILL_DIALOG)
217 WebRuntimeFeatures::enableRequestAutocomplete(true); 209 WebRuntimeFeatures::enableRequestAutocomplete(true);
218 #endif 210 #endif
219 211
220 if (command_line.HasSwitch(switches::kDisableJavaScriptHarmonyShipping)) { 212 if (command_line.HasSwitch(switches::kDisableJavaScriptHarmonyShipping)) {
221 std::string flag("--noharmony-shipping"); 213 std::string flag("--noharmony-shipping");
222 v8::V8::SetFlagsFromString(flag.c_str(), static_cast<int>(flag.size())); 214 v8::V8::SetFlagsFromString(flag.c_str(), static_cast<int>(flag.size()));
223 } 215 }
224 216
225 if (command_line.HasSwitch(switches::kJavaScriptHarmony)) { 217 if (command_line.HasSwitch(switches::kJavaScriptHarmony)) {
226 std::string flag("--harmony"); 218 std::string flag("--harmony");
227 v8::V8::SetFlagsFromString(flag.c_str(), static_cast<int>(flag.size())); 219 v8::V8::SetFlagsFromString(flag.c_str(), static_cast<int>(flag.size()));
228 } 220 }
229 221
230 RenderThread* thread = RenderThread::Get(); 222 RenderThread* thread = RenderThread::Get();
231 resource_delegate_.reset(new RendererResourceDelegate()); 223 resource_delegate_.reset(new RendererResourceDelegate());
232 thread->SetResourceDispatcherDelegate(resource_delegate_.get()); 224 thread->SetResourceDispatcherDelegate(resource_delegate_.get());
233 225
226 content::ServiceRegistry* service_registry = thread->GetServiceRegistry();
227 if (service_registry) {
228 service_registry->AddService<ResourceUsageReporter>(
229 base::Bind(CreateResourceUsageReporter));
230 }
231
234 // Configure modules that need access to resources. 232 // Configure modules that need access to resources.
235 net::NetModule::SetResourceProvider(chrome_common_net::NetResourceProvider); 233 net::NetModule::SetResourceProvider(chrome_common_net::NetResourceProvider);
236 234
237 #if defined(OS_POSIX) && !defined(OS_MACOSX) && defined(USE_NSS_CERTS) 235 #if defined(OS_POSIX) && !defined(OS_MACOSX) && defined(USE_NSS_CERTS)
238 // On platforms where we use system NSS shared libraries, 236 // On platforms where we use system NSS shared libraries,
239 // initialize NSS now because it won't be able to load the .so's 237 // initialize NSS now because it won't be able to load the .so's
240 // after we engage the sandbox. 238 // after we engage the sandbox.
241 if (!command_line.HasSwitch(switches::kSingleProcess)) 239 if (!command_line.HasSwitch(switches::kSingleProcess))
242 crypto::InitNSSSafely(); 240 crypto::InitNSSSafely();
243 #elif defined(OS_WIN) 241 #elif defined(OS_WIN)
(...skipping 10 matching lines...) Expand all
254 ChromeRenderProcessObserver::~ChromeRenderProcessObserver() { 252 ChromeRenderProcessObserver::~ChromeRenderProcessObserver() {
255 } 253 }
256 254
257 bool ChromeRenderProcessObserver::OnControlMessageReceived( 255 bool ChromeRenderProcessObserver::OnControlMessageReceived(
258 const IPC::Message& message) { 256 const IPC::Message& message) {
259 bool handled = true; 257 bool handled = true;
260 IPC_BEGIN_MESSAGE_MAP(ChromeRenderProcessObserver, message) 258 IPC_BEGIN_MESSAGE_MAP(ChromeRenderProcessObserver, message)
261 IPC_MESSAGE_HANDLER(ChromeViewMsg_SetIsIncognitoProcess, 259 IPC_MESSAGE_HANDLER(ChromeViewMsg_SetIsIncognitoProcess,
262 OnSetIsIncognitoProcess) 260 OnSetIsIncognitoProcess)
263 IPC_MESSAGE_HANDLER(ChromeViewMsg_SetFieldTrialGroup, OnSetFieldTrialGroup) 261 IPC_MESSAGE_HANDLER(ChromeViewMsg_SetFieldTrialGroup, OnSetFieldTrialGroup)
264 IPC_MESSAGE_HANDLER(ChromeViewMsg_GetV8HeapStats, OnGetV8HeapStats)
265 IPC_MESSAGE_HANDLER(ChromeViewMsg_GetCacheResourceStats, 262 IPC_MESSAGE_HANDLER(ChromeViewMsg_GetCacheResourceStats,
266 OnGetCacheResourceStats) 263 OnGetCacheResourceStats)
267 IPC_MESSAGE_HANDLER(ChromeViewMsg_SetContentSettingRules, 264 IPC_MESSAGE_HANDLER(ChromeViewMsg_SetContentSettingRules,
268 OnSetContentSettingRules) 265 OnSetContentSettingRules)
269 IPC_MESSAGE_UNHANDLED(handled = false) 266 IPC_MESSAGE_UNHANDLED(handled = false)
270 IPC_END_MESSAGE_MAP() 267 IPC_END_MESSAGE_MAP()
271 return handled; 268 return handled;
272 } 269 }
273 270
274 void ChromeRenderProcessObserver::WebKitInitialized() { 271 void ChromeRenderProcessObserver::WebKitInitialized() {
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
314 base::FieldTrial* trial = 311 base::FieldTrial* trial =
315 base::FieldTrialList::CreateFieldTrial(field_trial_name, group_name); 312 base::FieldTrialList::CreateFieldTrial(field_trial_name, group_name);
316 // TODO(mef): Remove this check after the investigation of 359406 is complete. 313 // TODO(mef): Remove this check after the investigation of 359406 is complete.
317 CHECK(trial) << field_trial_name << ":" << group_name; 314 CHECK(trial) << field_trial_name << ":" << group_name;
318 // Ensure the trial is marked as "used" by calling group() on it if it is 315 // Ensure the trial is marked as "used" by calling group() on it if it is
319 // marked as activated. 316 // marked as activated.
320 trial->group(); 317 trial->group();
321 chrome_variations::SetChildProcessLoggingVariationList(); 318 chrome_variations::SetChildProcessLoggingVariationList();
322 } 319 }
323 320
324 void ChromeRenderProcessObserver::OnGetV8HeapStats() {
325 HeapStatisticsCollector::Instance()->InitiateCollection();
326 }
327
328 const RendererContentSettingRules* 321 const RendererContentSettingRules*
329 ChromeRenderProcessObserver::content_setting_rules() const { 322 ChromeRenderProcessObserver::content_setting_rules() const {
330 return &content_setting_rules_; 323 return &content_setting_rules_;
331 } 324 }
332 325
333 void ChromeRenderProcessObserver::OnFieldTrialGroupFinalized( 326 void ChromeRenderProcessObserver::OnFieldTrialGroupFinalized(
334 const std::string& trial_name, 327 const std::string& trial_name,
335 const std::string& group_name) { 328 const std::string& group_name) {
336 content::RenderThread::Get()->Send( 329 content::RenderThread::Get()->Send(
337 new ChromeViewHostMsg_FieldTrialActivated(trial_name)); 330 new ChromeViewHostMsg_FieldTrialActivated(trial_name));
338 } 331 }
OLDNEW
« no previous file with comments | « chrome/renderer/chrome_render_process_observer.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698