Diff
Modified: trunk/Source/_javascript_Core/CMakeLists.txt (200657 => 200658)
--- trunk/Source/_javascript_Core/CMakeLists.txt 2016-05-11 00:02:02 UTC (rev 200657)
+++ trunk/Source/_javascript_Core/CMakeLists.txt 2016-05-11 00:08:50 UTC (rev 200658)
@@ -597,12 +597,14 @@
profiler/ProfilerCompilationKind.cpp
profiler/ProfilerCompiledBytecode.cpp
profiler/ProfilerDatabase.cpp
+ profiler/ProfilerEvent.cpp
profiler/ProfilerJettisonReason.cpp
profiler/ProfilerOSRExit.cpp
profiler/ProfilerOSRExitSite.cpp
profiler/ProfilerOrigin.cpp
profiler/ProfilerOriginStack.cpp
profiler/ProfilerProfiledBytecodes.cpp
+ profiler/ProfilerUID.cpp
runtime/ArgList.cpp
runtime/ArrayBuffer.cpp
Modified: trunk/Source/_javascript_Core/ChangeLog (200657 => 200658)
--- trunk/Source/_javascript_Core/ChangeLog 2016-05-11 00:02:02 UTC (rev 200657)
+++ trunk/Source/_javascript_Core/ChangeLog 2016-05-11 00:08:50 UTC (rev 200658)
@@ -1,3 +1,112 @@
+2016-05-10 Filip Pizlo <[email protected]>
+
+ 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.
+
+ 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:
+ * _javascript_Core.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):
+
2016-05-10 Joseph Pecoraro <[email protected]>
Web Inspector: Backend should initiate timeline recordings on page navigations to ensure nothing is missed
Modified: trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj (200657 => 200658)
--- trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj 2016-05-11 00:02:02 UTC (rev 200657)
+++ trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj 2016-05-11 00:08:50 UTC (rev 200658)
@@ -1992,6 +1992,10 @@
DC17E81A1C9C91E9008A6AB3 /* CCallHelpers.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DC17E8161C9C802B008A6AB3 /* CCallHelpers.cpp */; };
DC2143071CA32E55000A8869 /* ICStats.h in Headers */ = {isa = PBXBuildFile; fileRef = DC2143061CA32E52000A8869 /* ICStats.h */; };
DC2143081CA32E58000A8869 /* ICStats.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DC2143051CA32E52000A8869 /* ICStats.cpp */; };
+ DC605B5D1CE26EA000593718 /* ProfilerEvent.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DC605B591CE26E9800593718 /* ProfilerEvent.cpp */; };
+ DC605B5E1CE26EA200593718 /* ProfilerEvent.h in Headers */ = {isa = PBXBuildFile; fileRef = DC605B5A1CE26E9800593718 /* ProfilerEvent.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ DC605B5F1CE26EA500593718 /* ProfilerUID.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DC605B5B1CE26E9800593718 /* ProfilerUID.cpp */; };
+ DC605B601CE26EA700593718 /* ProfilerUID.h in Headers */ = {isa = PBXBuildFile; fileRef = DC605B5C1CE26E9800593718 /* ProfilerUID.h */; settings = {ATTRIBUTES = (Private, ); }; };
DC7997831CDE9FA0004D4A09 /* TagRegistersMode.h in Headers */ = {isa = PBXBuildFile; fileRef = DC7997821CDE9F9E004D4A09 /* TagRegistersMode.h */; settings = {ATTRIBUTES = (Private, ); }; };
DC7997841CDE9FA2004D4A09 /* TagRegistersMode.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DC7997811CDE9F9E004D4A09 /* TagRegistersMode.cpp */; };
DCF3D5691CD2946D003D5C65 /* LazyClassStructure.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DCF3D5641CD29468003D5C65 /* LazyClassStructure.cpp */; };
@@ -4206,6 +4210,10 @@
DC17E8161C9C802B008A6AB3 /* CCallHelpers.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CCallHelpers.cpp; sourceTree = "<group>"; };
DC2143051CA32E52000A8869 /* ICStats.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ICStats.cpp; sourceTree = "<group>"; };
DC2143061CA32E52000A8869 /* ICStats.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ICStats.h; sourceTree = "<group>"; };
+ DC605B591CE26E9800593718 /* ProfilerEvent.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ProfilerEvent.cpp; path = profiler/ProfilerEvent.cpp; sourceTree = "<group>"; };
+ DC605B5A1CE26E9800593718 /* ProfilerEvent.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ProfilerEvent.h; path = profiler/ProfilerEvent.h; sourceTree = "<group>"; };
+ DC605B5B1CE26E9800593718 /* ProfilerUID.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ProfilerUID.cpp; path = profiler/ProfilerUID.cpp; sourceTree = "<group>"; };
+ DC605B5C1CE26E9800593718 /* ProfilerUID.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ProfilerUID.h; path = profiler/ProfilerUID.h; sourceTree = "<group>"; };
DC7997811CDE9F9E004D4A09 /* TagRegistersMode.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TagRegistersMode.cpp; sourceTree = "<group>"; };
DC7997821CDE9F9E004D4A09 /* TagRegistersMode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TagRegistersMode.h; sourceTree = "<group>"; };
DCF3D5641CD29468003D5C65 /* LazyClassStructure.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = LazyClassStructure.cpp; sourceTree = "<group>"; };
@@ -6445,6 +6453,8 @@
0FF7299B166AD347000F5BA3 /* ProfilerCompiledBytecode.h */,
0FF7299C166AD347000F5BA3 /* ProfilerDatabase.cpp */,
0FF7299D166AD347000F5BA3 /* ProfilerDatabase.h */,
+ DC605B591CE26E9800593718 /* ProfilerEvent.cpp */,
+ DC605B5A1CE26E9800593718 /* ProfilerEvent.h */,
0FF7299E166AD347000F5BA3 /* ProfilerExecutionCounter.h */,
0F190CAA189D82F6000AE5F0 /* ProfilerJettisonReason.cpp */,
0F190CAB189D82F6000AE5F0 /* ProfilerJettisonReason.h */,
@@ -6458,6 +6468,8 @@
0FB1058A1675482E00F8AB6E /* ProfilerOSRExitSite.h */,
0F13912616771C30009CCB07 /* ProfilerProfiledBytecodes.cpp */,
0F13912716771C30009CCB07 /* ProfilerProfiledBytecodes.h */,
+ DC605B5B1CE26E9800593718 /* ProfilerUID.cpp */,
+ DC605B5C1CE26E9800593718 /* ProfilerUID.h */,
);
name = profiler;
sourceTree = "<group>";
@@ -7757,6 +7769,7 @@
70B7919C1C024A49002481E2 /* JSGeneratorFunction.h in Headers */,
BC18C42A0E16F5CD00B34460 /* JSType.h in Headers */,
0F2B66FB17B6B5AB00A7AE3F /* JSTypedArrayConstructors.h in Headers */,
+ DC605B601CE26EA700593718 /* ProfilerUID.h in Headers */,
0F2B66FD17B6B5AB00A7AE3F /* JSTypedArrayPrototypes.h in Headers */,
0F2B66FF17B6B5AB00A7AE3F /* JSTypedArrays.h in Headers */,
534C457C1BC72411007476A7 /* JSTypedArrayViewConstructor.h in Headers */,
@@ -7772,6 +7785,7 @@
86E3C615167BABD7006D760A /* JSVirtualMachine.h in Headers */,
86E3C61D167BABEE006D760A /* JSVirtualMachineInternal.h in Headers */,
7B98D1371B60CD620023B1A4 /* JSWASMModule.h in Headers */,
+ DC605B5E1CE26EA200593718 /* ProfilerEvent.h in Headers */,
A7CA3AE817DA41AE006538AF /* JSWeakMap.h in Headers */,
A7482E93116A7CAD003B0712 /* JSWeakObjectMapRefInternal.h in Headers */,
A7482B9311671147003B0712 /* JSWeakObjectMapRefPrivate.h in Headers */,
@@ -9208,6 +9222,7 @@
A700873D17CBE8D300C3E643 /* MapPrototype.cpp in Sources */,
C2B916C514DA040C00CBAC86 /* MarkedAllocator.cpp in Sources */,
142D6F0813539A2800B02E86 /* MarkedBlock.cpp in Sources */,
+ DC605B5D1CE26EA000593718 /* ProfilerEvent.cpp in Sources */,
14D2F3DA139F4BE200491031 /* MarkedSpace.cpp in Sources */,
142D6F1113539A4100B02E86 /* MarkStack.cpp in Sources */,
70B791981C024A29002481E2 /* GeneratorPrototype.cpp in Sources */,
@@ -9344,6 +9359,7 @@
705B41AF1A6E501E00716757 /* SymbolObject.cpp in Sources */,
705B41B11A6E501E00716757 /* SymbolPrototype.cpp in Sources */,
0F919D2815856773004A4E7D /* SymbolTable.cpp in Sources */,
+ DC605B5F1CE26EA500593718 /* ProfilerUID.cpp in Sources */,
70ECA6071AFDBEA200449739 /* TemplateRegistry.cpp in Sources */,
0FC314131814559100033232 /* TempRegisterSet.cpp in Sources */,
0FA2C17B17D7CF84009D015F /* TestRunnerUtils.cpp in Sources */,
Modified: trunk/Source/_javascript_Core/bytecode/CodeBlock.cpp (200657 => 200658)
--- trunk/Source/_javascript_Core/bytecode/CodeBlock.cpp 2016-05-11 00:02:02 UTC (rev 200657)
+++ trunk/Source/_javascript_Core/bytecode/CodeBlock.cpp 2016-05-11 00:08:50 UTC (rev 200658)
@@ -63,6 +63,7 @@
#include "TypeLocationCache.h"
#include "TypeProfiler.h"
#include "UnlinkedInstructionStream.h"
+#include "VMInlines.h"
#include <wtf/BagToHashMap.h>
#include <wtf/CommaPrinter.h>
#include <wtf/StringExtras.h>
@@ -3310,6 +3311,8 @@
UNUSED_PARAM(mode);
UNUSED_PARAM(detail);
#endif
+
+ CODEBLOCK_LOG_EVENT(this, "jettison", ("due to ", reason, ", counting = ", mode == CountReoptimization, ", detail = ", pointerDump(detail)));
RELEASE_ASSERT(reason != Profiler::NotJettisoned);
Modified: trunk/Source/_javascript_Core/bytecode/CodeBlock.h (200657 => 200658)
--- trunk/Source/_javascript_Core/bytecode/CodeBlock.h 2016-05-11 00:02:02 UTC (rev 200657)
+++ trunk/Source/_javascript_Core/bytecode/CodeBlock.h 2016-05-11 00:08:50 UTC (rev 200658)
@@ -59,7 +59,6 @@
#include "LazyOperandValueProfile.h"
#include "ObjectAllocationProfile.h"
#include "Options.h"
-#include "ProfilerCompilation.h"
#include "ProfilerJettisonReason.h"
#include "PutPropertySlot.h"
#include "RegExpObject.h"
@@ -1404,6 +1403,9 @@
}
}
+#define CODEBLOCK_LOG_EVENT(codeBlock, summary, details) \
+ (codeBlock->vm()->logEvent(codeBlock, summary, [&] () { return toCString details; }))
+
} // namespace JSC
#endif // CodeBlock_h
Modified: trunk/Source/_javascript_Core/bytecode/DFGExitProfile.cpp (200657 => 200658)
--- trunk/Source/_javascript_Core/bytecode/DFGExitProfile.cpp 2016-05-11 00:02:02 UTC (rev 200657)
+++ trunk/Source/_javascript_Core/bytecode/DFGExitProfile.cpp 2016-05-11 00:08:50 UTC (rev 200658)
@@ -29,6 +29,7 @@
#if ENABLE(DFG_JIT)
#include "CodeBlock.h"
+#include "VMInlines.h"
namespace JSC { namespace DFG {
@@ -44,6 +45,8 @@
{
ASSERT(site.jitType() != ExitFromAnything);
+ CODEBLOCK_LOG_EVENT(owner, "frequentExit", (site));
+
if (Options::verboseExitProfile())
dataLog(pointerDump(owner), ": Adding exit site: ", site, "\n");
Modified: trunk/Source/_javascript_Core/dfg/DFGJITFinalizer.cpp (200657 => 200658)
--- trunk/Source/_javascript_Core/dfg/DFGJITFinalizer.cpp 2016-05-11 00:02:02 UTC (rev 200657)
+++ trunk/Source/_javascript_Core/dfg/DFGJITFinalizer.cpp 2016-05-11 00:08:50 UTC (rev 200658)
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2013, 2015 Apple Inc. All rights reserved.
+ * Copyright (C) 2013, 2015-2016 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -91,7 +91,7 @@
#endif // ENABLE(FTL_JIT)
if (m_plan.compilation)
- m_plan.vm.m_perBytecodeProfiler->addCompilation(m_plan.compilation);
+ m_plan.vm.m_perBytecodeProfiler->addCompilation(m_plan.codeBlock, m_plan.compilation);
if (!m_plan.willTryToTierUp)
m_plan.codeBlock->baselineVersion()->m_didFailFTLCompilation = true;
Modified: trunk/Source/_javascript_Core/dfg/DFGNode.h (200657 => 200658)
--- trunk/Source/_javascript_Core/dfg/DFGNode.h 2016-05-11 00:02:02 UTC (rev 200657)
+++ trunk/Source/_javascript_Core/dfg/DFGNode.h 2016-05-11 00:08:50 UTC (rev 200658)
@@ -56,8 +56,14 @@
#include "ValueProfile.h"
#include <wtf/ListDump.h>
-namespace JSC { namespace DFG {
+namespace JSC {
+namespace Profiler {
+class ExecutionCounter;
+}
+
+namespace DFG {
+
class Graph;
class PromotedLocationDescriptor;
struct BasicBlock;
Modified: trunk/Source/_javascript_Core/dfg/DFGOperations.cpp (200657 => 200658)
--- trunk/Source/_javascript_Core/dfg/DFGOperations.cpp 2016-05-11 00:02:02 UTC (rev 200657)
+++ trunk/Source/_javascript_Core/dfg/DFGOperations.cpp 2016-05-11 00:08:50 UTC (rev 200658)
@@ -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)
Modified: trunk/Source/_javascript_Core/ftl/FTLJITFinalizer.cpp (200657 => 200658)
--- trunk/Source/_javascript_Core/ftl/FTLJITFinalizer.cpp 2016-05-11 00:02:02 UTC (rev 200657)
+++ trunk/Source/_javascript_Core/ftl/FTLJITFinalizer.cpp 2016-05-11 00:08:50 UTC (rev 200658)
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2013-2014, 2016 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -83,7 +83,7 @@
m_plan.codeBlock->setJITCode(jitCode);
if (m_plan.compilation)
- m_plan.vm.m_perBytecodeProfiler->addCompilation(m_plan.compilation);
+ m_plan.vm.m_perBytecodeProfiler->addCompilation(m_plan.codeBlock, m_plan.compilation);
return true;
}
Modified: trunk/Source/_javascript_Core/jit/JIT.cpp (200657 => 200658)
--- trunk/Source/_javascript_Core/jit/JIT.cpp 2016-05-11 00:02:02 UTC (rev 200657)
+++ trunk/Source/_javascript_Core/jit/JIT.cpp 2016-05-11 00:08:50 UTC (rev 200658)
@@ -81,6 +81,10 @@
{
}
+JIT::~JIT()
+{
+}
+
#if ENABLE(DFG_JIT)
void JIT::emitEnterOptimizationCheck()
{
@@ -738,7 +742,7 @@
if (m_compilation) {
if (Options::disassembleBaselineForProfiler())
m_disassembler->reportToProfiler(m_compilation.get(), patchBuffer);
- m_vm->m_perBytecodeProfiler->addCompilation(m_compilation);
+ m_vm->m_perBytecodeProfiler->addCompilation(m_codeBlock, m_compilation);
}
if (m_pcToCodeOriginMapBuilder.didBuildMapping())
Modified: trunk/Source/_javascript_Core/jit/JIT.h (200657 => 200658)
--- trunk/Source/_javascript_Core/jit/JIT.h 2016-05-11 00:02:02 UTC (rev 200657)
+++ trunk/Source/_javascript_Core/jit/JIT.h 2016-05-11 00:08:50 UTC (rev 200658)
@@ -257,6 +257,7 @@
private:
JIT(VM*, CodeBlock* = 0);
+ ~JIT();
void privateCompileMainPass();
void privateCompileLinkPass();
Modified: trunk/Source/_javascript_Core/jit/JITDisassembler.cpp (200657 => 200658)
--- trunk/Source/_javascript_Core/jit/JITDisassembler.cpp 2016-05-11 00:02:02 UTC (rev 200657)
+++ trunk/Source/_javascript_Core/jit/JITDisassembler.cpp 2016-05-11 00:08:50 UTC (rev 200658)
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2012, 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2012-2013, 2016 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,6 +33,7 @@
#include "JIT.h"
#include "JSCInlines.h"
#include "LinkBuffer.h"
+#include "ProfilerCompilation.h"
#include <wtf/StringPrintStream.h>
namespace JSC {
Modified: trunk/Source/_javascript_Core/jit/JITOperations.cpp (200657 => 200658)
--- trunk/Source/_javascript_Core/jit/JITOperations.cpp 2016-05-11 00:02:02 UTC (rev 200657)
+++ trunk/Source/_javascript_Core/jit/JITOperations.cpp 2016-05-11 00:08:50 UTC (rev 200658)
@@ -1235,6 +1235,7 @@
}
if (!codeBlock->checkIfOptimizationThresholdReached()) {
+ CODEBLOCK_LOG_EVENT(codeBlock, "delayOptimizeToDFG", ("counter = ", codeBlock->jitExecuteCounter()));
codeBlock->updateAllPredictions();
if (Options::verboseOSR())
dataLog("Choosing not to optimize ", *codeBlock, " yet, because the threshold hasn't been reached.\n");
@@ -1242,17 +1243,20 @@
}
if (vm.enabledProfiler()) {
+ CODEBLOCK_LOG_EVENT(codeBlock, "delayOptimizeToDFG", ("profiler is enabled"));
updateAllPredictionsAndOptimizeAfterWarmUp(codeBlock);
return encodeResult(0, 0);
}
Debugger* debugger = codeBlock->globalObject()->debugger();
if (debugger && (debugger->isStepping() || codeBlock->baselineAlternative()->hasDebuggerRequests())) {
+ CODEBLOCK_LOG_EVENT(codeBlock, "delayOptimizeToDFG", ("debugger is stepping or has requests"));
updateAllPredictionsAndOptimizeAfterWarmUp(codeBlock);
return encodeResult(0, 0);
}
if (codeBlock->m_shouldAlwaysBeInlined) {
+ CODEBLOCK_LOG_EVENT(codeBlock, "delayOptimizeToDFG", ("should always be inlined"));
updateAllPredictionsAndOptimizeAfterWarmUp(codeBlock);
if (Options::verboseOSR())
dataLog("Choosing not to optimize ", *codeBlock, " yet, because m_shouldAlwaysBeInlined == true.\n");
@@ -1293,6 +1297,7 @@
worklistState = DFG::Worklist::NotKnown;
if (worklistState == DFG::Worklist::Compiling) {
+ CODEBLOCK_LOG_EVENT(codeBlock, "delayOptimizeToDFG", ("compiling"));
// We cannot be in the process of asynchronous compilation and also have an optimized
// replacement.
RELEASE_ASSERT(!codeBlock->hasOptimizedReplacement());
@@ -1307,6 +1312,7 @@
// CodeBlock::setOptimizationThresholdBasedOnCompilationResult() and we have
// nothing left to do.
if (!codeBlock->hasOptimizedReplacement()) {
+ CODEBLOCK_LOG_EVENT(codeBlock, "delayOptimizeToDFG", ("compiled and failed"));
codeBlock->updateAllPredictions();
if (Options::verboseOSR())
dataLog("Code block ", *codeBlock, " was compiled but it doesn't have an optimized replacement.\n");
@@ -1329,6 +1335,7 @@
// shouldReoptimizeFromLoopNow() to always return true. But we make it do some
// additional checking anyway, to reduce the amount of recompilation thrashing.
if (codeBlock->replacement()->shouldReoptimizeFromLoopNow()) {
+ CODEBLOCK_LOG_EVENT(codeBlock, "delayOptimizeToDFG", ("should reoptimize from loop now"));
if (Options::verboseOSR()) {
dataLog(
"Triggering reoptimization of ", *codeBlock,
@@ -1339,6 +1346,7 @@
}
} else {
if (!codeBlock->shouldOptimizeNow()) {
+ CODEBLOCK_LOG_EVENT(codeBlock, "delayOptimizeToDFG", ("insufficient profiling"));
if (Options::verboseOSR()) {
dataLog(
"Delaying optimization for ", *codeBlock,
@@ -1369,14 +1377,17 @@
vm, replacementCodeBlock, nullptr, DFG::DFGMode, bytecodeIndex,
mustHandleValues, JITToDFGDeferredCompilationCallback::create());
- if (result != CompilationSuccessful)
+ if (result != CompilationSuccessful) {
+ CODEBLOCK_LOG_EVENT(codeBlock, "delayOptimizeToDFG", ("compilation failed"));
return encodeResult(0, 0);
+ }
}
CodeBlock* optimizedCodeBlock = codeBlock->replacement();
ASSERT(JITCode::isOptimizingJIT(optimizedCodeBlock->jitType()));
if (void* dataBuffer = DFG::prepareOSREntry(exec, optimizedCodeBlock, bytecodeIndex)) {
+ CODEBLOCK_LOG_EVENT(optimizedCodeBlock, "osrEntry", ("at bc#", bytecodeIndex));
if (Options::verboseOSR()) {
dataLog(
"Performing OSR ", *codeBlock, " -> ", *optimizedCodeBlock, ".\n");
@@ -1406,6 +1417,7 @@
// right now. So, we only trigger reoptimization only upon the more conservative (non-loop)
// reoptimization trigger.
if (optimizedCodeBlock->shouldReoptimizeNow()) {
+ CODEBLOCK_LOG_EVENT(codeBlock, "delayOptimizeToDFG", ("should reoptimize now"));
if (Options::verboseOSR()) {
dataLog(
"Triggering reoptimization of ", *codeBlock, " -> ",
@@ -1419,6 +1431,7 @@
// longer and then try again.
codeBlock->optimizeAfterWarmUp();
+ CODEBLOCK_LOG_EVENT(codeBlock, "delayOptimizeToDFG", ("OSR failed"));
return encodeResult(0, 0);
}
#endif
Modified: trunk/Source/_javascript_Core/llint/LLIntSlowPaths.cpp (200657 => 200658)
--- trunk/Source/_javascript_Core/llint/LLIntSlowPaths.cpp 2016-05-11 00:02:02 UTC (rev 200657)
+++ trunk/Source/_javascript_Core/llint/LLIntSlowPaths.cpp 2016-05-11 00:08:50 UTC (rev 200658)
@@ -319,6 +319,7 @@
codeBlock->updateAllValueProfilePredictions();
if (!codeBlock->checkIfJITThresholdReached()) {
+ CODEBLOCK_LOG_EVENT(codeBlock, "delayJITCompile", ("threshold not reached, counter = ", codeBlock->llintExecuteCounter()));
if (Options::verboseOSR())
dataLogF(" JIT threshold should be lifted.\n");
return false;
@@ -335,6 +336,7 @@
CompilationResult result = JIT::compile(&vm, codeBlock, JITCompilationCanFail);
switch (result) {
case CompilationFailed:
+ CODEBLOCK_LOG_EVENT(codeBlock, "delayJITCompile", ("compilation failed"));
if (Options::verboseOSR())
dataLogF(" JIT compilation failed.\n");
codeBlock->dontJITAnytimeSoon();
@@ -372,6 +374,8 @@
if (!jitCompileAndSetHeuristics(codeBlock, exec))
LLINT_RETURN_TWO(0, 0);
+ CODEBLOCK_LOG_EVENT(codeBlock, "OSR entry", ("in prologue"));
+
if (kind == Prologue)
LLINT_RETURN_TWO(codeBlock->jitCode()->executableAddress(), 0);
ASSERT(kind == ArityCheck);
@@ -429,6 +433,8 @@
if (!jitCompileAndSetHeuristics(codeBlock, exec))
LLINT_RETURN_TWO(0, 0);
+ CODEBLOCK_LOG_EVENT(codeBlock, "osrEntry", ("at bc#", pc - codeBlock->instructions().begin()));
+
ASSERT(codeBlock->jitType() == JITCode::BaselineJIT);
Vector<BytecodeAndMachineOffset> map;
Modified: trunk/Source/_javascript_Core/profiler/ProfilerCompilation.cpp (200657 => 200658)
--- trunk/Source/_javascript_Core/profiler/ProfilerCompilation.cpp 2016-05-11 00:02:02 UTC (rev 200657)
+++ trunk/Source/_javascript_Core/profiler/ProfilerCompilation.cpp 2016-05-11 00:08:50 UTC (rev 200658)
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2012, 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2012-2014, 2016 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -42,6 +42,7 @@
, m_numInlinedGetByIds(0)
, m_numInlinedPutByIds(0)
, m_numInlinedCalls(0)
+ , m_uid(UID::create())
{
}
@@ -106,6 +107,11 @@
m_additionalJettisonReason = CString();
}
+void Compilation::dump(PrintStream& out) const
+{
+ out.print("Comp", m_uid);
+}
+
JSValue Compilation::toJS(ExecState* exec) const
{
JSObject* result = constructEmptyObject(exec);
@@ -149,6 +155,8 @@
if (!m_additionalJettisonReason.isNull())
result->putDirect(exec->vm(), exec->propertyNames().additionalJettisonReason, jsString(exec, String::fromUTF8(m_additionalJettisonReason)));
+ result->putDirect(exec->vm(), exec->propertyNames().uid, m_uid.toJS(exec));
+
return result;
}
Modified: trunk/Source/_javascript_Core/profiler/ProfilerCompilation.h (200657 => 200658)
--- trunk/Source/_javascript_Core/profiler/ProfilerCompilation.h 2016-05-11 00:02:02 UTC (rev 200657)
+++ trunk/Source/_javascript_Core/profiler/ProfilerCompilation.h 2016-05-11 00:08:50 UTC (rev 200658)
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2012, 2013, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2012-2014, 2016 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -36,6 +36,7 @@
#include "ProfilerOSRExitSite.h"
#include "ProfilerOriginStack.h"
#include "ProfilerProfiledBytecodes.h"
+#include "ProfilerUID.h"
#include <wtf/RefCounted.h>
#include <wtf/SegmentedVector.h>
@@ -75,6 +76,9 @@
void setJettisonReason(JettisonReason, const FireDetail*);
+ UID uid() const { return m_uid; }
+
+ void dump(PrintStream&) const;
JSValue toJS(ExecState*) const;
private:
@@ -90,6 +94,7 @@
unsigned m_numInlinedGetByIds;
unsigned m_numInlinedPutByIds;
unsigned m_numInlinedCalls;
+ UID m_uid;
};
} } // namespace JSC::Profiler
Modified: trunk/Source/_javascript_Core/profiler/ProfilerDatabase.cpp (200657 => 200658)
--- trunk/Source/_javascript_Core/profiler/ProfilerDatabase.cpp 2016-05-11 00:02:02 UTC (rev 200657)
+++ trunk/Source/_javascript_Core/profiler/ProfilerDatabase.cpp 2016-05-11 00:08:50 UTC (rev 200658)
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2012, 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2012-2013, 2016 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -30,6 +30,7 @@
#include "JSONObject.h"
#include "ObjectConstructor.h"
#include "JSCInlines.h"
+#include <wtf/CurrentTime.h>
namespace JSC { namespace Profiler {
@@ -58,7 +59,11 @@
Bytecodes* Database::ensureBytecodesFor(CodeBlock* codeBlock)
{
LockHolder locker(m_lock);
-
+ return ensureBytecodesFor(locker, codeBlock);
+}
+
+Bytecodes* Database::ensureBytecodesFor(const LockHolder&, CodeBlock* codeBlock)
+{
codeBlock = codeBlock->baselineVersion();
HashMap<CodeBlock*, Bytecodes*>::iterator iter = m_bytecodesMap.find(codeBlock);
@@ -78,13 +83,18 @@
LockHolder locker(m_lock);
m_bytecodesMap.remove(codeBlock);
+ m_compilationMap.remove(codeBlock);
}
-void Database::addCompilation(PassRefPtr<Compilation> compilation)
+void Database::addCompilation(CodeBlock* codeBlock, PassRefPtr<Compilation> passedCompilation)
{
+ LockHolder locker(m_lock);
ASSERT(!isCompilationThread());
+
+ RefPtr<Compilation> compilation = passedCompilation;
m_compilations.append(compilation);
+ m_compilationMap.set(codeBlock, compilation);
}
JSValue Database::toJS(ExecState* exec) const
@@ -101,6 +111,11 @@
compilations->putDirectIndex(exec, i, m_compilations[i]->toJS(exec));
result->putDirect(exec->vm(), exec->propertyNames().compilations, compilations);
+ JSArray* events = constructEmptyArray(exec, 0);
+ for (unsigned i = 0; i < m_events.size(); ++i)
+ events->putDirectIndex(exec, i, m_events[i].toJS(exec));
+ result->putDirect(exec->vm(), exec->propertyNames().events, events);
+
return result;
}
@@ -133,6 +148,15 @@
m_shouldSaveAtExit = true;
}
+void Database::logEvent(CodeBlock* codeBlock, const char* summary, const CString& detail)
+{
+ LockHolder locker(m_lock);
+
+ Bytecodes* bytecodes = ensureBytecodesFor(locker, codeBlock);
+ Compilation* compilation = m_compilationMap.get(codeBlock);
+ m_events.append(Event(currentTime(), bytecodes, compilation, summary, detail));
+}
+
void Database::addDatabaseToAtExit()
{
if (++didRegisterAtExit == 1)
Modified: trunk/Source/_javascript_Core/profiler/ProfilerDatabase.h (200657 => 200658)
--- trunk/Source/_javascript_Core/profiler/ProfilerDatabase.h 2016-05-11 00:02:02 UTC (rev 200657)
+++ trunk/Source/_javascript_Core/profiler/ProfilerDatabase.h 2016-05-11 00:08:50 UTC (rev 200658)
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2012, 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2012-2013, 2016 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -30,6 +30,7 @@
#include "ProfilerBytecodes.h"
#include "ProfilerCompilation.h"
#include "ProfilerCompilationKind.h"
+#include "ProfilerEvent.h"
#include <wtf/FastMalloc.h>
#include <wtf/HashMap.h>
#include <wtf/Lock.h>
@@ -52,7 +53,7 @@
Bytecodes* ensureBytecodesFor(CodeBlock*);
void notifyDestruction(CodeBlock*);
- void addCompilation(PassRefPtr<Compilation>);
+ void addCompilation(CodeBlock*, PassRefPtr<Compilation>);
// Converts the database to a _javascript_ object that is suitable for JSON stringification.
// Note that it's probably a good idea to use an ExecState* associated with a global
@@ -70,7 +71,11 @@
void registerToSaveAtExit(const char* filename);
+ JS_EXPORT_PRIVATE void logEvent(CodeBlock* codeBlock, const char* summary, const CString& detail);
+
private:
+ Bytecodes* ensureBytecodesFor(const LockHolder&, CodeBlock*);
+
void addDatabaseToAtExit();
void removeDatabaseFromAtExit();
void performAtExitSave() const;
@@ -82,6 +87,8 @@
SegmentedVector<Bytecodes> m_bytecodes;
HashMap<CodeBlock*, Bytecodes*> m_bytecodesMap;
Vector<RefPtr<Compilation>> m_compilations;
+ HashMap<CodeBlock*, RefPtr<Compilation>> m_compilationMap;
+ Vector<Event> m_events;
bool m_shouldSaveAtExit;
CString m_atExitSaveFilename;
Database* m_nextRegisteredDatabase;
Added: trunk/Source/_javascript_Core/profiler/ProfilerEvent.cpp (0 => 200658)
--- trunk/Source/_javascript_Core/profiler/ProfilerEvent.cpp (rev 0)
+++ trunk/Source/_javascript_Core/profiler/ProfilerEvent.cpp 2016-05-11 00:08:50 UTC (rev 200658)
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2016 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.
+ */
+
+#include "config.h"
+#include "ProfilerEvent.h"
+
+#include "JSCInlines.h"
+#include "ObjectConstructor.h"
+#include "ProfilerBytecodes.h"
+#include "ProfilerCompilation.h"
+#include "ProfilerUID.h"
+
+namespace JSC { namespace Profiler {
+
+void Event::dump(PrintStream& out) const
+{
+ out.print(m_time, ": ", pointerDump(m_bytecodes));
+ if (m_compilation)
+ out.print(" ", *m_compilation);
+ out.print(": ", m_summary);
+ if (m_detail.length())
+ out.print(" (", m_detail, ")");
+}
+
+JSValue Event::toJS(ExecState* exec) const
+{
+ JSObject* result = constructEmptyObject(exec);
+
+ result->putDirect(exec->vm(), exec->propertyNames().time, jsNumber(m_time));
+ result->putDirect(exec->vm(), exec->propertyNames().bytecodesID, jsNumber(m_bytecodes->id()));
+ if (m_compilation)
+ result->putDirect(exec->vm(), exec->propertyNames().compilationUID, m_compilation->uid().toJS(exec));
+ result->putDirect(exec->vm(), exec->propertyNames().summary, jsString(exec, String::fromUTF8(m_summary)));
+ if (m_detail.length())
+ result->putDirect(exec->vm(), exec->propertyNames().detail, jsString(exec, String::fromUTF8(m_detail)));
+
+ return result;
+}
+
+} } // namespace JSC::Profiler
+
Added: trunk/Source/_javascript_Core/profiler/ProfilerEvent.h (0 => 200658)
--- trunk/Source/_javascript_Core/profiler/ProfilerEvent.h (rev 0)
+++ trunk/Source/_javascript_Core/profiler/ProfilerEvent.h 2016-05-11 00:08:50 UTC (rev 200658)
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2016 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 ProfilerEvent_h
+#define ProfilerEvent_h
+
+#include "JSCJSValue.h"
+#include <wtf/PrintStream.h>
+#include <wtf/text/CString.h>
+
+namespace JSC { namespace Profiler {
+
+class Bytecodes;
+class Compilation;
+
+class Event {
+public:
+ Event()
+ {
+ }
+
+ Event(double time, Bytecodes* bytecodes, Compilation* compilation, const char* summary, const CString& detail)
+ : m_time(time)
+ , m_bytecodes(bytecodes)
+ , m_compilation(compilation)
+ , m_summary(summary)
+ , m_detail(detail)
+ {
+ }
+
+ explicit operator bool() const
+ {
+ return m_bytecodes;
+ }
+
+ double time() const { return m_time; }
+ Bytecodes* bytecodes() const { return m_bytecodes; }
+ Compilation* compilation() const { return m_compilation; }
+ const char* summary() const { return m_summary; }
+ const CString& detail() const { return m_detail; }
+
+ void dump(PrintStream&) const;
+ JSValue toJS(ExecState*) const;
+
+private:
+ double m_time { 0 };
+ Bytecodes* m_bytecodes { nullptr };
+ Compilation* m_compilation { nullptr };
+ const char* m_summary { nullptr };
+ CString m_detail;
+};
+
+} } // namespace JSC::Profiler
+
+#endif // ProfilerEvent_h
+
Added: trunk/Source/_javascript_Core/profiler/ProfilerUID.cpp (0 => 200658)
--- trunk/Source/_javascript_Core/profiler/ProfilerUID.cpp (rev 0)
+++ trunk/Source/_javascript_Core/profiler/ProfilerUID.cpp 2016-05-11 00:08:50 UTC (rev 200658)
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2016 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.
+ */
+
+#include "config.h"
+#include "ProfilerUID.h"
+
+#include "JSCInlines.h"
+#include <wtf/Lock.h>
+
+namespace JSC { namespace Profiler {
+
+UID UID::create()
+{
+ static StaticLock lock;
+ static uint64_t counter;
+
+ LockHolder locker(lock);
+ UID result;
+ result.m_uid = ++counter;
+ return result;
+}
+
+void UID::dump(PrintStream& out) const
+{
+ out.print(m_uid);
+}
+
+JSValue UID::toJS(ExecState* exec) const
+{
+ return jsString(exec, toString(*this));
+}
+
+} } // namespace JSC::Profiler
+
Added: trunk/Source/_javascript_Core/profiler/ProfilerUID.h (0 => 200658)
--- trunk/Source/_javascript_Core/profiler/ProfilerUID.h (rev 0)
+++ trunk/Source/_javascript_Core/profiler/ProfilerUID.h 2016-05-11 00:08:50 UTC (rev 200658)
@@ -0,0 +1,114 @@
+/*
+ * Copyright (C) 2016 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 ProfilerUID_h
+#define ProfilerUID_h
+
+#include "JSCJSValue.h"
+#include <wtf/HashMap.h>
+#include <wtf/PrintStream.h>
+
+namespace JSC { namespace Profiler {
+
+class UID {
+public:
+ UID()
+ : m_uid(0)
+ {
+ }
+
+ static UID fromInt(uint64_t value)
+ {
+ UID result;
+ result.m_uid = value;
+ return result;
+ }
+
+ UID(WTF::HashTableDeletedValueType)
+ : m_uid(std::numeric_limits<uint64_t>::max())
+ {
+ }
+
+ static UID create();
+
+ uint64_t toInt() const
+ {
+ return m_uid;
+ }
+
+ bool operator==(const UID& other) const
+ {
+ return m_uid == other.m_uid;
+ }
+
+ bool operator!=(const UID& other) const
+ {
+ return !(*this == other);
+ }
+
+ explicit operator bool() const
+ {
+ return *this != UID();
+ }
+
+ bool isHashTableDeletedValue() const
+ {
+ return *this != UID(WTF::HashTableDeletedValue);
+ }
+
+ unsigned hash() const
+ {
+ return IntHash<uint64_t>::hash(m_uid);
+ }
+
+ void dump(PrintStream&) const;
+ JSValue toJS(ExecState*) const;
+
+private:
+ uint64_t m_uid;
+};
+
+struct UIDHash {
+ static unsigned hash(const UID& key) { return key.hash(); }
+ static bool equal(const UID& a, const UID& b) { return a == b; }
+ static const bool safeToCompareToEmptyOrDeleted = true;
+};
+
+} } // namespace JSC::Profiler
+
+namespace WTF {
+
+template<typename T> struct DefaultHash;
+template<> struct DefaultHash<JSC::Profiler::UID> {
+ typedef JSC::Profiler::UIDHash Hash;
+};
+
+template<typename T> struct HashTraits;
+template<> struct HashTraits<JSC::Profiler::UID> : SimpleClassHashTraits<JSC::Profiler::UID> { };
+
+} // namespace WTF
+
+#endif // ProfilerUID_h
+
Modified: trunk/Source/_javascript_Core/runtime/CommonIdentifiers.h (200657 => 200658)
--- trunk/Source/_javascript_Core/runtime/CommonIdentifiers.h 2016-05-11 00:02:02 UTC (rev 200657)
+++ trunk/Source/_javascript_Core/runtime/CommonIdentifiers.h 2016-05-11 00:08:50 UTC (rev 200658)
@@ -126,6 +126,7 @@
macro(collation) \
macro(column) \
macro(compilationKind) \
+ macro(compilationUID) \
macro(compilations) \
macro(compile) \
macro(configurable) \
@@ -136,12 +137,14 @@
macro(defineProperty) \
macro(description) \
macro(descriptions) \
+ macro(detail) \
macro(displayName) \
macro(document) \
macro(done) \
macro(enumerable) \
macro(era) \
macro(eval) \
+ macro(events) \
macro(exec) \
macro(executionCount) \
macro(exitKind) \
@@ -227,9 +230,11 @@
macro(stack) \
macro(sticky) \
macro(subarray) \
+ macro(summary) \
macro(target) \
macro(test) \
macro(then) \
+ macro(time) \
macro(timeZone) \
macro(timeZoneName) \
macro(toExponential) \
@@ -240,6 +245,7 @@
macro(toPrecision) \
macro(toString) \
macro(top) \
+ macro(uid) \
macro(unicode) \
macro(usage) \
macro(value) \
Modified: trunk/Source/_javascript_Core/runtime/Executable.cpp (200657 => 200658)
--- trunk/Source/_javascript_Core/runtime/Executable.cpp 2016-05-11 00:02:02 UTC (rev 200657)
+++ trunk/Source/_javascript_Core/runtime/Executable.cpp 2016-05-11 00:08:50 UTC (rev 200658)
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009, 2010, 2013, 2015 Apple Inc. All rights reserved.
+ * Copyright (C) 2009, 2010, 2013, 2015-2016 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -36,6 +36,7 @@
#include "Parser.h"
#include "ProfilerDatabase.h"
#include "TypeProfiler.h"
+#include "VMInlines.h"
#include "WASMFunctionParser.h"
#include <wtf/CommaPrinter.h>
#include <wtf/Vector.h>
@@ -176,6 +177,8 @@
{
ASSERT(vm.heap.isDeferred());
+ CODEBLOCK_LOG_EVENT(genericCodeBlock, "installCode", ());
+
CodeBlock* oldCodeBlock = nullptr;
switch (codeType) {
Modified: trunk/Source/_javascript_Core/runtime/VM.h (200657 => 200658)
--- trunk/Source/_javascript_Core/runtime/VM.h 2016-05-11 00:02:02 UTC (rev 200657)
+++ trunk/Source/_javascript_Core/runtime/VM.h 2016-05-11 00:08:50 UTC (rev 200658)
@@ -612,6 +612,9 @@
BytecodeIntrinsicRegistry& bytecodeIntrinsicRegistry() { return *m_bytecodeIntrinsicRegistry; }
ShadowChicken& shadowChicken() { return *m_shadowChicken; }
+
+ template<typename Func>
+ void logEvent(CodeBlock*, const char* summary, const Func& func);
private:
friend class LLIntOffsetsExtractor;
Modified: trunk/Source/_javascript_Core/runtime/VMInlines.h (200657 => 200658)
--- trunk/Source/_javascript_Core/runtime/VMInlines.h 2016-05-11 00:02:02 UTC (rev 200657)
+++ trunk/Source/_javascript_Core/runtime/VMInlines.h 2016-05-11 00:08:50 UTC (rev 200658)
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2015 Apple Inc. All rights reserved.
+ * Copyright (C) 2015-2016 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -26,6 +26,7 @@
#ifndef VMInlines_h
#define VMInlines_h
+#include "ProfilerDatabase.h"
#include "VM.h"
#include "Watchdog.h"
@@ -38,6 +39,15 @@
return watchdog()->shouldTerminate(exec);
}
+template<typename Func>
+void VM::logEvent(CodeBlock* codeBlock, const char* summary, const Func& func)
+{
+ if (LIKELY(!m_perBytecodeProfiler))
+ return;
+
+ m_perBytecodeProfiler->logEvent(codeBlock, summary, func());
+}
+
} // namespace JSC
#endif // LLIntData_h
Modified: trunk/Source/WTF/ChangeLog (200657 => 200658)
--- trunk/Source/WTF/ChangeLog 2016-05-11 00:02:02 UTC (rev 200657)
+++ trunk/Source/WTF/ChangeLog 2016-05-11 00:08:50 UTC (rev 200658)
@@ -1,3 +1,13 @@
+2016-05-10 Filip Pizlo <[email protected]>
+
+ 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.
+
+ * wtf/PrintStream.h:
+ (WTF::PrintStream::print):
+
2016-05-10 Chris Dumez <[email protected]>
Get rid of a lot of calls to RefPtr::release()
Modified: trunk/Source/WTF/wtf/PrintStream.h (200657 => 200658)
--- trunk/Source/WTF/wtf/PrintStream.h 2016-05-11 00:02:02 UTC (rev 200657)
+++ trunk/Source/WTF/wtf/PrintStream.h 2016-05-11 00:08:50 UTC (rev 200658)
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2012, 2014, 2015 Apple Inc. All rights reserved.
+ * Copyright (C) 2012, 2014-2016 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -55,6 +55,8 @@
// Typically a no-op for many subclasses of PrintStream, this is a hint that
// the implementation should flush its buffers if it had not done so already.
virtual void flush();
+
+ void print() { }
template<typename T>
void print(const T& value)
Modified: trunk/Tools/ChangeLog (200657 => 200658)
--- trunk/Tools/ChangeLog 2016-05-11 00:02:02 UTC (rev 200657)
+++ trunk/Tools/ChangeLog 2016-05-11 00:08:50 UTC (rev 200658)
@@ -1,3 +1,12 @@
+2016-05-10 Filip Pizlo <[email protected]>
+
+ 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.
+
+ * Scripts/display-profiler-output:
+
2016-05-10 Michael Catanzaro <[email protected]>
[Linux] Remove seccomp filters support
Modified: trunk/Tools/Scripts/display-profiler-output (200657 => 200658)
--- trunk/Tools/Scripts/display-profiler-output 2016-05-11 00:02:02 UTC (rev 200657)
+++ trunk/Tools/Scripts/display-profiler-output 2016-05-11 00:08:50 UTC (rev 200658)
@@ -1,6 +1,6 @@
#!/usr/bin/env ruby
-# Copyright (C) 2012, 2013, 2014 Apple Inc. All rights reserved.
+# Copyright (C) 2012-2014, 2016 Apple Inc. All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
@@ -331,7 +331,7 @@
class Compilation
attr_accessor :bytecode, :engine, :descriptions, :counters, :compilationIndex
attr_accessor :osrExits, :profiledBytecodes, :numInlinedGetByIds, :numInlinedPutByIds
- attr_accessor :numInlinedCalls, :jettisonReason, :additionalJettisonReason
+ attr_accessor :numInlinedCalls, :jettisonReason, :additionalJettisonReason, :uid
def initialize(json)
@bytecode = $bytecodes[json["bytecodesID"].to_i]
@@ -386,6 +386,7 @@
@numInlinedCalls = json["numInlinedCalls"]
@jettisonReason = json["jettisonReason"]
@additionalJettisonReason = json["additionalJettisonReason"]
+ @uid = json["uid"]
end
def codeHashSortKey
@@ -438,6 +439,20 @@
end
end
+class Event
+ attr_reader :time, :bytecode, :compilation, :summary, :detail
+
+ def initialize(json)
+ @time = json["time"].to_f
+ @bytecode = $bytecodes[json["bytecodesID"].to_i]
+ if json["compilationUID"]
+ @compilation = $compilationMap[json["compilationUID"]]
+ end
+ @summary = json["summary"]
+ @detail = json["detail"]
+ end
+end
+
def originToPrintStack(origin)
(0...(origin.size - 1)).map {
| index |
@@ -468,6 +483,15 @@
| subJson |
Compilation.new(subJson)
}
+$compilationMap = {}
+$compilations.each {
+ | compilation |
+ $compilationMap[compilation.uid] = compilation
+}
+$events = $json["events"].map {
+ | subJson |
+ Event.new(subJson)
+}
$engines = ["Baseline", "DFG", "FTL", "FTLForOSREntry"]
def isOptimizing(engine)
@@ -477,15 +501,17 @@
$showCounts = true
$sortMode = :time
-def lpad(str,chars)
- if str.length>chars
- str
- else
- "%#{chars}s"%(str)
- end
+def lpad(str, chars)
+ str = str.to_s
+ if str.length > chars
+ str
+ else
+ "%#{chars}s"%(str)
+ end
end
def rpad(str, chars)
+ str = str.to_s
while str.length < chars
str += " "
end
@@ -493,6 +519,7 @@
end
def center(str, chars)
+ str = str.to_s
while str.length < chars
str += " "
if str.length < chars
@@ -736,6 +763,7 @@
puts "bytecode (b) Show the bytecode for a code block, with counts."
puts "profiling (p) Show the (internal) profiling data for a code block."
puts "log (l) List the compilations, exits, and jettisons involving this code block."
+ puts "events (e) List of events involving this code block."
puts "display (d) Display details for a code block."
puts "inlines Show all inlining stacks that the code block was on."
puts "counts Set whether to show counts for 'bytecode' and 'display'."
@@ -875,6 +903,52 @@
end
end
}
+ when "events", "e"
+ if args.length != 1
+ puts "Usage: inlines <code block hash>"
+ return
+ end
+
+ hash = Regexp.new(Regexp.escape(args[0]))
+
+ events = []
+ $events.each {
+ | event |
+ if event.bytecode.to_s =~ hash
+ events << event
+ end
+ }
+
+ timeCols = 0
+ hashCols = 0
+ compilationCols = 0
+ summaryCols = 0
+ events.each {
+ | event |
+ timeCols = [event.time.to_s.size, timeCols].max
+ hashCols = [event.bytecode.to_s.size, hashCols].max
+ if event.compilation
+ compilationCols = [event.compilation.to_s.size, compilationCols].max
+ end
+ summaryCols = [event.summary.size, summaryCols].max
+ }
+
+ events.each {
+ | event |
+ print rpad(event.time.to_s, timeCols)
+ print " "
+ print rpad(event.bytecode.to_s, hashCols)
+ print " "
+ compilationStr = ""
+ if event.compilation
+ compilationStr = event.compilation.to_s
+ end
+ print rpad(compilationStr, compilationCols)
+ print " "
+ print rpad(event.summary, summaryCols)
+ print " "
+ puts event.detail
+ }
when "inlines"
if args.length != 1
puts "Usage: inlines <code block hash>"