5 #ifndef V8_ZONE_ZONE_H_ 6 #define V8_ZONE_ZONE_H_ 10 #include "src/base/hashmap.h" 11 #include "src/base/logging.h" 12 #include "src/base/threaded-list.h" 13 #include "src/globals.h" 14 #include "src/splay-tree.h" 15 #include "src/utils.h" 16 #include "src/zone/accounting-allocator.h" 19 #define STRINGIFY(x) #x 20 #define TOSTRING(x) STRINGIFY(x) 21 #define ZONE_NAME __FILE__ ":" TOSTRING(__LINE__) 40 enum class SegmentSize { kLarge, kDefault };
42 class V8_EXPORT_PRIVATE
Zone final {
45 SegmentSize segment_size = SegmentSize::kDefault);
50 void* New(
size_t size) {
51 #ifdef V8_USE_ADDRESS_SANITIZER 54 size = RoundUp(size, kAlignmentInBytes);
56 if (V8_UNLIKELY(size > limit_ - position_)) {
57 result = NewExpand(size);
61 return reinterpret_cast<void*
>(result);
64 void* AsanNew(
size_t size);
67 T* NewArray(
size_t length) {
68 DCHECK_LT(length, std::numeric_limits<size_t>::max() /
sizeof(
T));
69 return static_cast<T*
>(New(length *
sizeof(
T)));
73 void Seal() { sealed_ =
true; }
81 bool excess_allocation()
const {
82 return segment_bytes_allocated_ > kExcessLimit;
85 const char* name()
const {
return name_; }
87 size_t allocation_size()
const {
88 size_t extra = segment_head_ ? position_ - segment_head_->start() : 0;
89 return allocation_size_ + extra;
99 static const size_t kAlignmentInBytes = 8;
102 static const size_t kMinimumSegmentSize = 8 * KB;
105 static const size_t kMaximumSegmentSize = 1 * MB;
108 static const size_t kExcessLimit = 256 * MB;
111 size_t allocation_size_;
116 size_t segment_bytes_allocated_;
122 Address NewExpand(
size_t size);
126 inline Segment* NewSegment(
size_t requested_size);
139 SegmentSize segment_size_;
147 void*
operator new(
size_t size,
Zone* zone) {
return zone->New(size); }
157 void operator delete(
void*,
size_t) { UNREACHABLE(); }
158 void operator delete(
void* pointer,
Zone* zone) { UNREACHABLE(); }
166 void* New(
size_t size) {
return zone()->New(size); }
167 static void Delete(
void* pointer) {}
168 Zone* zone()
const {
return zone_; }
174 template <
typename T>
181 template <
typename T>
186 ZoneList(
int capacity,
Zone* zone) { Initialize(capacity, zone); }
188 ZoneList(std::initializer_list<T> list, Zone* zone) {
189 Initialize(static_cast<int>(list.size()), zone);
190 for (
auto&
i : list) Add(
i, zone);
193 ZoneList(
const ZoneList<T>& other, Zone* zone) {
194 Initialize(other.length(), zone);
198 V8_INLINE ~ZoneList() { DeleteData(data_); }
201 V8_INLINE
void operator delete(
void* p, ZoneAllocationPolicy allocator) {
205 void*
operator new(
size_t size, Zone* zone) {
return zone->New(size); }
210 inline T& operator[](
int i)
const {
212 DCHECK_GT(static_cast<unsigned>(length_), static_cast<unsigned>(
i));
215 inline T& at(
int i)
const {
return operator[](
i); }
216 inline T& last()
const {
return at(length_ - 1); }
217 inline T& first()
const {
return at(0); }
220 inline iterator begin()
const {
return &data_[0]; }
221 inline iterator end()
const {
return &data_[length_]; }
223 V8_INLINE
bool is_empty()
const {
return length_ == 0; }
224 V8_INLINE
int length()
const {
return length_; }
225 V8_INLINE
int capacity()
const {
return capacity_; }
227 Vector<T> ToVector()
const {
return Vector<T>(data_, length_); }
228 Vector<T> ToVector(
int start,
int length)
const {
229 return Vector<T>(data_ + start, Min(length_ - start, length));
232 Vector<const T> ToConstVector()
const {
233 return Vector<const T>(data_, length_);
236 V8_INLINE
void Initialize(
int capacity, Zone* zone) {
237 DCHECK_GE(capacity, 0);
238 data_ = (capacity > 0) ? NewData(capacity, ZoneAllocationPolicy(zone))
240 capacity_ = capacity;
246 void Add(
const T& element, Zone* zone);
248 void AddAll(
const ZoneList<T>& other, Zone* zone);
250 void AddAll(
const Vector<T>& other, Zone* zone);
252 void InsertAt(
int index,
const T& element, Zone* zone);
257 Vector<T> AddBlock(T value,
int count, Zone* zone);
260 void Set(
int index,
const T& element);
270 V8_INLINE T RemoveLast() {
return Remove(length_ - 1); }
275 V8_INLINE
void Clear();
278 V8_INLINE
void Rewind(
int pos);
280 inline bool Contains(
const T& elm)
const;
283 template <
class Visitor>
284 void Iterate(Visitor* visitor);
287 template <
typename CompareFunction>
288 void Sort(CompareFunction cmp);
289 template <
typename CompareFunction>
290 void StableSort(CompareFunction cmp,
size_t start,
size_t length);
292 void operator delete(
void* pointer) { UNREACHABLE(); }
293 void operator delete(
void* pointer, Zone* zone) { UNREACHABLE(); }
300 V8_INLINE T* NewData(
int n, ZoneAllocationPolicy allocator) {
301 return static_cast<T*
>(allocator.New(n *
sizeof(T)));
303 V8_INLINE
void DeleteData(T* data) { ZoneAllocationPolicy::Delete(data); }
307 void ResizeAdd(
const T& element, ZoneAllocationPolicy allocator);
311 void ResizeAddInternal(
const T& element, ZoneAllocationPolicy allocator);
314 void Resize(
int new_capacity, ZoneAllocationPolicy allocator);
316 DISALLOW_COPY_AND_ASSIGN(ZoneList);
321 template <
typename T>
322 using ZonePtrList = ZoneList<T*>;
324 template <
typename T>
328 : buffer_(*buffer), start_(buffer->size()), end_(buffer->size()) {}
333 DCHECK_EQ(buffer_.size(), end_);
334 buffer_.resize(start_);
338 int length()
const {
return static_cast<int>(end_ - start_); }
340 size_t index = start_ +
i;
341 DCHECK_LT(index, buffer_.size());
342 return reinterpret_cast<T*
>(buffer_[index]);
346 DCHECK_LE(end_, buffer_.size());
348 if (length() == 0)
return;
349 target->Initialize(length(), zone);
350 T** data =
reinterpret_cast<T**
>(&buffer_[start_]);
351 target->AddAll(
Vector<T*>(data, length()), zone);
355 DCHECK_EQ(buffer_.size(), end_);
356 buffer_.push_back(value);
361 DCHECK_EQ(buffer_.size(), end_);
362 buffer_.reserve(buffer_.size() + list.length());
363 for (
int i = 0;
i < list.length();
i++) {
364 buffer_.push_back(list.at(
i));
366 end_ += list.length();
370 std::vector<void*>& buffer_;
377 template <
typename T,
typename TLTraits = base::ThreadedListTraits<T>>
383 template <
typename Config>
395 void*
operator new(
size_t size,
Zone* zone) {
return zone->New(size); }
397 void operator delete(
void* pointer) { UNREACHABLE(); }
398 void operator delete(
void* pointer,
Zone* zone) { UNREACHABLE(); }
413 template <
class T,
typename =
typename std::enable_if<std::is_convertible<
415 void*
operator new(
size_t size, T zone) {
416 static_assert(
false &&
sizeof(T),
417 "Placement new with a zone is only permitted for classes " 418 "inheriting from ZoneObject");
422 #endif // V8_ZONE_ZONE_H_