| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2005, 2006, 2007, 2008 Apple Inc. All rights reserved. | 2 * Copyright (C) 2005, 2006, 2007, 2008 Apple Inc. All rights reserved. |
| 3 * | 3 * |
| 4 * This library is free software; you can redistribute it and/or | 4 * This library is free software; you can redistribute it and/or |
| 5 * modify it under the terms of the GNU Library General Public | 5 * modify it under the terms of the GNU Library General Public |
| 6 * License as published by the Free Software Foundation; either | 6 * License as published by the Free Software Foundation; either |
| 7 * version 2 of the License, or (at your option) any later version. | 7 * version 2 of the License, or (at your option) any later version. |
| 8 * | 8 * |
| 9 * This library is distributed in the hope that it will be useful, | 9 * This library is distributed in the hope that it will be useful, |
| 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of | 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| (...skipping 291 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 302 | 302 |
| 303 size_t allocationSize(size_t capacity) const | 303 size_t allocationSize(size_t capacity) const |
| 304 { | 304 { |
| 305 return Allocator::Quantizer::template quantizedSize<T>(capacity); | 305 return Allocator::Quantizer::template quantizedSize<T>(capacity); |
| 306 } | 306 } |
| 307 | 307 |
| 308 T* buffer() { return m_buffer; } | 308 T* buffer() { return m_buffer; } |
| 309 const T* buffer() const { return m_buffer; } | 309 const T* buffer() const { return m_buffer; } |
| 310 size_t capacity() const { return m_capacity; } | 310 size_t capacity() const { return m_capacity; } |
| 311 | 311 |
| 312 void clearUnusedSlots(T* from, T* to) |
| 313 { |
| 314 VectorUnusedSlotClearer<Allocator::isGarbageCollected && (VectorTrai
ts<T>::needsDestruction || ShouldBeTraced<VectorTraits<T> >::value || VectorTrai
ts<T>::isWeak), T>::clear(from, to); |
| 315 } |
| 316 |
| 312 protected: | 317 protected: |
| 313 VectorBufferBase() | 318 VectorBufferBase() |
| 314 : m_buffer(0) | 319 : m_buffer(0) |
| 315 , m_capacity(0) | 320 , m_capacity(0) |
| 316 { | 321 { |
| 317 } | 322 } |
| 318 | 323 |
| 319 VectorBufferBase(T* buffer, size_t capacity) | 324 VectorBufferBase(T* buffer, size_t capacity) |
| 320 : m_buffer(buffer) | 325 : m_buffer(buffer) |
| 321 , m_capacity(capacity) | 326 , m_capacity(capacity) |
| 322 { | 327 { |
| 323 } | 328 } |
| 324 | 329 |
| 325 T* m_buffer; | 330 T* m_buffer; |
| 326 unsigned m_capacity; | 331 unsigned m_capacity; |
| 327 unsigned m_size; | 332 unsigned m_size; |
| 328 }; | 333 }; |
| 329 | 334 |
| 330 template<typename T, size_t inlineCapacity, typename Allocator = DefaultAllo
cator> | 335 template<typename T, size_t inlineCapacity, typename Allocator = DefaultAllo
cator> |
| 331 class VectorBuffer; | 336 class VectorBuffer; |
| 332 | 337 |
| 333 template<typename T, typename Allocator> | 338 template<typename T, typename Allocator> |
| 334 class VectorBuffer<T, 0, Allocator> : private VectorBufferBase<T, Allocator>
{ | 339 class VectorBuffer<T, 0, Allocator> : protected VectorBufferBase<T, Allocato
r> { |
| 335 private: | 340 private: |
| 336 typedef VectorBufferBase<T, Allocator> Base; | 341 typedef VectorBufferBase<T, Allocator> Base; |
| 337 public: | 342 public: |
| 338 VectorBuffer() | 343 VectorBuffer() |
| 339 { | 344 { |
| 340 } | 345 } |
| 341 | 346 |
| 342 VectorBuffer(size_t capacity) | 347 VectorBuffer(size_t capacity) |
| 343 { | 348 { |
| 344 // Calling malloc(0) might take a lock and may actually do an | 349 // Calling malloc(0) might take a lock and may actually do an |
| (...skipping 24 matching lines...) Expand all Loading... |
| 369 std::swap(m_buffer, other.m_buffer); | 374 std::swap(m_buffer, other.m_buffer); |
| 370 std::swap(m_capacity, other.m_capacity); | 375 std::swap(m_capacity, other.m_capacity); |
| 371 } | 376 } |
| 372 | 377 |
| 373 using Base::allocateBuffer; | 378 using Base::allocateBuffer; |
| 374 using Base::allocationSize; | 379 using Base::allocationSize; |
| 375 | 380 |
| 376 using Base::buffer; | 381 using Base::buffer; |
| 377 using Base::capacity; | 382 using Base::capacity; |
| 378 | 383 |
| 379 protected: | 384 using Base::clearUnusedSlots; |
| 380 using Base::m_size; | |
| 381 | 385 |
| 382 bool hasOutOfLineBuffer() const | 386 bool hasOutOfLineBuffer() const |
| 383 { | 387 { |
| 384 // When inlineCapacity is 0 we have an out of line buffer if we have
a buffer. | 388 // When inlineCapacity is 0 we have an out of line buffer if we have
a buffer. |
| 385 return buffer(); | 389 return buffer(); |
| 386 } | 390 } |
| 387 | 391 |
| 392 protected: |
| 393 using Base::m_size; |
| 394 |
| 388 private: | 395 private: |
| 389 using Base::m_buffer; | 396 using Base::m_buffer; |
| 390 using Base::m_capacity; | 397 using Base::m_capacity; |
| 391 }; | 398 }; |
| 392 | 399 |
| 393 template<typename T, size_t inlineCapacity, typename Allocator> | 400 template<typename T, size_t inlineCapacity, typename Allocator> |
| 394 class VectorBuffer : private VectorBufferBase<T, Allocator> { | 401 class VectorBuffer : protected VectorBufferBase<T, Allocator> { |
| 395 WTF_MAKE_NONCOPYABLE(VectorBuffer); | 402 WTF_MAKE_NONCOPYABLE(VectorBuffer); |
| 396 private: | 403 private: |
| 397 typedef VectorBufferBase<T, Allocator> Base; | 404 typedef VectorBufferBase<T, Allocator> Base; |
| 398 public: | 405 public: |
| 399 VectorBuffer() | 406 VectorBuffer() |
| 400 : Base(inlineBuffer(), inlineCapacity) | 407 : Base(inlineBuffer(), inlineCapacity) |
| 401 { | 408 { |
| 402 } | 409 } |
| 403 | 410 |
| 404 VectorBuffer(size_t capacity) | 411 VectorBuffer(size_t capacity) |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 472 std::swap(m_capacity, other.m_capacity); | 479 std::swap(m_capacity, other.m_capacity); |
| 473 } else { | 480 } else { |
| 474 std::swap(m_buffer, other.m_buffer); | 481 std::swap(m_buffer, other.m_buffer); |
| 475 std::swap(m_capacity, other.m_capacity); | 482 std::swap(m_capacity, other.m_capacity); |
| 476 } | 483 } |
| 477 } | 484 } |
| 478 | 485 |
| 479 using Base::buffer; | 486 using Base::buffer; |
| 480 using Base::capacity; | 487 using Base::capacity; |
| 481 | 488 |
| 482 protected: | |
| 483 using Base::m_size; | |
| 484 | |
| 485 bool hasOutOfLineBuffer() const | 489 bool hasOutOfLineBuffer() const |
| 486 { | 490 { |
| 487 return buffer() && buffer() != inlineBuffer(); | 491 return buffer() && buffer() != inlineBuffer(); |
| 488 } | 492 } |
| 489 | 493 |
| 494 protected: |
| 495 using Base::m_size; |
| 496 |
| 490 private: | 497 private: |
| 491 using Base::m_buffer; | 498 using Base::m_buffer; |
| 492 using Base::m_capacity; | 499 using Base::m_capacity; |
| 493 | 500 |
| 494 static const size_t m_inlineBufferSize = inlineCapacity * sizeof(T); | 501 static const size_t m_inlineBufferSize = inlineCapacity * sizeof(T); |
| 495 T* inlineBuffer() { return reinterpret_cast_ptr<T*>(m_inlineBuffer.buffe
r); } | 502 T* inlineBuffer() { return reinterpret_cast_ptr<T*>(m_inlineBuffer.buffe
r); } |
| 496 const T* inlineBuffer() const { return reinterpret_cast_ptr<const T*>(m_
inlineBuffer.buffer); } | 503 const T* inlineBuffer() const { return reinterpret_cast_ptr<const T*>(m_
inlineBuffer.buffer); } |
| 497 | 504 |
| 498 AlignedBuffer<m_inlineBufferSize, WTF_ALIGN_OF(T)> m_inlineBuffer; | 505 AlignedBuffer<m_inlineBufferSize, WTF_ALIGN_OF(T)> m_inlineBuffer; |
| 499 }; | 506 }; |
| 500 | 507 |
| 501 template<typename T, size_t inlineCapacity, typename Allocator> | 508 template<typename T, size_t inlineCapacity, typename Allocator> |
| 502 class Vector; | 509 class Vector; |
| 503 | 510 |
| 504 // VectorDestructorBase defines the destructor of a vector. This base is use
d in order to | 511 // VectorDestructorBase defines the destructor of a vector. This base is use
d in order to |
| 505 // completely avoid creating a destructor for a vector that does not need to
be destructed. | 512 // completely avoid creating a destructor for a vector that does not need to
be destructed. |
| 506 // By doing so, the clang compiler will have correct information about wheth
er or not a | 513 // By doing so, the clang compiler will have correct information about wheth
er or not a |
| 507 // vector has a trivial destructor and we use that in a compiler plugin to e
nsure the | 514 // vector has a trivial destructor and we use that in a compiler plugin to e
nsure the |
| 508 // correctness of non-finalized garbage-collected classes and the use of Vec
torTraits::needsDestruction. | 515 // correctness of non-finalized garbage-collected classes and the use of Vec
torTraits::needsDestruction. |
| 509 | 516 |
| 510 // All non-GC managed vectors needs a destructor. This destructor will simpl
y call finalize on the actual vector type. | 517 // All non-GC managed vectors need a destructor. This destructor will simply
call finalize on the actual vector type. |
| 511 template<typename Derived, typename Elements, bool hasInlineCapacity, bool i
sGarbageCollected> | 518 template<typename Derived, typename Elements, bool hasInlineCapacity, bool i
sGarbageCollected> |
| 512 class VectorDestructorBase { | 519 class VectorDestructorBase { |
| 513 public: | 520 public: |
| 514 ~VectorDestructorBase() { static_cast<Derived*>(this)->finalize(); } | 521 ~VectorDestructorBase() { static_cast<Derived*>(this)->finalize(); } |
| 515 }; | 522 }; |
| 516 | 523 |
| 517 // Heap-allocated vectors with no inlineCapacity never need a destructor. | 524 // Heap-allocated vectors with no inlineCapacity never need a destructor. |
| 518 template<typename Derived, typename Elements> | 525 template<typename Derived, typename Elements> |
| 519 class VectorDestructorBase<Derived, Elements, false, true> { }; | 526 class VectorDestructorBase<Derived, Elements, false, true> { }; |
| 520 | 527 |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 604 } | 611 } |
| 605 | 612 |
| 606 Base::destruct(); | 613 Base::destruct(); |
| 607 } | 614 } |
| 608 | 615 |
| 609 void finalizeGarbageCollectedObject() | 616 void finalizeGarbageCollectedObject() |
| 610 { | 617 { |
| 611 finalize(); | 618 finalize(); |
| 612 } | 619 } |
| 613 | 620 |
| 614 void clearUnusedSlots(T* from, T* to) | |
| 615 { | |
| 616 VectorUnusedSlotClearer<Allocator::isGarbageCollected && (VectorTrai
ts<T>::needsDestruction || ShouldBeTraced<VectorTraits<T> >::value || VectorTrai
ts<T>::isWeak), T>::clear(from, to); | |
| 617 } | |
| 618 | |
| 619 Vector(const Vector&); | 621 Vector(const Vector&); |
| 620 template<size_t otherCapacity> | 622 template<size_t otherCapacity> |
| 621 explicit Vector(const Vector<T, otherCapacity, Allocator>&); | 623 explicit Vector(const Vector<T, otherCapacity, Allocator>&); |
| 622 | 624 |
| 623 Vector& operator=(const Vector&); | 625 Vector& operator=(const Vector&); |
| 624 template<size_t otherCapacity> | 626 template<size_t otherCapacity> |
| 625 Vector& operator=(const Vector<T, otherCapacity, Allocator>&); | 627 Vector& operator=(const Vector<T, otherCapacity, Allocator>&); |
| 626 | 628 |
| 627 #if COMPILER_SUPPORTS(CXX_RVALUE_REFERENCES) | 629 #if COMPILER_SUPPORTS(CXX_RVALUE_REFERENCES) |
| 628 Vector(Vector&&); | 630 Vector(Vector&&); |
| (...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 728 template<typename U> U* expandCapacity(size_t newMinCapacity, U*); | 730 template<typename U> U* expandCapacity(size_t newMinCapacity, U*); |
| 729 void shrinkCapacity(size_t newCapacity); | 731 void shrinkCapacity(size_t newCapacity); |
| 730 template<typename U> void appendSlowCase(const U&); | 732 template<typename U> void appendSlowCase(const U&); |
| 731 | 733 |
| 732 using Base::m_size; | 734 using Base::m_size; |
| 733 using Base::buffer; | 735 using Base::buffer; |
| 734 using Base::capacity; | 736 using Base::capacity; |
| 735 using Base::swapVectorBuffer; | 737 using Base::swapVectorBuffer; |
| 736 using Base::allocateBuffer; | 738 using Base::allocateBuffer; |
| 737 using Base::allocationSize; | 739 using Base::allocationSize; |
| 740 using Base::clearUnusedSlots; |
| 738 }; | 741 }; |
| 739 | 742 |
| 740 template<typename T, size_t inlineCapacity, typename Allocator> | 743 template<typename T, size_t inlineCapacity, typename Allocator> |
| 741 Vector<T, inlineCapacity, Allocator>::Vector(const Vector& other) | 744 Vector<T, inlineCapacity, Allocator>::Vector(const Vector& other) |
| 742 : Base(other.capacity()) | 745 : Base(other.capacity()) |
| 743 { | 746 { |
| 744 m_size = other.size(); | 747 m_size = other.size(); |
| 745 TypeOperations::uninitializedCopy(other.begin(), other.end(), begin()); | 748 TypeOperations::uninitializedCopy(other.begin(), other.end(), begin()); |
| 746 } | 749 } |
| 747 | 750 |
| (...skipping 453 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1201 } | 1204 } |
| 1202 if (this->hasOutOfLineBuffer()) | 1205 if (this->hasOutOfLineBuffer()) |
| 1203 Allocator::markNoTracing(visitor, buffer()); | 1206 Allocator::markNoTracing(visitor, buffer()); |
| 1204 } | 1207 } |
| 1205 | 1208 |
| 1206 } // namespace WTF | 1209 } // namespace WTF |
| 1207 | 1210 |
| 1208 using WTF::Vector; | 1211 using WTF::Vector; |
| 1209 | 1212 |
| 1210 #endif // WTF_Vector_h | 1213 #endif // WTF_Vector_h |
| OLD | NEW |