e861dbbcf1
This CL updates DetachableVector to store the data at a known place instead of in an std::vector<>, so that builtins can update it directly. Bug: v8:8124 Change-Id: Iba5fb2e9d4e0ddc689d0f7eeaea40bc3218edf3a Reviewed-on: https://chromium-review.googlesource.com/c/1297783 Commit-Queue: Taiju Tsuiki <tzik@chromium.org> Reviewed-by: Peter Marshall <petermarshall@chromium.org> Cr-Commit-Position: refs/heads/master@{#57452}
105 lines
2.5 KiB
C++
105 lines
2.5 KiB
C++
// Copyright 2017 the V8 project authors. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style license that can be
|
|
// found in the LICENSE file.
|
|
|
|
#ifndef V8_DETACHABLE_VECTOR_H_
|
|
#define V8_DETACHABLE_VECTOR_H_
|
|
|
|
#include <stddef.h>
|
|
|
|
#include <algorithm>
|
|
|
|
#include "src/base/logging.h"
|
|
#include "src/base/macros.h"
|
|
|
|
namespace v8 {
|
|
namespace internal {
|
|
|
|
class V8_EXPORT_PRIVATE DetachableVectorBase {
|
|
public:
|
|
// Clear our reference to the backing store. Does not delete it!
|
|
void detach() {
|
|
data_ = nullptr;
|
|
capacity_ = 0;
|
|
size_ = 0;
|
|
}
|
|
|
|
void pop_back() { --size_; }
|
|
size_t capacity() const { return capacity_; }
|
|
size_t size() const { return size_; }
|
|
bool empty() const { return size_ == 0; }
|
|
|
|
static const size_t kMinimumCapacity;
|
|
static const size_t kDataOffset;
|
|
static const size_t kCapacityOffset;
|
|
static const size_t kSizeOffset;
|
|
|
|
protected:
|
|
void* data_ = nullptr;
|
|
size_t capacity_ = 0;
|
|
size_t size_ = 0;
|
|
};
|
|
|
|
// This class wraps an array and provides a few of the common member
|
|
// functions for accessing the data. Two extra methods are also provided: free()
|
|
// and detach(), which allow for manual control of the backing store. This is
|
|
// currently required for use in the HandleScopeImplementer. Any other class
|
|
// should just use a std::vector.
|
|
template <typename T>
|
|
class DetachableVector : public DetachableVectorBase {
|
|
public:
|
|
DetachableVector() = default;
|
|
~DetachableVector() { delete[] data(); }
|
|
|
|
void push_back(const T& value) {
|
|
if (size_ == capacity_) {
|
|
size_t new_capacity = std::max(kMinimumCapacity, 2 * capacity_);
|
|
Resize(new_capacity);
|
|
}
|
|
|
|
data()[size_] = value;
|
|
++size_;
|
|
}
|
|
|
|
// Free the backing store and clear our reference to it.
|
|
void free() {
|
|
delete[] data();
|
|
data_ = nullptr;
|
|
capacity_ = 0;
|
|
size_ = 0;
|
|
}
|
|
|
|
T& at(size_t i) const {
|
|
DCHECK_LT(i, size_);
|
|
return data()[i];
|
|
}
|
|
T& back() const { return at(size_ - 1); }
|
|
T& front() const { return at(0); }
|
|
|
|
void shrink_to_fit() {
|
|
size_t new_capacity = std::max(size_, kMinimumCapacity);
|
|
if (new_capacity < capacity_ / 2) {
|
|
Resize(new_capacity);
|
|
}
|
|
}
|
|
|
|
private:
|
|
T* data() const { return static_cast<T*>(data_); }
|
|
|
|
void Resize(size_t new_capacity) {
|
|
DCHECK_LE(size_, new_capacity);
|
|
T* new_data_ = new T[new_capacity];
|
|
|
|
std::copy(data(), data() + size_, new_data_);
|
|
delete[] data();
|
|
|
|
data_ = new_data_;
|
|
capacity_ = new_capacity;
|
|
}
|
|
};
|
|
|
|
} // namespace internal
|
|
} // namespace v8
|
|
|
|
#endif // V8_DETACHABLE_VECTOR_H_
|