Changeset 134950 in webkit


Ignore:
Timestamp:
Nov 16, 2012 7:47:06 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-11-16
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::toWebCoreStringResourceBase):
(WebCore):
(WebCore::WebCoreStringResourceBase::visitStrings):

  • bindings/v8/V8ValueCache.h:

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

Location:
trunk/Source/WebCore
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r134949 r134950  
     12012-11-16  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::toWebCoreStringResourceBase):
     26        (WebCore):
     27        (WebCore::WebCoreStringResourceBase::visitStrings):
     28        * bindings/v8/V8ValueCache.h:
     29        (WebCoreStringResourceBase):
     30        (WebCore::WebCoreStringResourceBase::WebCoreStringResourceBase):
     31        (WebCore::WebCoreStringResourceBase::~WebCoreStringResourceBase):
     32        (WebCore::WebCoreStringResourceBase::atomicString):
     33        (WebCore::WebCoreStringResourceBase::memoryConsumption):
     34        (WebCoreStringResource16):
     35        (WebCore::WebCoreStringResource16::WebCoreStringResource16):
     36        (WebCore):
     37        (WebCoreStringResource8):
     38        (WebCore::WebCoreStringResource8::WebCoreStringResource8):
     39
    1402012-11-16  Erik Arvidsson  <arv@chromium.org>
    241
  • trunk/Source/WebCore/bindings/v8/V8PerIsolateData.cpp

    r134393 r134950  
    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

    r133319 r134950  
    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 result = String::createUninitialized(length, buffer);
     90    v8String->Write(reinterpret_cast<uint16_t*>(buffer), 0, length);
     91    return AtomicString(result);
     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<>
     105AtomicString StringTraits<AtomicString>::fromV8String<true>(v8::Handle<v8::String> v8String, int length)
     106{
     107    ASSERT(v8String->Length() == length);
     108    static const int inlineBufferSize = 32;
     109    if (length <= inlineBufferSize) {
     110        LChar inlineBuffer[inlineBufferSize];
     111        v8String->WriteAscii(reinterpret_cast<char*>(inlineBuffer), 0, length, v8::String::PRESERVE_ASCII_NULL);
     112        return AtomicString(inlineBuffer, length);
     113    }
     114    LChar* buffer;
     115    String string = String::createUninitialized(length, buffer);
     116    v8String->WriteAscii(reinterpret_cast<char*>(buffer), 0, length, v8::String::PRESERVE_ASCII_NULL);
     117    return AtomicString(string);
     118}
     119
     120template<typename StringType>
    81121StringType v8StringToWebCoreString(v8::Handle<v8::String> v8String, ExternalMode external)
    82122{
    83     WebCoreStringResource* stringResource = WebCoreStringResource::toStringResource(v8String);
    84     if (stringResource)
    85         return StringTraits<StringType>::fromStringResource(stringResource);
     123    {
     124        // A lot of WebCoreStringResourceBase::toWebCoreStringResourceBase is copied here by hand for performance reasons.
     125        // This portion of this function is very hot in certain Dromeao benchmarks.
     126        v8::String::Encoding encoding;
     127        v8::String::ExternalStringResourceBase* resource = v8String->GetExternalStringResourceBase(&encoding);
     128        if (LIKELY(!!resource)) {
     129            WebCoreStringResourceBase* base;
     130            if (encoding == v8::String::ASCII_ENCODING)
     131                base = static_cast<WebCoreStringResource8*>(resource);
     132            else
     133                base = static_cast<WebCoreStringResource16*>(resource);
     134            return StringTraits<StringType>::fromStringResource(base);
     135        }
     136    }
    86137
    87138    int length = v8String->Length();
    88     if (!length)
     139    if (UNLIKELY(!length))
    89140        return String("");
    90141
    91     StringType result(StringTraits<StringType>::fromV8String(v8String, length));
     142    bool nonAscii = v8String->MayContainNonAscii();
     143    StringType result(nonAscii ? StringTraits<StringType>::template fromV8String<false>(v8String, length) : StringTraits<StringType>::template fromV8String<true>(v8String, length));
    92144
    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.
     145    if (external != Externalize || !v8String->CanMakeExternal())
     146        return result;
     147
     148    if (!nonAscii && !StringTraits<StringType>::is16BitAtomicString(result)) {
     149        WebCoreStringResource8* stringResource = new WebCoreStringResource8(result);
     150        if (UNLIKELY(!v8String->MakeExternal(stringResource)))
    97151            delete stringResource;
    98         }
     152    } else {
     153        WebCoreStringResource16* stringResource = new WebCoreStringResource16(result);
     154        if (UNLIKELY(!v8String->MakeExternal(stringResource)))
     155            delete stringResource;
    99156    }
    100157    return result;
  • trunk/Source/WebCore/bindings/v8/V8ValueCache.cpp

    r133479 r134950  
    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())
     
    94102}
    95103
    96 void WebCoreStringResource::visitStrings(ExternalStringVisitor* visitor)
     104WebCoreStringResourceBase* WebCoreStringResourceBase::toWebCoreStringResourceBase(v8::Handle<v8::String> string)
     105{
     106    v8::String::Encoding encoding;
     107    v8::String::ExternalStringResourceBase* resource = string->GetExternalStringResourceBase(&encoding);
     108    if (!resource)
     109        return 0;
     110    if (encoding == v8::String::ASCII_ENCODING)
     111        return static_cast<WebCoreStringResource8*>(resource);
     112    return static_cast<WebCoreStringResource16*>(resource);
     113}
     114
     115void WebCoreStringResourceBase::visitStrings(ExternalStringVisitor* visitor)
    97116{
    98117    visitor->visitJSExternalString(m_plainString.impl());
  • trunk/Source/WebCore/bindings/v8/V8ValueCache.h

    r133319 r134950  
    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.