Line data Source code
1 : // Copyright 2017 the V8 project authors. All rights reserved.
2 : // Use of this source code is governed by a BSD-style license that can be
3 : // found in the LICENSE file.
4 :
5 : #ifndef V8_DETACHABLE_VECTOR_H_
6 : #define V8_DETACHABLE_VECTOR_H_
7 :
8 : #include <stddef.h>
9 :
10 : #include <algorithm>
11 :
12 : #include "src/base/logging.h"
13 : #include "src/base/macros.h"
14 :
15 : namespace v8 {
16 : namespace internal {
17 :
18 62421 : class V8_EXPORT_PRIVATE DetachableVectorBase {
19 : public:
20 : // Clear our reference to the backing store. Does not delete it!
21 : void detach() {
22 129853 : data_ = nullptr;
23 129853 : capacity_ = 0;
24 129853 : size_ = 0;
25 : }
26 :
27 11371120 : void pop_back() { --size_; }
28 : size_t capacity() const { return capacity_; }
29 : size_t size() const { return size_; }
30 2 : bool empty() const { return size_ == 0; }
31 :
32 : static const size_t kMinimumCapacity;
33 : static const size_t kDataOffset;
34 : static const size_t kCapacityOffset;
35 : static const size_t kSizeOffset;
36 :
37 : protected:
38 : void* data_ = nullptr;
39 : size_t capacity_ = 0;
40 : size_t size_ = 0;
41 : };
42 :
43 : // This class wraps an array and provides a few of the common member
44 : // functions for accessing the data. Two extra methods are also provided: free()
45 : // and detach(), which allow for manual control of the backing store. This is
46 : // currently required for use in the HandleScopeImplementer. Any other class
47 : // should just use a std::vector.
48 : template <typename T>
49 : class DetachableVector : public DetachableVectorBase {
50 : public:
51 : DetachableVector() = default;
52 62412 : ~DetachableVector() { delete[] data(); }
53 :
54 15781164 : void push_back(const T& value) {
55 15781164 : if (size_ == capacity_) {
56 524050 : size_t new_capacity = std::max(kMinimumCapacity, 2 * capacity_);
57 262025 : Resize(new_capacity);
58 : }
59 :
60 15781164 : data()[size_] = value;
61 15781164 : ++size_;
62 15781164 : }
63 :
64 : // Free the backing store and clear our reference to it.
65 : void free() {
66 23673 : delete[] data();
67 23673 : data_ = nullptr;
68 23673 : capacity_ = 0;
69 23673 : size_ = 0;
70 : }
71 :
72 : T& at(size_t i) const {
73 : DCHECK_LT(i, size_);
74 15142400 : return data()[i];
75 : }
76 14637279 : T& back() const { return at(size_ - 1); }
77 : T& front() const { return at(0); }
78 :
79 1124238 : void shrink_to_fit() {
80 2248476 : size_t new_capacity = std::max(size_, kMinimumCapacity);
81 1124238 : if (new_capacity < capacity_ / 2) {
82 5 : Resize(new_capacity);
83 : }
84 1124238 : }
85 :
86 : private:
87 : T* data() const { return static_cast<T*>(data_); }
88 :
89 262030 : void Resize(size_t new_capacity) {
90 : DCHECK_LE(size_, new_capacity);
91 1311618 : T* new_data_ = new T[new_capacity];
92 :
93 262030 : std::copy(data(), data() + size_, new_data_);
94 262030 : delete[] data();
95 :
96 262030 : data_ = new_data_;
97 262030 : capacity_ = new_capacity;
98 262030 : }
99 : };
100 :
101 : } // namespace internal
102 : } // namespace v8
103 :
104 : #endif // V8_DETACHABLE_VECTOR_H_
|