Diff
Modified: branches/jsCStack/Source/_javascript_Core/ChangeLog (161704 => 161705)
--- branches/jsCStack/Source/_javascript_Core/ChangeLog 2014-01-11 01:26:40 UTC (rev 161704)
+++ branches/jsCStack/Source/_javascript_Core/ChangeLog 2014-01-11 01:29:24 UTC (rev 161705)
@@ -1,5 +1,30 @@
2014-01-10 Filip Pizlo <[email protected]>
+ It should be easier to diagnose FTL performance issues due to register preservation thunks
+ https://bugs.webkit.org/show_bug.cgi?id=126798
+
+ Not yet reviewed.
+
+ You can now use --verboseFTLToJSThunk=true --verboseFTLFailure=true to figure out
+ which code blocks are rejected by the FTL and yet get called from functions that
+ were FTL compiled. Any such rejections in major benchmarks should be fixed.
+
+ * bytecode/CodeBlock.cpp:
+ (JSC::CodeBlock::CodeBlock):
+ * ftl/FTLCapabilities.cpp:
+ (JSC::FTL::verboseCapabilities):
+ (JSC::FTL::canCompile):
+ * jit/RegisterPreservationWrapperGenerator.cpp:
+ (JSC::generateRegisterPreservationWrapper):
+ * runtime/Executable.cpp:
+ (JSC::ExecutableBase::dump):
+ * runtime/Executable.h:
+ * runtime/Options.cpp:
+ (JSC::Options::initialize):
+ * runtime/Options.h:
+
+2014-01-10 Filip Pizlo <[email protected]>
+
Unreviewed, add a test for the case where LLVM finds a constant folding
opportunity that the DFG missed, and it involves a large constant, and then we
exit with the large constant folded into a stackmap for an OSR exit.
Modified: branches/jsCStack/Source/_javascript_Core/bytecode/CodeBlock.cpp (161704 => 161705)
--- branches/jsCStack/Source/_javascript_Core/bytecode/CodeBlock.cpp 2014-01-11 01:26:40 UTC (rev 161704)
+++ branches/jsCStack/Source/_javascript_Core/bytecode/CodeBlock.cpp 2014-01-11 01:29:24 UTC (rev 161705)
@@ -1843,18 +1843,7 @@
// If the concurrent thread will want the code block's hash, then compute it here
// synchronously.
- if (Options::showDisassembly()
- || Options::showDFGDisassembly()
- || Options::dumpBytecodeAtDFGTime()
- || Options::dumpGraphAtEachPhase()
- || Options::verboseCompilation()
- || Options::logCompilationChanges()
- || Options::validateGraph()
- || Options::validateGraphAtEachPhase()
- || Options::verboseOSR()
- || Options::verboseCompilationQueue()
- || Options::reportCompileTimes()
- || Options::verboseCFA())
+ if (Options::alwaysComputeHash())
hash();
if (Options::dumpGeneratedBytecodes())
Modified: branches/jsCStack/Source/_javascript_Core/ftl/FTLCapabilities.cpp (161704 => 161705)
--- branches/jsCStack/Source/_javascript_Core/ftl/FTLCapabilities.cpp 2014-01-11 01:26:40 UTC (rev 161704)
+++ branches/jsCStack/Source/_javascript_Core/ftl/FTLCapabilities.cpp 2014-01-11 01:29:24 UTC (rev 161705)
@@ -32,6 +32,11 @@
using namespace DFG;
+static bool verboseCapabilities()
+{
+ return verboseCompilationEnabled() || Options::verboseFTLFailure();
+}
+
inline CapabilityLevel canCompile(Node* node)
{
// NOTE: If we ever have phantom arguments, we can compile them but we cannot
@@ -234,8 +239,8 @@
CapabilityLevel canCompile(Graph& graph)
{
if (graph.m_codeBlock->codeType() != FunctionCode) {
- if (verboseCompilationEnabled())
- dataLog("FTL rejecting code block that doesn't belong to a function.\n");
+ if (verboseCapabilities())
+ dataLog("FTL rejecting ", *graph.m_codeBlock, " because it doesn't belong to a function.\n");
return CannotCompile;
}
@@ -243,8 +248,8 @@
// Need this because although we also don't support
// CreateActivation/TearOffActivation, we might not see those nodes in case of
// OSR entry.
- if (verboseCompilationEnabled())
- dataLog("FTL rejecting code block that uses activations.\n");
+ if (verboseCapabilities())
+ dataLog("FTL rejecting ", *graph.m_codeBlock, " because it uses activations.\n");
return CannotCompile;
}
@@ -285,8 +290,8 @@
break;
default:
// Don't know how to handle anything else.
- if (verboseCompilationEnabled()) {
- dataLog("FTL rejecting node because of bad use kind: ", edge.useKind(), " in node:\n");
+ if (verboseCapabilities()) {
+ dataLog("FTL rejecting node in ", *graph.m_codeBlock, " because of bad use kind: ", edge.useKind(), " in node:\n");
graph.dump(WTF::dataFile(), " ", node);
}
return CannotCompile;
@@ -295,8 +300,8 @@
switch (canCompile(node)) {
case CannotCompile:
- if (verboseCompilationEnabled()) {
- dataLog("FTL rejecting node:\n");
+ if (verboseCapabilities()) {
+ dataLog("FTL rejecting node in ", *graph.m_codeBlock, ":\n");
graph.dump(WTF::dataFile(), " ", node);
}
return CannotCompile;
Modified: branches/jsCStack/Source/_javascript_Core/jit/RegisterPreservationWrapperGenerator.cpp (161704 => 161705)
--- branches/jsCStack/Source/_javascript_Core/jit/RegisterPreservationWrapperGenerator.cpp 2014-01-11 01:26:40 UTC (rev 161704)
+++ branches/jsCStack/Source/_javascript_Core/jit/RegisterPreservationWrapperGenerator.cpp 2014-01-11 01:29:24 UTC (rev 161705)
@@ -116,6 +116,9 @@
LinkBuffer linkBuffer(vm, &jit, GLOBAL_THUNK_ID);
linkBuffer.link(call, CodeLocationLabel(target));
+
+ if (Options::verboseFTLToJSThunk())
+ dataLog("Need a thunk for calls from FTL to non-FTL version of ", *executable, "\n");
return FINALIZE_DFG_CODE(linkBuffer, ("Register preservation wrapper for %s/%s, %p", toCString(executable->hashFor(CodeForCall)).data(), toCString(executable->hashFor(CodeForConstruct)).data(), target.executableAddress()));
#else // ENABLE(FTL_JIT)
Modified: branches/jsCStack/Source/_javascript_Core/runtime/Executable.cpp (161704 => 161705)
--- branches/jsCStack/Source/_javascript_Core/runtime/Executable.cpp 2014-01-11 01:26:40 UTC (rev 161704)
+++ branches/jsCStack/Source/_javascript_Core/runtime/Executable.cpp 2014-01-11 01:29:24 UTC (rev 161705)
@@ -606,6 +606,46 @@
return m_unlinkedExecutable->paramString();
}
+void ExecutableBase::dump(PrintStream& out) const
+{
+ ExecutableBase* realThis = const_cast<ExecutableBase*>(this);
+
+ if (classInfo() == NativeExecutable::info()) {
+ NativeExecutable* native = jsCast<NativeExecutable*>(realThis);
+ out.print("NativeExecutable:", RawPointer(bitwise_cast<void*>(native->function())), "/", RawPointer(bitwise_cast<void*>(native->constructor())));
+ return;
+ }
+
+ if (classInfo() == EvalExecutable::info()) {
+ EvalExecutable* eval = jsCast<EvalExecutable*>(realThis);
+ if (CodeBlock* codeBlock = eval->codeBlock())
+ out.print(*codeBlock);
+ else
+ out.print("EvalExecutable w/o CodeBlock");
+ return;
+ }
+
+ if (classInfo() == ProgramExecutable::info()) {
+ ProgramExecutable* eval = jsCast<ProgramExecutable*>(realThis);
+ if (CodeBlock* codeBlock = eval->codeBlock())
+ out.print(*codeBlock);
+ else
+ out.print("ProgramExecutable w/o CodeBlock");
+ return;
+ }
+
+ FunctionExecutable* function = jsCast<FunctionExecutable*>(realThis);
+ if (!function->eitherCodeBlock())
+ out.print("FunctionExecutable w/o CodeBlock");
+ else {
+ CommaPrinter comma("/");
+ if (function->codeBlockForCall())
+ out.print(comma, *function->codeBlockForCall());
+ if (function->codeBlockForConstruct())
+ out.print(comma, *function->codeBlockForConstruct());
+ }
+}
+
CodeBlockHash ExecutableBase::hashFor(CodeSpecializationKind kind) const
{
if (this->classInfo() == NativeExecutable::info())
Modified: branches/jsCStack/Source/_javascript_Core/runtime/Executable.h (161704 => 161705)
--- branches/jsCStack/Source/_javascript_Core/runtime/Executable.h 2014-01-11 01:26:40 UTC (rev 161704)
+++ branches/jsCStack/Source/_javascript_Core/runtime/Executable.h 2014-01-11 01:29:24 UTC (rev 161705)
@@ -269,6 +269,8 @@
return intrinsic();
return NoIntrinsic;
}
+
+ void dump(PrintStream&) const;
protected:
ExecutableBase* m_prev;
Modified: branches/jsCStack/Source/_javascript_Core/runtime/Options.cpp (161704 => 161705)
--- branches/jsCStack/Source/_javascript_Core/runtime/Options.cpp 2014-01-11 01:26:40 UTC (rev 161704)
+++ branches/jsCStack/Source/_javascript_Core/runtime/Options.cpp 2014-01-11 01:29:24 UTC (rev 161705)
@@ -211,7 +211,22 @@
#if !ENABLE(YARR_JIT)
useRegExpJIT() = false;
#endif
-
+
+ if (showDisassembly()
+ || showDFGDisassembly()
+ || dumpBytecodeAtDFGTime()
+ || dumpGraphAtEachPhase()
+ || verboseCompilation()
+ || logCompilationChanges()
+ || validateGraph()
+ || validateGraphAtEachPhase()
+ || verboseOSR()
+ || verboseCompilationQueue()
+ || reportCompileTimes()
+ || verboseCFA()
+ || verboseFTLFailure())
+ alwaysComputeHash() = true;
+
// Do range checks where needed and make corrections to the options:
ASSERT(thresholdForOptimizeAfterLongWarmUp() >= thresholdForOptimizeAfterWarmUp());
ASSERT(thresholdForOptimizeAfterWarmUp() >= thresholdForOptimizeSoon());
Modified: branches/jsCStack/Source/_javascript_Core/runtime/Options.h (161704 => 161705)
--- branches/jsCStack/Source/_javascript_Core/runtime/Options.h 2014-01-11 01:26:40 UTC (rev 161704)
+++ branches/jsCStack/Source/_javascript_Core/runtime/Options.h 2014-01-11 01:29:24 UTC (rev 161705)
@@ -124,6 +124,9 @@
v(bool, verboseCompilationQueue, false) \
v(bool, reportCompileTimes, false) \
v(bool, verboseCFA, false) \
+ v(bool, verboseFTLToJSThunk, false) \
+ v(bool, verboseFTLFailure, false) \
+ v(bool, alwaysComputeHash, false) \
\
v(bool, enableOSREntryToDFG, true) \
\