<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[185002] trunk</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/185002">185002</a></dd>
<dt>Author</dt> <dd>fpizlo@apple.com</dd>
<dt>Date</dt> <dd>2015-05-29 13:26:37 -0700 (Fri, 29 May 2015)</dd>
</dl>

<h3>Log Message</h3>
<pre>Non-speculative Branch should be fast in the FTL
https://bugs.webkit.org/show_bug.cgi?id=145452

Reviewed by Andreas Kling.
Source/JavaScriptCore:

        
Inlines the code for convertJSValueToBoolean into the FTL. This also includes some other
clean-ups that I found along the way.
        
I found this by looking at the hottest functions in DeltaBlue. Despite having so many
Branch specializations, apparently there was still a hot one that we missed that was going
down the untyped path. It was either Int32 or Other. Maybe we could specialize for that
combo, but it makes so much sense to just make all of this nonsense fast.

* dfg/DFGWatchpointCollectionPhase.cpp:
(JSC::DFG::WatchpointCollectionPhase::handle): Need to watch the masquerades watchpoint on UntypedUse: forms of Branch now.
* ftl/FTLLowerDFGToLLVM.cpp:
(JSC::FTL::LowerDFGToLLVM::boolify): The actual fix.
(JSC::FTL::LowerDFGToLLVM::int52ToStrictInt52):
(JSC::FTL::LowerDFGToLLVM::isInt32):
(JSC::FTL::LowerDFGToLLVM::isNotInt32):
(JSC::FTL::LowerDFGToLLVM::unboxInt32):
* runtime/JSCellInlines.h:
(JSC::JSCell::toBoolean): Symbol is always true.
(JSC::JSCell::pureToBoolean): Symbol is always true.
* runtime/JSString.cpp:
(JSC::JSString::getPrimitiveNumber):
(JSC::JSString::toNumber):
(JSC::JSString::toBoolean): Deleted. This is a tiny method. It doesn't need to be out-of-line.
* runtime/JSString.h:
(JSC::JSString::length):
(JSC::JSString::toBoolean): This method shouldbe inline.
* runtime/Symbol.cpp:
(JSC::Symbol::toPrimitive):
(JSC::Symbol::getPrimitiveNumber):
(JSC::Symbol::toBoolean): Deleted. A Symbol is always true, so we don't need a method for this.
* runtime/Symbol.h:

LayoutTests:


* js/regress/logical-not-weird-types-expected.txt: Added.
* js/regress/logical-not-weird-types.html: Added.
* js/regress/script-tests/logical-not-weird-types.js: Added.
(foo):</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsChangeLog">trunk/LayoutTests/ChangeLog</a></li>
<li><a href="#trunkSourceJavaScriptCoreChangeLog">trunk/Source/JavaScriptCore/ChangeLog</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGWatchpointCollectionPhasecpp">trunk/Source/JavaScriptCore/dfg/DFGWatchpointCollectionPhase.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreftlFTLLowerDFGToLLVMcpp">trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeJSCellInlinesh">trunk/Source/JavaScriptCore/runtime/JSCellInlines.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeJSStringcpp">trunk/Source/JavaScriptCore/runtime/JSString.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeJSStringh">trunk/Source/JavaScriptCore/runtime/JSString.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeSymbolcpp">trunk/Source/JavaScriptCore/runtime/Symbol.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeSymbolh">trunk/Source/JavaScriptCore/runtime/Symbol.h</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsjsregresslogicalnotweirdtypesexpectedtxt">trunk/LayoutTests/js/regress/logical-not-weird-types-expected.txt</a></li>
<li><a href="#trunkLayoutTestsjsregresslogicalnotweirdtypeshtml">trunk/LayoutTests/js/regress/logical-not-weird-types.html</a></li>
<li><a href="#trunkLayoutTestsjsregressscripttestslogicalnotweirdtypesjs">trunk/LayoutTests/js/regress/script-tests/logical-not-weird-types.js</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkLayoutTestsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/ChangeLog (185001 => 185002)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/ChangeLog        2015-05-29 20:13:09 UTC (rev 185001)
+++ trunk/LayoutTests/ChangeLog        2015-05-29 20:26:37 UTC (rev 185002)
</span><span class="lines">@@ -1,3 +1,15 @@
</span><ins>+2015-05-28  Filip Pizlo  &lt;fpizlo@apple.com&gt;
+
+        Non-speculative Branch should be fast in the FTL
+        https://bugs.webkit.org/show_bug.cgi?id=145452
+
+        Reviewed by Andreas Kling.
+
+        * js/regress/logical-not-weird-types-expected.txt: Added.
+        * js/regress/logical-not-weird-types.html: Added.
+        * js/regress/script-tests/logical-not-weird-types.js: Added.
+        (foo):
+
</ins><span class="cx"> 2015-05-29  Filip Pizlo  &lt;fpizlo@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Land some .html/-expected.txt files for some tests that were added without them.
</span></span></pre></div>
<a id="trunkLayoutTestsjsregresslogicalnotweirdtypesexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/js/regress/logical-not-weird-types-expected.txt (0 => 185002)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/js/regress/logical-not-weird-types-expected.txt                                (rev 0)
+++ trunk/LayoutTests/js/regress/logical-not-weird-types-expected.txt        2015-05-29 20:26:37 UTC (rev 185002)
</span><span class="lines">@@ -0,0 +1,10 @@
</span><ins>+JSRegress/logical-not-weird-types
+
+On success, you will see a series of &quot;PASS&quot; messages, followed by &quot;TEST COMPLETE&quot;.
+
+
+PASS no exception thrown
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
</ins></span></pre></div>
<a id="trunkLayoutTestsjsregresslogicalnotweirdtypeshtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/js/regress/logical-not-weird-types.html (0 => 185002)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/js/regress/logical-not-weird-types.html                                (rev 0)
+++ trunk/LayoutTests/js/regress/logical-not-weird-types.html        2015-05-29 20:26:37 UTC (rev 185002)
</span><span class="lines">@@ -0,0 +1,12 @@
</span><ins>+&lt;!DOCTYPE HTML PUBLIC &quot;-//IETF//DTD HTML//EN&quot;&gt;
+&lt;html&gt;
+&lt;head&gt;
+&lt;script src=&quot;../../resources/js-test-pre.js&quot;&gt;&lt;/script&gt;
+&lt;/head&gt;
+&lt;body&gt;
+&lt;script src=&quot;../../resources/regress-pre.js&quot;&gt;&lt;/script&gt;
+&lt;script src=&quot;script-tests/logical-not-weird-types.js&quot;&gt;&lt;/script&gt;
+&lt;script src=&quot;../../resources/regress-post.js&quot;&gt;&lt;/script&gt;
+&lt;script src=&quot;../../resources/js-test-post.js&quot;&gt;&lt;/script&gt;
+&lt;/body&gt;
+&lt;/html&gt;
</ins></span></pre></div>
<a id="trunkLayoutTestsjsregressscripttestslogicalnotweirdtypesjs"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/js/regress/script-tests/logical-not-weird-types.js (0 => 185002)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/js/regress/script-tests/logical-not-weird-types.js                                (rev 0)
+++ trunk/LayoutTests/js/regress/script-tests/logical-not-weird-types.js        2015-05-29 20:26:37 UTC (rev 185002)
</span><span class="lines">@@ -0,0 +1,32 @@
</span><ins>+function foo(value) {
+    return !!value;
+}
+
+noInline(foo);
+
+var tests = [
+    [0, false],
+    [1, true],
+    [0/0, false],
+    [0/-1, false],
+    [0.0, false],
+    [&quot;&quot;, false],
+    [&quot;f&quot;, true],
+    [&quot;hello&quot;, true],
+    [{}, true],
+    [[], true],
+    [null, false],
+    [void 0, false],
+    [false, false],
+    [true, true]
+];
+
+for (var i = 0; i &lt; 10000; ++i) {
+    for (var j = 0; j &lt; tests.length; ++j) {
+        var input = tests[j][0];
+        var expected = tests[j][1];
+        var result = foo(input);
+        if (result !== expected)
+            throw &quot;Error: bad result for &quot; + input + &quot;: &quot; + result;
+    }
+}
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ChangeLog (185001 => 185002)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ChangeLog        2015-05-29 20:13:09 UTC (rev 185001)
+++ trunk/Source/JavaScriptCore/ChangeLog        2015-05-29 20:26:37 UTC (rev 185002)
</span><span class="lines">@@ -1,3 +1,42 @@
</span><ins>+2015-05-28  Filip Pizlo  &lt;fpizlo@apple.com&gt;
+
+        Non-speculative Branch should be fast in the FTL
+        https://bugs.webkit.org/show_bug.cgi?id=145452
+
+        Reviewed by Andreas Kling.
+        
+        Inlines the code for convertJSValueToBoolean into the FTL. This also includes some other
+        clean-ups that I found along the way.
+        
+        I found this by looking at the hottest functions in DeltaBlue. Despite having so many
+        Branch specializations, apparently there was still a hot one that we missed that was going
+        down the untyped path. It was either Int32 or Other. Maybe we could specialize for that
+        combo, but it makes so much sense to just make all of this nonsense fast.
+
+        * dfg/DFGWatchpointCollectionPhase.cpp:
+        (JSC::DFG::WatchpointCollectionPhase::handle): Need to watch the masquerades watchpoint on UntypedUse: forms of Branch now.
+        * ftl/FTLLowerDFGToLLVM.cpp:
+        (JSC::FTL::LowerDFGToLLVM::boolify): The actual fix.
+        (JSC::FTL::LowerDFGToLLVM::int52ToStrictInt52):
+        (JSC::FTL::LowerDFGToLLVM::isInt32):
+        (JSC::FTL::LowerDFGToLLVM::isNotInt32):
+        (JSC::FTL::LowerDFGToLLVM::unboxInt32):
+        * runtime/JSCellInlines.h:
+        (JSC::JSCell::toBoolean): Symbol is always true.
+        (JSC::JSCell::pureToBoolean): Symbol is always true.
+        * runtime/JSString.cpp:
+        (JSC::JSString::getPrimitiveNumber):
+        (JSC::JSString::toNumber):
+        (JSC::JSString::toBoolean): Deleted. This is a tiny method. It doesn't need to be out-of-line.
+        * runtime/JSString.h:
+        (JSC::JSString::length):
+        (JSC::JSString::toBoolean): This method shouldbe inline.
+        * runtime/Symbol.cpp:
+        (JSC::Symbol::toPrimitive):
+        (JSC::Symbol::getPrimitiveNumber):
+        (JSC::Symbol::toBoolean): Deleted. A Symbol is always true, so we don't need a method for this.
+        * runtime/Symbol.h:
+
</ins><span class="cx"> 2015-05-29  Commit Queue  &lt;commit-queue@webkit.org&gt;
</span><span class="cx"> 
</span><span class="cx">         Unreviewed, rolling out r184860.
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGWatchpointCollectionPhasecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGWatchpointCollectionPhase.cpp (185001 => 185002)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGWatchpointCollectionPhase.cpp        2015-05-29 20:13:09 UTC (rev 185001)
+++ trunk/Source/JavaScriptCore/dfg/DFGWatchpointCollectionPhase.cpp        2015-05-29 20:26:37 UTC (rev 185002)
</span><span class="lines">@@ -87,8 +87,14 @@
</span><span class="cx">             
</span><span class="cx">         case LogicalNot:
</span><span class="cx">         case Branch:
</span><del>-            if (m_node-&gt;child1().useKind() == ObjectOrOtherUse)
</del><ins>+            switch (m_node-&gt;child1().useKind()) {
+            case ObjectOrOtherUse:
+            case UntypedUse:
</ins><span class="cx">                 handleMasqueradesAsUndefined();
</span><ins>+                break;
+            default:
+                break;
+            }
</ins><span class="cx">             break;
</span><span class="cx">             
</span><span class="cx">         case NewArray:
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreftlFTLLowerDFGToLLVMcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp (185001 => 185002)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp        2015-05-29 20:13:09 UTC (rev 185001)
+++ trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToLLVM.cpp        2015-05-29 20:26:37 UTC (rev 185002)
</span><span class="lines">@@ -6127,9 +6127,9 @@
</span><span class="cx">     {
</span><span class="cx">         switch (edge.useKind()) {
</span><span class="cx">         case BooleanUse:
</span><del>-            return lowBoolean(m_node-&gt;child1());
</del><ins>+            return lowBoolean(edge);
</ins><span class="cx">         case Int32Use:
</span><del>-            return m_out.notZero32(lowInt32(m_node-&gt;child1()));
</del><ins>+            return m_out.notZero32(lowInt32(edge));
</ins><span class="cx">         case DoubleRepUse:
</span><span class="cx">             return m_out.doubleNotEqual(lowDouble(edge), m_out.doubleZero);
</span><span class="cx">         case ObjectOrOtherUse:
</span><span class="lines">@@ -6138,32 +6138,108 @@
</span><span class="cx">                     edge, CellCaseSpeculatesObject, SpeculateNullOrUndefined,
</span><span class="cx">                     ManualOperandSpeculation));
</span><span class="cx">         case StringUse: {
</span><del>-            LValue stringValue = lowString(m_node-&gt;child1());
</del><ins>+            LValue stringValue = lowString(edge);
</ins><span class="cx">             LValue length = m_out.load32NonNegative(stringValue, m_heaps.JSString_length);
</span><span class="cx">             return m_out.notEqual(length, m_out.int32Zero);
</span><span class="cx">         }
</span><span class="cx">         case UntypedUse: {
</span><del>-            LValue value = lowJSValue(m_node-&gt;child1());
</del><ins>+            LValue value = lowJSValue(edge);
</ins><span class="cx">             
</span><del>-            LBasicBlock slowCase = FTL_NEW_BLOCK(m_out, (&quot;Boolify untyped slow case&quot;));
-            LBasicBlock fastCase = FTL_NEW_BLOCK(m_out, (&quot;Boolify untyped fast case&quot;));
</del><ins>+            // Implements the following control flow structure:
+            // if (value is cell) {
+            //     if (value is string)
+            //         result = !!value-&gt;length
+            //     else {
+            //         do evil things for masquerades-as-undefined
+            //         result = true
+            //     }
+            // } else if (value is int32) {
+            //     result = !!unboxInt32(value)
+            // } else if (value is number) {
+            //     result = !!unboxDouble(value)
+            // } else {
+            //     result = value == jsTrue
+            // }
+            
+            LBasicBlock cellCase = FTL_NEW_BLOCK(m_out, (&quot;Boolify untyped cell case&quot;));
+            LBasicBlock stringCase = FTL_NEW_BLOCK(m_out, (&quot;Boolify untyped string case&quot;));
+            LBasicBlock notStringCase = FTL_NEW_BLOCK(m_out, (&quot;Boolify untyped not string case&quot;));
+            LBasicBlock notCellCase = FTL_NEW_BLOCK(m_out, (&quot;Boolify untyped not cell case&quot;));
+            LBasicBlock int32Case = FTL_NEW_BLOCK(m_out, (&quot;Boolify untyped int32 case&quot;));
+            LBasicBlock notInt32Case = FTL_NEW_BLOCK(m_out, (&quot;Boolify untyped not int32 case&quot;));
+            LBasicBlock doubleCase = FTL_NEW_BLOCK(m_out, (&quot;Boolify untyped double case&quot;));
+            LBasicBlock notDoubleCase = FTL_NEW_BLOCK(m_out, (&quot;Boolify untyped not double case&quot;));
</ins><span class="cx">             LBasicBlock continuation = FTL_NEW_BLOCK(m_out, (&quot;Boolify untyped continuation&quot;));
</span><span class="cx">             
</span><ins>+            Vector&lt;ValueFromBlock&gt; results;
+            
+            m_out.branch(isCell(value, provenType(edge)), unsure(cellCase), unsure(notCellCase));
+            
+            LBasicBlock lastNext = m_out.appendTo(cellCase, stringCase);
</ins><span class="cx">             m_out.branch(
</span><del>-                isNotBoolean(value, provenType(m_node-&gt;child1())),
-                rarely(slowCase), usually(fastCase));
</del><ins>+                isString(value, provenType(edge) &amp; SpecCell),
+                unsure(stringCase), unsure(notStringCase));
</ins><span class="cx">             
</span><del>-            LBasicBlock lastNext = m_out.appendTo(fastCase, slowCase);
-            ValueFromBlock fastResult = m_out.anchor(unboxBoolean(value));
</del><ins>+            m_out.appendTo(stringCase, notStringCase);
+            LValue nonEmptyString = m_out.notZero32(
+                m_out.load32NonNegative(value, m_heaps.JSString_length));
+            results.append(m_out.anchor(nonEmptyString));
</ins><span class="cx">             m_out.jump(continuation);
</span><span class="cx">             
</span><del>-            m_out.appendTo(slowCase, continuation);
-            ValueFromBlock slowResult = m_out.anchor(m_out.notNull(vmCall(
-                m_out.operation(operationConvertJSValueToBoolean), m_callFrame, value)));
</del><ins>+            m_out.appendTo(notStringCase, notCellCase);
+            LValue isTruthyObject;
+            if (masqueradesAsUndefinedWatchpointIsStillValid())
+                isTruthyObject = m_out.booleanTrue;
+            else {
+                LBasicBlock masqueradesCase = FTL_NEW_BLOCK(m_out, (&quot;Boolify untyped masquerades case&quot;));
+                
+                results.append(m_out.anchor(m_out.booleanFalse));
+                
+                m_out.branch(
+                    m_out.testIsZero8(
+                        m_out.load8(value, m_heaps.JSCell_typeInfoFlags),
+                        m_out.constInt8(MasqueradesAsUndefined)),
+                    usually(continuation), rarely(masqueradesCase));
+                
+                m_out.appendTo(masqueradesCase);
+                
+                isTruthyObject = m_out.notEqual(
+                    m_out.constIntPtr(m_graph.globalObjectFor(m_node-&gt;origin.semantic)),
+                    m_out.loadPtr(loadStructure(value), m_heaps.Structure_globalObject));
+            }
+            results.append(m_out.anchor(isTruthyObject));
</ins><span class="cx">             m_out.jump(continuation);
</span><span class="cx">             
</span><ins>+            m_out.appendTo(notCellCase, int32Case);
+            m_out.branch(
+                isInt32(value, provenType(edge) &amp; ~SpecCell),
+                unsure(int32Case), unsure(notInt32Case));
+            
+            m_out.appendTo(int32Case, notInt32Case);
+            results.append(m_out.anchor(m_out.notZero32(unboxInt32(value))));
+            m_out.jump(continuation);
+            
+            m_out.appendTo(notInt32Case, doubleCase);
+            m_out.branch(
+                isNumber(value, provenType(edge) &amp; ~SpecCell),
+                unsure(doubleCase), unsure(notDoubleCase));
+            
+            m_out.appendTo(doubleCase, notDoubleCase);
+            // Note that doubleNotEqual() really means not-equal-and-ordered. It will return false
+            // if value is NaN.
+            LValue doubleIsTruthy = m_out.doubleNotEqual(
+                unboxDouble(value), m_out.constDouble(0));
+            results.append(m_out.anchor(doubleIsTruthy));
+            m_out.jump(continuation);
+            
+            m_out.appendTo(notDoubleCase, continuation);
+            LValue miscIsTruthy = m_out.equal(
+                value, m_out.constInt64(JSValue::encode(jsBoolean(true))));
+            results.append(m_out.anchor(miscIsTruthy));
+            m_out.jump(continuation);
+            
</ins><span class="cx">             m_out.appendTo(continuation, lastNext);
</span><del>-            return m_out.phi(m_out.boolean, fastResult, slowResult);
</del><ins>+            return m_out.phi(m_out.boolean, results);
</ins><span class="cx">         }
</span><span class="cx">         default:
</span><span class="cx">             DFG_CRASH(m_graph, m_node, &quot;Bad use kind&quot;);
</span><span class="lines">@@ -7168,8 +7244,16 @@
</span><span class="cx">         return m_out.aShr(value, m_out.constInt64(JSValue::int52ShiftAmount));
</span><span class="cx">     }
</span><span class="cx">     
</span><del>-    LValue isNotInt32(LValue jsValue)
</del><ins>+    LValue isInt32(LValue jsValue, SpeculatedType type = SpecFullTop)
</ins><span class="cx">     {
</span><ins>+        if (LValue proven = isProvenValue(type, SpecInt32))
+            return proven;
+        return m_out.aboveOrEqual(jsValue, m_tagTypeNumber);
+    }
+    LValue isNotInt32(LValue jsValue, SpeculatedType type = SpecFullTop)
+    {
+        if (LValue proven = isProvenValue(type, ~SpecInt32))
+            return proven;
</ins><span class="cx">         return m_out.below(jsValue, m_tagTypeNumber);
</span><span class="cx">     }
</span><span class="cx">     LValue unboxInt32(LValue jsValue)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeJSCellInlinesh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/JSCellInlines.h (185001 => 185002)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/JSCellInlines.h        2015-05-29 20:13:09 UTC (rev 185001)
+++ trunk/Source/JavaScriptCore/runtime/JSCellInlines.h        2015-05-29 20:26:37 UTC (rev 185002)
</span><span class="lines">@@ -250,8 +250,6 @@
</span><span class="cx"> {
</span><span class="cx">     if (isString())
</span><span class="cx">         return static_cast&lt;const JSString*&gt;(this)-&gt;toBoolean();
</span><del>-    if (isSymbol())
-        return static_cast&lt;const Symbol*&gt;(this)-&gt;toBoolean();
</del><span class="cx">     return !structure()-&gt;masqueradesAsUndefined(exec-&gt;lexicalGlobalObject());
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -260,7 +258,7 @@
</span><span class="cx">     if (isString())
</span><span class="cx">         return static_cast&lt;const JSString*&gt;(this)-&gt;toBoolean() ? TrueTriState : FalseTriState;
</span><span class="cx">     if (isSymbol())
</span><del>-        return static_cast&lt;const Symbol*&gt;(this)-&gt;toBoolean() ? TrueTriState : FalseTriState;
</del><ins>+        return TrueTriState;
</ins><span class="cx">     return MixedTriState;
</span><span class="cx"> }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeJSStringcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/JSString.cpp (185001 => 185002)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/JSString.cpp        2015-05-29 20:13:09 UTC (rev 185001)
+++ trunk/Source/JavaScriptCore/runtime/JSString.cpp        2015-05-29 20:26:37 UTC (rev 185002)
</span><span class="lines">@@ -389,11 +389,6 @@
</span><span class="cx">     return false;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-bool JSString::toBoolean() const
-{
-    return m_length;
-}
-
</del><span class="cx"> double JSString::toNumber(ExecState* exec) const
</span><span class="cx"> {
</span><span class="cx">     return jsToNumber(view(exec));
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeJSStringh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/JSString.h (185001 => 185002)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/JSString.h        2015-05-29 20:13:09 UTC (rev 185001)
+++ trunk/Source/JavaScriptCore/runtime/JSString.h        2015-05-29 20:26:37 UTC (rev 185002)
</span><span class="lines">@@ -150,7 +150,7 @@
</span><span class="cx">     unsigned length() const { return m_length; }
</span><span class="cx"> 
</span><span class="cx">     JSValue toPrimitive(ExecState*, PreferredPrimitiveType) const;
</span><del>-    JS_EXPORT_PRIVATE bool toBoolean() const;
</del><ins>+    bool toBoolean() const { return !!m_length; }
</ins><span class="cx">     bool getPrimitiveNumber(ExecState*, double&amp; number, JSValue&amp;) const;
</span><span class="cx">     JSObject* toObject(ExecState*, JSGlobalObject*) const;
</span><span class="cx">     double toNumber(ExecState*) const;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeSymbolcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/Symbol.cpp (185001 => 185002)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/Symbol.cpp        2015-05-29 20:13:09 UTC (rev 185001)
+++ trunk/Source/JavaScriptCore/runtime/Symbol.cpp        2015-05-29 20:26:37 UTC (rev 185002)
</span><span class="lines">@@ -65,11 +65,6 @@
</span><span class="cx">     return const_cast&lt;Symbol*&gt;(this);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-bool Symbol::toBoolean() const
-{
-    return true;
-}
-
</del><span class="cx"> bool Symbol::getPrimitiveNumber(ExecState* exec, double&amp; number, JSValue&amp; result) const
</span><span class="cx"> {
</span><span class="cx">     result = this;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeSymbolh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/Symbol.h (185001 => 185002)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/Symbol.h        2015-05-29 20:13:09 UTC (rev 185001)
+++ trunk/Source/JavaScriptCore/runtime/Symbol.h        2015-05-29 20:26:37 UTC (rev 185002)
</span><span class="lines">@@ -75,7 +75,6 @@
</span><span class="cx">     String descriptiveString() const;
</span><span class="cx"> 
</span><span class="cx">     JSValue toPrimitive(ExecState*, PreferredPrimitiveType) const;
</span><del>-    JS_EXPORT_PRIVATE bool toBoolean() const;
</del><span class="cx">     bool getPrimitiveNumber(ExecState*, double&amp; number, JSValue&amp;) const;
</span><span class="cx">     JSObject* toObject(ExecState*, JSGlobalObject*) const;
</span><span class="cx">     double toNumber(ExecState*) const;
</span></span></pre>
</div>
</div>

</body>
</html>