- Revision
- 201361
- Author
- [email protected]
- Date
- 2016-05-24 16:03:09 -0700 (Tue, 24 May 2016)
Log Message
We should be able to use the sampling profiler with DRT/WTR.
https://bugs.webkit.org/show_bug.cgi?id=158041
Reviewed by Saam Barati.
This patch makes the sampling profiler use a new option, samplingProfilerPath, which
specifies the path to a directory to output sampling profiler data when the program
terminates or the VM is destroyed. Additionally, it fixes some other issues with the
bytecode profiler that would cause crashes on debug builds.
* profiler/ProfilerDatabase.cpp:
(JSC::Profiler::Database::ensureBytecodesFor):
(JSC::Profiler::Database::performAtExitSave):
* runtime/Options.h:
* runtime/SamplingProfiler.cpp:
(JSC::SamplingProfiler::registerForReportAtExit):
(JSC::SamplingProfiler::reportDataToOptionFile):
(JSC::SamplingProfiler::reportTopFunctions):
(JSC::SamplingProfiler::reportTopBytecodes):
* runtime/SamplingProfiler.h:
* runtime/VM.cpp:
(JSC::VM::VM):
(JSC::VM::~VM):
Modified Paths
Diff
Modified: trunk/Source/_javascript_Core/ChangeLog (201360 => 201361)
--- trunk/Source/_javascript_Core/ChangeLog 2016-05-24 23:02:14 UTC (rev 201360)
+++ trunk/Source/_javascript_Core/ChangeLog 2016-05-24 23:03:09 UTC (rev 201361)
@@ -1,3 +1,29 @@
+2016-05-24 Keith Miller <[email protected]>
+
+ We should be able to use the sampling profiler with DRT/WTR.
+ https://bugs.webkit.org/show_bug.cgi?id=158041
+
+ Reviewed by Saam Barati.
+
+ This patch makes the sampling profiler use a new option, samplingProfilerPath, which
+ specifies the path to a directory to output sampling profiler data when the program
+ terminates or the VM is destroyed. Additionally, it fixes some other issues with the
+ bytecode profiler that would cause crashes on debug builds.
+
+ * profiler/ProfilerDatabase.cpp:
+ (JSC::Profiler::Database::ensureBytecodesFor):
+ (JSC::Profiler::Database::performAtExitSave):
+ * runtime/Options.h:
+ * runtime/SamplingProfiler.cpp:
+ (JSC::SamplingProfiler::registerForReportAtExit):
+ (JSC::SamplingProfiler::reportDataToOptionFile):
+ (JSC::SamplingProfiler::reportTopFunctions):
+ (JSC::SamplingProfiler::reportTopBytecodes):
+ * runtime/SamplingProfiler.h:
+ * runtime/VM.cpp:
+ (JSC::VM::VM):
+ (JSC::VM::~VM):
+
2016-05-24 Saam barati <[email protected]>
We can cache lookups to JSScope::abstractResolve inside CodeBlock::finishCreation
Modified: trunk/Source/_javascript_Core/profiler/ProfilerDatabase.cpp (201360 => 201361)
--- trunk/Source/_javascript_Core/profiler/ProfilerDatabase.cpp 2016-05-24 23:02:14 UTC (rev 201360)
+++ trunk/Source/_javascript_Core/profiler/ProfilerDatabase.cpp 2016-05-24 23:03:09 UTC (rev 201361)
@@ -64,7 +64,7 @@
Bytecodes* Database::ensureBytecodesFor(const LockHolder&, CodeBlock* codeBlock)
{
- codeBlock = codeBlock->baselineVersion();
+ codeBlock = codeBlock->baselineAlternative();
HashMap<CodeBlock*, Bytecodes*>::iterator iter = m_bytecodesMap.find(codeBlock);
if (iter != m_bytecodesMap.end())
@@ -182,6 +182,7 @@
void Database::performAtExitSave() const
{
+ JSLockHolder lock(m_vm);
save(m_atExitSaveFilename.data());
}
Modified: trunk/Source/_javascript_Core/runtime/Options.h (201360 => 201361)
--- trunk/Source/_javascript_Core/runtime/Options.h 2016-05-24 23:02:14 UTC (rev 201360)
+++ trunk/Source/_javascript_Core/runtime/Options.h 2016-05-24 23:03:09 UTC (rev 201361)
@@ -327,6 +327,7 @@
v(bool, useSamplingProfiler, false, Normal, nullptr) \
v(unsigned, sampleInterval, 1000, Normal, "Time between stack traces in microseconds.") \
v(bool, collectSamplingProfilerDataForJSCShell, false, Normal, "This corresponds to the JSC shell's --sample option.") \
+ v(optionString, samplingProfilerPath, nullptr, Normal, "The path to the directory to write sampiling profiler output to. This probably will not work with WK2 unless the path is in the whitelist.") \
\
v(bool, alwaysGeneratePCToCodeOriginMap, false, Normal, "This will make sure we always generate a PCToCodeOriginMap for JITed code.") \
\
Modified: trunk/Source/_javascript_Core/runtime/SamplingProfiler.cpp (201360 => 201361)
--- trunk/Source/_javascript_Core/runtime/SamplingProfiler.cpp 2016-05-24 23:02:14 UTC (rev 201360)
+++ trunk/Source/_javascript_Core/runtime/SamplingProfiler.cpp 2016-05-24 23:03:09 UTC (rev 201361)
@@ -47,6 +47,8 @@
#include "StructureInlines.h"
#include "VM.h"
#include "VMEntryScope.h"
+#include <wtf/HashSet.h>
+#include <wtf/RefPtr.h>
namespace JSC {
@@ -760,8 +762,46 @@
return json.toString();
}
+void SamplingProfiler::registerForReportAtExit()
+{
+ static StaticLock registrationLock;
+ static HashSet<RefPtr<SamplingProfiler>>* profilesToReport;
+
+ LockHolder holder(registrationLock);
+
+ if (!profilesToReport) {
+ profilesToReport = new HashSet<RefPtr<SamplingProfiler>>();
+ atexit([]() {
+ for (auto profile : *profilesToReport)
+ profile->reportDataToOptionFile();
+ });
+ }
+
+ profilesToReport->add(adoptRef(this));
+ m_needsReportAtExit = true;
+}
+
+void SamplingProfiler::reportDataToOptionFile()
+{
+ if (m_needsReportAtExit) {
+ m_needsReportAtExit = false;
+ const char* path = Options::samplingProfilerPath();
+ StringPrintStream pathOut;
+ pathOut.print(path, "/");
+ pathOut.print("JSCSampilingProfile-", reinterpret_cast<uintptr_t>(this), ".txt");
+ auto out = FilePrintStream::open(pathOut.toCString().data(), "w");
+ reportTopFunctions(*out);
+ reportTopBytecodes(*out);
+ }
+}
+
void SamplingProfiler::reportTopFunctions()
{
+ reportTopFunctions(WTF::dataFile());
+}
+
+void SamplingProfiler::reportTopFunctions(PrintStream& out)
+{
LockHolder locker(m_lock);
{
@@ -794,19 +834,24 @@
return std::make_pair(maxFrameDescription, maxFrameCount);
};
- dataLog("\n\nSampling rate: ", m_timingInterval.count(), " microseconds\n");
- dataLog("Hottest functions as <numSamples 'functionName:sourceID'>\n");
+ out.print("\n\nSampling rate: ", m_timingInterval.count(), " microseconds\n");
+ out.print("Hottest functions as <numSamples 'functionName:sourceID'>\n");
for (size_t i = 0; i < 40; i++) {
auto pair = takeMax();
if (pair.first.isEmpty())
break;
- dataLogF("%6zu ", pair.second);
- dataLog(" '", pair.first, "'\n");
+ out.printf("%6zu ", pair.second);
+ out.print(" '", pair.first, "'\n");
}
}
void SamplingProfiler::reportTopBytecodes()
{
+ reportTopBytecodes(WTF::dataFile());
+}
+
+void SamplingProfiler::reportTopBytecodes(PrintStream& out)
+{
LockHolder locker(m_lock);
{
@@ -852,14 +897,14 @@
return std::make_pair(maxFrameDescription, maxFrameCount);
};
- dataLog("\n\nSampling rate: ", m_timingInterval.count(), " microseconds\n");
- dataLog("Hottest bytecodes as <numSamples 'functionName#hash:JITType:bytecodeIndex'>\n");
+ out.print("\n\nSampling rate: ", m_timingInterval.count(), " microseconds\n");
+ out.print("Hottest bytecodes as <numSamples 'functionName#hash:JITType:bytecodeIndex'>\n");
for (size_t i = 0; i < 80; i++) {
auto pair = takeMax();
if (pair.first.isEmpty())
break;
- dataLogF("%6zu ", pair.second);
- dataLog(" '", pair.first, "'\n");
+ out.printf("%6zu ", pair.second);
+ out.print(" '", pair.first, "'\n");
}
}
Modified: trunk/Source/_javascript_Core/runtime/SamplingProfiler.h (201360 => 201361)
--- trunk/Source/_javascript_Core/runtime/SamplingProfiler.h 2016-05-24 23:02:14 UTC (rev 201360)
+++ trunk/Source/_javascript_Core/runtime/SamplingProfiler.h 2016-05-24 23:03:09 UTC (rev 201361)
@@ -152,9 +152,13 @@
void setStopWatch(const LockHolder&, Ref<Stopwatch>&& stopwatch) { m_stopwatch = WTFMove(stopwatch); }
void pause(const LockHolder&);
- // Used for debugging in the JSC shell.
+ // Used for debugging in the JSC shell/DRT.
+ void registerForReportAtExit();
+ void reportDataToOptionFile();
JS_EXPORT_PRIVATE void reportTopFunctions();
+ JS_EXPORT_PRIVATE void reportTopFunctions(PrintStream&);
JS_EXPORT_PRIVATE void reportTopBytecodes();
+ JS_EXPORT_PRIVATE void reportTopBytecodes(PrintStream&);
private:
void clearData(const LockHolder&);
@@ -173,6 +177,7 @@
MachineThreads::Thread* m_jscExecutionThread;
bool m_isPaused;
bool m_isShutDown;
+ bool m_needsReportAtExit { false };
HashSet<JSCell*> m_liveCellPointers;
Vector<UnprocessedStackFrame> m_currentFrames;
};
Modified: trunk/Source/_javascript_Core/runtime/VM.cpp (201360 => 201361)
--- trunk/Source/_javascript_Core/runtime/VM.cpp 2016-05-24 23:02:14 UTC (rev 201360)
+++ trunk/Source/_javascript_Core/runtime/VM.cpp 2016-05-24 23:03:09 UTC (rev 201361)
@@ -315,6 +315,8 @@
Ref<Stopwatch> stopwatch = Stopwatch::create();
stopwatch->start();
m_samplingProfiler = adoptRef(new SamplingProfiler(*this, WTFMove(stopwatch)));
+ if (Options::samplingProfilerPath())
+ m_samplingProfiler->registerForReportAtExit();
m_samplingProfiler->start();
}
#endif // ENABLE(SAMPLING_PROFILER)
@@ -335,8 +337,10 @@
heap.incrementDeferralDepth();
#if ENABLE(SAMPLING_PROFILER)
- if (m_samplingProfiler)
+ if (m_samplingProfiler) {
+ m_samplingProfiler->reportDataToOptionFile();
m_samplingProfiler->shutdown();
+ }
#endif // ENABLE(SAMPLING_PROFILER)
#if ENABLE(DFG_JIT)