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 "content/common/child_process_messages.h"
9 #include "content/public/browser/browser_child_process_host_iterator.h"
10 #include "content/public/browser/browser_thread.h"
11 #include "content/public/browser/render_process_host.h"
12 #include "content/public/common/process_type.h"
13 #include "net/base/net_errors.h"
18 AboutTcmallocOutputs
* AboutTcmallocOutputs::GetInstance() {
19 return Singleton
<AboutTcmallocOutputs
>::get();
22 AboutTcmallocOutputs::AboutTcmallocOutputs() {}
24 AboutTcmallocOutputs::~AboutTcmallocOutputs() {}
26 void AboutTcmallocOutputs::OnStatsForChildProcess(
27 base::ProcessId pid
, int process_type
,
28 const std::string
& output
) {
29 std::string header
= GetProcessTypeNameInEnglish(process_type
);
30 base::StringAppendF(&header
, " PID %d", static_cast<int>(pid
));
31 SetOutput(header
, output
);
34 void AboutTcmallocOutputs::SetOutput(const std::string
& header
,
35 const std::string
& output
) {
36 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO
));
38 outputs_
[header
] = output
;
41 void AboutTcmallocOutputs::DumpToHTMLTable(std::string
* data
) {
42 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO
));
44 data
->append("<table width=\"100%\">\n");
45 for (AboutTcmallocOutputsType::const_iterator oit
= outputs_
.begin();
46 oit
!= outputs_
.end();
48 data
->append("<tr><td bgcolor=\"yellow\">");
49 data
->append(oit
->first
);
50 data
->append("</td></tr>\n");
51 data
->append("<tr><td><pre>\n");
52 data
->append(oit
->second
);
53 data
->append("</pre></td></tr>\n");
55 data
->append("</table>\n");
59 TcmallocInternalsRequestJob::TcmallocInternalsRequestJob(
60 net::URLRequest
* request
, net::NetworkDelegate
* network_delegate
)
61 : net::URLRequestSimpleJob(request
, network_delegate
) {
64 #if defined(USE_TCMALLOC)
65 void RequestTcmallocStatsFromChildRenderProcesses() {
66 RenderProcessHost::iterator
it(RenderProcessHost::AllHostsIterator());
67 while (!it
.IsAtEnd()) {
68 it
.GetCurrentValue()->Send(new ChildProcessMsg_GetTcmallocStats
);
73 void AboutTcmalloc(std::string
* data
) {
74 data
->append("<!DOCTYPE html>\n<html>\n<head>\n");
76 "<meta http-equiv=\"Content-Security-Policy\" "
77 "content=\"object-src 'none'; script-src 'none' 'unsafe-eval'\">");
78 data
->append("<title>tcmalloc stats</title>");
79 data
->append("</head><body>");
81 // Display any stats for which we sent off requests the last time.
82 data
->append("<p>Stats as of last page load;");
83 data
->append("reload to get stats as of this page load.</p>\n");
84 data
->append("<table width=\"100%\">\n");
86 AboutTcmallocOutputs::GetInstance()->DumpToHTMLTable(data
);
88 data
->append("</body></html>\n");
90 // Populate the collector with stats from the local browser process
91 // and send off requests to all the renderer processes.
92 char buffer
[1024 * 32];
93 base::allocator::GetStats(buffer
, sizeof(buffer
));
94 std::string
browser("Browser");
95 AboutTcmallocOutputs::GetInstance()->SetOutput(browser
, buffer
);
97 for (BrowserChildProcessHostIterator iter
; !iter
.Done(); ++iter
) {
98 iter
.Send(new ChildProcessMsg_GetTcmallocStats
);
101 BrowserThread::PostTask(BrowserThread::UI
, FROM_HERE
, base::Bind(
102 &RequestTcmallocStatsFromChildRenderProcesses
));
106 int TcmallocInternalsRequestJob::GetData(
107 std::string
* mime_type
,
108 std::string
* charset
,
110 const net::CompletionCallback
& callback
) const {
111 mime_type
->assign("text/html");
112 charset
->assign("UTF8");
115 #if defined(USE_TCMALLOC)
121 } // namespace content