Diff
Modified: trunk/LayoutTests/ChangeLog (183494 => 183495)
--- trunk/LayoutTests/ChangeLog 2015-04-28 18:36:59 UTC (rev 183494)
+++ trunk/LayoutTests/ChangeLog 2015-04-28 18:54:12 UTC (rev 183495)
@@ -1,3 +1,14 @@
+2015-04-28 Andreas Kling <[email protected]>
+
+ DFG should generate efficient code for branching on a string's boolean value.
+ <https://webkit.org/b/144317>
+
+ Reviewed by Geoff Garen & Filip Pizlo.
+
+ * js/regress/branch-on-string-as-boolean-expected.txt: Added.
+ * js/regress/branch-on-string-as-boolean.html: Added.
+ * js/regress/script-tests/branch-on-string-as-boolean.js: Added.
+
2015-04-27 Myles C. Maxfield <[email protected]>
Implement font-synthesis CSS property
Added: trunk/LayoutTests/js/regress/branch-on-string-as-boolean-expected.txt (0 => 183495)
--- trunk/LayoutTests/js/regress/branch-on-string-as-boolean-expected.txt (rev 0)
+++ trunk/LayoutTests/js/regress/branch-on-string-as-boolean-expected.txt 2015-04-28 18:54:12 UTC (rev 183495)
@@ -0,0 +1,10 @@
+JSRegress/branch-on-string-as-boolean
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS no exception thrown
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
Added: trunk/LayoutTests/js/regress/branch-on-string-as-boolean.html (0 => 183495)
--- trunk/LayoutTests/js/regress/branch-on-string-as-boolean.html (rev 0)
+++ trunk/LayoutTests/js/regress/branch-on-string-as-boolean.html 2015-04-28 18:54:12 UTC (rev 183495)
@@ -0,0 +1,12 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html>
+<head>
+<script src=""
+</head>
+<body>
+<script src=""
+<script src=""
+<script src=""
+<script src=""
+</body>
+</html>
Added: trunk/LayoutTests/js/regress/script-tests/branch-on-string-as-boolean.js (0 => 183495)
--- trunk/LayoutTests/js/regress/script-tests/branch-on-string-as-boolean.js (rev 0)
+++ trunk/LayoutTests/js/regress/script-tests/branch-on-string-as-boolean.js 2015-04-28 18:54:12 UTC (rev 183495)
@@ -0,0 +1,12 @@
+// This test branches on the boolean value of a string, which should be fast in the DFG.
+
+function foo(string) {
+ var bar;
+ for (var i = 0; i < 10000000; ++i) {
+ if (string)
+ bar++;
+ }
+ return bar;
+}
+
+result = foo('hurr im a string');
Modified: trunk/Source/_javascript_Core/ChangeLog (183494 => 183495)
--- trunk/Source/_javascript_Core/ChangeLog 2015-04-28 18:36:59 UTC (rev 183494)
+++ trunk/Source/_javascript_Core/ChangeLog 2015-04-28 18:54:12 UTC (rev 183495)
@@ -1,3 +1,28 @@
+2015-04-28 Andreas Kling <[email protected]>
+
+ DFG+FTL should generate efficient code for branching on a string's boolean value.
+ <https://webkit.org/b/144317>
+
+ Reviewed by Geoff Garen & Filip Pizlo
+
+ Teach Branch nodes about StringUse and have them generate an efficient zero-length string check
+ instead of dropping out to C++ whenever we branch on a string.
+
+ The FTL JIT already handled Branch nodes with StringUse through its use of boolify(), so only
+ the DFG JIT gets some new codegen logic in this patch.
+
+ Test: js/regress/branch-on-string-as-boolean.js (~4.5x speedup)
+
+ * dfg/DFGFixupPhase.cpp:
+ (JSC::DFG::FixupPhase::fixupNode):
+ * dfg/DFGSpeculativeJIT.cpp:
+ (JSC::DFG::SpeculativeJIT::emitStringBranch):
+ * dfg/DFGSpeculativeJIT.h:
+ * dfg/DFGSpeculativeJIT32_64.cpp:
+ (JSC::DFG::SpeculativeJIT::emitBranch):
+ * dfg/DFGSpeculativeJIT64.cpp:
+ (JSC::DFG::SpeculativeJIT::emitBranch):
+
2015-04-28 Filip Pizlo <[email protected]>
VarargsForwardingPhase should only consider MovHints that have the candidate as a child
Modified: trunk/Source/_javascript_Core/dfg/DFGFixupPhase.cpp (183494 => 183495)
--- trunk/Source/_javascript_Core/dfg/DFGFixupPhase.cpp 2015-04-28 18:36:59 UTC (rev 183494)
+++ trunk/Source/_javascript_Core/dfg/DFGFixupPhase.cpp 2015-04-28 18:54:12 UTC (rev 183495)
@@ -737,6 +737,8 @@
fixEdge<Int32Use>(node->child1());
else if (node->child1()->shouldSpeculateNumber())
fixEdge<DoubleRepUse>(node->child1());
+ else if (node->child1()->shouldSpeculateString())
+ fixEdge<StringUse>(node->child1());
break;
}
Modified: trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp (183494 => 183495)
--- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp 2015-04-28 18:36:59 UTC (rev 183494)
+++ trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp 2015-04-28 18:54:12 UTC (rev 183495)
@@ -4040,6 +4040,15 @@
unblessedBooleanResult(eqGPR, node);
}
+void SpeculativeJIT::emitStringBranch(Edge nodeUse, BasicBlock* taken, BasicBlock* notTaken)
+{
+ SpeculateCellOperand str(this, nodeUse);
+ speculateString(nodeUse, str.gpr());
+ branchTest32(JITCompiler::NonZero, MacroAssembler::Address(str.gpr(), JSString::offsetOfLength()), taken);
+ jump(notTaken);
+ noResult(m_currentNode);
+}
+
void SpeculativeJIT::compileConstantStoragePointer(Node* node)
{
GPRTemporary storage(this);
Modified: trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.h (183494 => 183495)
--- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.h 2015-04-28 18:36:59 UTC (rev 183494)
+++ trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.h 2015-04-28 18:54:12 UTC (rev 183495)
@@ -2103,6 +2103,7 @@
void compileMiscStrictEq(Node*);
void emitObjectOrOtherBranch(Edge value, BasicBlock* taken, BasicBlock* notTaken);
+ void emitStringBranch(Edge value, BasicBlock* taken, BasicBlock* notTaken);
void emitBranch(Node*);
struct StringSwitchCase {
Modified: trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT32_64.cpp (183494 => 183495)
--- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT32_64.cpp 2015-04-28 18:36:59 UTC (rev 183494)
+++ trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT32_64.cpp 2015-04-28 18:54:12 UTC (rev 183495)
@@ -1573,7 +1573,12 @@
emitObjectOrOtherBranch(node->child1(), taken, notTaken);
return;
}
-
+
+ case StringUse: {
+ emitStringBranch(node->child1(), taken, notTaken);
+ return;
+ }
+
case DoubleRepUse:
case Int32Use: {
if (node->child1().useKind() == Int32Use) {
Modified: trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT64.cpp (183494 => 183495)
--- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT64.cpp 2015-04-28 18:36:59 UTC (rev 183494)
+++ trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT64.cpp 2015-04-28 18:54:12 UTC (rev 183495)
@@ -1742,6 +1742,11 @@
return;
}
+ case StringUse: {
+ emitStringBranch(node->child1(), taken, notTaken);
+ return;
+ }
+
case UntypedUse:
case BooleanUse: {
JSValueOperand value(this, node->child1(), ManualOperandSpeculation);