• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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_UTILS_DETACHABLE_VECTOR_H_
6 #define V8_UTILS_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 #include "src/base/platform/wrappers.h"
15 
16 namespace v8 {
17 namespace internal {
18 
19 class V8_EXPORT_PRIVATE DetachableVectorBase {
20  public:
21   // Clear our reference to the backing store. Does not delete it!
detach()22   void detach() {
23     data_ = nullptr;
24     capacity_ = 0;
25     size_ = 0;
26   }
27 
pop_back()28   void pop_back() { --size_; }
capacity()29   size_t capacity() const { return capacity_; }
size()30   size_t size() const { return size_; }
empty()31   bool empty() const { return size_ == 0; }
32 
33   static const size_t kMinimumCapacity;
34   static const size_t kDataOffset;
35   static const size_t kCapacityOffset;
36   static const size_t kSizeOffset;
37 
38  protected:
39   void* data_ = nullptr;
40   size_t capacity_ = 0;
41   size_t size_ = 0;
42 };
43 
44 // This class wraps an array and provides a few of the common member
45 // functions for accessing the data. Two extra methods are also provided: free()
46 // and detach(), which allow for manual control of the backing store. This is
47 // currently required for use in the HandleScopeImplementer. Any other class
48 // should just use a std::vector.
49 template <typename T>
50 class DetachableVector : public DetachableVectorBase {
51  public:
52   DetachableVector() = default;
~DetachableVector()53   ~DetachableVector() { delete[] data(); }
54 
push_back(const T & value)55   void push_back(const T& value) {
56     if (size_ == capacity_) {
57       size_t new_capacity = std::max(kMinimumCapacity, 2 * capacity_);
58       Resize(new_capacity);
59     }
60 
61     data()[size_] = value;
62     ++size_;
63   }
64 
65   // Free the backing store and clear our reference to it.
free()66   void free() {
67     delete[] data();
68     data_ = nullptr;
69     capacity_ = 0;
70     size_ = 0;
71   }
72 
at(size_t i)73   T& at(size_t i) const {
74     DCHECK_LT(i, size_);
75     return data()[i];
76   }
back()77   T& back() const { return at(size_ - 1); }
front()78   T& front() const { return at(0); }
79 
shrink_to_fit()80   void shrink_to_fit() {
81     size_t new_capacity = std::max(size_, kMinimumCapacity);
82     if (new_capacity < capacity_ / 2) {
83       Resize(new_capacity);
84     }
85   }
86 
87  private:
data()88   T* data() const { return static_cast<T*>(data_); }
89 
Resize(size_t new_capacity)90   void Resize(size_t new_capacity) {
91     DCHECK_LE(size_, new_capacity);
92     T* new_data_ = new T[new_capacity];
93 
94     std::copy(data(), data() + size_, new_data_);
95     delete[] data();
96 
97     data_ = new_data_;
98     capacity_ = new_capacity;
99   }
100 };
101 
102 }  // namespace internal
103 }  // namespace v8
104 
105 #endif  // V8_UTILS_DETACHABLE_VECTOR_H_
106