[JSC] DFG should support relational comparisons of Number and Other
https://bugs.webkit.org/show_bug.cgi?id=156669
Patch by Benjamin Poulain <bpoulain@webkit.org> on 2016-04-16
Reviewed by Darin Adler.
In Sunspider/3d-raytrace, DFG falls back to JSValue in some important
relational compare because profiling sees "undefined" from time to time.
This case is fairly common outside Sunspider too because of out-of-bounds array access.
Unfortunately for us, our fallback for compare is really inefficient.
Fortunately, relational comparison with null/undefined/true/false are trival.
We can just convert both side to Double. That's what this patch adds.
I also extended constant folding for those cases because I noticed
a bunch of "undefined" constant going through DoubleRep at runtime.
* dfg/DFGAbstractInterpreterInlines.h:
(JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
* dfg/DFGFixupPhase.cpp:
(JSC::DFG::FixupPhase::fixupNode):
* tests/stress/compare-number-and-other.js: Added.
(opaqueSideEffect):
(let.operator.of.operators.eval.testPolymorphic):
(let.operator.of.operators.let.left.of.typeCases.let.right.of.typeCases.eval.testMonomorphic):
(let.operator.of.operators.let.left.of.typeCases.let.right.of.typeCases.testMonomorphicLeftConstant):
(let.operator.of.operators.let.left.of.typeCases.let.right.of.typeCases.testMonomorphicRightConstant):
(let.operator.of.operators.let.left.of.typeCases.let.right.of.typeCases.i.testPolymorphic):
git-svn-id: http://svn.webkit.org/repository/webkit/trunk@199639 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp b/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp
index 20dcd0d..d387a2e 100644
--- a/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp
+++ b/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp
@@ -453,6 +453,18 @@
if (Node::shouldSpeculateNumberOrBoolean(node->child1().node(), node->child2().node())) {
fixDoubleOrBooleanEdge(node->child1());
fixDoubleOrBooleanEdge(node->child2());
+ }
+ if (node->op() != CompareEq
+ && node->child1()->shouldSpeculateNotCell()
+ && node->child2()->shouldSpeculateNotCell()) {
+ if (node->child1()->shouldSpeculateNumberOrBoolean())
+ fixDoubleOrBooleanEdge(node->child1());
+ else
+ fixEdge<DoubleRepUse>(node->child1());
+ if (node->child2()->shouldSpeculateNumberOrBoolean())
+ fixDoubleOrBooleanEdge(node->child2());
+ else
+ fixEdge<DoubleRepUse>(node->child2());
node->clearFlags(NodeMustGenerate);
break;
}