Commit 63ced6ae authored by fpizlo@apple.com's avatar fpizlo@apple.com

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):


git-svn-id: http://svn.webkit.org/repository/webkit/trunk@94914 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent 0791391f
2011-09-10 Filip Pizlo <fpizlo@apple.com>
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 <cmarrin@apple.com>
requestAnimationFrame doesn't throttle on Mac
......
......@@ -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];
......
......@@ -202,6 +202,8 @@ protected:
, 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 -
......
......@@ -851,10 +851,6 @@ void JITCompiler::compileBody()
// 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();
......
......@@ -39,19 +39,21 @@ GPRReg SpeculativeJIT::fillSpeculateIntInternal(NodeIndex nodeIndex, DataFormat&
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(Node& node)
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 @@ void SpeculativeJIT::compile(BasicBlock& block)
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 @@ void SpeculativeJIT::compile(BasicBlock& block)
#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 @@ bool SpeculativeJIT::compile()
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;
......
......@@ -217,7 +217,19 @@ private:
// 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>
......
......@@ -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
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment