From 0e0510aef52b88017310c71e069b25396ea252f5 Mon Sep 17 00:00:00 2001 From: "utatane.tea@gmail.com" Date: Sat, 14 Jan 2017 16:19:33 +0000 Subject: [PATCH] Reserve capacity for StringBuilder in unescape https://bugs.webkit.org/show_bug.cgi?id=167008 Reviewed by Sam Weinig. JSTests: * stress/unescape.js: Added. (shouldBe): Source/JavaScriptCore: `unescape` function is frequently called in Kraken sha256-iterative. This patch just reserves the capacity for the StringBuilder. Currently, we select the length of the string for the reserved capacity. It improves the performance 2.73%. Benchmark report for Kraken on sakura-trick. VMs tested: "baseline" at /home/yusukesuzuki/dev/WebKit/WebKitBuild/untot/Release/bin/jsc "patched" at /home/yusukesuzuki/dev/WebKit/WebKitBuild/un/Release/bin/jsc Collected 100 samples per benchmark/VM, with 100 VM invocations per benchmark. Emitted a call to gc() between sample measurements. Used 1 benchmark iteration per VM invocation for warm-up. Used the jsc-specific preciseTime() function to get microsecond-level timing. Reporting benchmark execution times with 95% confidence intervals in milliseconds. baseline patched stanford-crypto-sha256-iterative 51.609+-0.672 50.237+-0.860 might be 1.0273x faster 51.609+-0.672 50.237+-0.860 might be 1.0273x faster * runtime/JSGlobalObjectFunctions.cpp: (JSC::globalFuncUnescape): git-svn-id: https://svn.webkit.org/repository/webkit/trunk@210766 268f45cc-cd09-0410-ab3c-d52691b4dbfc --- JSTests/ChangeLog | 10 +++++++ JSTests/stress/unescape.js | 7 +++++ Source/JavaScriptCore/ChangeLog | 33 ++++++++++++++++++++++ .../runtime/JSGlobalObjectFunctions.cpp | 20 +++++++------ 4 files changed, 62 insertions(+), 8 deletions(-) create mode 100644 JSTests/stress/unescape.js diff --git a/JSTests/ChangeLog b/JSTests/ChangeLog index c2c3743..c0e6c46 100644 --- a/JSTests/ChangeLog +++ b/JSTests/ChangeLog @@ -1,3 +1,13 @@ +2017-01-14 Yusuke Suzuki + + Reserve capacity for StringBuilder in unescape + https://bugs.webkit.org/show_bug.cgi?id=167008 + + Reviewed by Sam Weinig. + + * stress/unescape.js: Added. + (shouldBe): + 2017-01-12 Saam Barati Add a slice intrinsic to the DFG/FTL diff --git a/JSTests/stress/unescape.js b/JSTests/stress/unescape.js new file mode 100644 index 0000000..f8c1524 --- /dev/null +++ b/JSTests/stress/unescape.js @@ -0,0 +1,7 @@ +function shouldBe(actual, expected) { + if (actual !== expected) + throw new Error('bad value: ' + actual); +} + +shouldBe(unescape("%0"), "%0"); +shouldBe(unescape("%a"), "%a"); diff --git a/Source/JavaScriptCore/ChangeLog b/Source/JavaScriptCore/ChangeLog index a07ac08..552f736 100644 --- a/Source/JavaScriptCore/ChangeLog +++ b/Source/JavaScriptCore/ChangeLog @@ -1,3 +1,36 @@ +2017-01-14 Yusuke Suzuki + + Reserve capacity for StringBuilder in unescape + https://bugs.webkit.org/show_bug.cgi?id=167008 + + Reviewed by Sam Weinig. + + `unescape` function is frequently called in Kraken sha256-iterative. + This patch just reserves the capacity for the StringBuilder. + + Currently, we select the length of the string for the reserved capacity. + It improves the performance 2.73%. + + Benchmark report for Kraken on sakura-trick. + + VMs tested: + "baseline" at /home/yusukesuzuki/dev/WebKit/WebKitBuild/untot/Release/bin/jsc + "patched" at /home/yusukesuzuki/dev/WebKit/WebKitBuild/un/Release/bin/jsc + + Collected 100 samples per benchmark/VM, with 100 VM invocations per benchmark. Emitted a call to gc() between + sample measurements. Used 1 benchmark iteration per VM invocation for warm-up. Used the jsc-specific preciseTime() + function to get microsecond-level timing. Reporting benchmark execution times with 95% confidence intervals in + milliseconds. + + baseline patched + + stanford-crypto-sha256-iterative 51.609+-0.672 50.237+-0.860 might be 1.0273x faster + + 51.609+-0.672 50.237+-0.860 might be 1.0273x faster + + * runtime/JSGlobalObjectFunctions.cpp: + (JSC::globalFuncUnescape): + 2017-01-13 Joseph Pecoraro Remove ENABLE(DETAILS_ELEMENT) guards diff --git a/Source/JavaScriptCore/runtime/JSGlobalObjectFunctions.cpp b/Source/JavaScriptCore/runtime/JSGlobalObjectFunctions.cpp index 47e6ccd..d5e6f29 100644 --- a/Source/JavaScriptCore/runtime/JSGlobalObjectFunctions.cpp +++ b/Source/JavaScriptCore/runtime/JSGlobalObjectFunctions.cpp @@ -814,22 +814,26 @@ EncodedJSValue JSC_HOST_CALL globalFuncEscape(ExecState* exec) EncodedJSValue JSC_HOST_CALL globalFuncUnescape(ExecState* exec) { return JSValue::encode(toStringView(exec, exec->argument(0), [&] (StringView view) { - StringBuilder builder; + // We use int for k and length intentionally since we would like to evaluate + // the condition `k <= length -6` even if length is less than 6. int k = 0; - int len = view.length(); + int length = view.length(); + + StringBuilder builder; + builder.reserveCapacity(length); if (view.is8Bit()) { const LChar* characters = view.characters8(); LChar convertedLChar; - while (k < len) { + while (k < length) { const LChar* c = characters + k; - if (c[0] == '%' && k <= len - 6 && c[1] == 'u') { + if (c[0] == '%' && k <= length - 6 && c[1] == 'u') { if (isASCIIHexDigit(c[2]) && isASCIIHexDigit(c[3]) && isASCIIHexDigit(c[4]) && isASCIIHexDigit(c[5])) { builder.append(Lexer::convertUnicode(c[2], c[3], c[4], c[5])); k += 6; continue; } - } else if (c[0] == '%' && k <= len - 3 && isASCIIHexDigit(c[1]) && isASCIIHexDigit(c[2])) { + } else if (c[0] == '%' && k <= length - 3 && isASCIIHexDigit(c[1]) && isASCIIHexDigit(c[2])) { convertedLChar = LChar(Lexer::convertHex(c[1], c[2])); c = &convertedLChar; k += 2; @@ -840,16 +844,16 @@ EncodedJSValue JSC_HOST_CALL globalFuncUnescape(ExecState* exec) } else { const UChar* characters = view.characters16(); - while (k < len) { + while (k < length) { const UChar* c = characters + k; UChar convertedUChar; - if (c[0] == '%' && k <= len - 6 && c[1] == 'u') { + if (c[0] == '%' && k <= length - 6 && c[1] == 'u') { if (isASCIIHexDigit(c[2]) && isASCIIHexDigit(c[3]) && isASCIIHexDigit(c[4]) && isASCIIHexDigit(c[5])) { convertedUChar = Lexer::convertUnicode(c[2], c[3], c[4], c[5]); c = &convertedUChar; k += 5; } - } else if (c[0] == '%' && k <= len - 3 && isASCIIHexDigit(c[1]) && isASCIIHexDigit(c[2])) { + } else if (c[0] == '%' && k <= length - 3 && isASCIIHexDigit(c[1]) && isASCIIHexDigit(c[2])) { convertedUChar = UChar(Lexer::convertHex(c[1], c[2])); c = &convertedUChar; k += 2; -- 1.8.3.1