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