Changeset 132913 in webkit


Ignore:
Timestamp:
Oct 30, 2012 8:47:44 AM (11 years ago)
Author:
commit-queue@webkit.org
Message:

add 7 bit strings capabilities to the v8 binding layer
https://bugs.webkit.org/show_bug.cgi?id=91850

Patch by Dan Carney <dcarney@google.com> on 2012-10-30
Reviewed by Adam Barth.

This change enables the v8 binding layer to make use of webkit's
8 bit string capabilities. Using 8 bit strings leads to certain
benchmark performance improvemnts as can be seen in
https://bug-91850-attachments.webkit.org/attachment.cgi?id=163334.

No new tests. Test coverage already extensive.

  • bindings/v8/V8PerIsolateData.cpp:

(WebCore::V8PerIsolateData::visitExternalStrings):

  • bindings/v8/V8StringResource.cpp:

(StringTraits):
(WebCore::false):
(WebCore):
(WebCore::true):
(WebCore::v8StringToWebCoreString):

  • bindings/v8/V8ValueCache.cpp:

(WebCore::makeExternalString):
(WebCore::WebCoreStringResourceBase::visitStrings):

  • bindings/v8/V8ValueCache.h:

(WebCore::WebCoreStringResourceBase::WebCoreStringResourceBase):
(WebCore::WebCoreStringResourceBase::~WebCoreStringResourceBase):
(WebCore::WebCoreStringResourceBase::atomicString):
(WebCoreStringResourceBase):
(WebCore::WebCoreStringResourceBase::memoryConsumption):

Location:
trunk/Source/WebCore
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r132911 r132913  
     12012-10-30  Dan Carney  <dcarney@google.com>
     2
     3        add 7 bit strings capabilities to the v8 binding layer
     4        https://bugs.webkit.org/show_bug.cgi?id=91850
     5
     6        Reviewed by Adam Barth.
     7
     8        This change enables the v8 binding layer to make use of webkit's
     9        8 bit string capabilities. Using 8 bit strings leads to certain
     10        benchmark performance improvemnts as can be seen in
     11        https://bug-91850-attachments.webkit.org/attachment.cgi?id=163334.
     12
     13        No new tests. Test coverage already extensive.
     14
     15        * bindings/v8/V8PerIsolateData.cpp:
     16        (WebCore::V8PerIsolateData::visitExternalStrings):
     17        * bindings/v8/V8StringResource.cpp:
     18        (StringTraits):
     19        (WebCore::false):
     20        (WebCore):
     21        (WebCore::true):
     22        (WebCore::v8StringToWebCoreString):
     23        * bindings/v8/V8ValueCache.cpp:
     24        (WebCore::makeExternalString):
     25        (WebCore::WebCoreStringResourceBase::visitStrings):
     26        * bindings/v8/V8ValueCache.h:
     27        (WebCore::WebCoreStringResourceBase::WebCoreStringResourceBase):
     28        (WebCore::WebCoreStringResourceBase::~WebCoreStringResourceBase):
     29        (WebCore::WebCoreStringResourceBase::atomicString):
     30        (WebCoreStringResourceBase):
     31        (WebCore::WebCoreStringResourceBase::memoryConsumption):
     32
    1332012-10-30  Christophe Dumez  <christophe.dumez@intel.com>
    234
  • trunk/Source/WebCore/bindings/v8/V8PerIsolateData.cpp

    r132864 r132913  
    122122        virtual void VisitExternalString(v8::Handle<v8::String> string)
    123123        {
    124             WebCoreStringResource* resource = static_cast<WebCoreStringResource*>(string->GetExternalStringResource());
     124            WebCoreStringResourceBase* resource = WebCoreStringResourceBase::toWebCoreStringResourceBase(string);
    125125            if (resource)
    126126                resource->visitStrings(m_visitor);
  • trunk/Source/WebCore/bindings/v8/V8StringResource.cpp

    r131678 r132913  
    3131namespace WebCore {
    3232
    33 template <class StringClass> struct StringTraits {
    34     static const StringClass& fromStringResource(WebCoreStringResource*);
     33template<class StringClass> struct StringTraits {
     34    static const StringClass& fromStringResource(WebCoreStringResourceBase*);
     35    static bool is16BitAtomicString(StringClass&);
     36    template<bool ascii>
    3537    static StringClass fromV8String(v8::Handle<v8::String>, int);
    3638};
     
    3840template<>
    3941struct StringTraits<String> {
    40     static const String& fromStringResource(WebCoreStringResource* resource)
     42    static const String& fromStringResource(WebCoreStringResourceBase* resource)
    4143    {
    4244        return resource->webcoreString();
    4345    }
    44 
    45     static String fromV8String(v8::Handle<v8::String> v8String, int length)
     46    static bool is16BitAtomicString(String& string)
    4647    {
    47         ASSERT(v8String->Length() == length);
    48         // NOTE: as of now, String(const UChar*, int) performs String::createUninitialized
    49         // anyway, so no need to optimize like we do for AtomicString below.
    50         UChar* buffer;
    51         String result = String::createUninitialized(length, buffer);
    52         v8String->Write(reinterpret_cast<uint16_t*>(buffer), 0, length);
    53         return result;
     48        return false;
    5449    }
     50    template<bool ascii>
     51    static String fromV8String(v8::Handle<v8::String>, int);
    5552};
    5653
    5754template<>
    5855struct StringTraits<AtomicString> {
    59     static const AtomicString& fromStringResource(WebCoreStringResource* resource)
     56    static const AtomicString& fromStringResource(WebCoreStringResourceBase* resource)
    6057    {
    6158        return resource->atomicString();
    6259    }
    63 
    64     static AtomicString fromV8String(v8::Handle<v8::String> v8String, int length)
     60    static bool is16BitAtomicString(AtomicString& string)
    6561    {
    66         ASSERT(v8String->Length() == length);
    67         static const int inlineBufferSize = 16;
    68         if (length <= inlineBufferSize) {
    69             UChar inlineBuffer[inlineBufferSize];
    70             v8String->Write(reinterpret_cast<uint16_t*>(inlineBuffer), 0, length);
    71             return AtomicString(inlineBuffer, length);
    72         }
    73         UChar* buffer;
    74         String string = String::createUninitialized(length, buffer);
    75         v8String->Write(reinterpret_cast<uint16_t*>(buffer), 0, length);
    76         return AtomicString(string);
     62        return !string.string().is8Bit();
    7763    }
     64    template<bool ascii>
     65    static AtomicString fromV8String(v8::Handle<v8::String>, int);
    7866};
    7967
    80 template <typename StringType>
     68template<>
     69String StringTraits<String>::fromV8String<false>(v8::Handle<v8::String> v8String, int length)
     70{
     71    ASSERT(v8String->Length() == length);
     72    UChar* buffer;
     73    String result = String::createUninitialized(length, buffer);
     74    v8String->Write(reinterpret_cast<uint16_t*>(buffer), 0, length);
     75    return result;
     76}
     77
     78template<>
     79AtomicString StringTraits<AtomicString>::fromV8String<false>(v8::Handle<v8::String> v8String, int length)
     80{
     81    ASSERT(v8String->Length() == length);
     82    static const int inlineBufferSize = 16;
     83    if (length <= inlineBufferSize) {
     84        UChar inlineBuffer[inlineBufferSize];
     85        v8String->Write(reinterpret_cast<uint16_t*>(inlineBuffer), 0, length);
     86        return AtomicString(inlineBuffer, length);
     87    }
     88    UChar* buffer;
     89    String string = String::createUninitialized(length, buffer);
     90    v8String->Write(reinterpret_cast<uint16_t*>(buffer), 0, length);
     91    return AtomicString(string);
     92}
     93
     94template<>
     95String StringTraits<String>::fromV8String<true>(v8::Handle<v8::String> v8String, int length)
     96{
     97    ASSERT(v8String->Length() == length);
     98    LChar* buffer;
     99    String result = String::createUninitialized(length, buffer);
     100    v8String->WriteAscii(reinterpret_cast<char*>(buffer), 0, length, v8::String::PRESERVE_ASCII_NULL);
     101    return result;
     102}
     103
     104template<>
     105inline AtomicString StringTraits<AtomicString>::fromV8String<true>(v8::Handle<v8::String> v8String, int length)
     106{
     107    // FIXME: There is no inline fast path for 8 bit atomic strings.
     108    String result = StringTraits<String>::fromV8String<true>(v8String, length);
     109    return AtomicString(result);
     110}
     111
     112template<typename StringType>
    81113StringType v8StringToWebCoreString(v8::Handle<v8::String> v8String, ExternalMode external)
    82114{
    83     WebCoreStringResource* stringResource = WebCoreStringResource::toStringResource(v8String);
    84     if (stringResource)
    85         return StringTraits<StringType>::fromStringResource(stringResource);
     115    {
     116        // A lot of WebCoreStringResourceBase::toWebCoreStringResourceBase is copied here by hand for performance reasons.
     117        // This portion of this function is very hot in certain Dromeao benchmarks.
     118        v8::String::Encoding encoding;
     119        v8::String::ExternalStringResourceBase* resource = v8String->GetExternalStringResourceBase(&encoding);
     120        if (LIKELY(!!resource)) {
     121            WebCoreStringResourceBase* base;
     122            if (encoding == v8::String::ASCII_ENCODING)
     123                base = static_cast<WebCoreStringResource8*>(resource);
     124            else
     125                base = static_cast<WebCoreStringResource16*>(resource);
     126            return StringTraits<StringType>::fromStringResource(base);
     127        }
     128    }
    86129
    87130    int length = v8String->Length();
    88     if (!length)
     131    if (UNLIKELY(!length))
    89132        return String("");
    90133
    91     StringType result(StringTraits<StringType>::fromV8String(v8String, length));
     134    bool nonAscii = v8String->MayContainNonAscii();
     135    StringType result(nonAscii ? StringTraits<StringType>::template fromV8String<false>(v8String, length) : StringTraits<StringType>::template fromV8String<true>(v8String, length));
    92136
    93     if (external == Externalize && v8String->CanMakeExternal()) {
    94         stringResource = new WebCoreStringResource(result);
    95         if (!v8String->MakeExternal(stringResource)) {
    96             // In case of a failure delete the external resource as it was not used.
     137    if (external != Externalize || !v8String->CanMakeExternal())
     138        return result;
     139
     140    if (!nonAscii && !StringTraits<StringType>::is16BitAtomicString(result)) {
     141        WebCoreStringResource8* stringResource = new WebCoreStringResource8(result);
     142        if (UNLIKELY(!v8String->MakeExternal(stringResource)))
    97143            delete stringResource;
    98         }
     144    } else {
     145        WebCoreStringResource16* stringResource = new WebCoreStringResource16(result);
     146        if (UNLIKELY(!v8String->MakeExternal(stringResource)))
     147            delete stringResource;
    99148    }
    100149    return result;
  • trunk/Source/WebCore/bindings/v8/V8ValueCache.cpp

    r132151 r132913  
    3434static v8::Local<v8::String> makeExternalString(const String& string)
    3535{
    36     WebCoreStringResource* stringResource = new WebCoreStringResource(string);
     36    if (string.is8Bit() && string.containsOnlyASCII()) {
     37        WebCoreStringResource8* stringResource = new WebCoreStringResource8(string);
     38        v8::Local<v8::String> newString = v8::String::NewExternal(stringResource);
     39        if (newString.IsEmpty())
     40            delete stringResource;
     41        return newString;
     42    }
     43
     44    WebCoreStringResource16* stringResource = new WebCoreStringResource16(string);
    3745    v8::Local<v8::String> newString = v8::String::NewExternal(stringResource);
    3846    if (newString.IsEmpty())
     
    93101}
    94102
    95 void WebCoreStringResource::visitStrings(ExternalStringVisitor* visitor)
     103WebCoreStringResourceBase* WebCoreStringResourceBase::toWebCoreStringResourceBase(v8::Handle<v8::String> string)
     104{
     105    v8::String::Encoding encoding;
     106    v8::String::ExternalStringResourceBase* resource = string->GetExternalStringResourceBase(&encoding);
     107    if (!resource)
     108        return 0;
     109    if (encoding == v8::String::ASCII_ENCODING)
     110        return static_cast<WebCoreStringResource8*>(resource);
     111    return static_cast<WebCoreStringResource16*>(resource);
     112}
     113
     114void WebCoreStringResourceBase::visitStrings(ExternalStringVisitor* visitor)
    96115{
    97116    visitor->visitJSExternalString(m_plainString.impl());
  • trunk/Source/WebCore/bindings/v8/V8ValueCache.h

    r132151 r132913  
    7373// WebCoreStringResource is a helper class for v8ExternalString. It is used
    7474// to manage the life-cycle of the underlying buffer of the external string.
    75 class WebCoreStringResource : public v8::String::ExternalStringResource {
    76 public:
    77     explicit WebCoreStringResource(const String& string)
     75class WebCoreStringResourceBase {
     76public:
     77    static WebCoreStringResourceBase* toWebCoreStringResourceBase(v8::Handle<v8::String>);
     78
     79    explicit WebCoreStringResourceBase(const String& string)
    7880        : m_plainString(string)
    7981    {
     
    8284#endif
    8385        ASSERT(!string.isNull());
    84         v8::V8::AdjustAmountOfExternalAllocatedMemory(2 * string.length());
    85     }
    86 
    87     explicit WebCoreStringResource(const AtomicString& string)
     86        v8::V8::AdjustAmountOfExternalAllocatedMemory(memoryConsumption(string));
     87    }
     88
     89    explicit WebCoreStringResourceBase(const AtomicString& string)
    8890        : m_plainString(string.string())
    8991        , m_atomicString(string)
     
    9395#endif
    9496        ASSERT(!string.isNull());
    95         v8::V8::AdjustAmountOfExternalAllocatedMemory(2 * string.length());
    96     }
    97 
    98     virtual ~WebCoreStringResource()
     97        v8::V8::AdjustAmountOfExternalAllocatedMemory(memoryConsumption(string));
     98    }
     99
     100    virtual ~WebCoreStringResourceBase()
    99101    {
    100102#ifndef NDEBUG
    101103        ASSERT(m_threadId == WTF::currentThread());
    102104#endif
    103         int reducedExternalMemory = -2 * m_plainString.length();
     105        int reducedExternalMemory = -memoryConsumption(m_plainString);
    104106        if (m_plainString.impl() != m_atomicString.impl() && !m_atomicString.isNull())
    105             reducedExternalMemory *= 2;
     107            reducedExternalMemory -= memoryConsumption(m_atomicString.string());
    106108        v8::V8::AdjustAmountOfExternalAllocatedMemory(reducedExternalMemory);
    107109    }
    108 
    109     virtual const uint16_t* data() const
    110     {
    111         return reinterpret_cast<const uint16_t*>(m_plainString.impl()->characters());
    112     }
    113 
    114     virtual size_t length() const { return m_plainString.impl()->length(); }
    115110
    116111    const String& webcoreString() { return m_plainString; }
     
    125120            ASSERT(!m_atomicString.isNull());
    126121            if (m_plainString.impl() != m_atomicString.impl())
    127                 v8::V8::AdjustAmountOfExternalAllocatedMemory(2 * m_atomicString.length());
     122                v8::V8::AdjustAmountOfExternalAllocatedMemory(memoryConsumption(m_atomicString.string()));
    128123        }
    129124        return m_atomicString;
     
    132127    void visitStrings(ExternalStringVisitor*);
    133128
    134     static WebCoreStringResource* toStringResource(v8::Handle<v8::String> v8String)
    135     {
    136         return static_cast<WebCoreStringResource*>(v8String->GetExternalStringResource());
    137     }
    138 
    139 private:
     129protected:
    140130    // A shallow copy of the string. Keeps the string buffer alive until the V8 engine garbage collects it.
    141131    String m_plainString;
     
    147137    AtomicString m_atomicString;
    148138
     139private:
     140    static int memoryConsumption(const String& string)
     141    {
     142        return string.length() * (string.is8Bit() ? sizeof(LChar) : sizeof(UChar));
     143    }
    149144#ifndef NDEBUG
    150145    WTF::ThreadIdentifier m_threadId;
    151146#endif
     147};
     148
     149class WebCoreStringResource16 : public WebCoreStringResourceBase, public v8::String::ExternalStringResource {
     150public:
     151    explicit WebCoreStringResource16(const String& string) : WebCoreStringResourceBase(string) { }
     152    explicit WebCoreStringResource16(const AtomicString& string) : WebCoreStringResourceBase(string) { }
     153
     154    virtual size_t length() const OVERRIDE { return m_plainString.impl()->length(); }
     155    virtual const uint16_t* data() const OVERRIDE
     156    {
     157        return reinterpret_cast<const uint16_t*>(m_plainString.impl()->characters());
     158    }
     159};
     160
     161class WebCoreStringResource8 : public WebCoreStringResourceBase, public v8::String::ExternalAsciiStringResource {
     162public:
     163    explicit WebCoreStringResource8(const String& string) : WebCoreStringResourceBase(string) { }
     164    explicit WebCoreStringResource8(const AtomicString& string) : WebCoreStringResourceBase(string) { }
     165
     166    virtual size_t length() const OVERRIDE { return m_plainString.impl()->length(); }
     167    virtual const char* data() const OVERRIDE
     168    {
     169        return reinterpret_cast<const char*>(m_plainString.impl()->characters8());
     170    }
    152171};
    153172
Note: See TracChangeset for help on using the changeset viewer.