Ignore:
Timestamp:
Dec 11, 2009, 3:34:10 PM (15 years ago)
Author:
[email protected]
Message:

https://bugs.webkit.org/show_bug.cgi?id=32454
Refactor construction of simple strings to avoid string concatenation.

Reviewed by Oliver Hunt.

Building strings through concatenation has a memory and performance cost -
a memory cost since we must over-allocate the buffer to leave space to append
into, and performance in that the string may still require reallocation (and
thus copying during construction). Instead move the full construction to
within a single function call (makeString), so that the arguments' lengths
can be calculated and an appropriate sized buffer allocated before copying
any characters.

~No performance change (~2% progression on date tests).

  • bytecode/CodeBlock.cpp:

(JSC::escapeQuotes):
(JSC::valueToSourceString):
(JSC::constantName):
(JSC::idName):
(JSC::CodeBlock::registerName):
(JSC::regexpToSourceString):
(JSC::regexpName):

  • bytecompiler/NodesCodegen.cpp:

(JSC::substitute):

  • profiler/Profiler.cpp:

(JSC::Profiler::createCallIdentifier):

  • runtime/DateConstructor.cpp:

(JSC::callDate):

  • runtime/DateConversion.cpp:

(JSC::formatDate):
(JSC::formatDateUTCVariant):
(JSC::formatTime):
(JSC::formatTimeUTC):

  • runtime/DateConversion.h:

(JSC::):

  • runtime/DatePrototype.cpp:

(JSC::dateProtoFuncToString):
(JSC::dateProtoFuncToUTCString):
(JSC::dateProtoFuncToDateString):
(JSC::dateProtoFuncToTimeString):
(JSC::dateProtoFuncToGMTString):

  • runtime/ErrorPrototype.cpp:

(JSC::errorProtoFuncToString):

  • runtime/ExceptionHelpers.cpp:

(JSC::createUndefinedVariableError):
(JSC::createErrorMessage):
(JSC::createInvalidParamError):

  • runtime/FunctionPrototype.cpp:

(JSC::insertSemicolonIfNeeded):
(JSC::functionProtoFuncToString):

  • runtime/ObjectPrototype.cpp:

(JSC::objectProtoFuncToString):

  • runtime/RegExpConstructor.cpp:

(JSC::constructRegExp):

  • runtime/RegExpObject.cpp:

(JSC::RegExpObject::match):

  • runtime/RegExpPrototype.cpp:

(JSC::regExpProtoFuncCompile):
(JSC::regExpProtoFuncToString):

  • runtime/StringPrototype.cpp:

(JSC::stringProtoFuncBig):
(JSC::stringProtoFuncSmall):
(JSC::stringProtoFuncBlink):
(JSC::stringProtoFuncBold):
(JSC::stringProtoFuncFixed):
(JSC::stringProtoFuncItalics):
(JSC::stringProtoFuncStrike):
(JSC::stringProtoFuncSub):
(JSC::stringProtoFuncSup):
(JSC::stringProtoFuncFontcolor):
(JSC::stringProtoFuncFontsize):
(JSC::stringProtoFuncAnchor):

  • runtime/UString.h:

(JSC::):
(JSC::makeString):

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/JavaScriptCore/runtime/UString.h

    r51168 r52028  
    538538
    539539    void initializeUString();
     540
     541    template<typename StringType>
     542    class StringTypeAdapter {
     543    };
     544
     545    template<>
     546    class StringTypeAdapter<char*>
     547    {
     548    public:
     549        StringTypeAdapter<char*>(char* buffer)
     550            : m_buffer((unsigned char*)buffer)
     551            , m_length(strlen(buffer))
     552        {
     553        }
     554
     555        unsigned length() { return m_length; }
     556
     557        void writeTo(UChar* destination)
     558        {
     559            for (unsigned i = 0; i < m_length; ++i)
     560                destination[i] = m_buffer[i];
     561        }
     562
     563    private:
     564        const unsigned char* m_buffer;
     565        unsigned m_length;
     566    };
     567
     568    template<>
     569    class StringTypeAdapter<const char*>
     570    {
     571    public:
     572        StringTypeAdapter<const char*>(const char* buffer)
     573            : m_buffer((unsigned char*)buffer)
     574            , m_length(strlen(buffer))
     575        {
     576        }
     577
     578        unsigned length() { return m_length; }
     579
     580        void writeTo(UChar* destination)
     581        {
     582            for (unsigned i = 0; i < m_length; ++i)
     583                destination[i] = m_buffer[i];
     584        }
     585
     586    private:
     587        const unsigned char* m_buffer;
     588        unsigned m_length;
     589    };
     590
     591    template<>
     592    class StringTypeAdapter<UString>
     593    {
     594    public:
     595        StringTypeAdapter<UString>(UString& string)
     596            : m_data(string.data())
     597            , m_length(string.size())
     598        {
     599        }
     600
     601        unsigned length() { return m_length; }
     602
     603        void writeTo(UChar* destination)
     604        {
     605            for (unsigned i = 0; i < m_length; ++i)
     606                destination[i] = m_data[i];
     607        }
     608
     609    private:
     610        const UChar* m_data;
     611        unsigned m_length;
     612    };
     613
     614    template<typename StringType1, typename StringType2>
     615    UString makeString(StringType1 string1, StringType2 string2)
     616    {
     617        StringTypeAdapter<StringType1> adapter1(string1);
     618        StringTypeAdapter<StringType2> adapter2(string2);
     619
     620        UChar* buffer;
     621        unsigned length = adapter1.length() + adapter2.length();
     622        if (!tryFastMalloc(length * sizeof(UChar)).getValue(buffer))
     623            return UString();
     624
     625        UChar* result = buffer;
     626        adapter1.writeTo(result);
     627        result += adapter1.length();
     628        adapter2.writeTo(result);
     629
     630        return UString(buffer, length, false);
     631    }
     632
     633    template<typename StringType1, typename StringType2, typename StringType3>
     634    UString makeString(StringType1 string1, StringType2 string2, StringType3 string3)
     635    {
     636        StringTypeAdapter<StringType1> adapter1(string1);
     637        StringTypeAdapter<StringType2> adapter2(string2);
     638        StringTypeAdapter<StringType3> adapter3(string3);
     639
     640        UChar* buffer;
     641        unsigned length = adapter1.length() + adapter2.length() + adapter3.length();
     642        if (!tryFastMalloc(length * sizeof(UChar)).getValue(buffer))
     643            return UString();
     644
     645        UChar* result = buffer;
     646        adapter1.writeTo(result);
     647        result += adapter1.length();
     648        adapter2.writeTo(result);
     649        result += adapter2.length();
     650        adapter3.writeTo(result);
     651
     652        return UString(buffer, length, false);
     653    }
     654
     655    template<typename StringType1, typename StringType2, typename StringType3, typename StringType4>
     656    UString makeString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4)
     657    {
     658        StringTypeAdapter<StringType1> adapter1(string1);
     659        StringTypeAdapter<StringType2> adapter2(string2);
     660        StringTypeAdapter<StringType3> adapter3(string3);
     661        StringTypeAdapter<StringType4> adapter4(string4);
     662
     663        UChar* buffer;
     664        unsigned length = adapter1.length() + adapter2.length() + adapter3.length() + adapter4.length();
     665        if (!tryFastMalloc(length * sizeof(UChar)).getValue(buffer))
     666            return UString();
     667
     668        UChar* result = buffer;
     669        adapter1.writeTo(result);
     670        result += adapter1.length();
     671        adapter2.writeTo(result);
     672        result += adapter2.length();
     673        adapter3.writeTo(result);
     674        result += adapter3.length();
     675        adapter4.writeTo(result);
     676
     677        return UString(buffer, length, false);
     678    }
     679
     680    template<typename StringType1, typename StringType2, typename StringType3, typename StringType4, typename StringType5>
     681    UString makeString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4, StringType5 string5)
     682    {
     683        StringTypeAdapter<StringType1> adapter1(string1);
     684        StringTypeAdapter<StringType2> adapter2(string2);
     685        StringTypeAdapter<StringType3> adapter3(string3);
     686        StringTypeAdapter<StringType4> adapter4(string4);
     687        StringTypeAdapter<StringType5> adapter5(string5);
     688
     689        UChar* buffer;
     690        unsigned length = adapter1.length() + adapter2.length() + adapter3.length() + adapter4.length() + adapter5.length();
     691        if (!tryFastMalloc(length * sizeof(UChar)).getValue(buffer))
     692            return UString();
     693
     694        UChar* result = buffer;
     695        adapter1.writeTo(result);
     696        result += adapter1.length();
     697        adapter2.writeTo(result);
     698        result += adapter2.length();
     699        adapter3.writeTo(result);
     700        result += adapter3.length();
     701        adapter4.writeTo(result);
     702        result += adapter4.length();
     703        adapter5.writeTo(result);
     704
     705        return UString(buffer, length, false);
     706    }
     707
     708    template<typename StringType1, typename StringType2, typename StringType3, typename StringType4, typename StringType5, typename StringType6>
     709    UString makeString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4, StringType5 string5, StringType6 string6)
     710    {
     711        StringTypeAdapter<StringType1> adapter1(string1);
     712        StringTypeAdapter<StringType2> adapter2(string2);
     713        StringTypeAdapter<StringType3> adapter3(string3);
     714        StringTypeAdapter<StringType4> adapter4(string4);
     715        StringTypeAdapter<StringType5> adapter5(string5);
     716        StringTypeAdapter<StringType6> adapter6(string6);
     717
     718        UChar* buffer;
     719        unsigned length = adapter1.length() + adapter2.length() + adapter3.length() + adapter4.length() + adapter5.length() + adapter6.length();
     720        if (!tryFastMalloc(length * sizeof(UChar)).getValue(buffer))
     721            return UString();
     722
     723        UChar* result = buffer;
     724        adapter1.writeTo(result);
     725        result += adapter1.length();
     726        adapter2.writeTo(result);
     727        result += adapter2.length();
     728        adapter3.writeTo(result);
     729        result += adapter3.length();
     730        adapter4.writeTo(result);
     731        result += adapter4.length();
     732        adapter5.writeTo(result);
     733        result += adapter5.length();
     734        adapter6.writeTo(result);
     735
     736        return UString(buffer, length, false);
     737    }
     738
     739    template<typename StringType1, typename StringType2, typename StringType3, typename StringType4, typename StringType5, typename StringType6, typename StringType7>
     740    UString makeString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4, StringType5 string5, StringType6 string6, StringType7 string7)
     741    {
     742        StringTypeAdapter<StringType1> adapter1(string1);
     743        StringTypeAdapter<StringType2> adapter2(string2);
     744        StringTypeAdapter<StringType3> adapter3(string3);
     745        StringTypeAdapter<StringType4> adapter4(string4);
     746        StringTypeAdapter<StringType5> adapter5(string5);
     747        StringTypeAdapter<StringType6> adapter6(string6);
     748        StringTypeAdapter<StringType7> adapter7(string7);
     749
     750        UChar* buffer;
     751        unsigned length = adapter1.length() + adapter2.length() + adapter3.length() + adapter4.length() + adapter5.length() + adapter6.length() + adapter7.length();
     752        if (!tryFastMalloc(length * sizeof(UChar)).getValue(buffer))
     753            return UString();
     754
     755        UChar* result = buffer;
     756        adapter1.writeTo(result);
     757        result += adapter1.length();
     758        adapter2.writeTo(result);
     759        result += adapter2.length();
     760        adapter3.writeTo(result);
     761        result += adapter3.length();
     762        adapter4.writeTo(result);
     763        result += adapter4.length();
     764        adapter5.writeTo(result);
     765        result += adapter5.length();
     766        adapter6.writeTo(result);
     767        result += adapter6.length();
     768        adapter7.writeTo(result);
     769
     770        return UString(buffer, length, false);
     771    }
     772
     773    template<typename StringType1, typename StringType2, typename StringType3, typename StringType4, typename StringType5, typename StringType6, typename StringType7, typename StringType8>
     774    UString makeString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4, StringType5 string5, StringType6 string6, StringType7 string7, StringType8 string8)
     775    {
     776        StringTypeAdapter<StringType1> adapter1(string1);
     777        StringTypeAdapter<StringType2> adapter2(string2);
     778        StringTypeAdapter<StringType3> adapter3(string3);
     779        StringTypeAdapter<StringType4> adapter4(string4);
     780        StringTypeAdapter<StringType5> adapter5(string5);
     781        StringTypeAdapter<StringType6> adapter6(string6);
     782        StringTypeAdapter<StringType7> adapter7(string7);
     783        StringTypeAdapter<StringType8> adapter8(string8);
     784
     785        UChar* buffer;
     786        unsigned length = adapter1.length() + adapter2.length() + adapter3.length() + adapter4.length() + adapter5.length() + adapter6.length() + adapter7.length() + adapter8.length();
     787        if (!tryFastMalloc(length * sizeof(UChar)).getValue(buffer))
     788            return UString();
     789
     790        UChar* result = buffer;
     791        adapter1.writeTo(result);
     792        result += adapter1.length();
     793        adapter2.writeTo(result);
     794        result += adapter2.length();
     795        adapter3.writeTo(result);
     796        result += adapter3.length();
     797        adapter4.writeTo(result);
     798        result += adapter4.length();
     799        adapter5.writeTo(result);
     800        result += adapter5.length();
     801        adapter6.writeTo(result);
     802        result += adapter6.length();
     803        adapter7.writeTo(result);
     804        result += adapter7.length();
     805        adapter8.writeTo(result);
     806
     807        return UString(buffer, length, false);
     808    }
     809
    540810} // namespace JSC
    541811
Note: See TracChangeset for help on using the changeset viewer.