Internal JSC profiler should have a timestamped log of events for each code block
https://bugs.webkit.org/show_bug.cgi?id=157538
Reviewed by Benjamin Poulain.
Source/JavaScriptCore:
For example, in 3d-cube, I can query the events for MMulti and I get:
1462917476.17083 MMulti#DTZ7qc installCode
1462917476.179663 MMulti#DTZ7qc MMulti#DTZ7qc-1-Baseline installCode
1462917476.179664 MMulti#DTZ7qc MMulti#DTZ7qc-1-Baseline osrEntry at bc#49
1462917476.185651 MMulti#DTZ7qc MMulti#DTZ7qc-1-Baseline delayOptimizeToDFG counter = 1011.214233/1717.000000, -707
1462917476.187913 MMulti#DTZ7qc MMulti#DTZ7qc-2-DFG installCode
1462917476.187917 MMulti#DTZ7qc MMulti#DTZ7qc-2-DFG osrEntry at bc#49
1462917476.205365 MMulti#DTZ7qc MMulti#DTZ7qc-2-DFG jettison due to OSRExit, counting = true, detail = (null)
1462917476.205368 MMulti#DTZ7qc MMulti#DTZ7qc-1-Baseline frequentExit bc#65: BadCache/FromDFG
1462917476.205369 MMulti#DTZ7qc MMulti#DTZ7qc-1-Baseline installCode
1462917476.205482 MMulti#DTZ7qc MMulti#DTZ7qc-1-Baseline delayOptimizeToDFG counter = 1013.000000/3434.000000, -1000
1462917476.211547 MMulti#DTZ7qc MMulti#DTZ7qc-1-Baseline delayOptimizeToDFG counter = 2013.000000/3434.000000, -1000
1462917476.213721 MMulti#DTZ7qc MMulti#DTZ7qc-3-DFG installCode
1462917476.213726 MMulti#DTZ7qc MMulti#DTZ7qc-3-DFG osrEntry at bc#49
1462917476.223976 MMulti#DTZ7qc MMulti#DTZ7qc-3-DFG jettison due to OSRExit, counting = true, detail = (null)
1462917476.223981 MMulti#DTZ7qc MMulti#DTZ7qc-1-Baseline frequentExit bc#77: BadCache/FromDFG
1462917476.223982 MMulti#DTZ7qc MMulti#DTZ7qc-1-Baseline frequentExit bc#94: BadCache/FromDFG
1462917476.223982 MMulti#DTZ7qc MMulti#DTZ7qc-1-Baseline installCode
1462917476.224064 MMulti#DTZ7qc MMulti#DTZ7qc-1-Baseline delayOptimizeToDFG counter = 1013.000000/6868.000000, -1000
1462917476.224151 MMulti#DTZ7qc MMulti#DTZ7qc-1-Baseline delayOptimizeToDFG counter = 2013.000000/6868.000000, -1000
1462917476.224258 MMulti#DTZ7qc MMulti#DTZ7qc-1-Baseline delayOptimizeToDFG counter = 3013.000000/6868.000000, -1000
1462917476.224337 MMulti#DTZ7qc MMulti#DTZ7qc-1-Baseline delayOptimizeToDFG counter = 4023.000000/6868.000000, -1000
1462917476.224425 MMulti#DTZ7qc MMulti#DTZ7qc-1-Baseline delayOptimizeToDFG counter = 5023.000000/6868.000000, -1000
1462917476.224785 MMulti#DTZ7qc MMulti#DTZ7qc-1-Baseline delayOptimizeToDFG counter = 6023.396484/6868.000000, -862
1462917476.227669 MMulti#DTZ7qc MMulti#DTZ7qc-4-DFG installCode
1462917476.227675 MMulti#DTZ7qc MMulti#DTZ7qc-4-DFG osrEntry at bc#0
The output is ugly but useful. We can make it less ugly later.
* CMakeLists.txt:
* JavaScriptCore.xcodeproj/project.pbxproj:
* bytecode/CodeBlock.cpp:
(JSC::CodeBlock::jettison):
* bytecode/CodeBlock.h:
(JSC::ScriptExecutable::forEachCodeBlock):
* bytecode/DFGExitProfile.cpp:
(JSC::DFG::ExitProfile::add):
* dfg/DFGJITFinalizer.cpp:
(JSC::DFG::JITFinalizer::finalizeCommon):
* dfg/DFGOperations.cpp:
* ftl/FTLJITFinalizer.cpp:
(JSC::FTL::JITFinalizer::finalizeFunction):
* jit/JIT.cpp:
(JSC::JIT::privateCompile):
* jit/JITOperations.cpp:
* llint/LLIntSlowPaths.cpp:
(JSC::LLInt::jitCompileAndSetHeuristics):
(JSC::LLInt::entryOSR):
(JSC::LLInt::LLINT_SLOW_PATH_DECL):
* profiler/ProfilerCompilation.cpp:
(JSC::Profiler::Compilation::Compilation):
(JSC::Profiler::Compilation::setJettisonReason):
(JSC::Profiler::Compilation::dump):
(JSC::Profiler::Compilation::toJS):
* profiler/ProfilerCompilation.h:
(JSC::Profiler::Compilation::uid):
* profiler/ProfilerDatabase.cpp:
(JSC::Profiler::Database::ensureBytecodesFor):
(JSC::Profiler::Database::notifyDestruction):
(JSC::Profiler::Database::addCompilation):
(JSC::Profiler::Database::toJS):
(JSC::Profiler::Database::registerToSaveAtExit):
(JSC::Profiler::Database::logEvent):
(JSC::Profiler::Database::addDatabaseToAtExit):
* profiler/ProfilerDatabase.h:
* profiler/ProfilerEvent.cpp: Added.
(JSC::Profiler::Event::dump):
(JSC::Profiler::Event::toJS):
* profiler/ProfilerEvent.h: Added.
(JSC::Profiler::Event::Event):
(JSC::Profiler::Event::operator bool):
(JSC::Profiler::Event::time):
(JSC::Profiler::Event::bytecodes):
(JSC::Profiler::Event::compilation):
(JSC::Profiler::Event::summary):
(JSC::Profiler::Event::detail):
* profiler/ProfilerUID.cpp: Added.
(JSC::Profiler::UID::create):
(JSC::Profiler::UID::dump):
(JSC::Profiler::UID::toJS):
* profiler/ProfilerUID.h: Added.
(JSC::Profiler::UID::UID):
(JSC::Profiler::UID::fromInt):
(JSC::Profiler::UID::toInt):
(JSC::Profiler::UID::operator==):
(JSC::Profiler::UID::operator!=):
(JSC::Profiler::UID::operator bool):
(JSC::Profiler::UID::isHashTableDeletedValue):
(JSC::Profiler::UID::hash):
(JSC::Profiler::UIDHash::hash):
(JSC::Profiler::UIDHash::equal):
* runtime/CommonIdentifiers.h:
* runtime/Executable.cpp:
(JSC::ScriptExecutable::installCode):
* runtime/VM.h:
(JSC::VM::bytecodeIntrinsicRegistry):
(JSC::VM::shadowChicken):
* runtime/VMInlines.h:
(JSC::VM::shouldTriggerTermination):
(JSC::VM::logEvent):
Source/WTF:
* wtf/PrintStream.h:
(WTF::PrintStream::print):
Tools:
* Scripts/display-profiler-output:
git-svn-id: http://svn.webkit.org/repository/webkit/trunk@200658 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/Source/JavaScriptCore/dfg/DFGOperations.cpp b/Source/JavaScriptCore/dfg/DFGOperations.cpp
index 0f2e505..0198066 100644
--- a/Source/JavaScriptCore/dfg/DFGOperations.cpp
+++ b/Source/JavaScriptCore/dfg/DFGOperations.cpp
@@ -57,7 +57,7 @@
#include "Symbol.h"
#include "TypeProfilerLog.h"
#include "TypedArrayInlines.h"
-#include "VM.h"
+#include "VMInlines.h"
#include <wtf/InlineASM.h>
#if ENABLE(JIT)
@@ -1765,6 +1765,7 @@
static bool shouldTriggerFTLCompile(CodeBlock* codeBlock, JITCode* jitCode)
{
if (codeBlock->baselineVersion()->m_didFailFTLCompilation) {
+ CODEBLOCK_LOG_EVENT(codeBlock, "abortFTLCompile", ());
if (Options::verboseOSR())
dataLog("Deferring FTL-optimization of ", *codeBlock, " indefinitely because there was an FTL failure.\n");
jitCode->dontOptimizeAnytimeSoon(codeBlock);
@@ -1773,6 +1774,7 @@
if (!codeBlock->hasOptimizedReplacement()
&& !jitCode->checkIfOptimizationThresholdReached(codeBlock)) {
+ CODEBLOCK_LOG_EVENT(codeBlock, "delayFTLCompile", ("counter = ", jitCode->tierUpCounter));
if (Options::verboseOSR())
dataLog("Choosing not to FTL-optimize ", *codeBlock, " yet.\n");
return false;
@@ -1790,12 +1792,14 @@
worklistState = Worklist::NotKnown;
if (worklistState == Worklist::Compiling) {
+ CODEBLOCK_LOG_EVENT(codeBlock, "delayFTLCompile", ("still compiling"));
jitCode->setOptimizationThresholdBasedOnCompilationResult(
codeBlock, CompilationDeferred);
return;
}
if (codeBlock->hasOptimizedReplacement()) {
+ CODEBLOCK_LOG_EVENT(codeBlock, "delayFTLCompile", ("has replacement"));
// That's great, we've compiled the code - next time we call this function,
// we'll enter that replacement.
jitCode->optimizeSoon(codeBlock);
@@ -1803,6 +1807,7 @@
}
if (worklistState == Worklist::Compiled) {
+ CODEBLOCK_LOG_EVENT(codeBlock, "delayFTLCompile", ("compiled and failed"));
// This means that we finished compiling, but failed somehow; in that case the
// thresholds will be set appropriately.
if (Options::verboseOSR())
@@ -1810,6 +1815,7 @@
return;
}
+ CODEBLOCK_LOG_EVENT(codeBlock, "triggerFTLReplacement", ());
// We need to compile the code.
compile(
*vm, codeBlock->newReplacement(), codeBlock, FTLMode, UINT_MAX,
@@ -1845,12 +1851,14 @@
if (codeBlock->hasOptimizedReplacement()) {
if (jitCode->tierUpEntryTriggers.isEmpty()) {
+ CODEBLOCK_LOG_EVENT(codeBlock, "delayFTLCompile", ("replacement in place, delaying indefinitely"));
// There is nothing more we can do, the only way this will be entered
// is through the function entry point.
jitCode->dontOptimizeAnytimeSoon(codeBlock);
return;
}
if (jitCode->osrEntryBlock() && jitCode->tierUpEntryTriggers.size() == 1) {
+ CODEBLOCK_LOG_EVENT(codeBlock, "delayFTLCompile", ("trigger in place, delaying indefinitely"));
// There is only one outer loop and its trigger must have been set
// when the plan completed.
// Exiting the inner loop is useless, we can ignore the counter and leave
@@ -1876,12 +1884,14 @@
JITCode* jitCode = codeBlock->jitCode()->dfg();
if (worklistState == Worklist::Compiling) {
+ CODEBLOCK_LOG_EVENT(codeBlock, "delayFTLCompile", ("still compiling"));
jitCode->setOptimizationThresholdBasedOnCompilationResult(
codeBlock, CompilationDeferred);
return nullptr;
}
if (worklistState == Worklist::Compiled) {
+ CODEBLOCK_LOG_EVENT(codeBlock, "delayFTLCompile", ("compiled and failed"));
// This means that compilation failed and we already set the thresholds.
if (Options::verboseOSR())
dataLog("Code block ", *codeBlock, " was compiled but it doesn't have an optimized replacement.\n");
@@ -1892,8 +1902,10 @@
if (originBytecodeIndex == osrEntryBytecodeIndex) {
unsigned streamIndex = jitCode->bytecodeIndexToStreamIndex.get(originBytecodeIndex);
if (CodeBlock* entryBlock = jitCode->osrEntryBlock()) {
- if (void* address = FTL::prepareOSREntry(exec, codeBlock, entryBlock, originBytecodeIndex, streamIndex))
+ if (void* address = FTL::prepareOSREntry(exec, codeBlock, entryBlock, originBytecodeIndex, streamIndex)) {
+ CODEBLOCK_LOG_EVENT(entryBlock, "osrEntry", ("at bc#", originBytecodeIndex));
return static_cast<char*>(address);
+ }
}
}
@@ -1911,14 +1923,17 @@
return nullptr;
if (jitCode->osrEntryRetry < Options::ftlOSREntryRetryThreshold()) {
+ CODEBLOCK_LOG_EVENT(codeBlock, "delayFTLCompile", ("avoiding OSR entry compile"));
jitCode->osrEntryRetry++;
return nullptr;
}
- }
+ } else
+ CODEBLOCK_LOG_EVENT(codeBlock, "delayFTLCompile", ("avoiding replacement compile"));
// It's time to try to compile code for OSR entry.
if (CodeBlock* entryBlock = jitCode->osrEntryBlock()) {
if (jitCode->osrEntryRetry < Options::ftlOSREntryRetryThreshold()) {
+ CODEBLOCK_LOG_EVENT(codeBlock, "delayFTLCompile", ("OSR entry failed, OSR entry threshold not met"));
jitCode->osrEntryRetry++;
jitCode->setOptimizationThresholdBasedOnCompilationResult(
codeBlock, CompilationDeferred);
@@ -1929,6 +1944,7 @@
entryCode->countEntryFailure();
if (entryCode->entryFailureCount() <
Options::ftlOSREntryFailureCountForReoptimization()) {
+ CODEBLOCK_LOG_EVENT(codeBlock, "delayFTLCompile", ("OSR entry failed"));
jitCode->setOptimizationThresholdBasedOnCompilationResult(
codeBlock, CompilationDeferred);
return nullptr;
@@ -1936,6 +1952,7 @@
// OSR entry failed. Oh no! This implies that we need to retry. We retry
// without exponential backoff and we only do this for the entry code block.
+ CODEBLOCK_LOG_EVENT(codeBlock, "delayFTLCompile", ("OSR entry failed too many times"));
unsigned osrEntryBytecode = entryBlock->jitCode()->ftlForOSREntry()->bytecodeIndex();
jitCode->clearOSREntryBlock();
jitCode->osrEntryRetry = 0;
@@ -1967,6 +1984,7 @@
exec, codeBlock, CodeOrigin(osrEntryBytecodeIndex), streamIndex, mustHandleValues);
CodeBlock* replacementCodeBlock = codeBlock->newReplacement();
+ CODEBLOCK_LOG_EVENT(codeBlock, "triggerFTLOSR", ());
CompilationResult forEntryResult = compile(
*vm, replacementCodeBlock, codeBlock, FTLForOSREntryMode, osrEntryBytecodeIndex,
mustHandleValues, ToFTLForOSREntryDeferredCompilationCallback::create(triggerAddress));
@@ -1975,11 +1993,13 @@
triggerFTLReplacementCompile(vm, codeBlock, jitCode);
if (forEntryResult != CompilationSuccessful) {
+ CODEBLOCK_LOG_EVENT(codeBlock, "delayFTLCompile", ("OSR ecompilation not successful"));
jitCode->setOptimizationThresholdBasedOnCompilationResult(
codeBlock, CompilationDeferred);
return nullptr;
}
-
+
+ CODEBLOCK_LOG_EVENT(jitCode->osrEntryBlock(), "osrEntry", ("at bc#", originBytecodeIndex));
// It's possible that the for-entry compile already succeeded. In that case OSR
// entry will succeed unless we ran out of stack. It's not clear what we should do.
// We signal to try again after a while if that happens.
@@ -2016,8 +2036,10 @@
triggerFTLReplacementCompile(vm, codeBlock, jitCode);
// Since we cannot OSR Enter here, the default "optimizeSoon()" is not useful.
- if (codeBlock->hasOptimizedReplacement())
+ if (codeBlock->hasOptimizedReplacement()) {
+ CODEBLOCK_LOG_EVENT(codeBlock, "delayFTLCompile", ("OSR in loop failed, deferring"));
jitCode->setOptimizationThresholdBasedOnCompilationResult(codeBlock, CompilationDeferred);
+ }
}
char* JIT_OPERATION triggerOSREntryNow(ExecState* exec, unsigned bytecodeIndex)