Changeset 132913 in webkit
- Timestamp:
- Oct 30, 2012 8:47:44 AM (11 years ago)
- Location:
- trunk/Source/WebCore
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r132911 r132913 1 2012-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 1 33 2012-10-30 Christophe Dumez <christophe.dumez@intel.com> 2 34 -
trunk/Source/WebCore/bindings/v8/V8PerIsolateData.cpp
r132864 r132913 122 122 virtual void VisitExternalString(v8::Handle<v8::String> string) 123 123 { 124 WebCoreStringResource * resource = static_cast<WebCoreStringResource*>(string->GetExternalStringResource());124 WebCoreStringResourceBase* resource = WebCoreStringResourceBase::toWebCoreStringResourceBase(string); 125 125 if (resource) 126 126 resource->visitStrings(m_visitor); -
trunk/Source/WebCore/bindings/v8/V8StringResource.cpp
r131678 r132913 31 31 namespace WebCore { 32 32 33 template <class StringClass> struct StringTraits { 34 static const StringClass& fromStringResource(WebCoreStringResource*); 33 template<class StringClass> struct StringTraits { 34 static const StringClass& fromStringResource(WebCoreStringResourceBase*); 35 static bool is16BitAtomicString(StringClass&); 36 template<bool ascii> 35 37 static StringClass fromV8String(v8::Handle<v8::String>, int); 36 38 }; … … 38 40 template<> 39 41 struct StringTraits<String> { 40 static const String& fromStringResource(WebCoreStringResource * resource)42 static const String& fromStringResource(WebCoreStringResourceBase* resource) 41 43 { 42 44 return resource->webcoreString(); 43 45 } 44 45 static String fromV8String(v8::Handle<v8::String> v8String, int length) 46 static bool is16BitAtomicString(String& string) 46 47 { 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; 54 49 } 50 template<bool ascii> 51 static String fromV8String(v8::Handle<v8::String>, int); 55 52 }; 56 53 57 54 template<> 58 55 struct StringTraits<AtomicString> { 59 static const AtomicString& fromStringResource(WebCoreStringResource * resource)56 static const AtomicString& fromStringResource(WebCoreStringResourceBase* resource) 60 57 { 61 58 return resource->atomicString(); 62 59 } 63 64 static AtomicString fromV8String(v8::Handle<v8::String> v8String, int length) 60 static bool is16BitAtomicString(AtomicString& string) 65 61 { 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(); 77 63 } 64 template<bool ascii> 65 static AtomicString fromV8String(v8::Handle<v8::String>, int); 78 66 }; 79 67 80 template <typename StringType> 68 template<> 69 String 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 78 template<> 79 AtomicString 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 94 template<> 95 String 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 104 template<> 105 inline 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 112 template<typename StringType> 81 113 StringType v8StringToWebCoreString(v8::Handle<v8::String> v8String, ExternalMode external) 82 114 { 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 } 86 129 87 130 int length = v8String->Length(); 88 if ( !length)131 if (UNLIKELY(!length)) 89 132 return String(""); 90 133 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)); 92 136 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))) 97 143 delete stringResource; 98 } 144 } else { 145 WebCoreStringResource16* stringResource = new WebCoreStringResource16(result); 146 if (UNLIKELY(!v8String->MakeExternal(stringResource))) 147 delete stringResource; 99 148 } 100 149 return result; -
trunk/Source/WebCore/bindings/v8/V8ValueCache.cpp
r132151 r132913 34 34 static v8::Local<v8::String> makeExternalString(const String& string) 35 35 { 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); 37 45 v8::Local<v8::String> newString = v8::String::NewExternal(stringResource); 38 46 if (newString.IsEmpty()) … … 93 101 } 94 102 95 void WebCoreStringResource::visitStrings(ExternalStringVisitor* visitor) 103 WebCoreStringResourceBase* 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 114 void WebCoreStringResourceBase::visitStrings(ExternalStringVisitor* visitor) 96 115 { 97 116 visitor->visitJSExternalString(m_plainString.impl()); -
trunk/Source/WebCore/bindings/v8/V8ValueCache.h
r132151 r132913 73 73 // WebCoreStringResource is a helper class for v8ExternalString. It is used 74 74 // 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) 75 class WebCoreStringResourceBase { 76 public: 77 static WebCoreStringResourceBase* toWebCoreStringResourceBase(v8::Handle<v8::String>); 78 79 explicit WebCoreStringResourceBase(const String& string) 78 80 : m_plainString(string) 79 81 { … … 82 84 #endif 83 85 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) 88 90 : m_plainString(string.string()) 89 91 , m_atomicString(string) … … 93 95 #endif 94 96 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() 99 101 { 100 102 #ifndef NDEBUG 101 103 ASSERT(m_threadId == WTF::currentThread()); 102 104 #endif 103 int reducedExternalMemory = - 2 * m_plainString.length();105 int reducedExternalMemory = -memoryConsumption(m_plainString); 104 106 if (m_plainString.impl() != m_atomicString.impl() && !m_atomicString.isNull()) 105 reducedExternalMemory *= 2;107 reducedExternalMemory -= memoryConsumption(m_atomicString.string()); 106 108 v8::V8::AdjustAmountOfExternalAllocatedMemory(reducedExternalMemory); 107 109 } 108 109 virtual const uint16_t* data() const110 {111 return reinterpret_cast<const uint16_t*>(m_plainString.impl()->characters());112 }113 114 virtual size_t length() const { return m_plainString.impl()->length(); }115 110 116 111 const String& webcoreString() { return m_plainString; } … … 125 120 ASSERT(!m_atomicString.isNull()); 126 121 if (m_plainString.impl() != m_atomicString.impl()) 127 v8::V8::AdjustAmountOfExternalAllocatedMemory( 2 * m_atomicString.length());122 v8::V8::AdjustAmountOfExternalAllocatedMemory(memoryConsumption(m_atomicString.string())); 128 123 } 129 124 return m_atomicString; … … 132 127 void visitStrings(ExternalStringVisitor*); 133 128 134 static WebCoreStringResource* toStringResource(v8::Handle<v8::String> v8String) 135 { 136 return static_cast<WebCoreStringResource*>(v8String->GetExternalStringResource()); 137 } 138 139 private: 129 protected: 140 130 // A shallow copy of the string. Keeps the string buffer alive until the V8 engine garbage collects it. 141 131 String m_plainString; … … 147 137 AtomicString m_atomicString; 148 138 139 private: 140 static int memoryConsumption(const String& string) 141 { 142 return string.length() * (string.is8Bit() ? sizeof(LChar) : sizeof(UChar)); 143 } 149 144 #ifndef NDEBUG 150 145 WTF::ThreadIdentifier m_threadId; 151 146 #endif 147 }; 148 149 class WebCoreStringResource16 : public WebCoreStringResourceBase, public v8::String::ExternalStringResource { 150 public: 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 161 class WebCoreStringResource8 : public WebCoreStringResourceBase, public v8::String::ExternalAsciiStringResource { 162 public: 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 } 152 171 }; 153 172
Note: See TracChangeset
for help on using the changeset viewer.