Ignore:
Timestamp:
Oct 12, 2015, 12:44:52 PM (10 years ago)
Author:
[email protected]
Message:

"A + B" with strings shouldn't copy if A or B is empty.
<https://webkit.org/b/150034>

Reviewed by Anders Carlsson.

Source/JavaScriptCore:

  • runtime/JSStringBuilder.h:

(JSC::jsMakeNontrivialString):

  • runtime/Lookup.cpp:

(JSC::reifyStaticAccessor):

  • runtime/ObjectPrototype.cpp:

(JSC::objectProtoFuncToString):

Source/WTF:

Add a fast path to WTF's operator+ magic for concatenation of two strings where
one of them is empty. In that case, try to avoid allocation altogether by returning
the non-empty string.

Spotted this while analyzing memory peaks during page load; it turns out we were
duplicating whole text resources (JS, CSS) at the end of decoding, below
TextResourceDecoder::decodeAndFlush(). That function effectively does:

return decode() + flush();

Very often, flush() returns an empty string, so due to the naive operator+,
we'd allocate a new StringImpl of length (decode().length() + flush().length())
and copy the return value from decode() into it. So silly!

Had to make the tryMakeString() machinery use String as a return type instead of
RefPtr<StringImpl> to make all the right overloads gel. StringTypeAdapter templates
are now required to provide a toString() function.

  • wtf/text/StringConcatenate.h:

(WTF::StringTypeAdapter<char>::toString):
(WTF::StringTypeAdapter<UChar>::toString):
(WTF::StringTypeAdapter<Vector<char>>::toString):
(WTF::StringTypeAdapter<String>::toString):
(WTF::tryMakeString):
(WTF::makeString):

  • wtf/text/StringOperators.h:

(WTF::StringAppend::operator String):

  • wtf/text/StringView.h:

(WTF::StringTypeAdapter<StringView>::toString):

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/runtime/JSStringBuilder.h

    r174219 r190882  
    128128inline JSValue jsMakeNontrivialString(ExecState* exec, const StringType& string, const StringTypes&... strings)
    129129{
    130     RefPtr<StringImpl> result = WTF::tryMakeString(string, strings...);
     130    String result = WTF::tryMakeString(string, strings...);
    131131    if (!result)
    132132        return throwOutOfMemoryError(exec);
    133     return jsNontrivialString(exec, result.release());
     133    return jsNontrivialString(exec, result);
    134134}
    135135
Note: See TracChangeset for help on using the changeset viewer.