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 |