Diff
Modified: trunk/Source/_javascript_Core/ChangeLog (94913 => 94914)
--- trunk/Source/_javascript_Core/ChangeLog 2011-09-10 21:14:21 UTC (rev 94913)
+++ trunk/Source/_javascript_Core/ChangeLog 2011-09-10 21:23:45 UTC (rev 94914)
@@ -1,3 +1,24 @@
+2011-09-10 Filip Pizlo <[email protected]>
+
+ DFG JIT completely undoes speculative compilation even in the case of
+ a partial static speculation failure
+ https://bugs.webkit.org/show_bug.cgi?id=67798
+
+ Reviewed by Geoffrey Garen.
+
+ This is a regression with static speculation, so it is turned off by
+ default. But it is a necessary prerequisite for further work on
+ dynamic speculation.
+
+ * dfg/DFGJITCodeGenerator.cpp:
+ (JSC::DFG::JITCodeGenerator::clearGenerationInfo):
+ * dfg/DFGJITCodeGenerator.h:
+ * dfg/DFGSpeculativeJIT.cpp:
+ (JSC::DFG::SpeculativeJIT::fillSpeculateIntInternal):
+ (JSC::DFG::SpeculativeJIT::compile):
+ * dfg/DFGSpeculativeJIT.h:
+ (JSC::DFG::SpeculativeJIT::terminateSpeculativeExecution):
+
2011-09-09 Chris Marrin <[email protected]>
requestAnimationFrame doesn't throttle on Mac
Modified: trunk/Source/_javascript_Core/dfg/DFGJITCodeGenerator.cpp (94913 => 94914)
--- trunk/Source/_javascript_Core/dfg/DFGJITCodeGenerator.cpp 2011-09-10 21:14:21 UTC (rev 94913)
+++ trunk/Source/_javascript_Core/dfg/DFGJITCodeGenerator.cpp 2011-09-10 21:23:45 UTC (rev 94914)
@@ -34,6 +34,14 @@
namespace JSC { namespace DFG {
+void JITCodeGenerator::clearGenerationInfo()
+{
+ for (unsigned i = 0; i < m_generationInfo.size(); ++i)
+ m_generationInfo[i] = GenerationInfo();
+ m_gprs = RegisterBank<GPRInfo>();
+ m_fprs = RegisterBank<FPRInfo>();
+}
+
GPRReg JITCodeGenerator::fillInteger(NodeIndex nodeIndex, DataFormat& returnFormat)
{
Node& node = m_jit.graph()[nodeIndex];
Modified: trunk/Source/_javascript_Core/dfg/DFGJITCodeGenerator.h (94913 => 94914)
--- trunk/Source/_javascript_Core/dfg/DFGJITCodeGenerator.h 2011-09-10 21:14:21 UTC (rev 94913)
+++ trunk/Source/_javascript_Core/dfg/DFGJITCodeGenerator.h 2011-09-10 21:23:45 UTC (rev 94914)
@@ -202,6 +202,8 @@
, m_blockHeads(jit.graph().m_blocks.size())
{
}
+
+ void clearGenerationInfo();
// These methods are used when generating 'unexpected'
// calls out from JIT code to C++ helper routines -
Modified: trunk/Source/_javascript_Core/dfg/DFGJITCompiler.cpp (94913 => 94914)
--- trunk/Source/_javascript_Core/dfg/DFGJITCompiler.cpp 2011-09-10 21:14:21 UTC (rev 94913)
+++ trunk/Source/_javascript_Core/dfg/DFGJITCompiler.cpp 2011-09-10 21:23:45 UTC (rev 94914)
@@ -851,10 +851,6 @@
// Link the bail-outs from the speculative path to the corresponding entry points into the non-speculative one.
linkSpeculationChecks(speculative, nonSpeculative);
} else {
-#if DFG_DEBUG_VERBOSE
- fprintf(stderr, "SpeculativeJIT was terminated.\n");
-#endif
-
// If compilation through the SpeculativeJIT failed, throw away the code we generated.
m_calls.clear();
m_propertyAccesses.clear();
Modified: trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp (94913 => 94914)
--- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp 2011-09-10 21:14:21 UTC (rev 94913)
+++ trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp 2011-09-10 21:23:45 UTC (rev 94914)
@@ -39,19 +39,21 @@
switch (info.registerFormat()) {
case DataFormatNone: {
+ if (node.isConstant() && !isInt32Constant(nodeIndex)) {
+ terminateSpeculativeExecution();
+ returnFormat = DataFormatInteger;
+ return allocate();
+ }
+
GPRReg gpr = allocate();
if (node.isConstant()) {
m_gprs.retain(gpr, virtualRegister, SpillOrderConstant);
- if (isInt32Constant(nodeIndex)) {
- m_jit.move(MacroAssembler::Imm32(valueOfInt32Constant(nodeIndex)), gpr);
- info.fillInteger(gpr);
- returnFormat = DataFormatInteger;
- return gpr;
- }
- terminateSpeculativeExecution();
+ ASSERT(isInt32Constant(nodeIndex));
+ m_jit.move(MacroAssembler::Imm32(valueOfInt32Constant(nodeIndex)), gpr);
+ info.fillInteger(gpr);
returnFormat = DataFormatInteger;
- return allocate();
+ return gpr;
} else {
DataFormat spillFormat = info.spillFormat();
ASSERT(spillFormat & DataFormatJS);
@@ -1374,6 +1376,7 @@
void SpeculativeJIT::compile(BasicBlock& block)
{
+ ASSERT(m_compileOkay);
ASSERT(m_compileIndex == block.begin);
m_blockHeads[m_block] = m_jit.label();
#if DFG_JIT_BREAK_ON_EVERY_BLOCK
@@ -1384,7 +1387,7 @@
Node& node = m_jit.graph()[m_compileIndex];
if (!node.shouldGenerate())
continue;
-
+
#if DFG_DEBUG_VERBOSE
fprintf(stderr, "SpeculativeJIT generating Node @%d at JIT offset 0x%x ", (int)m_compileIndex, m_jit.debugOffset());
#endif
@@ -1393,8 +1396,14 @@
#endif
checkConsistency();
compile(node);
- if (!m_compileOkay)
+ if (!m_compileOkay) {
+#if ENABLE(DYNAMIC_TERMINATE_SPECULATION)
+ m_compileOkay = true;
+ m_compileIndex = block.end;
+ clearGenerationInfo();
+#endif
return;
+ }
#if DFG_DEBUG_VERBOSE
if (node.hasResult())
fprintf(stderr, "-> %s\n", dataFormatToString(m_generationInfo[node.virtualRegister()].registerFormat()));
@@ -1445,8 +1454,10 @@
ASSERT(!m_compileIndex);
for (m_block = 0; m_block < m_jit.graph().m_blocks.size(); ++m_block) {
compile(*m_jit.graph().m_blocks[m_block]);
+#if !ENABLE(DYNAMIC_OPTIMIZATION)
if (!m_compileOkay)
return false;
+#endif
}
linkBranches();
return true;
Modified: trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.h (94913 => 94914)
--- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.h 2011-09-10 21:14:21 UTC (rev 94913)
+++ trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.h 2011-09-10 21:23:45 UTC (rev 94914)
@@ -217,7 +217,19 @@
// Called when we statically determine that a speculation will fail.
void terminateSpeculativeExecution()
{
+#if DFG_DEBUG_VERBOSE
+ fprintf(stderr, "SpeculativeJIT was terminated.\n");
+#endif
+#if ENABLE(DYNAMIC_TERMINATE_SPECULATION)
+ if (!m_compileOkay)
+ return;
+ speculationCheck(m_jit.jump());
m_compileOkay = false;
+#else
+ // Under static speculation, it's more profitable to give up entirely at this
+ // point.
+ m_compileOkay = false;
+#endif
}
template<bool strict>
Modified: trunk/Source/_javascript_Core/wtf/Platform.h (94913 => 94914)
--- trunk/Source/_javascript_Core/wtf/Platform.h 2011-09-10 21:14:21 UTC (rev 94913)
+++ trunk/Source/_javascript_Core/wtf/Platform.h 2011-09-10 21:23:45 UTC (rev 94914)
@@ -969,6 +969,10 @@
#define ENABLE_DYNAMIC_OPTIMIZATION ENABLE_TIERED_COMPILATION
#endif
+#if !defined(ENABLE_DYNAMIC_TERMINATE_SPECULATION)
+#define ENABLE_DYNAMIC_TERMINATE_SPECULATION ENABLE_DYNAMIC_OPTIMIZATION
+#endif
+
#if !defined(ENABLE_VERBOSE_VALUE_PROFILE) && ENABLE(VALUE_PROFILER)
#define ENABLE_VERBOSE_VALUE_PROFILE 0
#endif