Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(61)

Side by Side Diff: Source/wtf/Vector.h

Issue 228403002: Deque: Add HeapDeque and prevent buggy use of swap and operator= (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Created 6 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698