Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge r235790 - [DFG] DFG should handle String#toString
https://bugs.webkit.org/show_bug.cgi?id=189151 Reviewed by Saam Barati. JSTests: The error message in String#toString and String#valueOf is poor, which will be handled in a separate bug[1]. [1]: https://bugs.webkit.org/show_bug.cgi?id=189357 * microbenchmarks/string-object-to-string.js: Added. (test): * microbenchmarks/string-object-value-of.js: Added. (test): * stress/string-to-string-error.js: Added. (shouldThrow): (test): * stress/string-to-string.js: Added. (shouldBe): (test1): (test2): (test3): * stress/string-value-of-error.js: Added. (shouldThrow): (test): * stress/string-value-of.js: Added. (shouldBe): (test1): (test2): (test3): Source/JavaScriptCore: We handle String#toString and String#valueOf in DFG by introducing StringValueOf node. In the fixup phase, we attempt to lower StringValueOf to the existing ToString or Identity nodes. If we fail to lower it, we have StringValueOf(UntypedUse), which may raise an error if an argument is neither String nor StringObject. The error message in String#toString and String#valueOf is poor, which will be handled in a separate bug[1]. It improves simple microbenchmarks by 53.4 - 67.6%. baseline patched string-object-to-string 21.7308+-3.3147 ^ 12.9655+-0.0527 ^ definitely 1.6760x faster string-object-value-of 20.1122+-0.0691 ^ 13.1134+-0.2482 ^ definitely 1.5337x faster [1]: https://bugs.webkit.org/show_bug.cgi?id=189357 * dfg/DFGAbstractInterpreterInlines.h: (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects): * dfg/DFGByteCodeParser.cpp: (JSC::DFG::ByteCodeParser::handleIntrinsicCall): * dfg/DFGClobberize.h: (JSC::DFG::clobberize): * dfg/DFGDoesGC.cpp: (JSC::DFG::doesGC): * dfg/DFGFixupPhase.cpp: (JSC::DFG::FixupPhase::fixupNode): (JSC::DFG::FixupPhase::fixupStringValueOf): * dfg/DFGNode.h: (JSC::DFG::Node::convertToToString): * dfg/DFGNodeType.h: * dfg/DFGOperations.cpp: * dfg/DFGOperations.h: * dfg/DFGPredictionPropagationPhase.cpp: * dfg/DFGSafeToExecute.h: (JSC::DFG::safeToExecute): * dfg/DFGSpeculativeJIT.cpp: (JSC::DFG::SpeculativeJIT::compileToStringOrCallStringConstructorOrStringValueOf): (JSC::DFG::SpeculativeJIT::compileToStringOrCallStringConstructor): Deleted. * dfg/DFGSpeculativeJIT.h: * dfg/DFGSpeculativeJIT32_64.cpp: (JSC::DFG::SpeculativeJIT::compile): * dfg/DFGSpeculativeJIT64.cpp: (JSC::DFG::SpeculativeJIT::compile): * ftl/FTLCapabilities.cpp: (JSC::FTL::canCompile): * ftl/FTLLowerDFGToB3.cpp: (JSC::FTL::DFG::LowerDFGToB3::compileNode): (JSC::FTL::DFG::LowerDFGToB3::compileToStringOrCallStringConstructorOrStringValueOf): (JSC::FTL::DFG::LowerDFGToB3::compileToStringOrCallStringConstructor): Deleted.
- Loading branch information
1 parent
b146f75
commit 245bd18
Showing
27 changed files
with
397 additions
and
32 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
const chars = 'abcdefghijklmnopqrstuvwxyz'; | ||
var prim = ''; | ||
for (var i = 0; i < 32768; i++) { | ||
prim += chars.charAt(~~(Math.random() * 26)); | ||
} | ||
const obj = new String(prim); | ||
|
||
function test(obj) | ||
{ | ||
return obj.toString(); | ||
} | ||
noInline(test); | ||
|
||
for (var i = 0; i < 1e6; ++i) | ||
test(obj); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
const chars = 'abcdefghijklmnopqrstuvwxyz'; | ||
var prim = ''; | ||
for (var i = 0; i < 32768; i++) { | ||
prim += chars.charAt(~~(Math.random() * 26)); | ||
} | ||
const obj = new String(prim); | ||
|
||
function test(obj) | ||
{ | ||
return obj.valueOf(); | ||
} | ||
noInline(test); | ||
|
||
for (var i = 0; i < 1e6; ++i) | ||
test(obj); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
function shouldBe(actual, expected) { | ||
if (actual !== expected) | ||
throw new Error('bad value: ' + actual); | ||
} | ||
|
||
function shouldThrow(func, errorMessage) { | ||
var errorThrown = false; | ||
var error = null; | ||
try { | ||
func(); | ||
} catch (e) { | ||
errorThrown = true; | ||
error = e; | ||
} | ||
if (!errorThrown) | ||
throw new Error('not thrown'); | ||
if (String(error) !== errorMessage) | ||
throw new Error(`bad error: ${String(error)}`); | ||
} | ||
|
||
var toString = String.prototype.toString; | ||
function test(string) | ||
{ | ||
return toString.call(string); | ||
} | ||
noInline(test); | ||
|
||
var object = {}; | ||
var symbol = Symbol("Cocoa"); | ||
for (var i = 0; i < 3e3; ++i) { | ||
shouldThrow(() => test(object), `TypeError: Type error`); | ||
shouldThrow(() => test(false), `TypeError: Type error`); | ||
shouldThrow(() => test(true), `TypeError: Type error`); | ||
shouldThrow(() => test(42), `TypeError: Type error`); | ||
shouldThrow(() => test(null), `TypeError: Type error`); | ||
shouldThrow(() => test(undefined), `TypeError: Type error`); | ||
shouldThrow(() => test(symbol), `TypeError: Type error`); | ||
} | ||
|
||
var string = "Hello"; | ||
var stringObject = new String(string); | ||
for (var i = 0; i < 1e2; ++i) { | ||
shouldBe(test(string), string); | ||
shouldBe(test(stringObject), string); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
function shouldBe(actual, expected) { | ||
if (actual !== expected) | ||
throw new Error('bad value: ' + actual); | ||
} | ||
|
||
function test1(string) | ||
{ | ||
return string.toString(); | ||
} | ||
noInline(test1); | ||
|
||
function test2(string) | ||
{ | ||
return string.toString(); | ||
} | ||
noInline(test2); | ||
|
||
function test3(string) | ||
{ | ||
return string.toString(); | ||
} | ||
noInline(test3); | ||
|
||
var string = "Hello"; | ||
var stringObject = new String(string); | ||
|
||
for (var i = 0; i < 1e6; ++i) { | ||
shouldBe(test1(string), string); | ||
shouldBe(test2(stringObject), string); | ||
if (i & 1) | ||
shouldBe(test3(string), string); | ||
else | ||
shouldBe(test3(stringObject), string); | ||
} | ||
|
||
shouldBe(test1({}), `[object Object]`); | ||
shouldBe(test2({}), `[object Object]`); | ||
shouldBe(test3({}), `[object Object]`); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
function shouldBe(actual, expected) { | ||
if (actual !== expected) | ||
throw new Error('bad value: ' + actual); | ||
} | ||
|
||
function shouldThrow(func, errorMessage) { | ||
var errorThrown = false; | ||
var error = null; | ||
try { | ||
func(); | ||
} catch (e) { | ||
errorThrown = true; | ||
error = e; | ||
} | ||
if (!errorThrown) | ||
throw new Error('not thrown'); | ||
if (String(error) !== errorMessage) | ||
throw new Error(`bad error: ${String(error)}`); | ||
} | ||
|
||
var valueOf = String.prototype.valueOf; | ||
function test(string) | ||
{ | ||
return valueOf.call(string); | ||
} | ||
noInline(test); | ||
|
||
var object = {}; | ||
var symbol = Symbol("Cocoa"); | ||
for (var i = 0; i < 3e3; ++i) { | ||
shouldThrow(() => test(object), `TypeError: Type error`); | ||
shouldThrow(() => test(false), `TypeError: Type error`); | ||
shouldThrow(() => test(true), `TypeError: Type error`); | ||
shouldThrow(() => test(42), `TypeError: Type error`); | ||
shouldThrow(() => test(null), `TypeError: Type error`); | ||
shouldThrow(() => test(undefined), `TypeError: Type error`); | ||
shouldThrow(() => test(symbol), `TypeError: Type error`); | ||
} | ||
|
||
var string = "Hello"; | ||
var stringObject = new String(string); | ||
for (var i = 0; i < 1e2; ++i) { | ||
shouldBe(test(string), string); | ||
shouldBe(test(stringObject), string); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
function shouldBe(actual, expected) { | ||
if (actual !== expected) | ||
throw new Error('bad value: ' + actual); | ||
} | ||
|
||
function test1(string) | ||
{ | ||
return string.valueOf(); | ||
} | ||
noInline(test1); | ||
|
||
function test2(string) | ||
{ | ||
return string.valueOf(); | ||
} | ||
noInline(test2); | ||
|
||
function test3(string) | ||
{ | ||
return string.valueOf(); | ||
} | ||
noInline(test3); | ||
|
||
var string = "Hello"; | ||
var stringObject = new String(string); | ||
|
||
for (var i = 0; i < 1e6; ++i) { | ||
shouldBe(test1(string), string); | ||
shouldBe(test2(stringObject), string); | ||
if (i & 1) | ||
shouldBe(test3(string), string); | ||
else | ||
shouldBe(test3(stringObject), string); | ||
} | ||
|
||
var object = {}; | ||
shouldBe(test1(object), object); | ||
shouldBe(test2(object), object); | ||
shouldBe(test3(object), object); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.