WebKit Bugzilla
New
Browse
Search+
Log In
×
Sign in with GitHub
or
Remember my login
Create Account
·
Forgot Password
Forgotten password account recovery
NEW
135593
Using +s to convert a string to a number badly confuses the DFG
https://bugs.webkit.org/show_bug.cgi?id=135593
Summary
Using +s to convert a string to a number badly confuses the DFG
Mark Hahnenberg
Reported
2014-08-04 21:27:40 PDT
I was writing a toy Huffman encoder/decoder in JS, and I was comparing the performance of JSC to nodejs. I ran the benchmark by hooking it into the octane harness. nodejs crushes JSC on this particular benchmark (by like 10x). I was curious and ran the profiler, and I noticed a very simple function was exiting a ton. Here's the source of the function: function (i) { return +i; } I'll attach the profiler output separately.
Attachments
profiler output
(37.60 KB, text/plain)
2014-08-04 21:29 PDT
,
Mark Hahnenberg
no flags
Details
graph dump
(129.85 KB, text/plain)
2014-08-04 21:29 PDT
,
Mark Hahnenberg
no flags
Details
huffman benchmark
(11.95 KB, application/javascript)
2014-08-04 21:30 PDT
,
Mark Hahnenberg
no flags
Details
huffman benchmark
(8.67 KB, application/javascript)
2014-08-04 21:33 PDT
,
Mark Hahnenberg
no flags
Details
Patch
(11.04 KB, patch)
2014-08-05 15:27 PDT
,
Mark Hahnenberg
no flags
Details
Formatted Diff
Diff
Patch
(14.77 KB, patch)
2014-08-06 14:15 PDT
,
Mark Hahnenberg
no flags
Details
Formatted Diff
Diff
Patch
(14.90 KB, patch)
2014-08-08 14:20 PDT
,
Mark Hahnenberg
fpizlo
: review+
Details
Formatted Diff
Diff
Show Obsolete
(3)
View All
Add attachment
proposed patch, testcase, etc.
Mark Hahnenberg
Comment 1
2014-08-04 21:29:08 PDT
Created
attachment 236001
[details]
profiler output
Mark Hahnenberg
Comment 2
2014-08-04 21:29:39 PDT
Created
attachment 236002
[details]
graph dump
Mark Hahnenberg
Comment 3
2014-08-04 21:30:24 PDT
Created
attachment 236003
[details]
huffman benchmark
Mark Hahnenberg
Comment 4
2014-08-04 21:33:10 PDT
Created
attachment 236004
[details]
huffman benchmark
Mark Hahnenberg
Comment 5
2014-08-04 21:38:50 PDT
It looks like during the prediction injection phase we notice that the argument is a StringIdent, but the Phantom continues to assume that it's a number which causes us to exit constantly.
Mark Hahnenberg
Comment 6
2014-08-05 15:27:36 PDT
Created
attachment 236052
[details]
Patch
Filip Pizlo
Comment 7
2014-08-05 15:41:04 PDT
Comment on
attachment 236052
[details]
Patch View in context:
https://bugs.webkit.org/attachment.cgi?id=236052&action=review
Almost there
> Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h:309 > + case ValueToNumber: {
Can we call it ToNumber?
> Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h:318 > + if (child && child.isInt32()) { > + setConstant(node, child); > + break; > + } > + if (child && child.isNumber()) { > + setConstant(node, jsDoubleNumber(child.asNumber())); > + break; > + }
I feel like this should just be: if (child && child.isNumber()) { setConstant(node, child); break; }
> Source/JavaScriptCore/dfg/DFGBackwardsPropagationPhase.cpp:362 > + node->child1()->mergeFlags(flags);
I would mask off NodeBytecodeUsesAsOther, as in: node->child1()->mergeFlags(flags & ~NodeNytecodeUsesAsOther)
> Source/JavaScriptCore/dfg/DFGClobberize.h:351 > + read(MiscFields);
It reads world.
> Source/JavaScriptCore/dfg/DFGFixupPhase.cpp:1153 > + case ValueToNumber:
This needs to have the identity stuff. And probably some stuff to use BooleanToNumber.
> Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp:479 > + changed |= setPrediction(SpecFullNumber);
This needs to be more granular. If the input is already an int or already a number then you should preserve the original input's type. Literally you want something like: if (node->child1()->prediction() & SpecCell) changed |= setPrediction(SpecFullNumber); else { SpeculatedType type = node->child1()->prediction(); if (type & SpecOther) { type &= ~SpecOther; type |= SpecInt32 | SpecDoubleNaN; } if (type & SpecBoolean) { type &= ~SpecBoolean; type |= SpecInt32; } mergePredicstion(type); }
Mark Hahnenberg
Comment 8
2014-08-06 14:15:25 PDT
Created
attachment 236135
[details]
Patch
Mark Hahnenberg
Comment 9
2014-08-08 14:20:08 PDT
Created
attachment 236304
[details]
Patch
Filip Pizlo
Comment 10
2014-08-21 15:20:08 PDT
Comment on
attachment 236304
[details]
Patch View in context:
https://bugs.webkit.org/attachment.cgi?id=236304&action=review
R=me. It would be slightly better if this also included the FTL implementation of ToNumber. Also, a test would be cool. I'm fine with the FTL implementation being a separate patch. As a test, maybe you could just land your huffman thing, if you haven't already? Even better, land both huffman, and a microbenchmark for +s.
> Source/JavaScriptCore/dfg/DFGFixupPhase.cpp:1283 > + void fixupToNumber(Node* node) > + { > + if (node->child1()->shouldSpeculateInt32()) { > + fixIntOrBooleanEdge(node->child1()); > + node->convertToIdentity(); > + return; > + } > + > + if (node->child1()->shouldSpeculateMachineInt()) { > + fixEdge<Int52RepUse>(node->child1()); > + node->convertToIdentity(); > + node->setResult(NodeResultInt52); > + return; > + } > + > + if (node->child1()->shouldSpeculateNumber()) { > + fixDoubleOrBooleanEdge(node->child1()); > + node->convertToIdentity(); > + node->setResult(NodeResultDouble); > + return; > + } > + } > +
You only call this in one place so you might as well inline it. :-) fixupToPrimitive() had a method because we would call it in more than one place. Hopefully that's still the case, or else someone should probably inline it.
Note
You need to
log in
before you can comment on or make changes to this bug.
Top of Page
Format For Printing
XML
Clone This Bug