Permalink
Show file tree
Hide file tree
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
[JSC] Optimize String#substring
https://bugs.webkit.org/show_bug.cgi?id=244754 <rdar://99770218> Reviewed by Mark Lam. This patch optimizes String#substring. 1. We avoid allocating the whole string when just comparing with substring. (JSString::equalSlowCase change). We get StringView with unsafeView, and use ensureStillAliveHere to keep both string cells alive. 2. We optimize JSString::equalSlowCase's equal function using StringView. 3. Optimize String#substring runtime function with int32 input fast path. 4. Add DFG StringSubstring node to handle String#substring efficiently in DFG / FTL. We also add StrengthReduction rule for String#substring so that we can constant-fold the result if arguments are the constants. We observed improvements in microbenchmarks. ToT Patched string-substring-constants 30.9691+-0.7392 ^ 6.9364+-0.1119 ^ definitely 4.4647x faster string-substring-constants-binary 29.5540+-0.0829 ^ 12.0035+-0.2692 ^ definitely 2.4621x faster string-starts-with-mod-prototype 69.7019+-0.6867 ^ 56.8859+-0.4956 ^ definitely 1.2253x faster string-substring 30.9168+-0.2336 ^ 18.9088+-0.1950 ^ definitely 1.6350x faster string-substring-length-constant 30.6379+-0.2457 ^ 6.9260+-0.1237 ^ definitely 4.4236x faster string-substring-constants-identity 9.5178+-0.1149 ^ 2.9170+-0.0326 ^ definitely 3.2629x faster string-starts-with 2.9473+-0.0220 2.9296+-0.0749 string-starts-with-mod 31.1585+-0.1608 ^ 12.9144+-0.0646 ^ definitely 2.4127x faster * JSTests/microbenchmarks/string-starts-with-mod-prototype.js: Added. (shouldBe): (String.prototype._startsWith): (test1): (test2): * JSTests/microbenchmarks/string-starts-with-mod.js: Added. (shouldBe): (_startsWith): (test1): (test2): * JSTests/microbenchmarks/string-starts-with.js: Added. (shouldBe): (test1): (test2): * JSTests/microbenchmarks/string-substring-constants-binary.js: Added. (shouldBe): (test1): * JSTests/microbenchmarks/string-substring-constants-identity.js: Added. (shouldBe): (test1): * JSTests/microbenchmarks/string-substring-constants.js: Added. (shouldBe): (test1): * JSTests/microbenchmarks/string-substring-length-constant.js: Added. (shouldBe): (test1): * JSTests/microbenchmarks/string-substring.js: Added. (shouldBe): (test1): * Source/JavaScriptCore/builtins/BuiltinNames.h: * Source/JavaScriptCore/builtins/RegExpPrototype.js: (linkTimeConstant.getSubstitution): (overriddenName.string_appeared_here.replace): (overriddenName.string_appeared_here.split): * Source/JavaScriptCore/builtins/StringPrototype.js: (linkTimeConstant.repeatCharactersSlowPath): * Source/JavaScriptCore/bytecode/LinkTimeConstant.h: * Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h: (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects): * Source/JavaScriptCore/dfg/DFGBackwardsPropagationPhase.cpp: (JSC::DFG::BackwardsPropagationPhase::propagate): * Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp: (JSC::DFG::ByteCodeParser::handleIntrinsicCall): * Source/JavaScriptCore/dfg/DFGClobberize.h: (JSC::DFG::clobberize): * Source/JavaScriptCore/dfg/DFGDoesGC.cpp: (JSC::DFG::doesGC): * Source/JavaScriptCore/dfg/DFGFixupPhase.cpp: (JSC::DFG::FixupPhase::fixupNode): * Source/JavaScriptCore/dfg/DFGNodeType.h: * Source/JavaScriptCore/dfg/DFGOperations.cpp: (JSC::DFG::JSC_DEFINE_JIT_OPERATION): * Source/JavaScriptCore/dfg/DFGOperations.h: * Source/JavaScriptCore/dfg/DFGPredictionPropagationPhase.cpp: * Source/JavaScriptCore/dfg/DFGSafeToExecute.h: (JSC::DFG::safeToExecute): * Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp: (JSC::DFG::SpeculativeJIT::compileStringSubstring): * Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h: * Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp: (JSC::DFG::SpeculativeJIT::compile): * Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp: (JSC::DFG::SpeculativeJIT::compile): * Source/JavaScriptCore/dfg/DFGStrengthReductionPhase.cpp: (JSC::DFG::StrengthReductionPhase::handleNode): * Source/JavaScriptCore/ftl/FTLCapabilities.cpp: (JSC::FTL::canCompile): * Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp: (JSC::FTL::DFG::LowerDFGToB3::compileNode): (JSC::FTL::DFG::LowerDFGToB3::compileCompareStrictEq): * Source/JavaScriptCore/runtime/Intrinsic.cpp: (JSC::intrinsicName): * Source/JavaScriptCore/runtime/Intrinsic.h: * Source/JavaScriptCore/runtime/JSGlobalObject.cpp: (JSC::JSGlobalObject::init): * Source/JavaScriptCore/runtime/JSGlobalObject.h: * Source/JavaScriptCore/runtime/JSGlobalObjectInlines.h: (JSC::JSGlobalObject::stringProtoSubstringFunction const): * Source/JavaScriptCore/runtime/JSString.cpp: (JSC::JSString::equalSlowCase const): * Source/JavaScriptCore/runtime/StringPrototype.cpp: (JSC::StringPrototype::finishCreation): (JSC::JSC_DEFINE_HOST_FUNCTION): (JSC::stringSubstringImpl): Deleted. * Source/JavaScriptCore/runtime/StringPrototype.h: * Source/JavaScriptCore/runtime/StringPrototypeInlines.h: (JSC::extractSubstringOffsets): (JSC::stringSubstring): * Source/WTF/wtf/text/StringCommon.h: (WTF::equalCommon): * Source/WTF/wtf/text/StringView.h: (WTF::equal): Canonical link: https://commits.webkit.org/255030@main
- Loading branch information
1 parent
2b695e1
commit 3de7e6fba239b0a69f618faa82c7cd642c57726b
Showing
41 changed files
with
371 additions
and
52 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
function shouldBe(actual, expected) { | ||
if (actual !== expected) | ||
throw new Error('bad value: ' + actual); | ||
} | ||
|
||
String.prototype._startsWith = function (find) { | ||
return this.substring(0,find.length) === find | ||
} | ||
|
||
function test1() { | ||
return "/assets/omfg"._startsWith('/assets/'); | ||
} | ||
noInline(test1); | ||
|
||
function test2(string) { | ||
return "/assets/omfg"._startsWith(string); | ||
} | ||
noInline(test2); | ||
|
||
var count = 0; | ||
for (var i = 0; i < 5e5; ++i) { | ||
if (test1()) | ||
++count; | ||
if (test2('/assets/')) | ||
++count; | ||
} | ||
shouldBe(count, 1e6); |
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,27 @@ | ||
function shouldBe(actual, expected) { | ||
if (actual !== expected) | ||
throw new Error('bad value: ' + actual); | ||
} | ||
|
||
function _startsWith(str, find) { | ||
return str.substring(0,find.length) === find | ||
} | ||
|
||
function test1() { | ||
return _startsWith("/assets/omfg", '/assets/'); | ||
} | ||
noInline(test1); | ||
|
||
function test2(string) { | ||
return _startsWith("/assets/omfg", string); | ||
} | ||
noInline(test2); | ||
|
||
var count = 0; | ||
for (var i = 0; i < 5e5; ++i) { | ||
if (test1()) | ||
++count; | ||
if (test2('/assets/')) | ||
++count; | ||
} | ||
shouldBe(count, 1e6); |
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,23 @@ | ||
function shouldBe(actual, expected) { | ||
if (actual !== expected) | ||
throw new Error('bad value: ' + actual); | ||
} | ||
|
||
function test1() { | ||
return "/assets/omfg".startsWith('/assets/'); | ||
} | ||
noInline(test1); | ||
|
||
function test2(string) { | ||
return "/assets/omfg".startsWith(string); | ||
} | ||
noInline(test2); | ||
|
||
var count = 0; | ||
for (var i = 0; i < 1e5; ++i) { | ||
if (test1()) | ||
++count; | ||
if (test2('/assets/')) | ||
++count; | ||
} | ||
shouldBe(count, 2e5); |
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,16 @@ | ||
function shouldBe(actual, expected) { | ||
if (actual !== expected) | ||
throw new Error('bad value: ' + actual); | ||
} | ||
|
||
function test1() { | ||
return "/assets/omfg".substring(1) === 'assets/omfg'; | ||
} | ||
noInline(test1); | ||
|
||
var count = 0; | ||
for (var i = 0; i < 1e6; ++i) { | ||
if (test1()) | ||
++count; | ||
} | ||
shouldBe(count, 1e6); |
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,16 @@ | ||
function shouldBe(actual, expected) { | ||
if (actual !== expected) | ||
throw new Error('bad value: ' + actual); | ||
} | ||
|
||
function test1() { | ||
return "/assets/omfg".substring(0) === '/assets/'; | ||
} | ||
noInline(test1); | ||
|
||
var count = 0; | ||
for (var i = 0; i < 1e6; ++i) { | ||
if (!test1()) | ||
++count; | ||
} | ||
shouldBe(count, 1e6); |
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,16 @@ | ||
function shouldBe(actual, expected) { | ||
if (actual !== expected) | ||
throw new Error('bad value: ' + actual); | ||
} | ||
|
||
function test1() { | ||
return "/assets/omfg".substring(0,8) === '/assets/'; | ||
} | ||
noInline(test1); | ||
|
||
var count = 0; | ||
for (var i = 0; i < 1e6; ++i) { | ||
if (test1()) | ||
++count; | ||
} | ||
shouldBe(count, 1e6); |
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,16 @@ | ||
function shouldBe(actual, expected) { | ||
if (actual !== expected) | ||
throw new Error('bad value: ' + actual); | ||
} | ||
|
||
function test1() { | ||
return "/assets/omfg".substring(0,'/assets/'.length) === '/assets/'; | ||
} | ||
noInline(test1); | ||
|
||
var count = 0; | ||
for (var i = 0; i < 1e6; ++i) { | ||
if (test1()) | ||
++count; | ||
} | ||
shouldBe(count, 1e6); |
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,16 @@ | ||
function shouldBe(actual, expected) { | ||
if (actual !== expected) | ||
throw new Error('bad value: ' + actual); | ||
} | ||
|
||
function test1(start, end) { | ||
return "/assets/omfg".substring(start, end) === '/assets/'; | ||
} | ||
noInline(test1); | ||
|
||
var count = 0; | ||
for (var i = 0; i < 1e6; ++i) { | ||
if (test1(0, 8)) | ||
++count; | ||
} | ||
shouldBe(count, 1e6); |
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
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.