Commit 7183460c authored by fpizlo@apple.com's avatar fpizlo@apple.com
Browse files

JSC_enableProfiler=true should also cause JSGlobalData to save the profiler output somewhere

https://bugs.webkit.org/show_bug.cgi?id=113144

Source/JavaScriptCore: 

Reviewed by Geoffrey Garen.
        
Added the ability to save profiler output with JSC_enableProfiler=true. It will save it
to the current directory, or JSC_PROFILER_PATH if the latter was specified.
        
This works by saving the Profiler::Database either when it is destroyed or atexit(),
whichever happens first.
        
This allows use of the profiler from any WebKit client.

* jsc.cpp:
(jscmain):
* profiler/ProfilerDatabase.cpp:
(Profiler):
(JSC::Profiler::Database::Database):
(JSC::Profiler::Database::~Database):
(JSC::Profiler::Database::registerToSaveAtExit):
(JSC::Profiler::Database::addDatabaseToAtExit):
(JSC::Profiler::Database::removeDatabaseFromAtExit):
(JSC::Profiler::Database::performAtExitSave):
(JSC::Profiler::Database::removeFirstAtExitDatabase):
(JSC::Profiler::Database::atExitCallback):
* profiler/ProfilerDatabase.h:
(JSC::Profiler::Database::databaseID):
(Database):
* runtime/JSGlobalData.cpp:
(JSC::JSGlobalData::JSGlobalData):

Source/WTF: 

Reviewed by Geoffrey Garen.
        
I got tired of the fact that getpid(2) is not a syscall on Windows (unless you do
_getpid() I believe), so I wrote a header that abstracts it. I also changed existing
code that uses getpid() to use WTF::getCurrentProcessID().

* GNUmakefile.list.am:
* WTF.gypi:
* WTF.pro:
* WTF.vcproj/WTF.vcproj:
* WTF.xcodeproj/project.pbxproj:
* wtf/CMakeLists.txt:
* wtf/MetaAllocator.cpp:
(WTF::MetaAllocator::dumpProfile):
* wtf/ProcessID.h: Added.
(WTF):
(WTF::getCurrentProcessID):
* wtf/text/StringImpl.cpp:
(WTF::StringStats::printStats):



git-svn-id: http://svn.webkit.org/repository/webkit/trunk@146932 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent efab0e3d
2013-03-25 Filip Pizlo <fpizlo@apple.com>
JSC_enableProfiler=true should also cause JSGlobalData to save the profiler output somewhere
https://bugs.webkit.org/show_bug.cgi?id=113144
Reviewed by Geoffrey Garen.
Added the ability to save profiler output with JSC_enableProfiler=true. It will save it
to the current directory, or JSC_PROFILER_PATH if the latter was specified.
This works by saving the Profiler::Database either when it is destroyed or atexit(),
whichever happens first.
This allows use of the profiler from any WebKit client.
* jsc.cpp:
(jscmain):
* profiler/ProfilerDatabase.cpp:
(Profiler):
(JSC::Profiler::Database::Database):
(JSC::Profiler::Database::~Database):
(JSC::Profiler::Database::registerToSaveAtExit):
(JSC::Profiler::Database::addDatabaseToAtExit):
(JSC::Profiler::Database::removeDatabaseFromAtExit):
(JSC::Profiler::Database::performAtExitSave):
(JSC::Profiler::Database::removeFirstAtExitDatabase):
(JSC::Profiler::Database::atExitCallback):
* profiler/ProfilerDatabase.h:
(JSC::Profiler::Database::databaseID):
(Database):
* runtime/JSGlobalData.cpp:
(JSC::JSGlobalData::JSGlobalData):
2013-03-25 Filip Pizlo <fpizlo@apple.com>
 
ArrayMode should not consider SpecOther when refining the base
......
......@@ -764,7 +764,7 @@ int jscmain(int argc, char** argv)
JSLockHolder lock(globalData.get());
int result;
if (options.m_profile)
if (options.m_profile && !globalData->m_perBytecodeProfiler)
globalData->m_perBytecodeProfiler = adoptPtr(new Profiler::Database(*globalData));
GlobalObject* globalObject = GlobalObject::create(*globalData, GlobalObject::createStructure(*globalData, jsNull()), options.m_arguments);
......
/*
* Copyright (C) 2012 Apple Inc. All rights reserved.
* Copyright (C) 2012, 2013 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
......@@ -33,13 +33,25 @@
namespace JSC { namespace Profiler {
static volatile int databaseCounter;
static SpinLock registrationLock;
static int didRegisterAtExit;
static Database* firstDatabase;
Database::Database(JSGlobalData& globalData)
: m_globalData(globalData)
: m_databaseID(atomicIncrement(&databaseCounter))
, m_globalData(globalData)
, m_shouldSaveAtExit(false)
, m_nextRegisteredDatabase(0)
{
}
Database::~Database()
{
if (m_shouldSaveAtExit) {
removeDatabaseFromAtExit();
performAtExitSave();
}
}
Bytecodes* Database::ensureBytecodesFor(CodeBlock* codeBlock)
......@@ -110,5 +122,62 @@ bool Database::save(const char* filename) const
return true;
}
void Database::registerToSaveAtExit(const char* filename)
{
m_atExitSaveFilename = filename;
if (m_shouldSaveAtExit)
return;
addDatabaseToAtExit();
m_shouldSaveAtExit = true;
}
void Database::addDatabaseToAtExit()
{
if (atomicIncrement(&didRegisterAtExit) == 1)
atexit(atExitCallback);
TCMalloc_SpinLockHolder holder(&registrationLock);
m_nextRegisteredDatabase = firstDatabase;
firstDatabase = this;
}
void Database::removeDatabaseFromAtExit()
{
TCMalloc_SpinLockHolder holder(&registrationLock);
for (Database** current = &firstDatabase; *current; current = &(*current)->m_nextRegisteredDatabase) {
if (*current != this)
continue;
*current = m_nextRegisteredDatabase;
m_nextRegisteredDatabase = 0;
m_shouldSaveAtExit = false;
break;
}
}
void Database::performAtExitSave() const
{
save(m_atExitSaveFilename.data());
}
Database* Database::removeFirstAtExitDatabase()
{
TCMalloc_SpinLockHolder holder(&registrationLock);
Database* result = firstDatabase;
if (result) {
firstDatabase = result->m_nextRegisteredDatabase;
result->m_nextRegisteredDatabase = 0;
result->m_shouldSaveAtExit = false;
}
return result;
}
void Database::atExitCallback()
{
while (Database* database = removeFirstAtExitDatabase())
database->performAtExitSave();
}
} } // namespace JSC::Profiler
/*
* Copyright (C) 2012 Apple Inc. All rights reserved.
* Copyright (C) 2012, 2013 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
......@@ -45,6 +45,8 @@ public:
JS_EXPORT_PRIVATE Database(JSGlobalData&);
JS_EXPORT_PRIVATE ~Database();
int databaseID() const { return m_databaseID; }
Bytecodes* ensureBytecodesFor(CodeBlock*);
void notifyDestruction(CodeBlock*);
......@@ -65,12 +67,24 @@ public:
// save failed.
JS_EXPORT_PRIVATE bool save(const char* filename) const;
void registerToSaveAtExit(const char* filename);
private:
void addDatabaseToAtExit();
void removeDatabaseFromAtExit();
void performAtExitSave() const;
static Database* removeFirstAtExitDatabase();
static void atExitCallback();
int m_databaseID;
JSGlobalData& m_globalData;
SegmentedVector<Bytecodes> m_bytecodes;
HashMap<CodeBlock*, Bytecodes*> m_bytecodesMap;
Vector<RefPtr<Compilation> > m_compilations;
bool m_shouldSaveAtExit;
CString m_atExitSaveFilename;
Database* m_nextRegisteredDatabase;
};
} } // namespace JSC::Profiler
......
/*
* Copyright (C) 2008, 2011 Apple Inc. All rights reserved.
* Copyright (C) 2008, 2011, 2013 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
......@@ -60,7 +60,9 @@
#include "StrictEvalActivation.h"
#include "StrongInlines.h"
#include "UnlinkedCodeBlock.h"
#include <wtf/ProcessID.h>
#include <wtf/RetainPtr.h>
#include <wtf/StringPrintStream.h>
#include <wtf/Threading.h>
#include <wtf/WTFThreadData.h>
......@@ -247,9 +249,17 @@ JSGlobalData::JSGlobalData(GlobalDataType globalDataType, HeapType heapType)
LLInt::Data::performAssertions(*this);
if (Options::enableProfiler())
if (Options::enableProfiler()) {
m_perBytecodeProfiler = adoptPtr(new Profiler::Database(*this));
StringPrintStream pathOut;
const char* profilerPath = getenv("JSC_PROFILER_PATH");
if (profilerPath)
pathOut.print(profilerPath, "/");
pathOut.print("JSCProfile-", getCurrentProcessID(), "-", m_perBytecodeProfiler->databaseID(), ".json");
m_perBytecodeProfiler->registerToSaveAtExit(pathOut.toCString().data());
}
#if ENABLE(DFG_JIT)
if (canUseJIT())
m_dfgState = adoptPtr(new DFG::LongLivedState());
......
2013-03-23 Filip Pizlo <fpizlo@apple.com>
JSC_enableProfiler=true should also cause JSGlobalData to save the profiler output somewhere
https://bugs.webkit.org/show_bug.cgi?id=113144
Reviewed by Geoffrey Garen.
I got tired of the fact that getpid(2) is not a syscall on Windows (unless you do
_getpid() I believe), so I wrote a header that abstracts it. I also changed existing
code that uses getpid() to use WTF::getCurrentProcessID().
* GNUmakefile.list.am:
* WTF.gypi:
* WTF.pro:
* WTF.vcproj/WTF.vcproj:
* WTF.xcodeproj/project.pbxproj:
* wtf/CMakeLists.txt:
* wtf/MetaAllocator.cpp:
(WTF::MetaAllocator::dumpProfile):
* wtf/ProcessID.h: Added.
(WTF):
(WTF::getCurrentProcessID):
* wtf/text/StringImpl.cpp:
(WTF::StringStats::printStats):
2013-03-25 Kent Tamura <tkent@chromium.org>
 
Rename ENABLE_INPUT_TYPE_DATETIME
......
......@@ -139,6 +139,7 @@ wtf_sources += \
Source/WTF/wtf/PossiblyNull.h \
Source/WTF/wtf/PrintStream.cpp \
Source/WTF/wtf/PrintStream.h \
Source/WTF/wtf/ProcessID.h \
Source/WTF/wtf/RandomNumber.cpp \
Source/WTF/wtf/RandomNumber.h \
Source/WTF/wtf/RandomNumberSeed.h \
......
......@@ -84,6 +84,7 @@
'wtf/Platform.h',
'wtf/PossiblyNull.h',
'wtf/PrintStream.h',
'wtf/ProcessID.h',
'wtf/RandomNumber.h',
'wtf/RawPointer.h',
'wtf/RefCounted.h',
......
......@@ -130,6 +130,7 @@ HEADERS += \
Platform.h \
PossiblyNull.h \
PrintStream.h \
ProcessID.h \
RandomNumber.h \
RandomNumberSeed.h \
RawPointer.h \
......
......@@ -1128,6 +1128,10 @@
RelativePath="..\wtf\PrintStream.h"
>
</File>
<File
RelativePath="..\wtf\ProcessID.h"
>
</File>
<File
RelativePath="..\wtf\RandomNumber.cpp"
>
......
......@@ -26,6 +26,7 @@
0F9D3361165DBA73005AD387 /* FilePrintStream.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F9D335C165DBA73005AD387 /* FilePrintStream.h */; };
0F9D3362165DBA73005AD387 /* PrintStream.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F9D335D165DBA73005AD387 /* PrintStream.cpp */; };
0F9D3363165DBA73005AD387 /* PrintStream.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F9D335E165DBA73005AD387 /* PrintStream.h */; };
0FC4488316FE9FE100844BE9 /* ProcessID.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FC4488216FE9FE100844BE9 /* ProcessID.h */; };
0FC4EDE61696149600F65041 /* CommaPrinter.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FC4EDE51696149600F65041 /* CommaPrinter.h */; };
0FD81AC5154FB22E00983E72 /* FastBitVector.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FD81AC4154FB22E00983E72 /* FastBitVector.h */; settings = {ATTRIBUTES = (); }; };
0FDDBFA71666DFA300C55FEF /* StringPrintStream.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0FDDBFA51666DFA300C55FEF /* StringPrintStream.cpp */; };
......@@ -336,6 +337,7 @@
0F9D335C165DBA73005AD387 /* FilePrintStream.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FilePrintStream.h; sourceTree = "<group>"; };
0F9D335D165DBA73005AD387 /* PrintStream.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PrintStream.cpp; sourceTree = "<group>"; };
0F9D335E165DBA73005AD387 /* PrintStream.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PrintStream.h; sourceTree = "<group>"; };
0FC4488216FE9FE100844BE9 /* ProcessID.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ProcessID.h; sourceTree = "<group>"; };
0FC4EDE51696149600F65041 /* CommaPrinter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CommaPrinter.h; sourceTree = "<group>"; };
0FD81AC4154FB22E00983E72 /* FastBitVector.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FastBitVector.h; sourceTree = "<group>"; };
0FDDBFA51666DFA300C55FEF /* StringPrintStream.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = StringPrintStream.cpp; sourceTree = "<group>"; };
......@@ -833,6 +835,7 @@
A8A472F3151A825B004123FF /* PossiblyNull.h */,
0F9D335D165DBA73005AD387 /* PrintStream.cpp */,
0F9D335E165DBA73005AD387 /* PrintStream.h */,
0FC4488216FE9FE100844BE9 /* ProcessID.h */,
143F611D1565F0F900DB514A /* RAMSize.cpp */,
143F611E1565F0F900DB514A /* RAMSize.h */,
A8A472FB151A825B004123FF /* RandomNumber.cpp */,
......@@ -1285,6 +1288,7 @@
974CFC8E16A4F327006D5404 /* WeakPtr.h in Headers */,
A8A47446151A825B004123FF /* WTFString.h in Headers */,
A8A47487151A825B004123FF /* WTFThreadData.h in Headers */,
0FC4488316FE9FE100844BE9 /* ProcessID.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
......
......@@ -89,6 +89,7 @@ set(WTF_HEADERS
Platform.h
PossiblyNull.h
PrintStream.h
ProcessID.h
RandomNumber.h
RandomNumberSeed.h
RawPointer.h
......
......@@ -31,6 +31,7 @@
#include <wtf/DataLog.h>
#include <wtf/FastMalloc.h>
#include <wtf/ProcessID.h>
namespace WTF {
......@@ -449,8 +450,9 @@ void MetaAllocator::freeFreeSpaceNode(FreeSpaceNode* node)
#if ENABLE(META_ALLOCATOR_PROFILE)
void MetaAllocator::dumpProfile()
{
dataLogF("%d: MetaAllocator(%p): num allocations = %u, num frees = %u, allocated = %lu, reserved = %lu, committed = %lu\n",
getpid(), this, m_numAllocations, m_numFrees, m_bytesAllocated, m_bytesReserved, m_bytesCommitted);
dataLogF(
"%d: MetaAllocator(%p): num allocations = %u, num frees = %u, allocated = %lu, reserved = %lu, committed = %lu\n",
getCurrentProcessID(), this, m_numAllocations, m_numFrees, m_bytesAllocated, m_bytesReserved, m_bytesCommitted);
}
#endif
......
/*
* Copyright (C) 2013 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef ProcessID_h
#define ProcessID_h
#include <wtf/Platform.h>
#if OS(UNIX)
#include <unistd.h>
#endif
#if PLATFORM(WIN)
#include <windows.h>
#endif
namespace WTF {
inline int getCurrentProcessID()
{
#if PLATFORM(WIN)
return GetCurrentProcessId();
#else
return getpid();
#endif
}
} // namespace WTF
using WTF::getCurrentProcessID;
#endif // ProcessID_h
......@@ -28,6 +28,7 @@
#include "AtomicString.h"
#include "StringBuffer.h"
#include "StringHash.h"
#include <wtf/ProcessID.h>
#include <wtf/StdLibExtras.h>
#include <wtf/WTFThreadData.h>
#include <wtf/unicode/CharacterNames.h>
......@@ -81,7 +82,7 @@ void StringStats::removeString(StringImpl* string)
void StringStats::printStats()
{
dataLogF("String stats for process id %d:\n", getpid());
dataLogF("String stats for process id %d:\n", getCurrentProcessID());
unsigned long long totalNumberCharacters = m_total8BitData + m_total16BitData;
double percent8Bit = m_totalNumberStrings ? ((double)m_number8BitStrings * 100) / (double)m_totalNumberStrings : 0.0;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment