Chromium Code Reviews| 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 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 57 template <typename T, size_t inlineBuffer, typename Allocator> | 57 template <typename T, size_t inlineBuffer, typename Allocator> |
| 58 class Deque; | 58 class Deque; |
| 59 | 59 |
| 60 // | 60 // |
| 61 // Vector Traits | 61 // Vector Traits |
| 62 // | 62 // |
| 63 | 63 |
| 64 // Bunch of traits for Vector are defined here, with which you can customize | 64 // Bunch of traits for Vector are defined here, with which you can customize |
| 65 // Vector's behavior. In most cases the default traits are appropriate, so you | 65 // Vector's behavior. In most cases the default traits are appropriate, so you |
| 66 // usually don't have to specialize those traits by yourself. | 66 // usually don't have to specialize those traits by yourself. |
| 67 // | |
| 68 // The behavior of the implementation below can be controlled by VectorTraits. | |
| 69 // If you want to change the behavior of your type, take a look at VectorTraits | |
| 70 // (defined in VectorTraits.h), too. | |
| 67 | 71 |
| 68 template <bool needsDestruction, typename T> | 72 template <bool needsDestruction, typename T> |
| 69 struct VectorDestructor; | 73 struct VectorDestructor; |
| 70 | 74 |
| 71 template <typename T> | 75 template <typename T> |
| 72 struct VectorDestructor<false, T> { | 76 struct VectorDestructor<false, T> { |
| 73 STATIC_ONLY(VectorDestructor); | 77 STATIC_ONLY(VectorDestructor); |
| 74 static void destruct(T*, T*) {} | 78 static void destruct(T*, T*) {} |
| 75 }; | 79 }; |
| 76 | 80 |
| (...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 281 template <typename T> | 285 template <typename T> |
| 282 struct VectorElementComparer<std::unique_ptr<T>> { | 286 struct VectorElementComparer<std::unique_ptr<T>> { |
| 283 STATIC_ONLY(VectorElementComparer); | 287 STATIC_ONLY(VectorElementComparer); |
| 284 template <typename U> | 288 template <typename U> |
| 285 static bool compareElement(const std::unique_ptr<T>& left, const U& right) { | 289 static bool compareElement(const std::unique_ptr<T>& left, const U& right) { |
| 286 return left.get() == right; | 290 return left.get() == right; |
| 287 } | 291 } |
| 288 }; | 292 }; |
| 289 | 293 |
| 290 // A collection of all the traits used by Vector. This is basically an | 294 // A collection of all the traits used by Vector. This is basically an |
| 291 // implementation detail of Vector, and you should specialize individual traits | 295 // implementation detail of Vector, and you probably don't want to change this. |
| 292 // defined above, if you want to customize Vector's behavior. | 296 // If you want to customize Vector's behavior, you should specialize |
| 297 // VectorTraits instead (defined in VectorTraits.h). | |
| 293 template <typename T> | 298 template <typename T> |
| 294 struct VectorTypeOperations { | 299 struct VectorTypeOperations { |
| 295 STATIC_ONLY(VectorTypeOperations); | 300 STATIC_ONLY(VectorTypeOperations); |
| 296 static void destruct(T* begin, T* end) { | 301 static void destruct(T* begin, T* end) { |
| 297 VectorDestructor<VectorTraits<T>::needsDestruction, T>::destruct(begin, | 302 VectorDestructor<VectorTraits<T>::needsDestruction, T>::destruct(begin, |
| 298 end); | 303 end); |
| 299 } | 304 } |
| 300 | 305 |
| 301 static void initialize(T* begin, T* end) { | 306 static void initialize(T* begin, T* end) { |
| 302 VectorInitializer<VectorTraits<T>::canInitializeWithMemset, T>::initialize( | 307 VectorInitializer<VectorTraits<T>::canInitializeWithMemset, T>::initialize( |
| (...skipping 511 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 814 | 819 |
| 815 AlignedBuffer<m_inlineBufferSize, WTF_ALIGN_OF(T)> m_inlineBuffer; | 820 AlignedBuffer<m_inlineBufferSize, WTF_ALIGN_OF(T)> m_inlineBuffer; |
| 816 template <typename U, size_t inlineBuffer, typename V> | 821 template <typename U, size_t inlineBuffer, typename V> |
| 817 friend class Deque; | 822 friend class Deque; |
| 818 }; | 823 }; |
| 819 | 824 |
| 820 // | 825 // |
| 821 // Vector | 826 // Vector |
| 822 // | 827 // |
| 823 | 828 |
| 829 // Vector is a container that works just like std::vector. WTF's Vector has | |
| 830 // several extra functionalities: inline buffer, behavior customization via | |
| 831 // traits, and Oilpan support. Those are explained in the sections below. | |
| 832 // | |
| 833 // Vector is the most basic container, which stores its element in a contiguous | |
| 834 // buffer. The buffer is expanded automatically when necessary. The elements | |
| 835 // are automatically moved to the new buffer. This event is called a | |
| 836 // reallocation. A reallocation takes O(N)-time (N = number of elements), but | |
| 837 // its occurrences are rare, so its time cost should not be significant, | |
| 838 // compared to the time cost of other operations to the vector. | |
| 839 // | |
| 840 // Time complexity of key operations is as follows: | |
| 841 // | |
| 842 // * Indexed access -- O(1) | |
| 843 // * Insertion or removal of an element at the end -- amortized O(1) | |
| 844 // * Other insertion or removal -- O(N) | |
| 845 // * Swapping with another vector -- O(1) | |
| 846 // | |
| 847 // 1. Iterator invalidation semantics | |
| 848 // | |
| 849 // Vector provides STL-compatible iterators and reverse iterators. Iterators | |
| 850 // are _invalidated_ on certain occasions. Reading an invalidated iterator | |
| 851 // causes undefined behavior. | |
| 852 // | |
| 853 // Iterators are invalidated on the following situations: | |
| 854 // | |
| 855 // * When a reallocation happens on a vector, all the iterators for that | |
| 856 // vector will be invalidated. | |
| 857 // * Some member functions invalidate part of the existing iterators for | |
| 858 // the vector; see comments on the individual functions. | |
| 859 // * [Oilpan only] Heap compaction invalidates all the iterators for any | |
| 860 // HeapVectors. This means you can only store an iterator on stack, as | |
| 861 // a local variable. | |
| 862 // | |
| 863 // In this context, pointers or references to an element of a Vector are | |
| 864 // essentially equivalent to iterators, in that they also become invalid | |
| 865 // whenever corresponding iterators are invalidated. | |
| 866 // | |
| 867 // 2. Inline buffer | |
| 868 // | |
| 869 // Vectors may have an _inline buffer_. An inline buffer is a storage area | |
| 870 // that is contained in the vector itself, along with other metadata like | |
| 871 // m_size. It is used as a storage space when the vector's elements fit in | |
| 872 // that space. If the inline buffer becomes full and further space is | |
| 873 // necessary, an out-of-line buffer is allocated in the heap, and it will | |
| 874 // take over the role of the inline buffer. | |
| 875 // | |
| 876 // The existence of an inline buffer is indicated by non-zero |inlineCapacity| | |
| 877 // template argument. The value represents the number of elements that can be | |
| 878 // stored in the inline buffer. Zero |inlineCapacity| means the vector has no | |
| 879 // inline buffer. | |
| 880 // | |
| 881 // An inline buffer increases the size of the Vector instances, and, in trade | |
| 882 // for that, it gives you several performance benefits, as long as the number | |
| 883 // of elements do not exceed |inlineCapacity|: | |
| 884 // | |
| 885 // * No heap allocation will be made. | |
| 886 // * Memory locality will improve. | |
| 887 // | |
| 888 // Generally, having an inline buffer is useful for vectors that (1) are | |
| 889 // frequently accessed or modified, and (2) contain only a few elements at | |
| 890 // most. | |
| 891 // | |
| 892 // 3. Behavior customization | |
| 893 // | |
| 894 // You usually do not need to customize Vector's behavior, since the default | |
| 895 // behavior is appropriate for normal usage. The behavior is controlled by | |
| 896 // VectorTypeOperations traits template above. Read VectorTypeOperations | |
| 897 // and VectorTraits if you want to change the behavior for your types (i.e. | |
| 898 // if you really want faster vector operations). | |
| 899 // | |
| 900 // The default traits basically do the following: | |
| 901 // | |
| 902 // * Skip constructor call and fill zeros with memset for simple types; | |
| 903 // * Skip destructor call for simple types; | |
| 904 // * Copy or move by memcpy for simple types; and | |
| 905 // * Customize the comparisons for smart pointer types, so you can look | |
| 906 // up a std::unique_ptr<T> element with a raw pointer, for instance. | |
| 907 // | |
| 908 // 4. Oilpan | |
| 909 // | |
| 910 // If you want to store garbage collected objects in Vector, (1) use HeapVector | |
| 911 // (defined in HeapAllocator.h) instead of Vector, and (2) make sure your | |
| 912 // garbage-collected type is wrapped with Member or WeakMember, like: | |
|
haraken
2017/02/22 09:55:15
WeakMember is not supported in HeapVector.
Yuta Kitamura
2017/02/23 06:33:28
Done.
| |
| 913 // | |
| 914 // HeapVector<Member<Node>> nodes; | |
| 915 // | |
| 916 // Unlike normal garbage-collected objects, a HeapVector object itself is | |
| 917 // NOT a garbage-collected object, but its backing buffer is allocated in | |
| 918 // Oilpan heap, and it may still carry garbage-collected objects. | |
| 919 // | |
| 920 // Even though a HeapVector object is not garbage-collected, you still need | |
| 921 // to trace it, if you stored it in your class. Also, you can allocate it | |
| 922 // as a local variable. This is useful when you want to build a vector locally | |
| 923 // and put it in an on-heap vector with swap(). | |
| 924 // | |
| 925 // If WeakMember is stored in a HeapVector, an element may become null on | |
| 926 // some GC operation, like normal WeakMembers. | |
|
haraken
2017/02/22 09:55:15
Remove this paragraph.
Yuta Kitamura
2017/02/23 06:33:28
Done.
| |
| 927 // | |
| 928 // Also, heap compaction, which may happen at any time when Blink code is not | |
| 929 // running (i.e. Blink code does not appear in the call stack), may invalidate | |
| 930 // existing iterators for any HeapVectors. So, essentially, you should always | |
| 931 // allocate an iterator on stack (as a local variable), and you should not | |
| 932 // store iterators in another heap object. | |
| 933 | |
| 824 template <typename T, | 934 template <typename T, |
| 825 size_t inlineCapacity = 0, | 935 size_t inlineCapacity = 0, |
| 826 typename Allocator = PartitionAllocator> | 936 typename Allocator = PartitionAllocator> |
| 827 class Vector | 937 class Vector |
| 828 : private VectorBuffer<T, INLINE_CAPACITY, Allocator>, | 938 : private VectorBuffer<T, INLINE_CAPACITY, Allocator>, |
| 829 // Heap-allocated vectors with no inlineCapacity never need a destructor. | 939 // Heap-allocated vectors with no inlineCapacity never need a destructor. |
| 830 public ConditionalDestructor<Vector<T, INLINE_CAPACITY, Allocator>, | 940 public ConditionalDestructor<Vector<T, INLINE_CAPACITY, Allocator>, |
| 831 (INLINE_CAPACITY == 0) && | 941 (INLINE_CAPACITY == 0) && |
| 832 Allocator::isGarbageCollected> { | 942 Allocator::isGarbageCollected> { |
| 833 USE_ALLOCATOR(Vector, Allocator); | 943 USE_ALLOCATOR(Vector, Allocator); |
| (...skipping 959 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1793 visitor, *const_cast<T*>(bufferEntry)); | 1903 visitor, *const_cast<T*>(bufferEntry)); |
| 1794 checkUnusedSlots(buffer() + size(), buffer() + capacity()); | 1904 checkUnusedSlots(buffer() + size(), buffer() + capacity()); |
| 1795 } | 1905 } |
| 1796 } | 1906 } |
| 1797 | 1907 |
| 1798 } // namespace WTF | 1908 } // namespace WTF |
| 1799 | 1909 |
| 1800 using WTF::Vector; | 1910 using WTF::Vector; |
| 1801 | 1911 |
| 1802 #endif // WTF_Vector_h | 1912 #endif // WTF_Vector_h |
| OLD | NEW |