Skip to content
Permalink
Browse files
Source/JavaScriptCore:
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):

LayoutTests:
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.

Canonical link: https://commits.webkit.org/162348@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@183495 268f45cc-cd09-0410-ab3c-d52691b4dbfc
  • Loading branch information
Andreas Kling committed Apr 28, 2015
1 parent c3910ab commit a4e019356bdd1f966372153612f8430dbf9ad071
@@ -1,3 +1,14 @@
2015-04-28 Andreas Kling <akling@apple.com>

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 <mmaxfield@apple.com>

Implement font-synthesis CSS property
@@ -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

@@ -0,0 +1,12 @@
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
<html>
<head>
<script src="../../resources/js-test-pre.js"></script>
</head>
<body>
<script src="../../resources/regress-pre.js"></script>
<script src="script-tests/branch-on-string-as-boolean.js"></script>
<script src="../../resources/regress-post.js"></script>
<script src="../../resources/js-test-post.js"></script>
</body>
</html>
@@ -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');
@@ -1,3 +1,28 @@
2015-04-28 Andreas Kling <akling@apple.com>

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 <fpizlo@apple.com>

VarargsForwardingPhase should only consider MovHints that have the candidate as a child
@@ -737,6 +737,8 @@ class FixupPhase : public Phase {
fixEdge<Int32Use>(node->child1());
else if (node->child1()->shouldSpeculateNumber())
fixEdge<DoubleRepUse>(node->child1());
else if (node->child1()->shouldSpeculateString())
fixEdge<StringUse>(node->child1());
break;
}

@@ -4040,6 +4040,15 @@ void SpeculativeJIT::compileStringZeroLength(Node* node)
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);
@@ -2103,6 +2103,7 @@ class SpeculativeJIT {
void compileMiscStrictEq(Node*);

void emitObjectOrOtherBranch(Edge value, BasicBlock* taken, BasicBlock* notTaken);
void emitStringBranch(Edge value, BasicBlock* taken, BasicBlock* notTaken);
void emitBranch(Node*);

struct StringSwitchCase {
@@ -1573,7 +1573,12 @@ void SpeculativeJIT::emitBranch(Node* node)
emitObjectOrOtherBranch(node->child1(), taken, notTaken);
return;
}


case StringUse: {
emitStringBranch(node->child1(), taken, notTaken);
return;
}

case DoubleRepUse:
case Int32Use: {
if (node->child1().useKind() == Int32Use) {
@@ -1742,6 +1742,11 @@ void SpeculativeJIT::emitBranch(Node* node)
return;
}

case StringUse: {
emitStringBranch(node->child1(), taken, notTaken);
return;
}

case UntypedUse:
case BooleanUse: {
JSValueOperand value(this, node->child1(), ManualOperandSpeculation);

0 comments on commit a4e0193

Please sign in to comment.