[webkit-changes] [WebKit/WebKit] 9d0a97: [JSC] Optimize Array#join's toString operation for...

Yusuke Suzuki noreply at github.com
Wed Apr 19 00:08:08 PDT 2023


  Branch: refs/heads/main
  Home:   https://github.com/WebKit/WebKit
  Commit: 9d0a972fc0bfc1429382127b4ee62cbc5a7bf151
      https://github.com/WebKit/WebKit/commit/9d0a972fc0bfc1429382127b4ee62cbc5a7bf151
  Author: Yusuke Suzuki <ysuzuki at apple.com>
  Date:   2023-04-19 (Wed, 19 Apr 2023)

  Changed paths:
    A JSTests/microbenchmarks/array-join-object.js
    M JSTests/microbenchmarks/string-index-of-10000001-404.js
    M JSTests/microbenchmarks/u16-string-index-of-10000001-404.js
    M JSTests/microbenchmarks/u16-string-index-of-10000001-beg.js
    M JSTests/microbenchmarks/u16-string-index-of-10000001-end.js
    M JSTests/microbenchmarks/u16-string-index-of-10000001-mid.js
    M Source/JavaScriptCore/runtime/ArrayPrototype.cpp
    M Source/JavaScriptCore/runtime/JSCJSValue.cpp
    M Source/JavaScriptCore/runtime/JSCast.h
    M Source/JavaScriptCore/runtime/JSCell.cpp
    M Source/JavaScriptCore/runtime/JSCell.h
    M Source/JavaScriptCore/runtime/JSCellInlines.h
    M Source/JavaScriptCore/runtime/JSGenericTypedArrayViewPrototypeFunctions.h
    M Source/JavaScriptCore/runtime/JSObject.cpp
    M Source/JavaScriptCore/runtime/JSString.h
    M Source/JavaScriptCore/runtime/JSStringJoiner.cpp
    M Source/JavaScriptCore/runtime/JSStringJoiner.h
    M Source/JavaScriptCore/runtime/ObjectPrototypeInlines.h
    M Source/JavaScriptCore/runtime/SmallStrings.cpp
    M Source/JavaScriptCore/runtime/SmallStrings.h
    M Source/WTF/wtf/text/StringView.h

  Log Message:
  -----------
  [JSC] Optimize Array#join's toString operation for Objects
https://bugs.webkit.org/show_bug.cgi?id=255638
rdar://108239715

Reviewed by Mark Lam.

This patch optimizes Array#join via several optimizations.

1. Borrow V8's idea. We cache the last string for Array#join, and if it is identical,
   then we just count it instead of appending it to the vector. Like, "[object Object]" x 100.
   Then we can keep JSStringJoiner's buffer in a reasonable size. We pre-allocate 16 for Vector
   capacity and which can cover many cases with this without Vector allocation and deallocation.
2. Our "[object Object]" tag string generation is too generic. We should have spec-defined ones
   in SmallStrings, and use JSString from that. This also helps (1) since now "[object Object]"
   will get the exact same JSString.
3. With (1), JSStringJoiner now knows the last JSString*. So if Array#join only sees one element,
   we can just return this string directly.
4. This is the last optimization having the largest effect in the 4. We revisit JSValue::toString
   and JSStringJoiner's toString operation, and optimize the fast path for Object#toString cases.
   We add JSCell::toStringInline which can handle the cached cases quickly. This also cleans up
   JSValue::toStringSlowCase by extracting JSCell related things to JSCell::toStringInline.

                                  ToT                     Patched

    array-join-object       28.6489+-0.0592     ^     16.4209+-0.1264        ^ definitely 1.7447x faster

* JSTests/microbenchmarks/array-join-object.js: Added.
* Source/JavaScriptCore/runtime/ArrayPrototype.cpp:
(JSC::fastJoin):
(JSC::JSC_DEFINE_HOST_FUNCTION):
* Source/JavaScriptCore/runtime/JSCJSValue.cpp:
(JSC::JSValue::toStringSlowCase const):
(): Deleted.
* Source/JavaScriptCore/runtime/JSCast.h:
* Source/JavaScriptCore/runtime/JSCell.cpp:
(JSC::JSCell::toStringSlowCase const):
* Source/JavaScriptCore/runtime/JSCell.h:
* Source/JavaScriptCore/runtime/JSCellInlines.h:
(JSC::JSCell::toStringInline const):
* Source/JavaScriptCore/runtime/JSGenericTypedArrayViewPrototypeFunctions.h:
(JSC::genericTypedArrayViewProtoFuncJoin):
* Source/JavaScriptCore/runtime/JSObject.cpp:
(JSC::JSObject::toString const):
* Source/JavaScriptCore/runtime/JSString.h:
* Source/JavaScriptCore/runtime/JSStringJoiner.cpp:
(JSC::joinStrings):
(JSC::JSStringJoiner::joinedLength const):
(JSC::JSStringJoiner::~JSStringJoiner): Deleted.
* Source/JavaScriptCore/runtime/JSStringJoiner.h:
(JSC::JSStringJoiner::JSStringJoiner):
(JSC::JSStringJoiner::reserveCapacity):
(JSC::JSStringJoiner::join):
(JSC::JSStringJoiner::append):
(JSC::JSStringJoiner::append8Bit):
(JSC::JSStringJoiner::appendEmptyString):
(JSC::JSStringJoiner::appendWithoutSideEffects):
* Source/JavaScriptCore/runtime/ObjectPrototypeInlines.h:
(JSC::objectPrototypeToStringSlow):
(JSC::objectPrototypeToString):
(JSC::inferBuiltinTag): Deleted.
* Source/JavaScriptCore/runtime/SmallStrings.cpp:
(JSC::SmallStrings::initializeCommonStrings):
(JSC::SmallStrings::visitStrongReferences):
* Source/JavaScriptCore/runtime/SmallStrings.h:
(JSC::SmallStrings::objectNullString const):
(JSC::SmallStrings::objectUndefinedString const):
(JSC::SmallStrings::objectObjectString const):
(JSC::SmallStrings::objectArrayString const):
(JSC::SmallStrings::objectFunctionString const):
(JSC::SmallStrings::objectArgumentsString const):
(JSC::SmallStrings::objectDateString const):
(JSC::SmallStrings::objectRegExpString const):
(JSC::SmallStrings::objectErrorString const):
(JSC::SmallStrings::objectBooleanString const):
(JSC::SmallStrings::objectNumberString const):
(JSC::SmallStrings::objectStringString const):
(JSC::SmallStrings::nullObjectString const): Deleted.
(JSC::SmallStrings::undefinedObjectString const): Deleted.
* Source/WTF/wtf/text/StringView.h:
(WTF::StringViewWithUnderlyingString::StringViewWithUnderlyingString):

Canonical link: https://commits.webkit.org/263117@main




More information about the webkit-changes mailing list