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
3 // found in the LICENSE file.
5 #include "content/browser/tcmalloc_internals_request_job.h"
7 #include "base/allocator/allocator_extension.h"
8 #include "base/profiler/scoped_tracker.h"
9 #include "content/common/child_process_messages.h"
10 #include "content/public/browser/browser_child_process_host_iterator.h"
11 #include "content/public/browser/browser_thread.h"
12 #include "content/public/browser/render_process_host.h"
13 #include "content/public/common/process_type.h"
14 #include "net/base/net_errors.h"
19 AboutTcmallocOutputs
* AboutTcmallocOutputs::GetInstance() {
20 return Singleton
<AboutTcmallocOutputs
>::get();
23 AboutTcmallocOutputs::AboutTcmallocOutputs() {}
25 AboutTcmallocOutputs::~AboutTcmallocOutputs() {}
27 void AboutTcmallocOutputs::OnStatsForChildProcess(
28 base::ProcessId pid
, int process_type
,
29 const std::string
& output
) {
30 std::string header
= GetProcessTypeNameInEnglish(process_type
);
31 base::StringAppendF(&header
, " PID %d", static_cast<int>(pid
));
32 SetOutput(header
, output
);
35 void AboutTcmallocOutputs::SetOutput(const std::string
& header
,
36 const std::string
& output
) {
37 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO
));
39 outputs_
[header
] = output
;
42 void AboutTcmallocOutputs::DumpToHTMLTable(std::string
* data
) {
43 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO
));
45 data
->append("<table width=\"100%\">\n");
46 for (AboutTcmallocOutputsType::const_iterator oit
= outputs_
.begin();
47 oit
!= outputs_
.end();
49 data
->append("<tr><td bgcolor=\"yellow\">");
50 data
->append(oit
->first
);
51 data
->append("</td></tr>\n");
52 data
->append("<tr><td><pre>\n");
53 data
->append(oit
->second
);
54 data
->append("</pre></td></tr>\n");
56 data
->append("</table>\n");
60 TcmallocInternalsRequestJob::TcmallocInternalsRequestJob(
61 net::URLRequest
* request
, net::NetworkDelegate
* network_delegate
)
62 : net::URLRequestSimpleJob(request
, network_delegate
) {
65 #if defined(USE_TCMALLOC)
66 void RequestTcmallocStatsFromChildRenderProcesses() {
67 RenderProcessHost::iterator
it(RenderProcessHost::AllHostsIterator());
68 while (!it
.IsAtEnd()) {
69 it
.GetCurrentValue()->Send(new ChildProcessMsg_GetTcmallocStats
);
74 void AboutTcmalloc(std::string
* data
) {
75 data
->append("<!DOCTYPE html>\n<html>\n<head>\n");
77 "<meta http-equiv=\"Content-Security-Policy\" "
78 "content=\"object-src 'none'; script-src 'none'\">");
79 data
->append("<title>tcmalloc stats</title>");
80 data
->append("</head><body>");
82 // Display any stats for which we sent off requests the last time.
83 data
->append("<p>Stats as of last page load;");
84 data
->append("reload to get stats as of this page load.</p>\n");
85 data
->append("<table width=\"100%\">\n");
87 AboutTcmallocOutputs::GetInstance()->DumpToHTMLTable(data
);
89 data
->append("</body></html>\n");
91 // Populate the collector with stats from the local browser process
92 // and send off requests to all the renderer processes.
93 char buffer
[1024 * 32];
94 base::allocator::GetStats(buffer
, sizeof(buffer
));
95 std::string
browser("Browser");
96 AboutTcmallocOutputs::GetInstance()->SetOutput(browser
, buffer
);
98 for (BrowserChildProcessHostIterator iter
; !iter
.Done(); ++iter
) {
99 iter
.Send(new ChildProcessMsg_GetTcmallocStats
);
102 BrowserThread::PostTask(BrowserThread::UI
, FROM_HERE
, base::Bind(
103 &RequestTcmallocStatsFromChildRenderProcesses
));
107 int TcmallocInternalsRequestJob::GetData(
108 std::string
* mime_type
,
109 std::string
* charset
,
111 const net::CompletionCallback
& callback
) const {
112 // TODO(vadimt): Remove ScopedTracker below once crbug.com/422489 is fixed.
113 tracked_objects::ScopedTracker
tracking_profile(
114 FROM_HERE_WITH_EXPLICIT_FUNCTION(
115 "422489 TcmallocInternalsRequestJob::GetData"));
117 mime_type
->assign("text/html");
118 charset
->assign("UTF8");
121 #if defined(USE_TCMALLOC)
127 } // namespace content