/Users/buildslave/jenkins/workspace/coverage/llvm-project/clang/include/clang/Analysis/Support/BumpVector.h
Line | Count | Source (jump to first uncovered line) |
1 | | //===- BumpVector.h - Vector-like ADT that uses bump allocation -*- C++ -*-===// |
2 | | // |
3 | | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
4 | | // See https://llvm.org/LICENSE.txt for license information. |
5 | | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
6 | | // |
7 | | //===----------------------------------------------------------------------===// |
8 | | // |
9 | | // This file provides BumpVector, a vector-like ADT whose contents are |
10 | | // allocated from a BumpPtrAllocator. |
11 | | // |
12 | | //===----------------------------------------------------------------------===// |
13 | | |
14 | | // FIXME: Most of this is copy-and-paste from SmallVector.h. We can |
15 | | // refactor this core logic into something common that is shared between |
16 | | // the two. The main thing that is different is the allocation strategy. |
17 | | |
18 | | #ifndef LLVM_CLANG_ANALYSIS_SUPPORT_BUMPVECTOR_H |
19 | | #define LLVM_CLANG_ANALYSIS_SUPPORT_BUMPVECTOR_H |
20 | | |
21 | | #include "llvm/ADT/PointerIntPair.h" |
22 | | #include "llvm/Support/Allocator.h" |
23 | | #include <cassert> |
24 | | #include <cstddef> |
25 | | #include <cstring> |
26 | | #include <iterator> |
27 | | #include <memory> |
28 | | #include <type_traits> |
29 | | |
30 | | namespace clang { |
31 | | |
32 | | class BumpVectorContext { |
33 | | llvm::PointerIntPair<llvm::BumpPtrAllocator*, 1> Alloc; |
34 | | |
35 | | public: |
36 | | /// Construct a new BumpVectorContext that creates a new BumpPtrAllocator |
37 | | /// and destroys it when the BumpVectorContext object is destroyed. |
38 | 220k | BumpVectorContext() : Alloc(new llvm::BumpPtrAllocator(), 1) {} |
39 | | |
40 | 3.16k | BumpVectorContext(BumpVectorContext &&Other) : Alloc(Other.Alloc) { |
41 | 3.16k | Other.Alloc.setInt(false); |
42 | 3.16k | Other.Alloc.setPointer(nullptr); |
43 | 3.16k | } |
44 | | |
45 | | /// Construct a new BumpVectorContext that reuses an existing |
46 | | /// BumpPtrAllocator. This BumpPtrAllocator is not destroyed when the |
47 | | /// BumpVectorContext object is destroyed. |
48 | 3.80k | BumpVectorContext(llvm::BumpPtrAllocator &A) : Alloc(&A, 0) {} |
49 | | |
50 | 224k | ~BumpVectorContext() { |
51 | 224k | if (Alloc.getInt()) |
52 | 220k | delete Alloc.getPointer(); |
53 | 224k | } |
54 | | |
55 | 9.91M | llvm::BumpPtrAllocator &getAllocator() { return *Alloc.getPointer(); } |
56 | | }; |
57 | | |
58 | | template<typename T> |
59 | | class BumpVector { |
60 | | T *Begin = nullptr; |
61 | | T *End = nullptr; |
62 | | T *Capacity = nullptr; |
63 | | |
64 | | public: |
65 | | // Default ctor - Initialize to empty. |
66 | 2.50M | explicit BumpVector(BumpVectorContext &C, unsigned N) { |
67 | 2.50M | reserve(C, N); |
68 | 2.50M | } clang::BumpVector<clang::VarDecl const*>::BumpVector(clang::BumpVectorContext&, unsigned int) Line | Count | Source | 66 | 399 | explicit BumpVector(BumpVectorContext &C, unsigned N) { | 67 | 399 | reserve(C, N); | 68 | 399 | } |
clang::BumpVector<clang::CFGElement>::BumpVector(clang::BumpVectorContext&, unsigned int) Line | Count | Source | 66 | 760k | explicit BumpVector(BumpVectorContext &C, unsigned N) { | 67 | 760k | reserve(C, N); | 68 | 760k | } |
clang::BumpVector<clang::CFGBlock::AdjacentBlock>::BumpVector(clang::BumpVectorContext&, unsigned int) Line | Count | Source | 66 | 1.52M | explicit BumpVector(BumpVectorContext &C, unsigned N) { | 67 | 1.52M | reserve(C, N); | 68 | 1.52M | } |
clang::BumpVector<clang::CFGBlock*>::BumpVector(clang::BumpVectorContext&, unsigned int) Line | Count | Source | 66 | 178k | explicit BumpVector(BumpVectorContext &C, unsigned N) { | 67 | 178k | reserve(C, N); | 68 | 178k | } |
clang::BumpVector<clang::VarDecl*>::BumpVector(clang::BumpVectorContext&, unsigned int) Line | Count | Source | 66 | 3.16k | explicit BumpVector(BumpVectorContext &C, unsigned N) { | 67 | 3.16k | reserve(C, N); | 68 | 3.16k | } |
clang::BumpVector<clang::ento::ExplodedNode*>::BumpVector(clang::BumpVectorContext&, unsigned int) Line | Count | Source | 66 | 39.7k | explicit BumpVector(BumpVectorContext &C, unsigned N) { | 67 | 39.7k | reserve(C, N); | 68 | 39.7k | } |
clang::BumpVector<clang::ento::MemRegion const*>::BumpVector(clang::BumpVectorContext&, unsigned int) Line | Count | Source | 66 | 472 | explicit BumpVector(BumpVectorContext &C, unsigned N) { | 67 | 472 | reserve(C, N); | 68 | 472 | } |
|
69 | | |
70 | 178k | ~BumpVector() { |
71 | 178k | if (std::is_class<T>::value) { |
72 | | // Destroy the constructed elements in the vector. |
73 | 0 | destroy_range(Begin, End); |
74 | 0 | } |
75 | 178k | } |
76 | | |
77 | | using size_type = size_t; |
78 | | using difference_type = ptrdiff_t; |
79 | | using value_type = T; |
80 | | using iterator = T *; |
81 | | using const_iterator = const T *; |
82 | | |
83 | | using const_reverse_iterator = std::reverse_iterator<const_iterator>; |
84 | | using reverse_iterator = std::reverse_iterator<iterator>; |
85 | | |
86 | | using reference = T &; |
87 | | using const_reference = const T &; |
88 | | using pointer = T *; |
89 | | using const_pointer = const T *; |
90 | | |
91 | | // forward iterator creation methods. |
92 | 1.05M | iterator begin() { return Begin; } clang::BumpVector<clang::CFGElement>::begin() Line | Count | Source | 92 | 84.1k | iterator begin() { return Begin; } |
clang::BumpVector<clang::CFGBlock::AdjacentBlock>::begin() Line | Count | Source | 92 | 153k | iterator begin() { return Begin; } |
clang::BumpVector<clang::CFGBlock*>::begin() Line | Count | Source | 92 | 802k | iterator begin() { return Begin; } |
clang::BumpVector<clang::ento::ExplodedNode*>::begin() Line | Count | Source | 92 | 13.4k | iterator begin() { return Begin; } |
clang::BumpVector<clang::ento::MemRegion const*>::begin() Line | Count | Source | 92 | 4.57k | iterator begin() { return Begin; } |
|
93 | 1.61M | const_iterator begin() const { return Begin; } clang::BumpVector<clang::CFGElement>::begin() const Line | Count | Source | 93 | 348k | const_iterator begin() const { return Begin; } |
clang::BumpVector<clang::CFGBlock::AdjacentBlock>::begin() const Line | Count | Source | 93 | 1.25M | const_iterator begin() const { return Begin; } |
clang::BumpVector<clang::CFGBlock*>::begin() const Line | Count | Source | 93 | 5.11k | const_iterator begin() const { return Begin; } |
clang::BumpVector<clang::VarDecl const*>::begin() const Line | Count | Source | 93 | 789 | const_iterator begin() const { return Begin; } |
|
94 | 1.99M | iterator end() { return End; } clang::BumpVector<clang::CFGElement>::end() Line | Count | Source | 94 | 84.0k | iterator end() { return End; } |
clang::BumpVector<clang::CFGBlock::AdjacentBlock>::end() Line | Count | Source | 94 | 153k | iterator end() { return End; } |
clang::BumpVector<clang::CFGBlock*>::end() Line | Count | Source | 94 | 1.74M | iterator end() { return End; } |
clang::BumpVector<clang::ento::ExplodedNode*>::end() Line | Count | Source | 94 | 12.1k | iterator end() { return End; } |
clang::BumpVector<clang::ento::MemRegion const*>::end() Line | Count | Source | 94 | 4.57k | iterator end() { return End; } |
|
95 | 1.51M | const_iterator end() const { return End; } clang::BumpVector<clang::CFGElement>::end() const Line | Count | Source | 95 | 393k | const_iterator end() const { return End; } |
clang::BumpVector<clang::CFGBlock::AdjacentBlock>::end() const Line | Count | Source | 95 | 1.11M | const_iterator end() const { return End; } |
clang::BumpVector<clang::CFGBlock*>::end() const Line | Count | Source | 95 | 5.13k | const_iterator end() const { return End; } |
clang::BumpVector<clang::VarDecl const*>::end() const Line | Count | Source | 95 | 789 | const_iterator end() const { return End; } |
|
96 | | |
97 | | // reverse iterator creation methods. |
98 | 84.1k | reverse_iterator rbegin() { return reverse_iterator(end()); } clang::BumpVector<clang::CFGElement>::rbegin() Line | Count | Source | 98 | 84.0k | reverse_iterator rbegin() { return reverse_iterator(end()); } |
Unexecuted instantiation: clang::BumpVector<clang::CFGBlock::AdjacentBlock>::rbegin() clang::BumpVector<clang::CFGBlock*>::rbegin() Line | Count | Source | 98 | 76 | reverse_iterator rbegin() { return reverse_iterator(end()); } |
|
99 | 78.5k | const_reverse_iterator rbegin() const{ return const_reverse_iterator(end()); } clang::BumpVector<clang::CFGElement>::rbegin() const Line | Count | Source | 99 | 77.9k | const_reverse_iterator rbegin() const{ return const_reverse_iterator(end()); } |
Unexecuted instantiation: clang::BumpVector<clang::CFGBlock*>::rbegin() const clang::BumpVector<clang::CFGBlock::AdjacentBlock>::rbegin() const Line | Count | Source | 99 | 548 | const_reverse_iterator rbegin() const{ return const_reverse_iterator(end()); } |
|
100 | 84.1k | reverse_iterator rend() { return reverse_iterator(begin()); } clang::BumpVector<clang::CFGElement>::rend() Line | Count | Source | 100 | 84.1k | reverse_iterator rend() { return reverse_iterator(begin()); } |
Unexecuted instantiation: clang::BumpVector<clang::CFGBlock::AdjacentBlock>::rend() clang::BumpVector<clang::CFGBlock*>::rend() Line | Count | Source | 100 | 76 | reverse_iterator rend() { return reverse_iterator(begin()); } |
|
101 | 78.3k | const_reverse_iterator rend() const { |
102 | 78.3k | return const_reverse_iterator(begin()); |
103 | 78.3k | } clang::BumpVector<clang::CFGElement>::rend() const Line | Count | Source | 101 | 77.9k | const_reverse_iterator rend() const { | 102 | 77.9k | return const_reverse_iterator(begin()); | 103 | 77.9k | } |
Unexecuted instantiation: clang::BumpVector<clang::CFGBlock*>::rend() const clang::BumpVector<clang::CFGBlock::AdjacentBlock>::rend() const Line | Count | Source | 101 | 396 | const_reverse_iterator rend() const { | 102 | 396 | return const_reverse_iterator(begin()); | 103 | 396 | } |
|
104 | | |
105 | 1.32M | bool empty() const { return Begin == End; } clang::BumpVector<clang::CFGElement>::empty() const Line | Count | Source | 105 | 1.28M | bool empty() const { return Begin == End; } |
clang::BumpVector<clang::CFGBlock::AdjacentBlock>::empty() const Line | Count | Source | 105 | 40.9k | bool empty() const { return Begin == End; } |
|
106 | 10.7M | size_type size() const { return End-Begin; } clang::BumpVector<clang::CFGElement>::size() const Line | Count | Source | 106 | 8.52M | size_type size() const { return End-Begin; } |
clang::BumpVector<clang::CFGBlock::AdjacentBlock>::size() const Line | Count | Source | 106 | 1.93M | size_type size() const { return End-Begin; } |
clang::BumpVector<clang::CFGBlock*>::size() const Line | Count | Source | 106 | 186k | size_type size() const { return End-Begin; } |
clang::BumpVector<clang::VarDecl const*>::size() const Line | Count | Source | 106 | 399 | size_type size() const { return End-Begin; } |
clang::BumpVector<clang::VarDecl*>::size() const Line | Count | Source | 106 | 7.97k | size_type size() const { return End-Begin; } |
clang::BumpVector<clang::ento::ExplodedNode*>::size() const Line | Count | Source | 106 | 125k | size_type size() const { return End-Begin; } |
clang::BumpVector<clang::ento::MemRegion const*>::size() const Line | Count | Source | 106 | 472 | size_type size() const { return End-Begin; } |
|
107 | | |
108 | | reference operator[](unsigned idx) { |
109 | | assert(Begin + idx < End); |
110 | | return Begin[idx]; |
111 | | } |
112 | 3.22M | const_reference operator[](unsigned idx) const { |
113 | 3.22M | assert(Begin + idx < End); |
114 | 3.22M | return Begin[idx]; |
115 | 3.22M | } clang::BumpVector<clang::VarDecl*>::operator[](unsigned int) const Line | Count | Source | 112 | 20.5k | const_reference operator[](unsigned idx) const { | 113 | 20.5k | assert(Begin + idx < End); | 114 | 20.5k | return Begin[idx]; | 115 | 20.5k | } |
clang::BumpVector<clang::CFGElement>::operator[](unsigned int) const Line | Count | Source | 112 | 3.20M | const_reference operator[](unsigned idx) const { | 113 | 3.20M | assert(Begin + idx < End); | 114 | 3.20M | return Begin[idx]; | 115 | 3.20M | } |
|
116 | | |
117 | 0 | reference front() { |
118 | 0 | return begin()[0]; |
119 | 0 | } |
120 | 62.7k | const_reference front() const { |
121 | 62.7k | return begin()[0]; |
122 | 62.7k | } |
123 | | |
124 | 937k | reference back() { |
125 | 937k | return end()[-1]; |
126 | 937k | } |
127 | 109k | const_reference back() const { |
128 | 109k | return end()[-1]; |
129 | 109k | } |
130 | | |
131 | | void pop_back() { |
132 | | --End; |
133 | | End->~T(); |
134 | | } |
135 | | |
136 | | T pop_back_val() { |
137 | | T Result = back(); |
138 | | pop_back(); |
139 | | return Result; |
140 | | } |
141 | | |
142 | | void clear() { |
143 | | if (std::is_class<T>::value) { |
144 | | destroy_range(Begin, End); |
145 | | } |
146 | | End = Begin; |
147 | | } |
148 | | |
149 | | /// data - Return a pointer to the vector's buffer, even if empty(). |
150 | | pointer data() { |
151 | | return pointer(Begin); |
152 | | } |
153 | | |
154 | | /// data - Return a pointer to the vector's buffer, even if empty(). |
155 | | const_pointer data() const { |
156 | | return const_pointer(Begin); |
157 | | } |
158 | | |
159 | 5.26M | void push_back(const_reference Elt, BumpVectorContext &C) { |
160 | 5.26M | if (End < Capacity) { |
161 | 5.26M | Retry: |
162 | 5.26M | new (End) T(Elt); |
163 | 5.26M | ++End; |
164 | 5.26M | return; |
165 | 567k | } |
166 | 567k | grow(C); |
167 | 567k | goto Retry; |
168 | 567k | } clang::BumpVector<clang::CFGElement>::push_back(clang::CFGElement const&, clang::BumpVectorContext&) Line | Count | Source | 159 | 3.03M | void push_back(const_reference Elt, BumpVectorContext &C) { | 160 | 3.03M | if (End < Capacity) { | 161 | 3.03M | Retry: | 162 | 3.03M | new (End) T(Elt); | 163 | 3.03M | ++End; | 164 | 3.03M | return; | 165 | 350k | } | 166 | 350k | grow(C); | 167 | 350k | goto Retry; | 168 | 350k | } |
clang::BumpVector<clang::VarDecl const*>::push_back(clang::VarDecl const* const&, clang::BumpVectorContext&) Line | Count | Source | 159 | 327 | void push_back(const_reference Elt, BumpVectorContext &C) { | 160 | 327 | if (End < Capacity) { | 161 | 327 | Retry: | 162 | 327 | new (End) T(Elt); | 163 | 327 | ++End; | 164 | 327 | return; | 165 | 0 | } | 166 | 0 | grow(C); | 167 | 0 | goto Retry; | 168 | 0 | } |
clang::BumpVector<clang::VarDecl*>::push_back(clang::VarDecl* const&, clang::BumpVectorContext&) Line | Count | Source | 159 | 4.78k | void push_back(const_reference Elt, BumpVectorContext &C) { | 160 | 4.78k | if (End < Capacity) { | 161 | 4.78k | Retry: | 162 | 4.78k | new (End) T(Elt); | 163 | 4.78k | ++End; | 164 | 4.78k | return; | 165 | 22 | } | 166 | 22 | grow(C); | 167 | 22 | goto Retry; | 168 | 22 | } |
clang::BumpVector<clang::CFGBlock*>::push_back(clang::CFGBlock* const&, clang::BumpVectorContext&) Line | Count | Source | 159 | 760k | void push_back(const_reference Elt, BumpVectorContext &C) { | 160 | 760k | if (End < Capacity) { | 161 | 760k | Retry: | 162 | 760k | new (End) T(Elt); | 163 | 760k | ++End; | 164 | 760k | return; | 165 | 8.72k | } | 166 | 8.72k | grow(C); | 167 | 8.72k | goto Retry; | 168 | 8.72k | } |
clang::BumpVector<clang::CFGBlock::AdjacentBlock>::push_back(clang::CFGBlock::AdjacentBlock const&, clang::BumpVectorContext&) Line | Count | Source | 159 | 1.38M | void push_back(const_reference Elt, BumpVectorContext &C) { | 160 | 1.38M | if (End < Capacity) { | 161 | 1.38M | Retry: | 162 | 1.38M | new (End) T(Elt); | 163 | 1.38M | ++End; | 164 | 1.38M | return; | 165 | 207k | } | 166 | 207k | grow(C); | 167 | 207k | goto Retry; | 168 | 207k | } |
clang::BumpVector<clang::ento::ExplodedNode*>::push_back(clang::ento::ExplodedNode* const&, clang::BumpVectorContext&) Line | Count | Source | 159 | 82.8k | void push_back(const_reference Elt, BumpVectorContext &C) { | 160 | 82.8k | if (End < Capacity) { | 161 | 82.8k | Retry: | 162 | 82.8k | new (End) T(Elt); | 163 | 82.8k | ++End; | 164 | 82.8k | return; | 165 | 251 | } | 166 | 251 | grow(C); | 167 | 251 | goto Retry; | 168 | 251 | } |
clang::BumpVector<clang::ento::MemRegion const*>::push_back(clang::ento::MemRegion const* const&, clang::BumpVectorContext&) Line | Count | Source | 159 | 594 | void push_back(const_reference Elt, BumpVectorContext &C) { | 160 | 594 | if (End < Capacity) { | 161 | 594 | Retry: | 162 | 594 | new (End) T(Elt); | 163 | 594 | ++End; | 164 | 594 | return; | 165 | 0 | } | 166 | 0 | grow(C); | 167 | 0 | goto Retry; | 168 | 0 | } |
|
169 | | |
170 | | /// insert - Insert some number of copies of element into a position. Return |
171 | | /// iterator to position after last inserted copy. |
172 | | iterator insert(iterator I, size_t Cnt, const_reference E, |
173 | 70 | BumpVectorContext &C) { |
174 | 70 | assert(I >= Begin && I <= End && "Iterator out of bounds."); |
175 | 70 | if (End + Cnt <= Capacity) { |
176 | 70 | Retry: |
177 | 70 | move_range_right(I, End, Cnt); |
178 | 70 | construct_range(I, I + Cnt, E); |
179 | 70 | End += Cnt; |
180 | 70 | return I + Cnt; |
181 | 0 | } |
182 | 0 | ptrdiff_t D = I - Begin; |
183 | 0 | grow(C, size() + Cnt); |
184 | 0 | I = Begin + D; |
185 | 0 | goto Retry; |
186 | 0 | } |
187 | | |
188 | 2.50M | void reserve(BumpVectorContext &C, unsigned N) { |
189 | 2.50M | if (unsigned(Capacity-Begin) < N) |
190 | 2.50M | grow(C, N); |
191 | 2.50M | } clang::BumpVector<clang::CFGElement>::reserve(clang::BumpVectorContext&, unsigned int) Line | Count | Source | 188 | 760k | void reserve(BumpVectorContext &C, unsigned N) { | 189 | 760k | if (unsigned(Capacity-Begin) < N) | 190 | 760k | grow(C, N); | 191 | 760k | } |
clang::BumpVector<clang::CFGBlock::AdjacentBlock>::reserve(clang::BumpVectorContext&, unsigned int) Line | Count | Source | 188 | 1.52M | void reserve(BumpVectorContext &C, unsigned N) { | 189 | 1.52M | if (unsigned(Capacity-Begin) < N) | 190 | 1.52M | grow(C, N); | 191 | 1.52M | } |
clang::BumpVector<clang::CFGBlock*>::reserve(clang::BumpVectorContext&, unsigned int) Line | Count | Source | 188 | 178k | void reserve(BumpVectorContext &C, unsigned N) { | 189 | 178k | if (unsigned(Capacity-Begin) < N) | 190 | 178k | grow(C, N); | 191 | 178k | } |
clang::BumpVector<clang::VarDecl const*>::reserve(clang::BumpVectorContext&, unsigned int) Line | Count | Source | 188 | 399 | void reserve(BumpVectorContext &C, unsigned N) { | 189 | 399 | if (unsigned(Capacity-Begin) < N) | 190 | 399 | grow(C, N); | 191 | 399 | } |
clang::BumpVector<clang::VarDecl*>::reserve(clang::BumpVectorContext&, unsigned int) Line | Count | Source | 188 | 3.16k | void reserve(BumpVectorContext &C, unsigned N) { | 189 | 3.16k | if (unsigned(Capacity-Begin) < N) | 190 | 3.16k | grow(C, N); | 191 | 3.16k | } |
clang::BumpVector<clang::ento::ExplodedNode*>::reserve(clang::BumpVectorContext&, unsigned int) Line | Count | Source | 188 | 39.7k | void reserve(BumpVectorContext &C, unsigned N) { | 189 | 39.7k | if (unsigned(Capacity-Begin) < N) | 190 | 39.7k | grow(C, N); | 191 | 39.7k | } |
clang::BumpVector<clang::ento::MemRegion const*>::reserve(clang::BumpVectorContext&, unsigned int) Line | Count | Source | 188 | 472 | void reserve(BumpVectorContext &C, unsigned N) { | 189 | 472 | if (unsigned(Capacity-Begin) < N) | 190 | 472 | grow(C, N); | 191 | 472 | } |
|
192 | | |
193 | | /// capacity - Return the total number of elements in the currently allocated |
194 | | /// buffer. |
195 | | size_t capacity() const { return Capacity - Begin; } |
196 | | |
197 | | private: |
198 | | /// grow - double the size of the allocated memory, guaranteeing space for at |
199 | | /// least one more element or MinSize if specified. |
200 | | void grow(BumpVectorContext &C, size_type MinSize = 1); |
201 | | |
202 | 70 | void construct_range(T *S, T *E, const T &Elt) { |
203 | 97 | for (; S != E; ++S27 ) |
204 | 27 | new (S) T(Elt); |
205 | 70 | } |
206 | | |
207 | 558k | void destroy_range(T *S, T *E) { |
208 | 3.48M | while (S != E) { |
209 | 2.92M | --E; |
210 | 2.92M | E->~T(); |
211 | 2.92M | } |
212 | 558k | } clang::BumpVector<clang::CFGElement>::destroy_range(clang::CFGElement*, clang::CFGElement*) Line | Count | Source | 207 | 350k | void destroy_range(T *S, T *E) { | 208 | 3.04M | while (S != E) { | 209 | 2.69M | --E; | 210 | 2.69M | E->~T(); | 211 | 2.69M | } | 212 | 350k | } |
clang::BumpVector<clang::CFGBlock::AdjacentBlock>::destroy_range(clang::CFGBlock::AdjacentBlock*, clang::CFGBlock::AdjacentBlock*) Line | Count | Source | 207 | 207k | void destroy_range(T *S, T *E) { | 208 | 440k | while (S != E) { | 209 | 233k | --E; | 210 | 233k | E->~T(); | 211 | 233k | } | 212 | 207k | } |
Unexecuted instantiation: clang::BumpVector<clang::CFGBlock*>::destroy_range(clang::CFGBlock**, clang::CFGBlock**) Unexecuted instantiation: clang::BumpVector<clang::VarDecl const*>::destroy_range(clang::VarDecl const**, clang::VarDecl const**) Unexecuted instantiation: clang::BumpVector<clang::VarDecl*>::destroy_range(clang::VarDecl**, clang::VarDecl**) Unexecuted instantiation: clang::BumpVector<clang::ento::ExplodedNode*>::destroy_range(clang::ento::ExplodedNode**, clang::ento::ExplodedNode**) Unexecuted instantiation: clang::BumpVector<clang::ento::MemRegion const*>::destroy_range(clang::ento::MemRegion const**, clang::ento::MemRegion const**) |
213 | | |
214 | 70 | void move_range_right(T *S, T *E, size_t D) { |
215 | 169 | for (T *I = E + D - 1, *IL = S + D - 1; I != IL; --I99 ) { |
216 | 99 | --E; |
217 | 99 | new (I) T(*E); |
218 | 99 | E->~T(); |
219 | 99 | } |
220 | 70 | } |
221 | | }; |
222 | | |
223 | | // Define this out-of-line to dissuade the C++ compiler from inlining it. |
224 | | template <typename T> |
225 | 3.06M | void BumpVector<T>::grow(BumpVectorContext &C, size_t MinSize) { |
226 | 3.06M | size_t CurCapacity = Capacity-Begin; |
227 | 3.06M | size_t CurSize = size(); |
228 | 3.06M | size_t NewCapacity = 2*CurCapacity; |
229 | 3.06M | if (NewCapacity < MinSize) |
230 | 2.50M | NewCapacity = MinSize; |
231 | | |
232 | | // Allocate the memory from the BumpPtrAllocator. |
233 | 3.06M | T *NewElts = C.getAllocator().template Allocate<T>(NewCapacity); |
234 | | |
235 | | // Copy the elements over. |
236 | 3.06M | if (Begin != End) { |
237 | 567k | if (std::is_class<T>::value) { |
238 | 558k | std::uninitialized_copy(Begin, End, NewElts); |
239 | | // Destroy the original elements. |
240 | 558k | destroy_range(Begin, End); |
241 | 8.99k | } else { |
242 | | // Use memcpy for PODs (std::uninitialized_copy optimizes to memmove). |
243 | 8.99k | memcpy(NewElts, Begin, CurSize * sizeof(T)); |
244 | 8.99k | } |
245 | 567k | } |
246 | | |
247 | | // For now, leak 'Begin'. We can add it back to a freelist in |
248 | | // BumpVectorContext. |
249 | 3.06M | Begin = NewElts; |
250 | 3.06M | End = NewElts+CurSize; |
251 | 3.06M | Capacity = Begin+NewCapacity; |
252 | 3.06M | } clang::BumpVector<clang::CFGElement>::grow(clang::BumpVectorContext&, unsigned long) Line | Count | Source | 225 | 1.11M | void BumpVector<T>::grow(BumpVectorContext &C, size_t MinSize) { | 226 | 1.11M | size_t CurCapacity = Capacity-Begin; | 227 | 1.11M | size_t CurSize = size(); | 228 | 1.11M | size_t NewCapacity = 2*CurCapacity; | 229 | 1.11M | if (NewCapacity < MinSize) | 230 | 760k | NewCapacity = MinSize; | 231 | | | 232 | | // Allocate the memory from the BumpPtrAllocator. | 233 | 1.11M | T *NewElts = C.getAllocator().template Allocate<T>(NewCapacity); | 234 | | | 235 | | // Copy the elements over. | 236 | 1.11M | if (Begin != End) { | 237 | 350k | if (std::is_class<T>::value) { | 238 | 350k | std::uninitialized_copy(Begin, End, NewElts); | 239 | | // Destroy the original elements. | 240 | 350k | destroy_range(Begin, End); | 241 | 0 | } else { | 242 | | // Use memcpy for PODs (std::uninitialized_copy optimizes to memmove). | 243 | 0 | memcpy(NewElts, Begin, CurSize * sizeof(T)); | 244 | 0 | } | 245 | 350k | } | 246 | | | 247 | | // For now, leak 'Begin'. We can add it back to a freelist in | 248 | | // BumpVectorContext. | 249 | 1.11M | Begin = NewElts; | 250 | 1.11M | End = NewElts+CurSize; | 251 | 1.11M | Capacity = Begin+NewCapacity; | 252 | 1.11M | } |
clang::BumpVector<clang::CFGBlock::AdjacentBlock>::grow(clang::BumpVectorContext&, unsigned long) Line | Count | Source | 225 | 1.72M | void BumpVector<T>::grow(BumpVectorContext &C, size_t MinSize) { | 226 | 1.72M | size_t CurCapacity = Capacity-Begin; | 227 | 1.72M | size_t CurSize = size(); | 228 | 1.72M | size_t NewCapacity = 2*CurCapacity; | 229 | 1.72M | if (NewCapacity < MinSize) | 230 | 1.52M | NewCapacity = MinSize; | 231 | | | 232 | | // Allocate the memory from the BumpPtrAllocator. | 233 | 1.72M | T *NewElts = C.getAllocator().template Allocate<T>(NewCapacity); | 234 | | | 235 | | // Copy the elements over. | 236 | 1.72M | if (Begin != End) { | 237 | 207k | if (std::is_class<T>::value) { | 238 | 207k | std::uninitialized_copy(Begin, End, NewElts); | 239 | | // Destroy the original elements. | 240 | 207k | destroy_range(Begin, End); | 241 | 0 | } else { | 242 | | // Use memcpy for PODs (std::uninitialized_copy optimizes to memmove). | 243 | 0 | memcpy(NewElts, Begin, CurSize * sizeof(T)); | 244 | 0 | } | 245 | 207k | } | 246 | | | 247 | | // For now, leak 'Begin'. We can add it back to a freelist in | 248 | | // BumpVectorContext. | 249 | 1.72M | Begin = NewElts; | 250 | 1.72M | End = NewElts+CurSize; | 251 | 1.72M | Capacity = Begin+NewCapacity; | 252 | 1.72M | } |
clang::BumpVector<clang::CFGBlock*>::grow(clang::BumpVectorContext&, unsigned long) Line | Count | Source | 225 | 186k | void BumpVector<T>::grow(BumpVectorContext &C, size_t MinSize) { | 226 | 186k | size_t CurCapacity = Capacity-Begin; | 227 | 186k | size_t CurSize = size(); | 228 | 186k | size_t NewCapacity = 2*CurCapacity; | 229 | 186k | if (NewCapacity < MinSize) | 230 | 178k | NewCapacity = MinSize; | 231 | | | 232 | | // Allocate the memory from the BumpPtrAllocator. | 233 | 186k | T *NewElts = C.getAllocator().template Allocate<T>(NewCapacity); | 234 | | | 235 | | // Copy the elements over. | 236 | 186k | if (Begin != End) { | 237 | 8.72k | if (std::is_class<T>::value) { | 238 | 0 | std::uninitialized_copy(Begin, End, NewElts); | 239 | | // Destroy the original elements. | 240 | 0 | destroy_range(Begin, End); | 241 | 8.72k | } else { | 242 | | // Use memcpy for PODs (std::uninitialized_copy optimizes to memmove). | 243 | 8.72k | memcpy(NewElts, Begin, CurSize * sizeof(T)); | 244 | 8.72k | } | 245 | 8.72k | } | 246 | | | 247 | | // For now, leak 'Begin'. We can add it back to a freelist in | 248 | | // BumpVectorContext. | 249 | 186k | Begin = NewElts; | 250 | 186k | End = NewElts+CurSize; | 251 | 186k | Capacity = Begin+NewCapacity; | 252 | 186k | } |
clang::BumpVector<clang::VarDecl const*>::grow(clang::BumpVectorContext&, unsigned long) Line | Count | Source | 225 | 399 | void BumpVector<T>::grow(BumpVectorContext &C, size_t MinSize) { | 226 | 399 | size_t CurCapacity = Capacity-Begin; | 227 | 399 | size_t CurSize = size(); | 228 | 399 | size_t NewCapacity = 2*CurCapacity; | 229 | 399 | if (NewCapacity < MinSize) | 230 | 399 | NewCapacity = MinSize; | 231 | | | 232 | | // Allocate the memory from the BumpPtrAllocator. | 233 | 399 | T *NewElts = C.getAllocator().template Allocate<T>(NewCapacity); | 234 | | | 235 | | // Copy the elements over. | 236 | 399 | if (Begin != End) { | 237 | 0 | if (std::is_class<T>::value) { | 238 | 0 | std::uninitialized_copy(Begin, End, NewElts); | 239 | | // Destroy the original elements. | 240 | 0 | destroy_range(Begin, End); | 241 | 0 | } else { | 242 | | // Use memcpy for PODs (std::uninitialized_copy optimizes to memmove). | 243 | 0 | memcpy(NewElts, Begin, CurSize * sizeof(T)); | 244 | 0 | } | 245 | 0 | } | 246 | | | 247 | | // For now, leak 'Begin'. We can add it back to a freelist in | 248 | | // BumpVectorContext. | 249 | 399 | Begin = NewElts; | 250 | 399 | End = NewElts+CurSize; | 251 | 399 | Capacity = Begin+NewCapacity; | 252 | 399 | } |
clang::BumpVector<clang::VarDecl*>::grow(clang::BumpVectorContext&, unsigned long) Line | Count | Source | 225 | 3.19k | void BumpVector<T>::grow(BumpVectorContext &C, size_t MinSize) { | 226 | 3.19k | size_t CurCapacity = Capacity-Begin; | 227 | 3.19k | size_t CurSize = size(); | 228 | 3.19k | size_t NewCapacity = 2*CurCapacity; | 229 | 3.19k | if (NewCapacity < MinSize) | 230 | 3.16k | NewCapacity = MinSize; | 231 | | | 232 | | // Allocate the memory from the BumpPtrAllocator. | 233 | 3.19k | T *NewElts = C.getAllocator().template Allocate<T>(NewCapacity); | 234 | | | 235 | | // Copy the elements over. | 236 | 3.19k | if (Begin != End) { | 237 | 22 | if (std::is_class<T>::value) { | 238 | 0 | std::uninitialized_copy(Begin, End, NewElts); | 239 | | // Destroy the original elements. | 240 | 0 | destroy_range(Begin, End); | 241 | 22 | } else { | 242 | | // Use memcpy for PODs (std::uninitialized_copy optimizes to memmove). | 243 | 22 | memcpy(NewElts, Begin, CurSize * sizeof(T)); | 244 | 22 | } | 245 | 22 | } | 246 | | | 247 | | // For now, leak 'Begin'. We can add it back to a freelist in | 248 | | // BumpVectorContext. | 249 | 3.19k | Begin = NewElts; | 250 | 3.19k | End = NewElts+CurSize; | 251 | 3.19k | Capacity = Begin+NewCapacity; | 252 | 3.19k | } |
clang::BumpVector<clang::ento::ExplodedNode*>::grow(clang::BumpVectorContext&, unsigned long) Line | Count | Source | 225 | 40.0k | void BumpVector<T>::grow(BumpVectorContext &C, size_t MinSize) { | 226 | 40.0k | size_t CurCapacity = Capacity-Begin; | 227 | 40.0k | size_t CurSize = size(); | 228 | 40.0k | size_t NewCapacity = 2*CurCapacity; | 229 | 40.0k | if (NewCapacity < MinSize) | 230 | 39.7k | NewCapacity = MinSize; | 231 | | | 232 | | // Allocate the memory from the BumpPtrAllocator. | 233 | 40.0k | T *NewElts = C.getAllocator().template Allocate<T>(NewCapacity); | 234 | | | 235 | | // Copy the elements over. | 236 | 40.0k | if (Begin != End) { | 237 | 251 | if (std::is_class<T>::value) { | 238 | 0 | std::uninitialized_copy(Begin, End, NewElts); | 239 | | // Destroy the original elements. | 240 | 0 | destroy_range(Begin, End); | 241 | 251 | } else { | 242 | | // Use memcpy for PODs (std::uninitialized_copy optimizes to memmove). | 243 | 251 | memcpy(NewElts, Begin, CurSize * sizeof(T)); | 244 | 251 | } | 245 | 251 | } | 246 | | | 247 | | // For now, leak 'Begin'. We can add it back to a freelist in | 248 | | // BumpVectorContext. | 249 | 40.0k | Begin = NewElts; | 250 | 40.0k | End = NewElts+CurSize; | 251 | 40.0k | Capacity = Begin+NewCapacity; | 252 | 40.0k | } |
clang::BumpVector<clang::ento::MemRegion const*>::grow(clang::BumpVectorContext&, unsigned long) Line | Count | Source | 225 | 472 | void BumpVector<T>::grow(BumpVectorContext &C, size_t MinSize) { | 226 | 472 | size_t CurCapacity = Capacity-Begin; | 227 | 472 | size_t CurSize = size(); | 228 | 472 | size_t NewCapacity = 2*CurCapacity; | 229 | 472 | if (NewCapacity < MinSize) | 230 | 472 | NewCapacity = MinSize; | 231 | | | 232 | | // Allocate the memory from the BumpPtrAllocator. | 233 | 472 | T *NewElts = C.getAllocator().template Allocate<T>(NewCapacity); | 234 | | | 235 | | // Copy the elements over. | 236 | 472 | if (Begin != End) { | 237 | 0 | if (std::is_class<T>::value) { | 238 | 0 | std::uninitialized_copy(Begin, End, NewElts); | 239 | | // Destroy the original elements. | 240 | 0 | destroy_range(Begin, End); | 241 | 0 | } else { | 242 | | // Use memcpy for PODs (std::uninitialized_copy optimizes to memmove). | 243 | 0 | memcpy(NewElts, Begin, CurSize * sizeof(T)); | 244 | 0 | } | 245 | 0 | } | 246 | | | 247 | | // For now, leak 'Begin'. We can add it back to a freelist in | 248 | | // BumpVectorContext. | 249 | 472 | Begin = NewElts; | 250 | 472 | End = NewElts+CurSize; | 251 | 472 | Capacity = Begin+NewCapacity; | 252 | 472 | } |
|
253 | | |
254 | | } // namespace clang |
255 | | |
256 | | #endif // LLVM_CLANG_ANALYSIS_SUPPORT_BUMPVECTOR_H |