WebMemorySamplerLinux.cpp [plain text]
#include "config.h"
#include "WebMemorySampler.h"
#if ENABLE(MEMORY_SAMPLER)
#include <JavaScriptCore/MemoryStatistics.h>
#include <WebCore/CommonVM.h>
#include <WebCore/JSDOMWindow.h>
#include <WebCore/NotImplemented.h>
#include <runtime/JSCInlines.h>
#include <runtime/JSLock.h>
#include <string.h>
#include <sys/sysinfo.h>
#include <wtf/CurrentTime.h>
#include <wtf/linux/CurrentProcessMemoryStatus.h>
#include <wtf/text/WTFString.h>
using namespace WebCore;
using namespace JSC;
using namespace WTF;
namespace WebKit {
static const unsigned int maxBuffer = 128;
static const unsigned int maxProcessPath = 35;
static inline String nextToken(FILE* file)
{
ASSERT(file);
if (!file)
return String();
char buffer[maxBuffer] = {0, };
unsigned int index = 0;
while (index < maxBuffer) {
int ch = fgetc(file);
if (ch == EOF || (isASCIISpace(ch) && index)) break;
if (!isASCIISpace(ch)) {
buffer[index] = ch;
index++;
}
}
return String(buffer);
}
static inline void appendKeyValuePair(WebMemoryStatistics& stats, const String& key, size_t value)
{
stats.keys.append(key);
stats.values.append(value);
}
String WebMemorySampler::processName() const
{
char processPath[maxProcessPath];
snprintf(processPath, maxProcessPath, "/proc/self/status");
FILE* statusFileDescriptor = fopen(processPath, "r");
if (!statusFileDescriptor)
return String();
nextToken(statusFileDescriptor);
String processName = nextToken(statusFileDescriptor);
fclose(statusFileDescriptor);
return processName;
}
WebMemoryStatistics WebMemorySampler::sampleWebKit() const
{
WebMemoryStatistics webKitMemoryStats;
double now = currentTime();
appendKeyValuePair(webKitMemoryStats, ASCIILiteral("Timestamp"), now);
ProcessMemoryStatus processMemoryStatus;
currentProcessMemoryStatus(processMemoryStatus);
appendKeyValuePair(webKitMemoryStats, ASCIILiteral("Total Program Bytes"), processMemoryStatus.size);
appendKeyValuePair(webKitMemoryStats, ASCIILiteral("Resident Set Bytes"), processMemoryStatus.resident);
appendKeyValuePair(webKitMemoryStats, ASCIILiteral("Resident Shared Bytes"), processMemoryStatus.shared);
appendKeyValuePair(webKitMemoryStats, ASCIILiteral("Text Bytes"), processMemoryStatus.text);
appendKeyValuePair(webKitMemoryStats, ASCIILiteral("Library Bytes"), processMemoryStatus.lib);
appendKeyValuePair(webKitMemoryStats, ASCIILiteral("Data + Stack Bytes"), processMemoryStatus.data);
appendKeyValuePair(webKitMemoryStats, ASCIILiteral("Dirty Bytes"), processMemoryStatus.dt);
size_t totalBytesInUse = 0;
size_t totalBytesCommitted = 0;
FastMallocStatistics fastMallocStatistics = WTF::fastMallocStatistics();
size_t fastMallocBytesInUse = fastMallocStatistics.committedVMBytes - fastMallocStatistics.freeListBytes;
size_t fastMallocBytesCommitted = fastMallocStatistics.committedVMBytes;
totalBytesInUse += fastMallocBytesInUse;
totalBytesCommitted += fastMallocBytesCommitted;
appendKeyValuePair(webKitMemoryStats, ASCIILiteral("Fast Malloc In Use"), fastMallocBytesInUse);
appendKeyValuePair(webKitMemoryStats, ASCIILiteral("Fast Malloc Committed Memory"), fastMallocBytesCommitted);
size_t jscHeapBytesInUse = commonVM().heap.size();
size_t jscHeapBytesCommitted = commonVM().heap.capacity();
totalBytesInUse += jscHeapBytesInUse;
totalBytesCommitted += jscHeapBytesCommitted;
GlobalMemoryStatistics globalMemoryStats = globalMemoryStatistics();
totalBytesInUse += globalMemoryStats.stackBytes + globalMemoryStats.JITBytes;
totalBytesCommitted += globalMemoryStats.stackBytes + globalMemoryStats.JITBytes;
appendKeyValuePair(webKitMemoryStats, ASCIILiteral("JavaScript Heap In Use"), jscHeapBytesInUse);
appendKeyValuePair(webKitMemoryStats, ASCIILiteral("JavaScript Heap Committed Memory"), jscHeapBytesCommitted);
appendKeyValuePair(webKitMemoryStats, ASCIILiteral("JavaScript Stack Bytes"), globalMemoryStats.stackBytes);
appendKeyValuePair(webKitMemoryStats, ASCIILiteral("JavaScript JIT Bytes"), globalMemoryStats.JITBytes);
appendKeyValuePair(webKitMemoryStats, ASCIILiteral("Total Memory In Use"), totalBytesInUse);
appendKeyValuePair(webKitMemoryStats, ASCIILiteral("Total Committed Memory"), totalBytesCommitted);
struct sysinfo systemInfo;
if (!sysinfo(&systemInfo)) {
appendKeyValuePair(webKitMemoryStats, ASCIILiteral("System Total Bytes"), systemInfo.totalram);
appendKeyValuePair(webKitMemoryStats, ASCIILiteral("Available Bytes"), systemInfo.freeram);
appendKeyValuePair(webKitMemoryStats, ASCIILiteral("Shared Bytes"), systemInfo.sharedram);
appendKeyValuePair(webKitMemoryStats, ASCIILiteral("Buffer Bytes"), systemInfo.bufferram);
appendKeyValuePair(webKitMemoryStats, ASCIILiteral("Total Swap Bytes"), systemInfo.totalswap);
appendKeyValuePair(webKitMemoryStats, ASCIILiteral("Available Swap Bytes"), systemInfo.freeswap);
}
return webKitMemoryStats;
}
void WebMemorySampler::sendMemoryPressureEvent()
{
notImplemented();
}
}
#endif