Changeset 16622 in webkit
- Timestamp:
- Sep 28, 2006 2:07:39 PM (18 years ago)
- Location:
- trunk
- Files:
-
- 11 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/JavaScriptCore/ChangeLog
r16614 r16622 1 2006-09-28 Darin Adler <darin@apple.com> 2 3 Reviewed by Alice. 4 5 - support for change that should fix <rdar://problem/4733044> 6 REGRESSION: XML iBench shows 10% perf. regression (copying 7 strings while decoding) 8 9 * wtf/Vector.h: Changed VectorBuffer so that the general case 10 contains an instance of the 0 case, since deriving from it 11 was violating the Liskov Substitution Principle. 12 (WTF::VectorBuffer::releaseBuffer): Added. Releases the buffer so it can 13 be adopted by another data structure that uses the FastMalloc.h allocator. 14 Returns 0 if the internal buffer was being used. 15 (WTF::Vector::releaseBuffer): Added. Releases the buffer as above or creates 16 a new one in the case where the internal buffer was being used. 17 1 18 2006-09-28 Maciej Stachowiak <mjs@apple.com> 2 19 -
trunk/JavaScriptCore/wtf/Vector.h
r16533 r16622 219 219 220 220 template<typename T> 221 class VectorBuffer<T, 0> 222 { 221 class VectorBuffer<T, 0> { 223 222 public: 224 223 VectorBuffer() 224 : m_buffer(0), m_capacity(0) 225 { 226 } 227 228 VectorBuffer(size_t capacity) 229 #if !ASSERT_DISABLED 225 230 : m_capacity(0) 226 , m_buffer(0) 227 { 228 } 229 230 VectorBuffer(size_t capacity) 231 : m_capacity(0) 231 #endif 232 232 { 233 233 allocateBuffer(capacity); … … 239 239 } 240 240 241 void deallocateBuffer(T* buffer)241 static void deallocateBuffer(T* buffer) 242 242 { 243 243 fastFree(buffer); … … 250 250 if (newCapacity > std::numeric_limits<size_t>::max() / sizeof(T)) 251 251 abort(); 252 m_buffer = reinterpret_cast<T*>(fastMalloc(newCapacity * sizeof(T)));252 m_buffer = static_cast<T*>(fastMalloc(newCapacity * sizeof(T))); 253 253 } 254 254 … … 257 257 size_t capacity() const { return m_capacity; } 258 258 259 T* releaseBuffer() 260 { 261 T* buffer = m_buffer; 262 m_buffer = 0; 263 m_capacity = 0; 264 return buffer; 265 } 266 259 267 protected: 260 268 VectorBuffer(T* buffer, size_t capacity) 261 : m_capacity(capacity) 262 , m_buffer(buffer) 263 { 264 } 265 269 : m_buffer(buffer), m_capacity(capacity) 270 { 271 } 272 273 T* m_buffer; 274 275 private: 266 276 size_t m_capacity; 267 T *m_buffer; 268 }; 269 270 template<typename T, size_t inlineCapacity> 271 class VectorBuffer : public VectorBuffer<T, 0> { 277 }; 278 279 template<typename T, size_t inlineCapacity> 280 class VectorBuffer : private VectorBuffer<T, 0> { 272 281 private: 273 282 typedef VectorBuffer<T, 0> BaseBuffer; 274 283 public: 275 VectorBuffer() 284 VectorBuffer() 276 285 : BaseBuffer(inlineBuffer(), inlineCapacity) 277 286 { … … 282 291 { 283 292 if (capacity > inlineCapacity) 284 BaseBuffer::allocateBuffer(capacity);293 allocateBuffer(capacity); 285 294 } 286 295 287 296 ~VectorBuffer() 288 297 { 289 if ( BaseBuffer::buffer() == inlineBuffer())298 if (buffer() == inlineBuffer()) 290 299 BaseBuffer::m_buffer = 0; 291 300 } … … 297 306 } 298 307 308 using BaseBuffer::allocateBuffer; 309 310 using BaseBuffer::buffer; 311 using BaseBuffer::capacity; 312 313 T* releaseBuffer() 314 { 315 if (buffer() == inlineBuffer()) 316 return 0; 317 return BaseBuffer::releaseBuffer(); 318 } 319 299 320 private: 300 321 static const size_t m_inlineBufferSize = inlineCapacity * sizeof(T); 301 T *inlineBuffer() { return reinterpret_cast<T *>(&m_inlineBuffer); } 322 T* inlineBuffer() { return reinterpret_cast<T*>(&m_inlineBuffer); } 323 302 324 char m_inlineBuffer[m_inlineBufferSize]; 303 325 }; … … 409 431 void fill(const T& val) { fill(val, size()); } 410 432 433 T* releaseBuffer(); 434 411 435 private: 412 436 void expandCapacity(size_t newMinCapacity); … … 598 622 599 623 template<typename T, size_t inlineCapacity> 624 T* Vector<T, inlineCapacity>::releaseBuffer() 625 { 626 T* buffer = m_impl.releaseBuffer(); 627 if (!buffer && m_size) { 628 // If the vector had some data, but no buffer to release, 629 // that means it was using the inline buffer. In that case, 630 // we create a brand new buffer so the caller always gets one. 631 size_t bytes = m_size * sizeof(T); 632 buffer = static_cast<T*>(fastMalloc(bytes)); 633 memcpy(buffer, data(), bytes); 634 } 635 m_size = 0; 636 return buffer; 637 } 638 639 template<typename T, size_t inlineCapacity> 600 640 void deleteAllValues(const Vector<T, inlineCapacity>& collection) 601 641 { -
trunk/WebCore/ChangeLog
r16616 r16622 1 2006-09-28 Darin Adler <darin@apple.com> 2 3 Reviewed by Alice. 4 5 - change that should fix <rdar://problem/4733044> REGRESSION: XML iBench shows 6 10% perf. regression (copying strings while decoding) 7 8 Use Vector<UChar> instead of String when building up the decoded string in 9 the ICU and Mac decoders. Using String leads to O(n^2) behavior because 10 String grows the buffer every single time that append is called. Using 11 Vector::append instead of String::append also avoids constructing a string 12 each time just to append and a questionable copy that is done inside the 13 String::append function which also contributed to the slowness. 14 15 * platform/PlatformString.h: 16 * platform/String.cpp: (WebCore::String::adopt): Added. Makes a String from a 17 Vector<UChar>, adopting the buffer from the vector to avoid copying and memory 18 allocation. 19 * platform/StringImpl.h: 20 * platform/StringImpl.cpp: (WebCore::StringImpl::adopt): Ditto. 21 22 * platform/StreamingTextDecoder.h: 23 * platform/StreamingTextDecoder.cpp: (WebCore::TextCodec::appendOmittingBOM): 24 Change to use a Vector<UChar> instead of a String, since vectors have better 25 resizing performance (they store a separate capacity). 26 27 * platform/StreamingTextDecoderICU.cpp: (WebCore::TextCodecICU::decode): 28 * platform/mac/StreamingTextDecoderMac.cpp: (WebCore::TextCodecMac::decode): 29 Change to use Vector<UChar> instead of String and then create a string at 30 the end of the process using the new adopt function. 31 1 32 2006-09-28 Sam Weinig <sam.weinig@gmail.com> 2 33 -
trunk/WebCore/platform/PlatformString.h
r16568 r16622 61 61 62 62 static String newUninitialized(size_t length, UChar*& characterBuffer); 63 static String adopt(Vector<UChar>&); 63 64 64 65 operator KJS::Identifier() const; -
trunk/WebCore/platform/StreamingTextDecoder.cpp
r16245 r16622 40 40 // We strip BOM characters because they can show up both at the start of content 41 41 // and inside content, and we never want them to end up in the decoded text. 42 void TextCodec::appendOmittingBOM( String& s, const UChar* characters, size_t length)42 void TextCodec::appendOmittingBOM(Vector<UChar>& v, const UChar* characters, size_t length) 43 43 { 44 44 size_t start = 0; … … 46 46 if (BOM == characters[i]) { 47 47 if (start != i) 48 s.append(String(&characters[start], i - start));48 v.append(&characters[start], i - start); 49 49 start = i + 1; 50 50 } 51 51 } 52 52 if (start != length) 53 s.append(String(&characters[start], length - start));53 v.append(&characters[start], length - start); 54 54 } 55 55 -
trunk/WebCore/platform/StreamingTextDecoder.h
r16245 r16622 31 31 #include <memory> 32 32 #include <wtf/Noncopyable.h> 33 #include <wtf/Vector.h> 33 34 34 35 namespace WebCore { … … 46 47 47 48 protected: 48 static void appendOmittingBOM( String&, const UChar*, size_t length);49 static void appendOmittingBOM(Vector<UChar>&, const UChar*, size_t length); 49 50 }; 50 51 -
trunk/WebCore/platform/StreamingTextDecoderICU.cpp
r16245 r16622 192 192 } 193 193 194 String result = "";194 Vector<UChar> result; 195 195 196 196 UChar buffer[ConversionBufferSize]; … … 221 221 } 222 222 223 return result;223 return String::adopt(result); 224 224 } 225 225 -
trunk/WebCore/platform/String.cpp
r16568 r16622 489 489 } 490 490 491 String String::adopt(Vector<UChar>& buffer) 492 { 493 // For an empty buffer, construct an empty string, not a null string, 494 // and use a standard constructor so we get the shared empty string. 495 if (buffer.isEmpty()) 496 return ""; 497 return StringImpl::adopt(buffer); 498 } 499 491 500 } // namespace WebCore 492 501 -
trunk/WebCore/platform/StringImpl.cpp
r16570 r16622 1069 1069 } 1070 1070 1071 StringImpl* StringImpl::adopt(Vector<UChar>& buffer) 1072 { 1073 size_t size = buffer.size(); 1074 UChar* data = buffer.releaseBuffer(); 1075 data = static_cast<UChar*>(fastRealloc(data, size * sizeof(UChar))); 1076 1077 StringImpl* result = new StringImpl; 1078 result->m_length = size; 1079 result->m_data = data; 1080 return result; 1081 } 1082 1071 1083 } // namespace WebCore -
trunk/WebCore/platform/StringImpl.h
r16568 r16622 67 67 68 68 static StringImpl* newUninitialized(size_t length, UChar*& characterBuffer); 69 static StringImpl* adopt(Vector<UChar>&); 69 70 70 71 const UChar* characters() const { return m_data; } -
trunk/WebCore/platform/mac/StreamingTextDecoderMac.cpp
r16245 r16622 194 194 return String(); 195 195 196 String result("");196 Vector<UChar> result; 197 197 198 198 const unsigned char* sourcePointer = reinterpret_cast<const unsigned char*>(bytes); … … 254 254 } 255 255 256 String resultString = String::adopt(result); 257 256 258 // Workaround for a bug in the Text Encoding Converter (see bug 3225472). 257 259 // Simplified Chinese pages use the code U+A3A0 to mean "full-width space". … … 259 261 // To work around, just change all occurences of U+E5E5 to U+3000 (ideographic space). 260 262 if (m_encoding == kCFStringEncodingGB_18030_2000) 261 result .replace(0xE5E5, 0x3000);263 resultString.replace(0xE5E5, 0x3000); 262 264 263 return result ;265 return resultString; 264 266 } 265 267
Note: See TracChangeset
for help on using the changeset viewer.