/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 | 289k | BumpVectorContext() : Alloc(new llvm::BumpPtrAllocator(), 1) {} |
39 | | |
40 | 3.43k | BumpVectorContext(BumpVectorContext &&Other) : Alloc(Other.Alloc) { |
41 | 3.43k | Other.Alloc.setInt(false); |
42 | 3.43k | Other.Alloc.setPointer(nullptr); |
43 | 3.43k | } |
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 | 4.09k | BumpVectorContext(llvm::BumpPtrAllocator &A) : Alloc(&A, 0) {} |
49 | | |
50 | 293k | ~BumpVectorContext() { |
51 | 293k | if (Alloc.getInt()) |
52 | 289k | delete Alloc.getPointer(); |
53 | 293k | } |
54 | | |
55 | 15.7M | 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 | 3.33M | explicit BumpVector(BumpVectorContext &C, unsigned N) { |
67 | 3.33M | reserve(C, N); |
68 | 3.33M | } clang::BumpVector<clang::VarDecl const*>::BumpVector(clang::BumpVectorContext&, unsigned int) Line | Count | Source | 66 | 418 | explicit BumpVector(BumpVectorContext &C, unsigned N) { | 67 | 418 | reserve(C, N); | 68 | 418 | } |
clang::BumpVector<clang::CFGElement>::BumpVector(clang::BumpVectorContext&, unsigned int) Line | Count | Source | 66 | 1.01M | explicit BumpVector(BumpVectorContext &C, unsigned N) { | 67 | 1.01M | reserve(C, N); | 68 | 1.01M | } |
clang::BumpVector<clang::CFGBlock::AdjacentBlock>::BumpVector(clang::BumpVectorContext&, unsigned int) Line | Count | Source | 66 | 2.02M | explicit BumpVector(BumpVectorContext &C, unsigned N) { | 67 | 2.02M | reserve(C, N); | 68 | 2.02M | } |
clang::BumpVector<clang::CFGBlock*>::BumpVector(clang::BumpVectorContext&, unsigned int) Line | Count | Source | 66 | 233k | explicit BumpVector(BumpVectorContext &C, unsigned N) { | 67 | 233k | reserve(C, N); | 68 | 233k | } |
clang::BumpVector<clang::VarDecl*>::BumpVector(clang::BumpVectorContext&, unsigned int) Line | Count | Source | 66 | 3.43k | explicit BumpVector(BumpVectorContext &C, unsigned N) { | 67 | 3.43k | reserve(C, N); | 68 | 3.43k | } |
clang::BumpVector<clang::ento::ExplodedNode*>::BumpVector(clang::BumpVectorContext&, unsigned int) Line | Count | Source | 66 | 60.2k | explicit BumpVector(BumpVectorContext &C, unsigned N) { | 67 | 60.2k | reserve(C, N); | 68 | 60.2k | } |
clang::BumpVector<clang::ento::MemRegion const*>::BumpVector(clang::BumpVectorContext&, unsigned int) Line | Count | Source | 66 | 490 | explicit BumpVector(BumpVectorContext &C, unsigned N) { | 67 | 490 | reserve(C, N); | 68 | 490 | } |
|
69 | | |
70 | 233k | ~BumpVector() { |
71 | 233k | if (std::is_class<T>::value) { |
72 | | // Destroy the constructed elements in the vector. |
73 | 0 | destroy_range(Begin, End); |
74 | 0 | } |
75 | 233k | } |
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.40M | iterator begin() { return Begin; } clang::BumpVector<clang::CFGElement>::begin() Line | Count | Source | 92 | 103k | iterator begin() { return Begin; } |
clang::BumpVector<clang::CFGBlock::AdjacentBlock>::begin() Line | Count | Source | 92 | 187k | iterator begin() { return Begin; } |
clang::BumpVector<clang::CFGBlock*>::begin() Line | Count | Source | 92 | 1.05M | iterator begin() { return Begin; } |
clang::BumpVector<clang::ento::ExplodedNode*>::begin() Line | Count | Source | 92 | 44.1k | iterator begin() { return Begin; } |
clang::BumpVector<clang::ento::MemRegion const*>::begin() Line | Count | Source | 92 | 4.77k | iterator begin() { return Begin; } |
|
93 | 2.11M | const_iterator begin() const { return Begin; } clang::BumpVector<clang::CFGElement>::begin() const Line | Count | Source | 93 | 423k | const_iterator begin() const { return Begin; } |
clang::BumpVector<clang::CFGBlock::AdjacentBlock>::begin() const Line | Count | Source | 93 | 1.68M | const_iterator begin() const { return Begin; } |
clang::BumpVector<clang::CFGBlock*>::begin() const Line | Count | Source | 93 | 6.67k | const_iterator begin() const { return Begin; } |
clang::BumpVector<clang::VarDecl const*>::begin() const Line | Count | Source | 93 | 827 | const_iterator begin() const { return Begin; } |
|
94 | 2.64M | iterator end() { return End; } clang::BumpVector<clang::CFGElement>::end() Line | Count | Source | 94 | 103k | iterator end() { return End; } |
clang::BumpVector<clang::CFGBlock::AdjacentBlock>::end() Line | Count | Source | 94 | 187k | iterator end() { return End; } |
clang::BumpVector<clang::CFGBlock*>::end() Line | Count | Source | 94 | 2.30M | iterator end() { return End; } |
clang::BumpVector<clang::ento::ExplodedNode*>::end() Line | Count | Source | 94 | 42.3k | iterator end() { return End; } |
clang::BumpVector<clang::ento::MemRegion const*>::end() Line | Count | Source | 94 | 4.77k | iterator end() { return End; } |
|
95 | 1.99M | const_iterator end() const { return End; } clang::BumpVector<clang::CFGElement>::end() const Line | Count | Source | 95 | 492k | const_iterator end() const { return End; } |
clang::BumpVector<clang::CFGBlock::AdjacentBlock>::end() const Line | Count | Source | 95 | 1.49M | const_iterator end() const { return End; } |
clang::BumpVector<clang::CFGBlock*>::end() const Line | Count | Source | 95 | 6.69k | const_iterator end() const { return End; } |
clang::BumpVector<clang::VarDecl const*>::end() const Line | Count | Source | 95 | 827 | const_iterator end() const { return End; } |
|
96 | | |
97 | | // reverse iterator creation methods. |
98 | 103k | reverse_iterator rbegin() { return reverse_iterator(end()); } clang::BumpVector<clang::CFGElement>::rbegin() Line | Count | Source | 98 | 103k | reverse_iterator rbegin() { return reverse_iterator(end()); } |
Unexecuted instantiation: clang::BumpVector<clang::CFGBlock::AdjacentBlock>::rbegin() clang::BumpVector<clang::CFGBlock*>::rbegin() Line | Count | Source | 98 | 83 | reverse_iterator rbegin() { return reverse_iterator(end()); } |
|
99 | 75.6k | const_reverse_iterator rbegin() const{ return const_reverse_iterator(end()); } clang::BumpVector<clang::CFGElement>::rbegin() const Line | Count | Source | 99 | 75.0k | 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 | 645 | const_reverse_iterator rbegin() const{ return const_reverse_iterator(end()); } |
|
100 | 103k | reverse_iterator rend() { return reverse_iterator(begin()); } clang::BumpVector<clang::CFGElement>::rend() Line | Count | Source | 100 | 103k | reverse_iterator rend() { return reverse_iterator(begin()); } |
Unexecuted instantiation: clang::BumpVector<clang::CFGBlock::AdjacentBlock>::rend() clang::BumpVector<clang::CFGBlock*>::rend() Line | Count | Source | 100 | 83 | reverse_iterator rend() { return reverse_iterator(begin()); } |
|
101 | 75.4k | const_reverse_iterator rend() const { |
102 | 75.4k | return const_reverse_iterator(begin()); |
103 | 75.4k | } clang::BumpVector<clang::CFGElement>::rend() const Line | Count | Source | 101 | 74.9k | const_reverse_iterator rend() const { | 102 | 74.9k | return const_reverse_iterator(begin()); | 103 | 74.9k | } |
Unexecuted instantiation: clang::BumpVector<clang::CFGBlock*>::rend() const clang::BumpVector<clang::CFGBlock::AdjacentBlock>::rend() const Line | Count | Source | 101 | 474 | const_reverse_iterator rend() const { | 102 | 474 | return const_reverse_iterator(begin()); | 103 | 474 | } |
|
104 | | |
105 | 1.74M | bool empty() const { return Begin == End; } clang::BumpVector<clang::CFGElement>::empty() const Line | Count | Source | 105 | 1.69M | bool empty() const { return Begin == End; } |
clang::BumpVector<clang::CFGBlock::AdjacentBlock>::empty() const Line | Count | Source | 105 | 57.7k | bool empty() const { return Begin == End; } |
|
106 | 14.4M | size_type size() const { return End-Begin; } clang::BumpVector<clang::CFGElement>::size() const Line | Count | Source | 106 | 11.4M | size_type size() const { return End-Begin; } |
clang::BumpVector<clang::CFGBlock::AdjacentBlock>::size() const Line | Count | Source | 106 | 2.55M | size_type size() const { return End-Begin; } |
clang::BumpVector<clang::CFGBlock*>::size() const Line | Count | Source | 106 | 244k | size_type size() const { return End-Begin; } |
clang::BumpVector<clang::VarDecl const*>::size() const Line | Count | Source | 106 | 418 | size_type size() const { return End-Begin; } |
clang::BumpVector<clang::VarDecl*>::size() const Line | Count | Source | 106 | 8.55k | size_type size() const { return End-Begin; } |
clang::BumpVector<clang::ento::ExplodedNode*>::size() const Line | Count | Source | 106 | 160k | size_type size() const { return End-Begin; } |
clang::BumpVector<clang::ento::MemRegion const*>::size() const Line | Count | Source | 106 | 490 | size_type size() const { return End-Begin; } |
|
107 | | |
108 | | reference operator[](unsigned idx) { |
109 | | assert(Begin + idx < End); |
110 | | return Begin[idx]; |
111 | | } |
112 | 4.29M | const_reference operator[](unsigned idx) const { |
113 | 4.29M | assert(Begin + idx < End); |
114 | 4.29M | return Begin[idx]; |
115 | 4.29M | } clang::BumpVector<clang::VarDecl*>::operator[](unsigned int) const Line | Count | Source | 112 | 22.0k | const_reference operator[](unsigned idx) const { | 113 | 22.0k | assert(Begin + idx < End); | 114 | 22.0k | return Begin[idx]; | 115 | 22.0k | } |
clang::BumpVector<clang::CFGElement>::operator[](unsigned int) const Line | Count | Source | 112 | 4.27M | const_reference operator[](unsigned idx) const { | 113 | 4.27M | assert(Begin + idx < End); | 114 | 4.27M | return Begin[idx]; | 115 | 4.27M | } |
|
116 | | |
117 | 0 | reference front() { |
118 | 0 | return begin()[0]; |
119 | 0 | } |
120 | 67.3k | const_reference front() const { |
121 | 67.3k | return begin()[0]; |
122 | 67.3k | } |
123 | | |
124 | 1.24M | reference back() { |
125 | 1.24M | return end()[-1]; |
126 | 1.24M | } |
127 | 138k | const_reference back() const { |
128 | 138k | return end()[-1]; |
129 | 138k | } |
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 | 7.13M | void push_back(const_reference Elt, BumpVectorContext &C) { |
160 | 7.13M | if (End < Capacity) { |
161 | 7.13M | Retry: |
162 | 7.13M | new (End) T(Elt); |
163 | 7.13M | ++End; |
164 | 7.13M | return; |
165 | 6.34M | } |
166 | 797k | grow(C); |
167 | 797k | goto Retry; |
168 | 7.13M | } clang::BumpVector<clang::CFGElement>::push_back(clang::CFGElement const&, clang::BumpVectorContext&) Line | Count | Source | 159 | 4.12M | void push_back(const_reference Elt, BumpVectorContext &C) { | 160 | 4.12M | if (End < Capacity) { | 161 | 4.12M | Retry: | 162 | 4.12M | new (End) T(Elt); | 163 | 4.12M | ++End; | 164 | 4.12M | return; | 165 | 3.62M | } | 166 | 501k | grow(C); | 167 | 501k | goto Retry; | 168 | 4.12M | } |
clang::BumpVector<clang::VarDecl const*>::push_back(clang::VarDecl const* const&, clang::BumpVectorContext&) Line | Count | Source | 159 | 339 | void push_back(const_reference Elt, BumpVectorContext &C) { | 160 | 339 | if (End < Capacity) { | 161 | 339 | Retry: | 162 | 339 | new (End) T(Elt); | 163 | 339 | ++End; | 164 | 339 | return; | 165 | 339 | } | 166 | 0 | grow(C); | 167 | 0 | goto Retry; | 168 | 339 | } |
clang::BumpVector<clang::VarDecl*>::push_back(clang::VarDecl* const&, clang::BumpVectorContext&) Line | Count | Source | 159 | 5.09k | void push_back(const_reference Elt, BumpVectorContext &C) { | 160 | 5.09k | if (End < Capacity) { | 161 | 5.09k | Retry: | 162 | 5.09k | new (End) T(Elt); | 163 | 5.09k | ++End; | 164 | 5.09k | return; | 165 | 5.06k | } | 166 | 30 | grow(C); | 167 | 30 | goto Retry; | 168 | 5.09k | } |
clang::BumpVector<clang::CFGBlock*>::push_back(clang::CFGBlock* const&, clang::BumpVectorContext&) Line | Count | Source | 159 | 1.01M | void push_back(const_reference Elt, BumpVectorContext &C) { | 160 | 1.01M | if (End < Capacity) { | 161 | 1.01M | Retry: | 162 | 1.01M | new (End) T(Elt); | 163 | 1.01M | ++End; | 164 | 1.01M | return; | 165 | 1.00M | } | 166 | 10.9k | grow(C); | 167 | 10.9k | goto Retry; | 168 | 1.01M | } |
clang::BumpVector<clang::CFGBlock::AdjacentBlock>::push_back(clang::CFGBlock::AdjacentBlock const&, clang::BumpVectorContext&) Line | Count | Source | 159 | 1.85M | void push_back(const_reference Elt, BumpVectorContext &C) { | 160 | 1.85M | if (End < Capacity) { | 161 | 1.85M | Retry: | 162 | 1.85M | new (End) T(Elt); | 163 | 1.85M | ++End; | 164 | 1.85M | return; | 165 | 1.57M | } | 166 | 283k | grow(C); | 167 | 283k | goto Retry; | 168 | 1.85M | } |
clang::BumpVector<clang::ento::ExplodedNode*>::push_back(clang::ento::ExplodedNode* const&, clang::BumpVectorContext&) Line | Count | Source | 159 | 138k | void push_back(const_reference Elt, BumpVectorContext &C) { | 160 | 138k | if (End < Capacity) { | 161 | 138k | Retry: | 162 | 138k | new (End) T(Elt); | 163 | 138k | ++End; | 164 | 138k | return; | 165 | 136k | } | 166 | 1.61k | grow(C); | 167 | 1.61k | goto Retry; | 168 | 138k | } |
clang::BumpVector<clang::ento::MemRegion const*>::push_back(clang::ento::MemRegion const* const&, clang::BumpVectorContext&) Line | Count | Source | 159 | 616 | void push_back(const_reference Elt, BumpVectorContext &C) { | 160 | 616 | if (End < Capacity) { | 161 | 616 | Retry: | 162 | 616 | new (End) T(Elt); | 163 | 616 | ++End; | 164 | 616 | return; | 165 | 616 | } | 166 | 0 | grow(C); | 167 | 0 | goto Retry; | 168 | 616 | } |
|
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 | 73 | BumpVectorContext &C) { |
174 | 73 | assert(I >= Begin && I <= End && "Iterator out of bounds."); |
175 | 73 | if (End + Cnt <= Capacity) { |
176 | 73 | Retry: |
177 | 73 | move_range_right(I, End, Cnt); |
178 | 73 | construct_range(I, I + Cnt, E); |
179 | 73 | End += Cnt; |
180 | 73 | return I + Cnt; |
181 | 73 | } |
182 | 0 | ptrdiff_t D = I - Begin; |
183 | 0 | grow(C, size() + Cnt); |
184 | 0 | I = Begin + D; |
185 | 0 | goto Retry; |
186 | 73 | } |
187 | | |
188 | 3.33M | void reserve(BumpVectorContext &C, unsigned N) { |
189 | 3.33M | if (unsigned(Capacity-Begin) < N) |
190 | 3.33M | grow(C, N); |
191 | 3.33M | } clang::BumpVector<clang::CFGElement>::reserve(clang::BumpVectorContext&, unsigned int) Line | Count | Source | 188 | 1.01M | void reserve(BumpVectorContext &C, unsigned N) { | 189 | 1.01M | if (unsigned(Capacity-Begin) < N) | 190 | 1.01M | grow(C, N); | 191 | 1.01M | } |
clang::BumpVector<clang::CFGBlock::AdjacentBlock>::reserve(clang::BumpVectorContext&, unsigned int) Line | Count | Source | 188 | 2.02M | void reserve(BumpVectorContext &C, unsigned N) { | 189 | 2.02M | if (unsigned(Capacity-Begin) < N) | 190 | 2.02M | grow(C, N); | 191 | 2.02M | } |
clang::BumpVector<clang::CFGBlock*>::reserve(clang::BumpVectorContext&, unsigned int) Line | Count | Source | 188 | 233k | void reserve(BumpVectorContext &C, unsigned N) { | 189 | 233k | if (unsigned(Capacity-Begin) < N) | 190 | 233k | grow(C, N); | 191 | 233k | } |
clang::BumpVector<clang::VarDecl const*>::reserve(clang::BumpVectorContext&, unsigned int) Line | Count | Source | 188 | 418 | void reserve(BumpVectorContext &C, unsigned N) { | 189 | 418 | if (unsigned(Capacity-Begin) < N) | 190 | 418 | grow(C, N); | 191 | 418 | } |
clang::BumpVector<clang::VarDecl*>::reserve(clang::BumpVectorContext&, unsigned int) Line | Count | Source | 188 | 3.43k | void reserve(BumpVectorContext &C, unsigned N) { | 189 | 3.43k | if (unsigned(Capacity-Begin) < N) | 190 | 3.43k | grow(C, N); | 191 | 3.43k | } |
clang::BumpVector<clang::ento::ExplodedNode*>::reserve(clang::BumpVectorContext&, unsigned int) Line | Count | Source | 188 | 60.2k | void reserve(BumpVectorContext &C, unsigned N) { | 189 | 60.2k | if (unsigned(Capacity-Begin) < N) | 190 | 60.2k | grow(C, N); | 191 | 60.2k | } |
clang::BumpVector<clang::ento::MemRegion const*>::reserve(clang::BumpVectorContext&, unsigned int) Line | Count | Source | 188 | 490 | void reserve(BumpVectorContext &C, unsigned N) { | 189 | 490 | if (unsigned(Capacity-Begin) < N) | 190 | 490 | grow(C, N); | 191 | 490 | } |
|
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 | 73 | void construct_range(T *S, T *E, const T &Elt) { |
203 | 103 | for (; S != E; ++S30 ) |
204 | 30 | new (S) T(Elt); |
205 | 73 | } |
206 | | |
207 | 784k | void destroy_range(T *S, T *E) { |
208 | 4.76M | while (S != E) { |
209 | 3.98M | --E; |
210 | 3.98M | E->~T(); |
211 | 3.98M | } |
212 | 784k | } clang::BumpVector<clang::CFGElement>::destroy_range(clang::CFGElement*, clang::CFGElement*) Line | Count | Source | 207 | 501k | void destroy_range(T *S, T *E) { | 208 | 4.16M | while (S != E) { | 209 | 3.66M | --E; | 210 | 3.66M | E->~T(); | 211 | 3.66M | } | 212 | 501k | } |
clang::BumpVector<clang::CFGBlock::AdjacentBlock>::destroy_range(clang::CFGBlock::AdjacentBlock*, clang::CFGBlock::AdjacentBlock*) Line | Count | Source | 207 | 283k | void destroy_range(T *S, T *E) { | 208 | 601k | while (S != E) { | 209 | 318k | --E; | 210 | 318k | E->~T(); | 211 | 318k | } | 212 | 283k | } |
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 | 73 | void move_range_right(T *S, T *E, size_t D) { |
215 | 172 | 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 | 73 | } |
221 | | }; |
222 | | |
223 | | // Define this out-of-line to dissuade the C++ compiler from inlining it. |
224 | | template <typename T> |
225 | 4.13M | void BumpVector<T>::grow(BumpVectorContext &C, size_t MinSize) { |
226 | 4.13M | size_t CurCapacity = Capacity-Begin; |
227 | 4.13M | size_t CurSize = size(); |
228 | 4.13M | size_t NewCapacity = 2*CurCapacity; |
229 | 4.13M | if (NewCapacity < MinSize) |
230 | 3.33M | NewCapacity = MinSize; |
231 | | |
232 | | // Allocate the memory from the BumpPtrAllocator. |
233 | 4.13M | T *NewElts = C.getAllocator().template Allocate<T>(NewCapacity); |
234 | | |
235 | | // Copy the elements over. |
236 | 4.13M | if (Begin != End) { |
237 | 797k | if (std::is_class<T>::value) { |
238 | 784k | std::uninitialized_copy(Begin, End, NewElts); |
239 | | // Destroy the original elements. |
240 | 784k | destroy_range(Begin, End); |
241 | 784k | } else { |
242 | | // Use memcpy for PODs (std::uninitialized_copy optimizes to memmove). |
243 | 12.5k | memcpy(NewElts, Begin, CurSize * sizeof(T)); |
244 | 12.5k | } |
245 | 797k | } |
246 | | |
247 | | // For now, leak 'Begin'. We can add it back to a freelist in |
248 | | // BumpVectorContext. |
249 | 4.13M | Begin = NewElts; |
250 | 4.13M | End = NewElts+CurSize; |
251 | 4.13M | Capacity = Begin+NewCapacity; |
252 | 4.13M | } clang::BumpVector<clang::CFGElement>::grow(clang::BumpVectorContext&, unsigned long) Line | Count | Source | 225 | 1.51M | void BumpVector<T>::grow(BumpVectorContext &C, size_t MinSize) { | 226 | 1.51M | size_t CurCapacity = Capacity-Begin; | 227 | 1.51M | size_t CurSize = size(); | 228 | 1.51M | size_t NewCapacity = 2*CurCapacity; | 229 | 1.51M | if (NewCapacity < MinSize) | 230 | 1.01M | NewCapacity = MinSize; | 231 | | | 232 | | // Allocate the memory from the BumpPtrAllocator. | 233 | 1.51M | T *NewElts = C.getAllocator().template Allocate<T>(NewCapacity); | 234 | | | 235 | | // Copy the elements over. | 236 | 1.51M | if (Begin != End) { | 237 | 501k | if (std::is_class<T>::value) { | 238 | 501k | std::uninitialized_copy(Begin, End, NewElts); | 239 | | // Destroy the original elements. | 240 | 501k | destroy_range(Begin, End); | 241 | 501k | } else { | 242 | | // Use memcpy for PODs (std::uninitialized_copy optimizes to memmove). | 243 | 0 | memcpy(NewElts, Begin, CurSize * sizeof(T)); | 244 | 0 | } | 245 | 501k | } | 246 | | | 247 | | // For now, leak 'Begin'. We can add it back to a freelist in | 248 | | // BumpVectorContext. | 249 | 1.51M | Begin = NewElts; | 250 | 1.51M | End = NewElts+CurSize; | 251 | 1.51M | Capacity = Begin+NewCapacity; | 252 | 1.51M | } |
clang::BumpVector<clang::CFGBlock::AdjacentBlock>::grow(clang::BumpVectorContext&, unsigned long) Line | Count | Source | 225 | 2.30M | void BumpVector<T>::grow(BumpVectorContext &C, size_t MinSize) { | 226 | 2.30M | size_t CurCapacity = Capacity-Begin; | 227 | 2.30M | size_t CurSize = size(); | 228 | 2.30M | size_t NewCapacity = 2*CurCapacity; | 229 | 2.30M | if (NewCapacity < MinSize) | 230 | 2.02M | NewCapacity = MinSize; | 231 | | | 232 | | // Allocate the memory from the BumpPtrAllocator. | 233 | 2.30M | T *NewElts = C.getAllocator().template Allocate<T>(NewCapacity); | 234 | | | 235 | | // Copy the elements over. | 236 | 2.30M | if (Begin != End) { | 237 | 283k | if (std::is_class<T>::value) { | 238 | 283k | std::uninitialized_copy(Begin, End, NewElts); | 239 | | // Destroy the original elements. | 240 | 283k | destroy_range(Begin, End); | 241 | 283k | } else { | 242 | | // Use memcpy for PODs (std::uninitialized_copy optimizes to memmove). | 243 | 0 | memcpy(NewElts, Begin, CurSize * sizeof(T)); | 244 | 0 | } | 245 | 283k | } | 246 | | | 247 | | // For now, leak 'Begin'. We can add it back to a freelist in | 248 | | // BumpVectorContext. | 249 | 2.30M | Begin = NewElts; | 250 | 2.30M | End = NewElts+CurSize; | 251 | 2.30M | Capacity = Begin+NewCapacity; | 252 | 2.30M | } |
clang::BumpVector<clang::CFGBlock*>::grow(clang::BumpVectorContext&, unsigned long) Line | Count | Source | 225 | 244k | void BumpVector<T>::grow(BumpVectorContext &C, size_t MinSize) { | 226 | 244k | size_t CurCapacity = Capacity-Begin; | 227 | 244k | size_t CurSize = size(); | 228 | 244k | size_t NewCapacity = 2*CurCapacity; | 229 | 244k | if (NewCapacity < MinSize) | 230 | 233k | NewCapacity = MinSize; | 231 | | | 232 | | // Allocate the memory from the BumpPtrAllocator. | 233 | 244k | T *NewElts = C.getAllocator().template Allocate<T>(NewCapacity); | 234 | | | 235 | | // Copy the elements over. | 236 | 244k | if (Begin != End) { | 237 | 10.9k | 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 | 10.9k | } else { | 242 | | // Use memcpy for PODs (std::uninitialized_copy optimizes to memmove). | 243 | 10.9k | memcpy(NewElts, Begin, CurSize * sizeof(T)); | 244 | 10.9k | } | 245 | 10.9k | } | 246 | | | 247 | | // For now, leak 'Begin'. We can add it back to a freelist in | 248 | | // BumpVectorContext. | 249 | 244k | Begin = NewElts; | 250 | 244k | End = NewElts+CurSize; | 251 | 244k | Capacity = Begin+NewCapacity; | 252 | 244k | } |
clang::BumpVector<clang::VarDecl const*>::grow(clang::BumpVectorContext&, unsigned long) Line | Count | Source | 225 | 418 | void BumpVector<T>::grow(BumpVectorContext &C, size_t MinSize) { | 226 | 418 | size_t CurCapacity = Capacity-Begin; | 227 | 418 | size_t CurSize = size(); | 228 | 418 | size_t NewCapacity = 2*CurCapacity; | 229 | 418 | if (NewCapacity < MinSize) | 230 | 418 | NewCapacity = MinSize; | 231 | | | 232 | | // Allocate the memory from the BumpPtrAllocator. | 233 | 418 | T *NewElts = C.getAllocator().template Allocate<T>(NewCapacity); | 234 | | | 235 | | // Copy the elements over. | 236 | 418 | 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 | 418 | Begin = NewElts; | 250 | 418 | End = NewElts+CurSize; | 251 | 418 | Capacity = Begin+NewCapacity; | 252 | 418 | } |
clang::BumpVector<clang::VarDecl*>::grow(clang::BumpVectorContext&, unsigned long) Line | Count | Source | 225 | 3.46k | void BumpVector<T>::grow(BumpVectorContext &C, size_t MinSize) { | 226 | 3.46k | size_t CurCapacity = Capacity-Begin; | 227 | 3.46k | size_t CurSize = size(); | 228 | 3.46k | size_t NewCapacity = 2*CurCapacity; | 229 | 3.46k | if (NewCapacity < MinSize) | 230 | 3.43k | NewCapacity = MinSize; | 231 | | | 232 | | // Allocate the memory from the BumpPtrAllocator. | 233 | 3.46k | T *NewElts = C.getAllocator().template Allocate<T>(NewCapacity); | 234 | | | 235 | | // Copy the elements over. | 236 | 3.46k | if (Begin != End) { | 237 | 30 | 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 | 30 | } else { | 242 | | // Use memcpy for PODs (std::uninitialized_copy optimizes to memmove). | 243 | 30 | memcpy(NewElts, Begin, CurSize * sizeof(T)); | 244 | 30 | } | 245 | 30 | } | 246 | | | 247 | | // For now, leak 'Begin'. We can add it back to a freelist in | 248 | | // BumpVectorContext. | 249 | 3.46k | Begin = NewElts; | 250 | 3.46k | End = NewElts+CurSize; | 251 | 3.46k | Capacity = Begin+NewCapacity; | 252 | 3.46k | } |
clang::BumpVector<clang::ento::ExplodedNode*>::grow(clang::BumpVectorContext&, unsigned long) Line | Count | Source | 225 | 61.8k | void BumpVector<T>::grow(BumpVectorContext &C, size_t MinSize) { | 226 | 61.8k | size_t CurCapacity = Capacity-Begin; | 227 | 61.8k | size_t CurSize = size(); | 228 | 61.8k | size_t NewCapacity = 2*CurCapacity; | 229 | 61.8k | if (NewCapacity < MinSize) | 230 | 60.2k | NewCapacity = MinSize; | 231 | | | 232 | | // Allocate the memory from the BumpPtrAllocator. | 233 | 61.8k | T *NewElts = C.getAllocator().template Allocate<T>(NewCapacity); | 234 | | | 235 | | // Copy the elements over. | 236 | 61.8k | if (Begin != End) { | 237 | 1.61k | 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 | 1.61k | } else { | 242 | | // Use memcpy for PODs (std::uninitialized_copy optimizes to memmove). | 243 | 1.61k | memcpy(NewElts, Begin, CurSize * sizeof(T)); | 244 | 1.61k | } | 245 | 1.61k | } | 246 | | | 247 | | // For now, leak 'Begin'. We can add it back to a freelist in | 248 | | // BumpVectorContext. | 249 | 61.8k | Begin = NewElts; | 250 | 61.8k | End = NewElts+CurSize; | 251 | 61.8k | Capacity = Begin+NewCapacity; | 252 | 61.8k | } |
clang::BumpVector<clang::ento::MemRegion const*>::grow(clang::BumpVectorContext&, unsigned long) Line | Count | Source | 225 | 490 | void BumpVector<T>::grow(BumpVectorContext &C, size_t MinSize) { | 226 | 490 | size_t CurCapacity = Capacity-Begin; | 227 | 490 | size_t CurSize = size(); | 228 | 490 | size_t NewCapacity = 2*CurCapacity; | 229 | 490 | if (NewCapacity < MinSize) | 230 | 490 | NewCapacity = MinSize; | 231 | | | 232 | | // Allocate the memory from the BumpPtrAllocator. | 233 | 490 | T *NewElts = C.getAllocator().template Allocate<T>(NewCapacity); | 234 | | | 235 | | // Copy the elements over. | 236 | 490 | 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 | 490 | Begin = NewElts; | 250 | 490 | End = NewElts+CurSize; | 251 | 490 | Capacity = Begin+NewCapacity; | 252 | 490 | } |
|
253 | | |
254 | | } // namespace clang |
255 | | |
256 | | #endif // LLVM_CLANG_ANALYSIS_SUPPORT_BUMPVECTOR_H |