Diff
Modified: trunk/LayoutTests/ChangeLog (153214 => 153215)
--- trunk/LayoutTests/ChangeLog 2013-07-25 04:02:15 UTC (rev 153214)
+++ trunk/LayoutTests/ChangeLog 2013-07-25 04:02:17 UTC (rev 153215)
@@ -1,3 +1,17 @@
+2013-06-07 Filip Pizlo <fpi...@apple.com>
+
+ fourthTier: don't insert ForceOSRExits except for inadequate coverage
+ https://bugs.webkit.org/show_bug.cgi?id=117363
+
+ Reviewed by Mark Hahnenberg.
+
+ Convert this test, since this was the test originally added for
+ ConstantFoldingPhase::paintUnreachableCode(). I wanted to make sure that I had good coverage
+ for this since I am removing that method.
+
+ * fast/js/dfg-force-exit-then-sparse-conditional-constant-prop-in-loop-expected.txt:
+ * fast/js/script-tests/dfg-force-exit-then-sparse-conditional-constant-prop-in-loop.js:
+
2013-06-03 Filip Pizlo <fpi...@apple.com>
Unreviewed, unbreak all of the tests.
Modified: trunk/LayoutTests/fast/js/dfg-force-exit-then-sparse-conditional-constant-prop-in-loop-expected.txt (153214 => 153215)
--- trunk/LayoutTests/fast/js/dfg-force-exit-then-sparse-conditional-constant-prop-in-loop-expected.txt 2013-07-25 04:02:15 UTC (rev 153214)
+++ trunk/LayoutTests/fast/js/dfg-force-exit-then-sparse-conditional-constant-prop-in-loop-expected.txt 2013-07-25 04:02:17 UTC (rev 153215)
@@ -3,207 +3,7 @@
On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
-PASS foo(array) is 8746
-PASS foo(array) is 8746
-PASS foo(array) is 8746
-PASS foo(array) is 8746
-PASS foo(array) is 8746
-PASS foo(array) is 8746
-PASS foo(array) is 8746
-PASS foo(array) is 8746
-PASS foo(array) is 8746
-PASS foo(array) is 8746
-PASS foo(array) is 8746
-PASS foo(array) is 8746
-PASS foo(array) is 8746
-PASS foo(array) is 8746
-PASS foo(array) is 8746
-PASS foo(array) is 8746
-PASS foo(array) is 8746
-PASS foo(array) is 8746
-PASS foo(array) is 8746
-PASS foo(array) is 8746
-PASS foo(array) is 8746
-PASS foo(array) is 8746
-PASS foo(array) is 8746
-PASS foo(array) is 8746
-PASS foo(array) is 8746
-PASS foo(array) is 8746
-PASS foo(array) is 8746
-PASS foo(array) is 8746
-PASS foo(array) is 8746
-PASS foo(array) is 8746
-PASS foo(array) is 8746
-PASS foo(array) is 8746
-PASS foo(array) is 8746
-PASS foo(array) is 8746
-PASS foo(array) is 8746
-PASS foo(array) is 8746
-PASS foo(array) is 8746
-PASS foo(array) is 8746
-PASS foo(array) is 8746
-PASS foo(array) is 8746
-PASS foo(array) is 8746
-PASS foo(array) is 8746
-PASS foo(array) is 8746
-PASS foo(array) is 8746
-PASS foo(array) is 8746
-PASS foo(array) is 8746
-PASS foo(array) is 8746
-PASS foo(array) is 8746
-PASS foo(array) is 8746
-PASS foo(array) is 8746
-PASS foo(array) is 8746
-PASS foo(array) is 8746
-PASS foo(array) is 8746
-PASS foo(array) is 8746
-PASS foo(array) is 8746
-PASS foo(array) is 8746
-PASS foo(array) is 8746
-PASS foo(array) is 8746
-PASS foo(array) is 8746
-PASS foo(array) is 8746
-PASS foo(array) is 8746
-PASS foo(array) is 8746
-PASS foo(array) is 8746
-PASS foo(array) is 8746
-PASS foo(array) is 8746
-PASS foo(array) is 8746
-PASS foo(array) is 8746
-PASS foo(array) is 8746
-PASS foo(array) is 8746
-PASS foo(array) is 8746
-PASS foo(array) is 8746
-PASS foo(array) is 8746
-PASS foo(array) is 8746
-PASS foo(array) is 8746
-PASS foo(array) is 8746
-PASS foo(array) is 8746
-PASS foo(array) is 8746
-PASS foo(array) is 8746
-PASS foo(array) is 8746
-PASS foo(array) is 8746
-PASS foo(array) is 8746
-PASS foo(array) is 8746
-PASS foo(array) is 8746
-PASS foo(array) is 8746
-PASS foo(array) is 8746
-PASS foo(array) is 8746
-PASS foo(array) is 8746
-PASS foo(array) is 8746
-PASS foo(array) is 8746
-PASS foo(array) is 8746
-PASS foo(array) is 8746
-PASS foo(array) is 8746
-PASS foo(array) is 8746
-PASS foo(array) is 8746
-PASS foo(array) is 8746
-PASS foo(array) is 8746
-PASS foo(array) is 8746
-PASS foo(array) is 8746
-PASS foo(array) is 8746
-PASS foo(array) is 8746
-PASS foo(array) is 8746
-PASS foo(array) is 8746
-PASS foo(array) is 8746
-PASS foo(array) is 8746
-PASS foo(array) is 8746
-PASS foo(array) is 8746
-PASS foo(array) is 8746
-PASS foo(array) is 8746
-PASS foo(array) is 8746
-PASS foo(array) is 8746
-PASS foo(array) is 8746
-PASS foo(array) is 8746
-PASS foo(array) is 8746
-PASS foo(array) is 8746
-PASS foo(array) is 8746
-PASS foo(array) is 8746
-PASS foo(array) is 8746
-PASS foo(array) is 8746
-PASS foo(array) is 8746
-PASS foo(array) is 8746
-PASS foo(array) is 8746
-PASS foo(array) is 8746
-PASS foo(array) is 8746
-PASS foo(array) is 8746
-PASS foo(array) is 8746
-PASS foo(array) is 8746
-PASS foo(array) is 8746
-PASS foo(array) is 8746
-PASS foo(array) is 8746
-PASS foo(array) is 8746
-PASS foo(array) is 8746
-PASS foo(array) is 8746
-PASS foo(array) is 8746
-PASS foo(array) is 8746
-PASS foo(array) is 8746
-PASS foo(array) is 8746
-PASS foo(array) is 8746
-PASS foo(array) is 8746
-PASS foo(array) is 8746
-PASS foo(array) is 8746
-PASS foo(array) is 8746
-PASS foo(array) is 8746
-PASS foo(array) is 8746
-PASS foo(array) is 8746
-PASS foo(array) is 8746
-PASS foo(array) is 8746
-PASS foo(array) is 8746
-PASS foo(array) is 8746
-PASS foo(array) is 8746
-PASS foo(array) is 8746
-PASS foo(array) is 8746
-PASS foo(array) is 8746
-PASS foo(array) is 8746
-PASS foo(array) is 8746
-PASS foo(array) is 8746
-PASS foo(array) is 8746
-PASS foo(array) is 8746
-PASS foo(array) is 8746
-PASS foo(array) is 8746
-PASS foo(array) is 8746
-PASS foo(array) is 8746
-PASS foo(array) is 8746
-PASS foo(array) is 8746
-PASS foo(array) is 8746
-PASS foo(array) is 8746
-PASS foo(array) is 8746
-PASS foo(array) is 8746
-PASS foo(array) is 8746
-PASS foo(array) is 8746
-PASS foo(array) is 8746
-PASS foo(array) is 8746
-PASS foo(array) is 8746
-PASS foo(array) is 8746
-PASS foo(array) is 8746
-PASS foo(array) is 8746
-PASS foo(array) is 8746
-PASS foo(array) is 8746
-PASS foo(array) is 8746
-PASS foo(array) is 8746
-PASS foo(array) is 8746
-PASS foo(array) is 8746
-PASS foo(array) is 8746
-PASS foo(array) is 8746
-PASS foo(array) is 8746
-PASS foo(array) is 8746
-PASS foo(array) is 8746
-PASS foo(array) is 8746
-PASS foo(array) is 8746
-PASS foo(array) is 8746
-PASS foo(array) is 8746
-PASS foo(array) is 8746
-PASS foo(array) is 8746
-PASS foo(array) is 8746
-PASS foo(array) is 8746
-PASS foo(array) is 8746
-PASS foo(array) is 8746
-PASS foo(array) is 8746
-PASS foo(array) is 8746
-PASS foo(array) is 8746
-PASS foo(array) is 8746
-PASS successfullyParsed is true
+Passed some tests silently.
TEST COMPLETE
Modified: trunk/LayoutTests/fast/js/script-tests/dfg-force-exit-then-sparse-conditional-constant-prop-in-loop.js (153214 => 153215)
--- trunk/LayoutTests/fast/js/script-tests/dfg-force-exit-then-sparse-conditional-constant-prop-in-loop.js 2013-07-25 04:02:15 UTC (rev 153214)
+++ trunk/LayoutTests/fast/js/script-tests/dfg-force-exit-then-sparse-conditional-constant-prop-in-loop.js 2013-07-25 04:02:17 UTC (rev 153215)
@@ -18,5 +18,8 @@
var array = [54, 5432, 1234, 54, 1235, 64, 75, 532, 64, 2];
-for (var i = 0; i < 200; ++i)
+silentTestPass = true;
+noInline(foo);
+
+for (var i = 0; i < 2; i = dfgIncrement({f:foo, i:i + 1, n:1}))
shouldBe("foo(array)", "8746");
Modified: trunk/Source/_javascript_Core/ChangeLog (153214 => 153215)
--- trunk/Source/_javascript_Core/ChangeLog 2013-07-25 04:02:15 UTC (rev 153214)
+++ trunk/Source/_javascript_Core/ChangeLog 2013-07-25 04:02:17 UTC (rev 153215)
@@ -1,5 +1,65 @@
+2013-06-08 Mark Lam <mark....@apple.com>
+
+ Removed bogus assertion in CallFrame::setLocationAsBytecodeOffset().
+ https://bugs.webkit.org/show_bug.cgi?id=117373.
+
+ Reviewed by Oliver Hunt.
+
+ The assertion wrongly assumes that the incoming offset argument is in
+ units of bytes. This is not true. It is in units of Instruction*. Hence,
+ the assertion which checks for the low 2 bits to be clear can fail.
+
+ * interpreter/CallFrame.cpp:
+ (JSC::CallFrame::setLocationAsBytecodeOffset):
+
2013-06-07 Filip Pizlo <fpi...@apple.com>
+ fourthTier: don't insert ForceOSRExits except for inadequate coverage
+ https://bugs.webkit.org/show_bug.cgi?id=117363
+
+ Reviewed by Mark Hahnenberg.
+
+ Previously (in http://trac.webkit.org/changeset/151303) I made it so that we
+ inserted ForceOSRExits more eagerly. I now think it's better to have
+ contradictions execute normally and exit with full OSR exit profiling. It's
+ better at catching the few cases where the DFG will end up with different
+ types than the baseline engines.
+
+ This simplifies a bunch of code. For example it gets rid of
+ ConstantFoldingPhase::paintUnreachableCode().
+
+ You can think of this as a partial roll-out of r151303, except that it uses
+ the facilities introduced by that patch to give us run-time assertions that
+ check the CFA's correctness: if the CFA thought that something was a
+ contradiction but the code didn't exit, we'll now trap.
+
+ * dfg/DFGAbstractState.cpp:
+ (JSC::DFG::AbstractState::AbstractState):
+ (JSC::DFG::AbstractState::startExecuting):
+ (JSC::DFG::AbstractState::executeEffects):
+ (JSC::DFG::AbstractState::execute):
+ (JSC::DFG::AbstractState::filter):
+ (JSC::DFG::AbstractState::filterArrayModes):
+ (JSC::DFG::AbstractState::filterByValue):
+ (DFG):
+ * dfg/DFGAbstractState.h:
+ (AbstractState):
+ (JSC::DFG::AbstractState::filter):
+ (JSC::DFG::AbstractState::filterArrayModes):
+ (JSC::DFG::AbstractState::filterByValue):
+ * dfg/DFGCFAPhase.cpp:
+ (JSC::DFG::CFAPhase::performBlockCFA):
+ * dfg/DFGConstantFoldingPhase.cpp:
+ (JSC::DFG::ConstantFoldingPhase::run):
+ (JSC::DFG::ConstantFoldingPhase::foldConstants):
+ (ConstantFoldingPhase):
+ * dfg/DFGSpeculativeJIT.cpp:
+ (JSC::DFG::SpeculativeJIT::compile):
+ * ftl/FTLLowerDFGToLLVM.cpp:
+ (JSC::FTL::LowerDFGToLLVM::compileNode):
+
+2013-06-07 Filip Pizlo <fpi...@apple.com>
+
Unreviewed, fix release build.
* ftl/FTLLink.cpp:
Modified: trunk/Source/_javascript_Core/dfg/DFGAbstractState.cpp (153214 => 153215)
--- trunk/Source/_javascript_Core/dfg/DFGAbstractState.cpp 2013-07-25 04:02:15 UTC (rev 153214)
+++ trunk/Source/_javascript_Core/dfg/DFGAbstractState.cpp 2013-07-25 04:02:17 UTC (rev 153215)
@@ -43,7 +43,6 @@
, m_variables(m_codeBlock->numParameters(), graph.m_localVars)
, m_block(0)
, m_currentNode(0)
- , m_executionMode(CleanFiltration)
{
}
@@ -233,7 +232,7 @@
return UnknownBooleanResult;
}
-bool AbstractState::startExecuting(Node* node, ExecutionMode executionMode)
+bool AbstractState::startExecuting(Node* node)
{
ASSERT(m_block);
ASSERT(m_isValid);
@@ -244,18 +243,16 @@
if (!node->shouldGenerate()) {
m_currentNode = 0;
- m_executionMode = CleanFiltration;
return false;
}
m_currentNode = node;
- m_executionMode = executionMode;
return true;
}
-bool AbstractState::startExecuting(unsigned indexInBlock, ExecutionMode executionMode)
+bool AbstractState::startExecuting(unsigned indexInBlock)
{
- return startExecuting(m_block->at(indexInBlock), executionMode);
+ return startExecuting(m_block->at(indexInBlock));
}
void AbstractState::executeEdges(Node* node)
@@ -1105,8 +1102,7 @@
// structure.
filter(
node->child1(),
- m_graph.globalObjectFor(node->codeOrigin)->stringObjectStructure(),
- NotStringObject);
+ m_graph.globalObjectFor(node->codeOrigin)->stringObjectStructure());
node->setCanExit(true); // We could be more precise but it's likely not worth it.
break;
case StringOrStringObjectUse:
@@ -1325,7 +1321,7 @@
forNode(node).set(m_graph, status.specificValue());
else
forNode(node).makeTop();
- filter(node->child1(), status.structureSet(), BadCache);
+ filter(node->child1(), status.structureSet());
m_foundConstants = true;
break;
@@ -1363,12 +1359,6 @@
break;
}
- ExitKind exitKind;
- if (node->child1()->op() == WeakJSConstant)
- exitKind = BadWeakConstantCache;
- else
- exitKind = BadCache;
-
node->setCanExit(true);
// If this structure check is attempting to prove knowledge already held in
@@ -1377,11 +1367,11 @@
if (value.m_futurePossibleStructure.isSubsetOf(set)
&& value.m_futurePossibleStructure.hasSingleton()) {
m_foundConstants = true;
- filter(value, value.m_futurePossibleStructure.singleton(), exitKind);
+ filter(value, value.m_futurePossibleStructure.singleton());
break;
}
- filter(value, set, exitKind);
+ filter(value, set);
m_haveStructures = true;
break;
}
@@ -1390,12 +1380,6 @@
case ForwardStructureTransitionWatchpoint: {
AbstractValue& value = forNode(node->child1());
- ExitKind exitKind;
- if (node->child1()->op() == WeakJSConstant)
- exitKind = BadWeakConstantCache;
- else
- exitKind = BadCache;
-
// It's only valid to issue a structure transition watchpoint if we already
// know that the watchpoint covers a superset of the structures known to
// belong to the set of future structures that this value may have.
@@ -1406,7 +1390,7 @@
value.m_futurePossibleStructure.isSubsetOf(StructureSet(node->structure()))
|| m_graph.watchpoints().shouldAssumeMixedState(node->structure()->transitionWatchpointSet()));
- filter(value, node->structure(), exitKind);
+ filter(value, node->structure());
m_haveStructures = true;
node->setCanExit(true);
break;
@@ -1501,7 +1485,7 @@
m_foundConstants = true;
node->setCanExit(true);
clobberStructures(indexInBlock);
- filter(value, set, BadIndexingType);
+ filter(value, set);
m_haveStructures = true;
break;
}
@@ -1527,7 +1511,7 @@
}
node->setCanExit(true); // Lies! We can do better.
- filterByValue(node->child1(), node->function(), BadFunction);
+ filterByValue(node->child1(), node->function());
break;
}
@@ -1542,7 +1526,7 @@
m_graph.identifiers()[node->identifierNumber()],
node->op() == PutByIdDirect);
if (status.isSimpleReplace()) {
- filter(node->child1(), structure, BadCache);
+ filter(node->child1(), structure);
m_foundConstants = true;
break;
}
@@ -1631,10 +1615,10 @@
return executeEffects(indexInBlock, m_block->at(indexInBlock));
}
-bool AbstractState::execute(unsigned indexInBlock, ExecutionMode executionMode)
+bool AbstractState::execute(unsigned indexInBlock)
{
Node* node = m_block->at(indexInBlock);
- if (!startExecuting(node, executionMode))
+ if (!startExecuting(node))
return true;
executeEdges(node);
@@ -1868,61 +1852,39 @@
}
}
-FiltrationResult AbstractState::filter(
- AbstractValue& value, const StructureSet& set, ExitKind exitKind)
+FiltrationResult AbstractState::filter(AbstractValue& value, const StructureSet& set)
{
if (value.filter(m_graph, set) == FiltrationOK)
return FiltrationOK;
- bail(exitKind);
+ m_isValid = false;
return Contradiction;
}
-FiltrationResult AbstractState::filterArrayModes(
- AbstractValue& value, ArrayModes arrayModes, ExitKind exitKind)
+FiltrationResult AbstractState::filterArrayModes(AbstractValue& value, ArrayModes arrayModes)
{
if (value.filterArrayModes(arrayModes) == FiltrationOK)
return FiltrationOK;
- bail(exitKind);
+ m_isValid = false;
return Contradiction;
}
-FiltrationResult AbstractState::filter(
- AbstractValue& value, SpeculatedType type, ExitKind exitKind)
+FiltrationResult AbstractState::filter(AbstractValue& value, SpeculatedType type)
{
if (value.filter(type) == FiltrationOK)
return FiltrationOK;
- bail(exitKind);
+ m_isValid = false;
return Contradiction;
}
FiltrationResult AbstractState::filterByValue(
- AbstractValue& abstractValue, JSValue concreteValue, ExitKind exitKind)
+ AbstractValue& abstractValue, JSValue concreteValue)
{
if (abstractValue.filterByValue(concreteValue) == FiltrationOK)
return FiltrationOK;
- bail(exitKind);
+ m_isValid = false;
return Contradiction;
}
-void AbstractState::bail(ExitKind exitKind)
-{
- ASSERT(m_currentNode);
- m_isValid = false;
- switch (m_executionMode) {
- case StillConverging:
- return;
- case AfterConvergence: {
- m_graph.baselineCodeBlockFor(m_currentNode->codeOrigin)->addFrequentExitSite(
- FrequentExitSite(m_currentNode->codeOrigin.bytecodeIndex, exitKind));
- return;
- }
- case CleanFiltration:
- RELEASE_ASSERT_NOT_REACHED();
- return;
- }
- RELEASE_ASSERT_NOT_REACHED();
-}
-
} } // namespace JSC::DFG
#endif // ENABLE(DFG_JIT)
Modified: trunk/Source/_javascript_Core/dfg/DFGAbstractState.h (153214 => 153215)
--- trunk/Source/_javascript_Core/dfg/DFGAbstractState.h 2013-07-25 04:02:15 UTC (rev 153214)
+++ trunk/Source/_javascript_Core/dfg/DFGAbstractState.h 2013-07-25 04:02:17 UTC (rev 153215)
@@ -93,21 +93,6 @@
MergeToSuccessors
};
- enum ExecutionMode {
- // If we encounter a contradiction, assume that this might just
- // be because we haven't converged yet.
- StillConverging,
-
- // If we encounter a contradition, assume that this contradiction
- // is real and report it to the profiling infrastructure as if it
- // happened at run time.
- AfterConvergence,
-
- // Assume that there cannot be any contradictions other than
- // ForceOSRExit because we have already cleaned the graph.
- CleanFiltration
- };
-
AbstractState(Graph&);
~AbstractState();
@@ -191,12 +176,12 @@
//
// This is guaranteed to be equivalent to doing:
//
- // if (state.startExecuting(index, executionMode)) {
+ // if (state.startExecuting(index)) {
// state.executeEdges(index);
// result = state.executeEffects(index);
// } else
// result = true;
- bool execute(unsigned indexInBlock, ExecutionMode);
+ bool execute(unsigned indexInBlock);
// Indicate the start of execution of the node. It resets any state in the node,
// that is progressively built up by executeEdges() and executeEffects(). In
@@ -204,8 +189,8 @@
// startExecuting() and executeEdges()/Effects() whether the last run of the
// analysis concluded that the node can exit, you should probably set that
// information aside prior to calling startExecuting().
- bool startExecuting(Node*, ExecutionMode);
- bool startExecuting(unsigned indexInBlock, ExecutionMode);
+ bool startExecuting(Node*);
+ bool startExecuting(unsigned indexInBlock);
// Abstractly execute the edges of the given node. This runs filterEdgeByUse()
// on all edges of the node. You can skip this step, if you have already used
@@ -247,37 +232,34 @@
void dump(PrintStream& out);
template<typename T>
- FiltrationResult filter(T node, const StructureSet& set, ExitKind exitKind)
+ FiltrationResult filter(T node, const StructureSet& set)
{
- return filter(forNode(node), set, exitKind);
+ return filter(forNode(node), set);
}
template<typename T>
- FiltrationResult filterArrayModes(
- T node, ArrayModes arrayModes, ExitKind exitKind = BadIndexingType)
+ FiltrationResult filterArrayModes(T node, ArrayModes arrayModes)
{
- return filterArrayModes(forNode(node), arrayModes, exitKind);
+ return filterArrayModes(forNode(node), arrayModes);
}
template<typename T>
- FiltrationResult filter(T node, SpeculatedType type, ExitKind exitKind = BadType)
+ FiltrationResult filter(T node, SpeculatedType type)
{
- return filter(forNode(node), type, exitKind);
+ return filter(forNode(node), type);
}
template<typename T>
- FiltrationResult filterByValue(T node, JSValue value, ExitKind exitKind)
+ FiltrationResult filterByValue(T node, JSValue value)
{
- return filterByValue(forNode(node), value, exitKind);
+ return filterByValue(forNode(node), value);
}
- FiltrationResult filter(AbstractValue&, const StructureSet&, ExitKind);
- FiltrationResult filterArrayModes(AbstractValue&, ArrayModes, ExitKind = BadIndexingType);
- FiltrationResult filter(AbstractValue&, SpeculatedType, ExitKind = BadType);
- FiltrationResult filterByValue(AbstractValue&, JSValue, ExitKind);
+ FiltrationResult filter(AbstractValue&, const StructureSet&);
+ FiltrationResult filterArrayModes(AbstractValue&, ArrayModes);
+ FiltrationResult filter(AbstractValue&, SpeculatedType);
+ FiltrationResult filterByValue(AbstractValue&, JSValue);
- void bail(ExitKind);
-
private:
void clobberWorld(const CodeOrigin&, unsigned indexInBlock);
void clobberCapturedVars(const CodeOrigin&);
@@ -332,7 +314,6 @@
Operands<AbstractValue> m_variables;
BasicBlock* m_block;
Node* m_currentNode;
- ExecutionMode m_executionMode;
bool m_haveStructures;
bool m_foundConstants;
Modified: trunk/Source/_javascript_Core/dfg/DFGCFAPhase.cpp (153214 => 153215)
--- trunk/Source/_javascript_Core/dfg/DFGCFAPhase.cpp 2013-07-25 04:02:15 UTC (rev 153214)
+++ trunk/Source/_javascript_Core/dfg/DFGCFAPhase.cpp 2013-07-25 04:02:17 UTC (rev 153215)
@@ -101,7 +101,7 @@
m_state.dump(WTF::dataFile());
dataLogF("\n");
}
- if (!m_state.execute(i, AbstractState::StillConverging)) {
+ if (!m_state.execute(i)) {
if (verbose)
dataLogF(" Expect OSR exit.\n");
break;
Modified: trunk/Source/_javascript_Core/dfg/DFGConstantFoldingPhase.cpp (153214 => 153215)
--- trunk/Source/_javascript_Core/dfg/DFGConstantFoldingPhase.cpp 2013-07-25 04:02:15 UTC (rev 153214)
+++ trunk/Source/_javascript_Core/dfg/DFGConstantFoldingPhase.cpp 2013-07-25 04:02:17 UTC (rev 153215)
@@ -56,8 +56,6 @@
BasicBlock* block = m_graph.m_blocks[blockIndex].get();
if (!block)
continue;
- if (!block->cfaDidFinish)
- changed |= paintUnreachableCode(blockIndex);
if (block->cfaFoundConstants)
changed |= foldConstants(blockIndex);
}
@@ -103,7 +101,7 @@
else
set = node->structureSet();
if (value.m_currentKnownStructure.isSubsetOf(set)) {
- m_state.execute(indexInBlock, AbstractState::CleanFiltration); // Catch the fact that we may filter on cell.
+ m_state.execute(indexInBlock); // Catch the fact that we may filter on cell.
node->convertToPhantom();
eliminated = true;
break;
@@ -112,7 +110,7 @@
if (structureValue.isSubsetOf(set)
&& structureValue.hasSingleton()) {
Structure* structure = structureValue.singleton();
- m_state.execute(indexInBlock, AbstractState::CleanFiltration); // Catch the fact that we may filter on cell.
+ m_state.execute(indexInBlock); // Catch the fact that we may filter on cell.
AdjacencyList children = node->children;
children.removeEdge(0);
if (!!children.child1()) {
@@ -181,7 +179,7 @@
// Now before we do anything else, push the CFA forward over the GetById
// and make sure we signal to the loop that it should continue and not
// do any eliminations.
- m_state.execute(indexInBlock, AbstractState::CleanFiltration);
+ m_state.execute(indexInBlock);
eliminated = true;
if (needsWatchpoint) {
@@ -245,7 +243,7 @@
// Now before we do anything else, push the CFA forward over the PutById
// and make sure we signal to the loop that it should continue and not
// do any eliminations.
- m_state.execute(indexInBlock, AbstractState::CleanFiltration);
+ m_state.execute(indexInBlock);
eliminated = true;
if (needsWatchpoint) {
@@ -334,7 +332,7 @@
continue;
}
- m_state.execute(indexInBlock, AbstractState::CleanFiltration);
+ m_state.execute(indexInBlock);
if (!node->shouldGenerate() || m_state.didClobber() || node->hasConstant())
continue;
JSValue value = m_state.forNode(node).value();
@@ -422,54 +420,6 @@
OpInfo(m_graph.addStructureSet(cell->structure())), Edge(weakConstant, CellUse));
}
- // This is necessary because the CFA may reach conclusions about constants based on its
- // assumption that certain code must exit, but then those constants may lead future
- // reexecutions of the CFA to believe that the same code will now no longer exit. Thus
- // to ensure soundness, we must paint unreachable code as such, by inserting an
- // unconditional ForceOSRExit wherever we find that a node would have always exited.
- // This will only happen in cases where we are making static speculations, or we're
- // making totally wrong speculations due to imprecision in the prediction propagator.
- bool paintUnreachableCode(BlockIndex blockIndex)
- {
- bool changed = false;
-
-#if DFG_ENABLE(DEBUG_PROPAGATION_VERBOSE)
- dataLogF("Painting unreachable code in Block #%u.\n", blockIndex);
-#endif
- BasicBlock* block = m_graph.m_blocks[blockIndex].get();
- m_state.beginBasicBlock(block);
-
- for (unsigned indexInBlock = 0; indexInBlock < block->size(); ++indexInBlock) {
- m_state.execute(indexInBlock, AbstractState::AfterConvergence);
- if (m_state.isValid())
- continue;
-
- Node* node = block->at(indexInBlock);
- switch (node->op()) {
- case Return:
- case Throw:
- case ThrowReferenceError:
- case ForceOSRExit:
- case ForwardForceOSRExit:
- // Do nothing. These nodes will already do the right thing.
- break;
-
- default:
- m_insertionSet.insertNode(
- indexInBlock, SpecNone,
- (node->flags() & NodeExitsForward) ? ForwardForceOSRExit : ForceOSRExit,
- node->codeOrigin);
- changed = true;
- break;
- }
- break;
- }
- m_state.reset();
- m_insertionSet.execute(block);
-
- return changed;
- }
-
AbstractState m_state;
InsertionSet m_insertionSet;
};
Modified: trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp (153214 => 153215)
--- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp 2013-07-25 04:02:15 UTC (rev 153214)
+++ trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp 2013-07-25 04:02:17 UTC (rev 153215)
@@ -1674,11 +1674,15 @@
for (m_indexInBlock = 0; m_indexInBlock < block.size(); ++m_indexInBlock) {
m_currentNode = block[m_indexInBlock];
- // If there was a contradiction then the constant folder ought to have caught it.
- RELEASE_ASSERT(m_state.isValid());
+ // We may have his a contradiction that the CFA was aware of but that the JIT
+ // didn't cause directly.
+ if (!m_state.isValid()) {
+ bail();
+ return;
+ }
m_canExit = m_currentNode->canExit();
- bool shouldExecuteEffects = m_state.startExecuting(m_currentNode, AbstractState::CleanFiltration);
+ bool shouldExecuteEffects = m_state.startExecuting(m_currentNode);
m_jit.setForNode(m_currentNode);
m_codeOriginForOSR = m_currentNode->codeOrigin;
if (!m_currentNode->shouldGenerate()) {
Modified: trunk/Source/_javascript_Core/ftl/FTLLowerDFGToLLVM.cpp (153214 => 153215)
--- trunk/Source/_javascript_Core/ftl/FTLLowerDFGToLLVM.cpp 2013-07-25 04:02:15 UTC (rev 153214)
+++ trunk/Source/_javascript_Core/ftl/FTLLowerDFGToLLVM.cpp 2013-07-25 04:02:17 UTC (rev 153215)
@@ -265,7 +265,7 @@
if (verboseCompilationEnabled())
dataLog("Lowering ", m_node, "\n");
- bool shouldExecuteEffects = m_state.startExecuting(m_node, AbstractState::CleanFiltration);
+ bool shouldExecuteEffects = m_state.startExecuting(m_node);
m_direction = (m_node->flags() & NodeExitsForward) ? ForwardSpeculation : BackwardSpeculation;
Modified: trunk/Source/_javascript_Core/interpreter/CallFrame.cpp (153214 => 153215)
--- trunk/Source/_javascript_Core/interpreter/CallFrame.cpp 2013-07-25 04:02:15 UTC (rev 153214)
+++ trunk/Source/_javascript_Core/interpreter/CallFrame.cpp 2013-07-25 04:02:17 UTC (rev 153215)
@@ -52,7 +52,6 @@
void CallFrame::setLocationAsBytecodeOffset(unsigned offset)
{
ASSERT(codeBlock());
- ASSERT(Location::isBytecodeLocation(offset));
setCurrentVPC(codeBlock()->instructions().begin() + offset);
ASSERT(hasLocationAsBytecodeOffset());
}