blob: db0c3dce7e5ff99eb597d4789a150c69747e1d18 [file] [log] [blame]
[email protected]3d662c32012-04-25 00:05:171// 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.
4
5#include "content/browser/tcmalloc_internals_request_job.h"
6
7#include "content/common/child_process_messages.h"
8#include "content/public/browser/browser_child_process_host_iterator.h"
9#include "content/public/browser/browser_thread.h"
10#include "content/public/browser/render_process_host.h"
11#include "content/public/common/process_type.h"
12
13#if defined(USE_TCMALLOC)
14#include "third_party/tcmalloc/chromium/src/gperftools/malloc_extension.h"
15#endif
16
17namespace content {
18
19// static
20AboutTcmallocOutputs* AboutTcmallocOutputs::GetInstance() {
21 return Singleton<AboutTcmallocOutputs>::get();
22}
23
24AboutTcmallocOutputs::AboutTcmallocOutputs() {}
25
26AboutTcmallocOutputs::~AboutTcmallocOutputs() {}
27
28void AboutTcmallocOutputs::OnStatsForChildProcess(
29 base::ProcessId pid, ProcessType process_type,
30 const std::string& output) {
31 std::string header = GetProcessTypeNameInEnglish(process_type);
32 base::StringAppendF(&header, " PID %d", static_cast<int>(pid));
33 SetOutput(header, output);
34}
35
36void AboutTcmallocOutputs::SetOutput(const std::string& header,
37 const std::string& output) {
38 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
39
40 outputs_[header] = output;
41}
42
43void AboutTcmallocOutputs::DumpToHTMLTable(std::string* data) {
44 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
45
46 data->append("<table width=\"100%\">\n");
47 for (AboutTcmallocOutputsType::const_iterator oit = outputs_.begin();
48 oit != outputs_.end();
49 oit++) {
50 data->append("<tr><td bgcolor=\"yellow\">");
51 data->append(oit->first);
52 data->append("</td></tr>\n");
53 data->append("<tr><td><pre>\n");
54 data->append(oit->second);
55 data->append("</pre></td></tr>\n");
56 }
57 data->append("</table>\n");
58 outputs_.clear();
59}
60
61TcmallocInternalsRequestJob::TcmallocInternalsRequestJob(
62 net::URLRequest* request) : net::URLRequestSimpleJob(request) {
63}
64
65#if defined(USE_TCMALLOC)
66void RequestTcmallocStatsFromChildRenderProcesses() {
67 RenderProcessHost::iterator it(RenderProcessHost::AllHostsIterator());
68 while (!it.IsAtEnd()) {
69 it.GetCurrentValue()->Send(new ChildProcessMsg_GetTcmallocStats);
70 it.Advance();
71 }
72}
73
74void AboutTcmalloc(std::string* data) {
75 data->append("<!DOCTYPE html>\n<html>\n<head>\n");
76 data->append("<title>tcmalloc stats</title>");
77 data->append("</head><body>");
78
79 // Display any stats for which we sent off requests the last time.
80 data->append("<p>Stats as of last page load;");
81 data->append("reload to get stats as of this page load.</p>\n");
82 data->append("<table width=\"100%\">\n");
83
84 AboutTcmallocOutputs::GetInstance()->DumpToHTMLTable(data);
85
86 data->append("</body></html>\n");
87
88 // Populate the collector with stats from the local browser process
89 // and send off requests to all the renderer processes.
90 char buffer[1024 * 32];
91 MallocExtension::instance()->GetStats(buffer, sizeof(buffer));
92 std::string browser("Browser");
93 AboutTcmallocOutputs::GetInstance()->SetOutput(browser, buffer);
94
95 for (BrowserChildProcessHostIterator iter; !iter.Done(); ++iter) {
96 iter.Send(new ChildProcessMsg_GetTcmallocStats);
97 }
98
99 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, base::Bind(
100 &RequestTcmallocStatsFromChildRenderProcesses));
101}
102#endif
103
104bool TcmallocInternalsRequestJob::GetData(std::string* mime_type,
105 std::string* charset,
106 std::string* data) const {
107 mime_type->assign("text/html");
108 charset->assign("UTF8");
109
110 data->clear();
111#if defined(USE_TCMALLOC)
112 AboutTcmalloc(data);
113#endif
114 return true;
115}
116
117} // namespace content