Strict Equality on objects should only check that one of the two sides is an object.
https://bugs.webkit.org/show_bug.cgi?id=145992
Source/JavaScriptCore:
This patch adds a new optimization for checking strict equality on objects.
If we speculate that a strict equality comparison has an object on one side
we only need to type check that side. Equality is then determined by a pointer
comparison between the two values (although in the 32-bit case we must also check
that the other side is a cell). Once LICM hoists type checks out of a loop we
can be cleverer about how we choose the operand we type check if both are
speculated to be objects.
For testing I added the addressOf function, which returns the address
of a Cell to the runtime.
Patch by Keith Miller <keith_miller@apple.com> on 2015-06-24
Reviewed by Mark Lam.
* dfg/DFGFixupPhase.cpp:
(JSC::DFG::FixupPhase::fixupNode):
* dfg/DFGSpeculativeJIT.cpp:
(JSC::DFG::SpeculativeJIT::compileStrictEq):
* dfg/DFGSpeculativeJIT.h:
* dfg/DFGSpeculativeJIT32_64.cpp:
(JSC::DFG::SpeculativeJIT::compileObjectStrictEquality):
(JSC::DFG::SpeculativeJIT::compilePeepHoleObjectStrictEquality):
* dfg/DFGSpeculativeJIT64.cpp:
(JSC::DFG::SpeculativeJIT::compileObjectStrictEquality):
(JSC::DFG::SpeculativeJIT::compilePeepHoleObjectStrictEquality):
* ftl/FTLCapabilities.cpp:
(JSC::FTL::canCompile):
* ftl/FTLLowerDFGToLLVM.cpp:
(JSC::FTL::DFG::LowerDFGToLLVM::compileCompareStrictEq):
* jsc.cpp:
(GlobalObject::finishCreation):
(functionAddressOf):
* tests/stress/equality-type-checking.js: Added.
(Foo):
(checkStrictEq):
(checkStrictEqOther):
LayoutTests:
Patch by Keith Miller <keith_miller@apple.com> on 2015-06-24
Reviewed by Mark Lam.
Adds a test that checks if strict equality checks with objects properly exit out of DFG code when
dealing with document.all, which is an object that masquerades as undefined.
* js/dom/document-all-strict-eq-expected.txt: Added.
* js/dom/document-all-strict-eq.html: Added.
* js/dom/script-tests/document-all-strict-eq.js: Added.
(f):
git-svn-id: http://svn.webkit.org/repository/webkit/trunk@185920 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp b/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp
index 872275d..1affa1a 100644
--- a/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp
+++ b/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp
@@ -471,7 +471,21 @@
fixEdge<StringUse>(node->child2());
break;
}
- if (node->child1()->shouldSpeculateObject() && node->child2()->shouldSpeculateObject()) {
+ WatchpointSet* masqueradesAsUndefinedWatchpoint = m_graph.globalObjectFor(node->origin.semantic)->masqueradesAsUndefinedWatchpoint();
+ if (masqueradesAsUndefinedWatchpoint->isStillValid()) {
+
+ if (node->child1()->shouldSpeculateObject()) {
+ m_graph.watchpoints().addLazily(masqueradesAsUndefinedWatchpoint);
+ fixEdge<ObjectUse>(node->child1());
+ break;
+ }
+ if (node->child2()->shouldSpeculateObject()) {
+ m_graph.watchpoints().addLazily(masqueradesAsUndefinedWatchpoint);
+ fixEdge<ObjectUse>(node->child2());
+ break;
+ }
+
+ } else if (node->child1()->shouldSpeculateObject() && node->child2()->shouldSpeculateObject()) {
fixEdge<ObjectUse>(node->child1());
fixEdge<ObjectUse>(node->child2());
break;