OSDN Git Service

Merge WebKit at r78450: Initial merge by git.
[android-x86/external-webkit.git] / Source / WebKit2 / Shared / WebMemorySampler.cpp
1 /*
2  * Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010 Apple Inc. All rights reserved.
3  * 
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1.  Redistributions of source code must retain the above copyright
8  * notice, this list of conditions and the following disclaimer.
9  * 2.  Redistributions in binary form must reproduce the above copyright
10  * notice, this list of conditions and the following disclaimer in the
11  * documentation and/or other materials provided with the distribution.
12  * 
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY
14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
15  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
16  * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
17  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
18  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
19  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
20  * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
21  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
22  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23  *
24  */
25
26 #include "config.h"
27 #include "WebMemorySampler.h"
28
29 #if ENABLE(MEMORY_SAMPLER)
30
31 #include <wtf/text/CString.h>
32
33 using namespace WebCore;
34
35 namespace WebKit {
36
37
38 WebMemorySampler* WebMemorySampler::shared()
39 {
40     static WebMemorySampler* sharedMemorySampler;
41     if (!sharedMemorySampler)
42         sharedMemorySampler = new WebMemorySampler();
43     return sharedMemorySampler;
44 }
45
46 WebMemorySampler::WebMemorySampler() 
47     : m_separator(String("\t"))  
48     , m_sampleTimer(this, &WebMemorySampler::sampleTimerFired)
49     , m_stopTimer(this, &WebMemorySampler::stopTimerFired)
50     , m_isRunning(false)
51     , m_runningTime(0)
52 {
53 }
54
55 void WebMemorySampler::start(const double interval) 
56 {
57     if (m_isRunning) 
58         return;
59     
60     initializeTempLogFile();
61     initializeTimers(interval);
62 }
63
64 void WebMemorySampler::start(const SandboxExtension::Handle& sampleLogFileHandle, const String& sampleLogFilePath, const double interval) 
65 {
66     if (m_isRunning) 
67         return;
68     
69     // If we are on a system without SandboxExtension the handle and filename will be empty
70     if (sampleLogFilePath.isEmpty()) {
71         start(interval);
72         return;
73     }
74         
75     initializeSandboxedLogFile(sampleLogFileHandle, sampleLogFilePath);
76     initializeTimers(interval);
77    
78 }
79
80 void WebMemorySampler::initializeTimers(double interval)
81 {
82     m_sampleTimer.startRepeating(1);
83     printf("Started memory sampler for process %s", processName().utf8().data());
84     if (interval > 0) {
85         m_stopTimer.startOneShot(interval);
86         printf(" for a interval of %g seconds", interval);
87     }
88     printf("; Sampler log file stored at: %s\n", m_sampleLogFilePath.utf8().data());
89     m_runningTime = interval;
90     m_isRunning = true;
91 }
92
93 void WebMemorySampler::stop() 
94 {
95     if (!m_isRunning) 
96         return;
97     m_sampleTimer.stop();
98     m_sampleLogFile = 0;
99     printf("Stopped memory sampler for process %s\n", processName().utf8().data());
100     // Flush stdout buffer so python script can be guaranteed to read up to this point.
101     fflush(stdout);
102     m_isRunning = false;
103     
104     if(m_stopTimer.isActive())
105         m_stopTimer.stop();
106     
107     if (m_sampleLogSandboxExtension) {
108         m_sampleLogSandboxExtension->invalidate();
109         m_sampleLogSandboxExtension = 0;
110     }    
111 }
112
113 bool WebMemorySampler::isRunning() const
114 {
115     return m_isRunning;
116 }
117     
118 void WebMemorySampler::initializeTempLogFile()
119 {
120     m_sampleLogFilePath = String((openTemporaryFile(processName().utf8().data(), m_sampleLogFile)).data());
121     writeHeaders();
122 }
123
124 void WebMemorySampler::initializeSandboxedLogFile(const SandboxExtension::Handle& sampleLogSandboxHandle, const String& sampleLogFilePath)
125 {
126     m_sampleLogSandboxExtension = SandboxExtension::create(sampleLogSandboxHandle);
127     if (m_sampleLogSandboxExtension)
128         m_sampleLogSandboxExtension->consume();
129     m_sampleLogFilePath = sampleLogFilePath;
130     m_sampleLogFile = openFile(m_sampleLogFilePath, OpenForWrite);
131     writeHeaders();
132 }
133
134 void WebMemorySampler::writeHeaders()
135 {
136     String processDetails = String("Process: ");
137     processDetails.append(processName());
138     processDetails.append(String("\n"));
139     writeToFile(m_sampleLogFile, processDetails.utf8().data(), processDetails.utf8().length());
140     
141     String header; 
142     WebMemoryStatistics stats = sampleWebKit();
143     if (!stats.keys.isEmpty()) {
144         for (size_t i = 0; i < stats.keys.size(); ++i) {
145             header.append(m_separator);
146             header.append(stats.keys[i].utf8().data());
147         }
148     }
149     header.append(String("\n"));
150     writeToFile(m_sampleLogFile, header.utf8().data(), header.utf8().length());
151 }
152
153 void WebMemorySampler::sampleTimerFired(Timer<WebMemorySampler>*)
154 {
155     appendCurrentMemoryUsageToFile(m_sampleLogFile); 
156 }
157
158 void WebMemorySampler::stopTimerFired(Timer<WebMemorySampler>*)
159 {
160     if (!m_isRunning)
161         return;
162     printf("%g seconds elapsed. Stopping memory sampler...\n", m_runningTime);
163     stop();
164 }
165
166 void WebMemorySampler::appendCurrentMemoryUsageToFile(PlatformFileHandle& file)
167 {
168     // Collect statistics from allocators and get RSIZE metric
169     String statString; 
170     WebMemoryStatistics memoryStats = sampleWebKit();
171
172     if (!memoryStats.values.isEmpty()) {
173         statString.append(m_separator);
174         for (size_t i = 0; i < memoryStats.values.size(); ++i) {
175             statString.append(m_separator);
176             statString.append(String::format("%lu", memoryStats.values[i]));
177         }
178     }
179     statString.append(String("\n"));
180     writeToFile(m_sampleLogFile, statString.utf8().data(), statString.utf8().length());
181 }
182
183 }
184
185 #endif