/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 | 284k | BumpVectorContext() : Alloc(new llvm::BumpPtrAllocator(), 1) {} |
39 | | |
40 | 3.33k | BumpVectorContext(BumpVectorContext &&Other) : Alloc(Other.Alloc) { |
41 | 3.33k | Other.Alloc.setInt(false); |
42 | 3.33k | Other.Alloc.setPointer(nullptr); |
43 | 3.33k | } |
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.97k | BumpVectorContext(llvm::BumpPtrAllocator &A) : Alloc(&A, 0) {} |
49 | | |
50 | 288k | ~BumpVectorContext() { |
51 | 288k | if (Alloc.getInt()) |
52 | 284k | delete Alloc.getPointer(); |
53 | 288k | } |
54 | | |
55 | 15.0M | 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.38M | explicit BumpVector(BumpVectorContext &C, unsigned N) { |
67 | 3.38M | reserve(C, N); |
68 | 3.38M | } clang::BumpVector<clang::VarDecl const*>::BumpVector(clang::BumpVectorContext&, unsigned int) Line | Count | Source | 66 | 406 | explicit BumpVector(BumpVectorContext &C, unsigned N) { | 67 | 406 | reserve(C, N); | 68 | 406 | } |
clang::BumpVector<clang::CFGElement>::BumpVector(clang::BumpVectorContext&, unsigned int) Line | Count | Source | 66 | 1.03M | explicit BumpVector(BumpVectorContext &C, unsigned N) { | 67 | 1.03M | reserve(C, N); | 68 | 1.03M | } |
clang::BumpVector<clang::CFGBlock::AdjacentBlock>::BumpVector(clang::BumpVectorContext&, unsigned int) Line | Count | Source | 66 | 2.07M | explicit BumpVector(BumpVectorContext &C, unsigned N) { | 67 | 2.07M | reserve(C, N); | 68 | 2.07M | } |
clang::BumpVector<clang::CFGBlock*>::BumpVector(clang::BumpVectorContext&, unsigned int) Line | Count | Source | 66 | 230k | explicit BumpVector(BumpVectorContext &C, unsigned N) { | 67 | 230k | reserve(C, N); | 68 | 230k | } |
clang::BumpVector<clang::VarDecl*>::BumpVector(clang::BumpVectorContext&, unsigned int) Line | Count | Source | 66 | 3.33k | explicit BumpVector(BumpVectorContext &C, unsigned N) { | 67 | 3.33k | reserve(C, N); | 68 | 3.33k | } |
clang::BumpVector<clang::ento::ExplodedNode*>::BumpVector(clang::BumpVectorContext&, unsigned int) Line | Count | Source | 66 | 44.3k | explicit BumpVector(BumpVectorContext &C, unsigned N) { | 67 | 44.3k | reserve(C, N); | 68 | 44.3k | } |
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 | 230k | ~BumpVector() { |
71 | 230k | if (std::is_class<T>::value) { |
72 | | // Destroy the constructed elements in the vector. |
73 | 0 | destroy_range(Begin, End); |
74 | 0 | } |
75 | 230k | } |
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.38M | iterator begin() { return Begin; } clang::BumpVector<clang::CFGElement>::begin() Line | Count | Source | 92 | 102k | iterator begin() { return Begin; } |
clang::BumpVector<clang::CFGBlock::AdjacentBlock>::begin() Line | Count | Source | 92 | 182k | iterator begin() { return Begin; } |
clang::BumpVector<clang::CFGBlock*>::begin() Line | Count | Source | 92 | 1.08M | iterator begin() { return Begin; } |
clang::BumpVector<clang::ento::ExplodedNode*>::begin() Line | Count | Source | 92 | 15.7k | iterator begin() { return Begin; } |
clang::BumpVector<clang::ento::MemRegion const*>::begin() Line | Count | Source | 92 | 4.57k | iterator begin() { return Begin; } |
|
93 | 2.08M | const_iterator begin() const { return Begin; } clang::BumpVector<clang::CFGElement>::begin() const Line | Count | Source | 93 | 408k | const_iterator begin() const { return Begin; } |
clang::BumpVector<clang::CFGBlock::AdjacentBlock>::begin() const Line | Count | Source | 93 | 1.66M | const_iterator begin() const { return Begin; } |
clang::BumpVector<clang::CFGBlock*>::begin() const Line | Count | Source | 93 | 6.22k | const_iterator begin() const { return Begin; } |
clang::BumpVector<clang::VarDecl const*>::begin() const Line | Count | Source | 93 | 803 | const_iterator begin() const { return Begin; } |
|
94 | 2.65M | iterator end() { return End; } clang::BumpVector<clang::CFGElement>::end() Line | Count | Source | 94 | 102k | iterator end() { return End; } |
clang::BumpVector<clang::CFGBlock::AdjacentBlock>::end() Line | Count | Source | 94 | 182k | iterator end() { return End; } |
clang::BumpVector<clang::CFGBlock*>::end() Line | Count | Source | 94 | 2.34M | iterator end() { return End; } |
clang::BumpVector<clang::ento::ExplodedNode*>::end() Line | Count | Source | 94 | 14.2k | iterator end() { return End; } |
clang::BumpVector<clang::ento::MemRegion const*>::end() Line | Count | Source | 94 | 4.57k | iterator end() { return End; } |
|
95 | 1.96M | const_iterator end() const { return End; } clang::BumpVector<clang::CFGElement>::end() const Line | Count | Source | 95 | 465k | 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.24k | const_iterator end() const { return End; } |
clang::BumpVector<clang::VarDecl const*>::end() const Line | Count | Source | 95 | 803 | const_iterator end() const { return End; } |
|
96 | | |
97 | | // reverse iterator creation methods. |
98 | 102k | reverse_iterator rbegin() { return reverse_iterator(end()); } clang::BumpVector<clang::CFGElement>::rbegin() Line | Count | Source | 98 | 102k | reverse_iterator rbegin() { return reverse_iterator(end()); } |
Unexecuted instantiation: clang::BumpVector<clang::CFGBlock::AdjacentBlock>::rbegin() clang::BumpVector<clang::CFGBlock*>::rbegin() Line | Count | Source | 98 | 79 | reverse_iterator rbegin() { return reverse_iterator(end()); } |
|
99 | 72.3k | const_reverse_iterator rbegin() const{ return const_reverse_iterator(end()); } clang::BumpVector<clang::CFGElement>::rbegin() const Line | Count | Source | 99 | 71.7k | 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 | 578 | const_reverse_iterator rbegin() const{ return const_reverse_iterator(end()); } |
|
100 | 102k | reverse_iterator rend() { return reverse_iterator(begin()); } clang::BumpVector<clang::CFGElement>::rend() Line | Count | Source | 100 | 102k | reverse_iterator rend() { return reverse_iterator(begin()); } |
Unexecuted instantiation: clang::BumpVector<clang::CFGBlock::AdjacentBlock>::rend() clang::BumpVector<clang::CFGBlock*>::rend() Line | Count | Source | 100 | 79 | reverse_iterator rend() { return reverse_iterator(begin()); } |
|
101 | 72.1k | const_reverse_iterator rend() const { |
102 | 72.1k | return const_reverse_iterator(begin()); |
103 | 72.1k | } clang::BumpVector<clang::CFGElement>::rend() const Line | Count | Source | 101 | 71.7k | const_reverse_iterator rend() const { | 102 | 71.7k | return const_reverse_iterator(begin()); | 103 | 71.7k | } |
Unexecuted instantiation: clang::BumpVector<clang::CFGBlock*>::rend() const clang::BumpVector<clang::CFGBlock::AdjacentBlock>::rend() const Line | Count | Source | 101 | 416 | const_reverse_iterator rend() const { | 102 | 416 | return const_reverse_iterator(begin()); | 103 | 416 | } |
|
104 | | |
105 | 1.66M | bool empty() const { return Begin == End; } clang::BumpVector<clang::CFGElement>::empty() const Line | Count | Source | 105 | 1.60M | bool empty() const { return Begin == End; } |
clang::BumpVector<clang::CFGBlock::AdjacentBlock>::empty() const Line | Count | Source | 105 | 57.4k | bool empty() const { return Begin == End; } |
|
106 | 14.0M | size_type size() const { return End-Begin; } clang::BumpVector<clang::CFGElement>::size() const Line | Count | Source | 106 | 11.0M | size_type size() const { return End-Begin; } |
clang::BumpVector<clang::CFGBlock::AdjacentBlock>::size() const Line | Count | Source | 106 | 2.62M | size_type size() const { return End-Begin; } |
clang::BumpVector<clang::CFGBlock*>::size() const Line | Count | Source | 106 | 242k | size_type size() const { return End-Begin; } |
clang::BumpVector<clang::VarDecl const*>::size() const Line | Count | Source | 106 | 406 | size_type size() const { return End-Begin; } |
clang::BumpVector<clang::VarDecl*>::size() const Line | Count | Source | 106 | 8.32k | size_type size() const { return End-Begin; } |
clang::BumpVector<clang::ento::ExplodedNode*>::size() const Line | Count | Source | 106 | 138k | 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 | 4.12M | const_reference operator[](unsigned idx) const { |
113 | 4.12M | assert(Begin + idx < End); |
114 | 0 | return Begin[idx]; |
115 | 4.12M | } clang::BumpVector<clang::VarDecl*>::operator[](unsigned int) const Line | Count | Source | 112 | 21.1k | const_reference operator[](unsigned idx) const { | 113 | 21.1k | assert(Begin + idx < End); | 114 | 0 | return Begin[idx]; | 115 | 21.1k | } |
clang::BumpVector<clang::CFGElement>::operator[](unsigned int) const Line | Count | Source | 112 | 4.10M | const_reference operator[](unsigned idx) const { | 113 | 4.10M | assert(Begin + idx < End); | 114 | 0 | return Begin[idx]; | 115 | 4.10M | } |
|
116 | | |
117 | 0 | reference front() { |
118 | 0 | return begin()[0]; |
119 | 0 | } |
120 | 66.8k | const_reference front() const { |
121 | 66.8k | return begin()[0]; |
122 | 66.8k | } |
123 | | |
124 | 1.26M | reference back() { |
125 | 1.26M | return end()[-1]; |
126 | 1.26M | } |
127 | 126k | const_reference back() const { |
128 | 126k | return end()[-1]; |
129 | 126k | } |
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.37M | void push_back(const_reference Elt, BumpVectorContext &C) { |
160 | 7.37M | if (End < Capacity) { |
161 | 7.37M | Retry: |
162 | 7.37M | new (End) T(Elt); |
163 | 7.37M | ++End; |
164 | 7.37M | return; |
165 | 6.52M | } |
166 | 852k | grow(C); |
167 | 852k | goto Retry; |
168 | 7.37M | } clang::BumpVector<clang::CFGElement>::push_back(clang::CFGElement const&, clang::BumpVectorContext&) Line | Count | Source | 159 | 4.29M | void push_back(const_reference Elt, BumpVectorContext &C) { | 160 | 4.29M | if (End < Capacity) { | 161 | 4.29M | Retry: | 162 | 4.29M | new (End) T(Elt); | 163 | 4.29M | ++End; | 164 | 4.29M | return; | 165 | 3.77M | } | 166 | 523k | grow(C); | 167 | 523k | goto Retry; | 168 | 4.29M | } |
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 | 327 | } | 166 | 0 | grow(C); | 167 | 0 | goto Retry; | 168 | 327 | } |
clang::BumpVector<clang::VarDecl*>::push_back(clang::VarDecl* const&, clang::BumpVectorContext&) Line | Count | Source | 159 | 4.96k | void push_back(const_reference Elt, BumpVectorContext &C) { | 160 | 4.96k | if (End < Capacity) { | 161 | 4.96k | Retry: | 162 | 4.96k | new (End) T(Elt); | 163 | 4.96k | ++End; | 164 | 4.96k | return; | 165 | 4.93k | } | 166 | 29 | grow(C); | 167 | 29 | goto Retry; | 168 | 4.96k | } |
clang::BumpVector<clang::CFGBlock*>::push_back(clang::CFGBlock* const&, clang::BumpVectorContext&) Line | Count | Source | 159 | 1.03M | void push_back(const_reference Elt, BumpVectorContext &C) { | 160 | 1.03M | if (End < Capacity) { | 161 | 1.03M | Retry: | 162 | 1.03M | new (End) T(Elt); | 163 | 1.03M | ++End; | 164 | 1.03M | return; | 165 | 1.02M | } | 166 | 12.0k | grow(C); | 167 | 12.0k | goto Retry; | 168 | 1.03M | } |
clang::BumpVector<clang::CFGBlock::AdjacentBlock>::push_back(clang::CFGBlock::AdjacentBlock const&, clang::BumpVectorContext&) Line | Count | Source | 159 | 1.94M | void push_back(const_reference Elt, BumpVectorContext &C) { | 160 | 1.94M | if (End < Capacity) { | 161 | 1.94M | Retry: | 162 | 1.94M | new (End) T(Elt); | 163 | 1.94M | ++End; | 164 | 1.94M | return; | 165 | 1.62M | } | 166 | 316k | grow(C); | 167 | 316k | goto Retry; | 168 | 1.94M | } |
clang::BumpVector<clang::ento::ExplodedNode*>::push_back(clang::ento::ExplodedNode* const&, clang::BumpVectorContext&) Line | Count | Source | 159 | 92.5k | void push_back(const_reference Elt, BumpVectorContext &C) { | 160 | 92.5k | if (End < Capacity) { | 161 | 92.5k | Retry: | 162 | 92.5k | new (End) T(Elt); | 163 | 92.5k | ++End; | 164 | 92.5k | return; | 165 | 92.2k | } | 166 | 287 | grow(C); | 167 | 287 | goto Retry; | 168 | 92.5k | } |
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 | 594 | } | 166 | 0 | grow(C); | 167 | 0 | goto Retry; | 168 | 594 | } |
|
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 | 74 | BumpVectorContext &C) { |
174 | 74 | assert(I >= Begin && I <= End && "Iterator out of bounds."); |
175 | 74 | if (End + Cnt <= Capacity) { |
176 | 74 | Retry: |
177 | 74 | move_range_right(I, End, Cnt); |
178 | 74 | construct_range(I, I + Cnt, E); |
179 | 74 | End += Cnt; |
180 | 74 | return I + Cnt; |
181 | 74 | } |
182 | 0 | ptrdiff_t D = I - Begin; |
183 | 0 | grow(C, size() + Cnt); |
184 | 0 | I = Begin + D; |
185 | 0 | goto Retry; |
186 | 74 | } |
187 | | |
188 | 3.38M | void reserve(BumpVectorContext &C, unsigned N) { |
189 | 3.38M | if (unsigned(Capacity-Begin) < N) |
190 | 3.38M | grow(C, N); |
191 | 3.38M | } clang::BumpVector<clang::CFGElement>::reserve(clang::BumpVectorContext&, unsigned int) Line | Count | Source | 188 | 1.03M | void reserve(BumpVectorContext &C, unsigned N) { | 189 | 1.03M | if (unsigned(Capacity-Begin) < N) | 190 | 1.03M | grow(C, N); | 191 | 1.03M | } |
clang::BumpVector<clang::CFGBlock::AdjacentBlock>::reserve(clang::BumpVectorContext&, unsigned int) Line | Count | Source | 188 | 2.07M | void reserve(BumpVectorContext &C, unsigned N) { | 189 | 2.07M | if (unsigned(Capacity-Begin) < N) | 190 | 2.07M | grow(C, N); | 191 | 2.07M | } |
clang::BumpVector<clang::CFGBlock*>::reserve(clang::BumpVectorContext&, unsigned int) Line | Count | Source | 188 | 230k | void reserve(BumpVectorContext &C, unsigned N) { | 189 | 230k | if (unsigned(Capacity-Begin) < N) | 190 | 230k | grow(C, N); | 191 | 230k | } |
clang::BumpVector<clang::VarDecl const*>::reserve(clang::BumpVectorContext&, unsigned int) Line | Count | Source | 188 | 406 | void reserve(BumpVectorContext &C, unsigned N) { | 189 | 406 | if (unsigned(Capacity-Begin) < N) | 190 | 406 | grow(C, N); | 191 | 406 | } |
clang::BumpVector<clang::VarDecl*>::reserve(clang::BumpVectorContext&, unsigned int) Line | Count | Source | 188 | 3.33k | void reserve(BumpVectorContext &C, unsigned N) { | 189 | 3.33k | if (unsigned(Capacity-Begin) < N) | 190 | 3.33k | grow(C, N); | 191 | 3.33k | } |
clang::BumpVector<clang::ento::ExplodedNode*>::reserve(clang::BumpVectorContext&, unsigned int) Line | Count | Source | 188 | 44.3k | void reserve(BumpVectorContext &C, unsigned N) { | 189 | 44.3k | if (unsigned(Capacity-Begin) < N) | 190 | 44.3k | grow(C, N); | 191 | 44.3k | } |
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 | 74 | void construct_range(T *S, T *E, const T &Elt) { |
203 | 104 | for (; S != E; ++S30 ) |
204 | 30 | new (S) T(Elt); |
205 | 74 | } |
206 | | |
207 | 839k | void destroy_range(T *S, T *E) { |
208 | 4.97M | while (S != E) { |
209 | 4.13M | --E; |
210 | 4.13M | E->~T(); |
211 | 4.13M | } |
212 | 839k | } clang::BumpVector<clang::CFGElement>::destroy_range(clang::CFGElement*, clang::CFGElement*) Line | Count | Source | 207 | 523k | void destroy_range(T *S, T *E) { | 208 | 4.30M | while (S != E) { | 209 | 3.77M | --E; | 210 | 3.77M | E->~T(); | 211 | 3.77M | } | 212 | 523k | } |
clang::BumpVector<clang::CFGBlock::AdjacentBlock>::destroy_range(clang::CFGBlock::AdjacentBlock*, clang::CFGBlock::AdjacentBlock*) Line | Count | Source | 207 | 316k | void destroy_range(T *S, T *E) { | 208 | 669k | while (S != E) { | 209 | 353k | --E; | 210 | 353k | E->~T(); | 211 | 353k | } | 212 | 316k | } |
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 | 74 | void move_range_right(T *S, T *E, size_t D) { |
215 | 173 | 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 | 74 | } |
221 | | }; |
222 | | |
223 | | // Define this out-of-line to dissuade the C++ compiler from inlining it. |
224 | | template <typename T> |
225 | 4.24M | void BumpVector<T>::grow(BumpVectorContext &C, size_t MinSize) { |
226 | 4.24M | size_t CurCapacity = Capacity-Begin; |
227 | 4.24M | size_t CurSize = size(); |
228 | 4.24M | size_t NewCapacity = 2*CurCapacity; |
229 | 4.24M | if (NewCapacity < MinSize) |
230 | 3.38M | NewCapacity = MinSize; |
231 | | |
232 | | // Allocate the memory from the BumpPtrAllocator. |
233 | 4.24M | T *NewElts = C.getAllocator().template Allocate<T>(NewCapacity); |
234 | | |
235 | | // Copy the elements over. |
236 | 4.24M | if (Begin != End) { |
237 | 852k | if (std::is_class<T>::value) { |
238 | 839k | std::uninitialized_copy(Begin, End, NewElts); |
239 | | // Destroy the original elements. |
240 | 839k | destroy_range(Begin, End); |
241 | 839k | } else { |
242 | | // Use memcpy for PODs (std::uninitialized_copy optimizes to memmove). |
243 | 12.3k | memcpy(NewElts, Begin, CurSize * sizeof(T)); |
244 | 12.3k | } |
245 | 852k | } |
246 | | |
247 | | // For now, leak 'Begin'. We can add it back to a freelist in |
248 | | // BumpVectorContext. |
249 | 4.24M | Begin = NewElts; |
250 | 4.24M | End = NewElts+CurSize; |
251 | 4.24M | Capacity = Begin+NewCapacity; |
252 | 4.24M | } clang::BumpVector<clang::CFGElement>::grow(clang::BumpVectorContext&, unsigned long) Line | Count | Source | 225 | 1.55M | void BumpVector<T>::grow(BumpVectorContext &C, size_t MinSize) { | 226 | 1.55M | size_t CurCapacity = Capacity-Begin; | 227 | 1.55M | size_t CurSize = size(); | 228 | 1.55M | size_t NewCapacity = 2*CurCapacity; | 229 | 1.55M | if (NewCapacity < MinSize) | 230 | 1.03M | NewCapacity = MinSize; | 231 | | | 232 | | // Allocate the memory from the BumpPtrAllocator. | 233 | 1.55M | T *NewElts = C.getAllocator().template Allocate<T>(NewCapacity); | 234 | | | 235 | | // Copy the elements over. | 236 | 1.55M | if (Begin != End) { | 237 | 523k | if (std::is_class<T>::value) { | 238 | 523k | std::uninitialized_copy(Begin, End, NewElts); | 239 | | // Destroy the original elements. | 240 | 523k | destroy_range(Begin, End); | 241 | 523k | } else { | 242 | | // Use memcpy for PODs (std::uninitialized_copy optimizes to memmove). | 243 | 0 | memcpy(NewElts, Begin, CurSize * sizeof(T)); | 244 | 0 | } | 245 | 523k | } | 246 | | | 247 | | // For now, leak 'Begin'. We can add it back to a freelist in | 248 | | // BumpVectorContext. | 249 | 1.55M | Begin = NewElts; | 250 | 1.55M | End = NewElts+CurSize; | 251 | 1.55M | Capacity = Begin+NewCapacity; | 252 | 1.55M | } |
clang::BumpVector<clang::CFGBlock::AdjacentBlock>::grow(clang::BumpVectorContext&, unsigned long) Line | Count | Source | 225 | 2.38M | void BumpVector<T>::grow(BumpVectorContext &C, size_t MinSize) { | 226 | 2.38M | size_t CurCapacity = Capacity-Begin; | 227 | 2.38M | size_t CurSize = size(); | 228 | 2.38M | size_t NewCapacity = 2*CurCapacity; | 229 | 2.38M | if (NewCapacity < MinSize) | 230 | 2.07M | NewCapacity = MinSize; | 231 | | | 232 | | // Allocate the memory from the BumpPtrAllocator. | 233 | 2.38M | T *NewElts = C.getAllocator().template Allocate<T>(NewCapacity); | 234 | | | 235 | | // Copy the elements over. | 236 | 2.38M | if (Begin != End) { | 237 | 316k | if (std::is_class<T>::value) { | 238 | 316k | std::uninitialized_copy(Begin, End, NewElts); | 239 | | // Destroy the original elements. | 240 | 316k | destroy_range(Begin, End); | 241 | 316k | } else { | 242 | | // Use memcpy for PODs (std::uninitialized_copy optimizes to memmove). | 243 | 0 | memcpy(NewElts, Begin, CurSize * sizeof(T)); | 244 | 0 | } | 245 | 316k | } | 246 | | | 247 | | // For now, leak 'Begin'. We can add it back to a freelist in | 248 | | // BumpVectorContext. | 249 | 2.38M | Begin = NewElts; | 250 | 2.38M | End = NewElts+CurSize; | 251 | 2.38M | Capacity = Begin+NewCapacity; | 252 | 2.38M | } |
clang::BumpVector<clang::CFGBlock*>::grow(clang::BumpVectorContext&, unsigned long) Line | Count | Source | 225 | 242k | void BumpVector<T>::grow(BumpVectorContext &C, size_t MinSize) { | 226 | 242k | size_t CurCapacity = Capacity-Begin; | 227 | 242k | size_t CurSize = size(); | 228 | 242k | size_t NewCapacity = 2*CurCapacity; | 229 | 242k | if (NewCapacity < MinSize) | 230 | 230k | NewCapacity = MinSize; | 231 | | | 232 | | // Allocate the memory from the BumpPtrAllocator. | 233 | 242k | T *NewElts = C.getAllocator().template Allocate<T>(NewCapacity); | 234 | | | 235 | | // Copy the elements over. | 236 | 242k | if (Begin != End) { | 237 | 12.0k | 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 | 12.0k | } else { | 242 | | // Use memcpy for PODs (std::uninitialized_copy optimizes to memmove). | 243 | 12.0k | memcpy(NewElts, Begin, CurSize * sizeof(T)); | 244 | 12.0k | } | 245 | 12.0k | } | 246 | | | 247 | | // For now, leak 'Begin'. We can add it back to a freelist in | 248 | | // BumpVectorContext. | 249 | 242k | Begin = NewElts; | 250 | 242k | End = NewElts+CurSize; | 251 | 242k | Capacity = Begin+NewCapacity; | 252 | 242k | } |
clang::BumpVector<clang::VarDecl const*>::grow(clang::BumpVectorContext&, unsigned long) Line | Count | Source | 225 | 406 | void BumpVector<T>::grow(BumpVectorContext &C, size_t MinSize) { | 226 | 406 | size_t CurCapacity = Capacity-Begin; | 227 | 406 | size_t CurSize = size(); | 228 | 406 | size_t NewCapacity = 2*CurCapacity; | 229 | 406 | if (NewCapacity < MinSize) | 230 | 406 | NewCapacity = MinSize; | 231 | | | 232 | | // Allocate the memory from the BumpPtrAllocator. | 233 | 406 | T *NewElts = C.getAllocator().template Allocate<T>(NewCapacity); | 234 | | | 235 | | // Copy the elements over. | 236 | 406 | 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 | 406 | Begin = NewElts; | 250 | 406 | End = NewElts+CurSize; | 251 | 406 | Capacity = Begin+NewCapacity; | 252 | 406 | } |
clang::BumpVector<clang::VarDecl*>::grow(clang::BumpVectorContext&, unsigned long) Line | Count | Source | 225 | 3.36k | void BumpVector<T>::grow(BumpVectorContext &C, size_t MinSize) { | 226 | 3.36k | size_t CurCapacity = Capacity-Begin; | 227 | 3.36k | size_t CurSize = size(); | 228 | 3.36k | size_t NewCapacity = 2*CurCapacity; | 229 | 3.36k | if (NewCapacity < MinSize) | 230 | 3.33k | NewCapacity = MinSize; | 231 | | | 232 | | // Allocate the memory from the BumpPtrAllocator. | 233 | 3.36k | T *NewElts = C.getAllocator().template Allocate<T>(NewCapacity); | 234 | | | 235 | | // Copy the elements over. | 236 | 3.36k | if (Begin != End) { | 237 | 29 | 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 | 29 | } else { | 242 | | // Use memcpy for PODs (std::uninitialized_copy optimizes to memmove). | 243 | 29 | memcpy(NewElts, Begin, CurSize * sizeof(T)); | 244 | 29 | } | 245 | 29 | } | 246 | | | 247 | | // For now, leak 'Begin'. We can add it back to a freelist in | 248 | | // BumpVectorContext. | 249 | 3.36k | Begin = NewElts; | 250 | 3.36k | End = NewElts+CurSize; | 251 | 3.36k | Capacity = Begin+NewCapacity; | 252 | 3.36k | } |
clang::BumpVector<clang::ento::ExplodedNode*>::grow(clang::BumpVectorContext&, unsigned long) Line | Count | Source | 225 | 44.6k | void BumpVector<T>::grow(BumpVectorContext &C, size_t MinSize) { | 226 | 44.6k | size_t CurCapacity = Capacity-Begin; | 227 | 44.6k | size_t CurSize = size(); | 228 | 44.6k | size_t NewCapacity = 2*CurCapacity; | 229 | 44.6k | if (NewCapacity < MinSize) | 230 | 44.3k | NewCapacity = MinSize; | 231 | | | 232 | | // Allocate the memory from the BumpPtrAllocator. | 233 | 44.6k | T *NewElts = C.getAllocator().template Allocate<T>(NewCapacity); | 234 | | | 235 | | // Copy the elements over. | 236 | 44.6k | if (Begin != End) { | 237 | 287 | 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 | 287 | } else { | 242 | | // Use memcpy for PODs (std::uninitialized_copy optimizes to memmove). | 243 | 287 | memcpy(NewElts, Begin, CurSize * sizeof(T)); | 244 | 287 | } | 245 | 287 | } | 246 | | | 247 | | // For now, leak 'Begin'. We can add it back to a freelist in | 248 | | // BumpVectorContext. | 249 | 44.6k | Begin = NewElts; | 250 | 44.6k | End = NewElts+CurSize; | 251 | 44.6k | Capacity = Begin+NewCapacity; | 252 | 44.6k | } |
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 |