Changeset 26618 in webkit for trunk/JavaScriptCore
- Timestamp:
- Oct 15, 2007, 1:39:10 PM (18 years ago)
- Location:
- trunk/JavaScriptCore
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/JavaScriptCore/ChangeLog
r26617 r26618 1 2007-10-15 Geoffrey Garen <[email protected]> 2 3 Reviewed by Maciej Stachowiak. 4 5 Some Vector optimizations. These are especially important when using 6 Vector as a stack for implementing recursive algorithms iteratively. 7 8 [ Broken off from http://bugs.webkit.org/show_bug.cgi?id=14868 ] 9 10 1. Added shrink(), which is a version of resize() that you can call 11 to save a branch / improve code generation and inlining when you know 12 that the vector is not getting bigger. 13 14 2. Changed subclassing relationship in VectorBuffer to remove a call to 15 fastFree() in the destructor for the inlineCapacity != 0 template 16 specialization. This brings inline Vectors one step closer to true 17 stack-allocated arrays. 18 19 Also changed abort() to CRASH(), since the latter works better. 20 21 * wtf/Vector.h: 22 (WTF::VectorBufferBase::allocateBuffer): 23 (WTF::VectorBufferBase::deallocateBuffer): 24 (WTF::VectorBufferBase::VectorBufferBase): 25 (WTF::VectorBufferBase::~VectorBufferBase): 26 (WTF::): 27 (WTF::VectorBuffer::VectorBuffer): 28 (WTF::VectorBuffer::~VectorBuffer): 29 (WTF::VectorBuffer::deallocateBuffer): 30 (WTF::VectorBuffer::releaseBuffer): 31 (WTF::Vector::clear): 32 (WTF::Vector::removeLast): 33 (WTF::::operator): 34 (WTF::::fill): 35 (WTF::::shrink): 36 1 37 2007-10-12 Geoffrey Garen <[email protected]> 2 38 -
trunk/JavaScriptCore/wtf/Vector.h
r26182 r26618 241 241 }; 242 242 243 template<typename T, size_t inlineCapacity> 244 class VectorBuffer; 245 246 template<typename T> 247 class VectorBuffer<T, 0> { 243 template<typename T> 244 class VectorBufferBase { 248 245 public: 249 VectorBuffer()250 : m_buffer(0), m_capacity(0)251 {252 }253 254 VectorBuffer(size_t capacity)255 #if !ASSERT_DISABLED256 : m_capacity(0)257 #endif258 {259 allocateBuffer(capacity);260 }261 262 ~VectorBuffer()263 {264 deallocateBuffer(m_buffer);265 }266 267 static void deallocateBuffer(T* buffer)268 {269 fastFree(buffer);270 }271 272 246 void allocateBuffer(size_t newCapacity) 273 247 { … … 275 249 m_capacity = newCapacity; 276 250 if (newCapacity > std::numeric_limits<size_t>::max() / sizeof(T)) 277 abort();251 CRASH(); 278 252 m_buffer = static_cast<T*>(fastMalloc(newCapacity * sizeof(T))); 253 } 254 255 void deallocateBuffer(T* bufferToDeallocate) 256 { 257 fastFree(bufferToDeallocate); 279 258 } 280 259 … … 282 261 const T* buffer() const { return m_buffer; } 283 262 size_t capacity() const { return m_capacity; } 284 285 void swap(VectorBuffer<T, 0>& other)286 {287 std::swap(m_capacity, other.m_capacity);288 std::swap(m_buffer, other.m_buffer);289 }290 263 291 264 T* releaseBuffer() … … 298 271 299 272 protected: 300 VectorBuffer(T* buffer, size_t capacity) 301 : m_buffer(buffer), m_capacity(capacity) 302 { 273 VectorBufferBase() 274 : m_buffer(0) 275 , m_capacity(0) 276 { 277 } 278 279 VectorBufferBase(T* buffer, size_t capacity) 280 : m_buffer(buffer) 281 , m_capacity(capacity) 282 { 283 } 284 285 ~VectorBufferBase() 286 { 287 // FIXME: It would be nice to find a way to ASSERT that m_buffer hasn't leaked here. 303 288 } 304 289 305 290 T* m_buffer; 306 291 size_t m_capacity; 292 }; 293 294 template<typename T, size_t inlineCapacity> 295 class VectorBuffer; 296 297 template<typename T> 298 class VectorBuffer<T, 0> : private VectorBufferBase<T> { 307 299 private: 308 size_t m_capacity; 309 }; 310 311 template<typename T, size_t inlineCapacity> 312 class VectorBuffer : private VectorBuffer<T, 0> { 313 private: 314 typedef VectorBuffer<T, 0> BaseBuffer; 300 typedef VectorBufferBase<T> Base; 315 301 public: 316 302 VectorBuffer() 317 : BaseBuffer(inlineBuffer(), inlineCapacity)318 303 { 319 304 } 320 305 321 306 VectorBuffer(size_t capacity) 322 : BaseBuffer(inlineBuffer(), inlineCapacity) 307 { 308 allocateBuffer(capacity); 309 } 310 311 ~VectorBuffer() 312 { 313 deallocateBuffer(buffer()); 314 } 315 316 void swap(VectorBuffer<T, 0>& other) 317 { 318 std::swap(m_buffer, other.m_buffer); 319 std::swap(m_capacity, other.m_capacity); 320 } 321 322 using Base::allocateBuffer; 323 using Base::deallocateBuffer; 324 325 using Base::buffer; 326 using Base::capacity; 327 328 using Base::releaseBuffer; 329 private: 330 using Base::m_buffer; 331 using Base::m_capacity; 332 }; 333 334 template<typename T, size_t inlineCapacity> 335 class VectorBuffer : private VectorBufferBase<T> { 336 private: 337 typedef VectorBufferBase<T> Base; 338 public: 339 VectorBuffer() 340 : Base(inlineBuffer(), inlineCapacity) 341 { 342 } 343 344 VectorBuffer(size_t capacity) 345 : Base(inlineBuffer(), inlineCapacity) 323 346 { 324 347 if (capacity > inlineCapacity) … … 328 351 ~VectorBuffer() 329 352 { 330 if (buffer() == inlineBuffer())331 BaseBuffer::m_buffer = 0;332 } 333 334 void deallocateBuffer(T* buffer) 335 {336 if (buffer != inlineBuffer())337 BaseBuffer::deallocateBuffer(buffer);338 }339 340 using BaseBuffer::allocateBuffer;341 342 using Base Buffer::buffer;343 using Base Buffer::capacity;353 deallocateBuffer(buffer()); 354 } 355 356 using Base::allocateBuffer; 357 358 void deallocateBuffer(T* bufferToDeallocate) 359 { 360 if (bufferToDeallocate == inlineBuffer()) 361 return; 362 Base::deallocateBuffer(bufferToDeallocate); 363 } 364 365 using Base::buffer; 366 using Base::capacity; 344 367 345 368 T* releaseBuffer() … … 347 370 if (buffer() == inlineBuffer()) 348 371 return 0; 349 return BaseBuffer::releaseBuffer(); 350 } 351 352 void swap(VectorBuffer<T, inlineCapacity>&); 372 return Base::releaseBuffer(); 373 } 353 374 354 375 private: 376 using Base::m_buffer; 377 using Base::m_capacity; 378 355 379 static const size_t m_inlineBufferSize = inlineCapacity * sizeof(T); 356 380 T* inlineBuffer() { return reinterpret_cast<T*>(&m_inlineBuffer); } … … 425 449 const T& last() const { return at(size() - 1); } 426 450 451 void shrink(size_t size); 427 452 void resize(size_t size); 428 453 void reserveCapacity(size_t newCapacity); 429 454 430 void clear() { resize(0); }455 void clear() { shrink(0); } 431 456 432 457 template<typename U> void append(const U*, size_t); … … 447 472 { 448 473 ASSERT(!isEmpty()); 449 resize(size() - 1);474 shrink(size() - 1); 450 475 } 451 476 … … 503 528 504 529 if (size() > other.size()) 505 resize(other.size());530 shrink(other.size()); 506 531 else if (other.size() > capacity()) { 507 532 clear(); … … 524 549 525 550 if (size() > other.size()) 526 resize(other.size());551 shrink(other.size()); 527 552 else if (other.size() > capacity()) { 528 553 clear(); … … 541 566 { 542 567 if (size() > newSize) 543 resize(newSize);568 shrink(newSize); 544 569 else if (newSize > capacity()) { 545 570 clear(); … … 596 621 } 597 622 623 m_size = size; 624 } 625 626 template<typename T, size_t inlineCapacity> 627 void Vector<T, inlineCapacity>::shrink(size_t size) 628 { 629 ASSERT(size <= m_size); 630 TypeOperations::destruct(begin() + size, end()); 598 631 m_size = size; 599 632 }
Note:
See TracChangeset
for help on using the changeset viewer.