Commit d81f7c6e authored by Igor Sheludko's avatar Igor Sheludko Committed by Commit Bot

[zone] Cleanup ZoneList and ScopedList classes

Also make ScopedList class Zone-agnostic and move it to src/utils.

Bug: v8:10506
Change-Id: Ibf0869566caa767809bdf95cb03c01e599613938
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2292234Reviewed-by: 's avatarToon Verwaest <verwaest@chromium.org>
Reviewed-by: 's avatarRoss McIlroy <rmcilroy@chromium.org>
Commit-Queue: Igor Sheludko <ishell@chromium.org>
Cr-Commit-Position: refs/heads/master@{#68825}
parent 010667b4
...@@ -3165,6 +3165,7 @@ v8_source_set("v8_base_without_compiler") { ...@@ -3165,6 +3165,7 @@ v8_source_set("v8_base_without_compiler") {
"src/utils/ostreams.cc", "src/utils/ostreams.cc",
"src/utils/ostreams.h", "src/utils/ostreams.h",
"src/utils/pointer-with-payload.h", "src/utils/pointer-with-payload.h",
"src/utils/scoped-list.h",
"src/utils/utils-inl.h", "src/utils/utils-inl.h",
"src/utils/utils.cc", "src/utils/utils.cc",
"src/utils/utils.h", "src/utils/utils.h",
...@@ -3248,7 +3249,6 @@ v8_source_set("v8_base_without_compiler") { ...@@ -3248,7 +3249,6 @@ v8_source_set("v8_base_without_compiler") {
"src/wasm/wasm-value.h", "src/wasm/wasm-value.h",
"src/zone/accounting-allocator.cc", "src/zone/accounting-allocator.cc",
"src/zone/accounting-allocator.h", "src/zone/accounting-allocator.h",
"src/zone/scoped-list.h",
"src/zone/zone-allocator.h", "src/zone/zone-allocator.h",
"src/zone/zone-chunk-list.h", "src/zone/zone-chunk-list.h",
"src/zone/zone-containers.h", "src/zone/zone-containers.h",
...@@ -3259,6 +3259,7 @@ v8_source_set("v8_base_without_compiler") { ...@@ -3259,6 +3259,7 @@ v8_source_set("v8_base_without_compiler") {
"src/zone/zone-list.h", "src/zone/zone-list.h",
"src/zone/zone-segment.cc", "src/zone/zone-segment.cc",
"src/zone/zone-segment.h", "src/zone/zone-segment.h",
"src/zone/zone-utils.h",
"src/zone/zone.cc", "src/zone/zone.cc",
"src/zone/zone.h", "src/zone/zone.h",
] ]
......
...@@ -950,9 +950,7 @@ Call::CallType Call::GetCallType() const { ...@@ -950,9 +950,7 @@ Call::CallType Call::GetCallType() const {
CaseClause::CaseClause(Zone* zone, Expression* label, CaseClause::CaseClause(Zone* zone, Expression* label,
const ScopedPtrList<Statement>& statements) const ScopedPtrList<Statement>& statements)
: label_(label), statements_(0, nullptr) { : label_(label), statements_(statements.ToConstVector(), zone) {}
statements.CopyTo(&statements_, zone);
}
bool Literal::IsPropertyName() const { bool Literal::IsPropertyName() const {
if (type() != kString) return false; if (type() != kString) return false;
......
...@@ -320,7 +320,7 @@ class Block final : public BreakableStatement { ...@@ -320,7 +320,7 @@ class Block final : public BreakableStatement {
void InitializeStatements(const ScopedPtrList<Statement>& statements, void InitializeStatements(const ScopedPtrList<Statement>& statements,
Zone* zone) { Zone* zone) {
DCHECK_EQ(0, statements_.length()); DCHECK_EQ(0, statements_.length());
statements.CopyTo(&statements_, zone); statements_ = ZonePtrList<Statement>(statements.ToConstVector(), zone);
} }
private: private:
...@@ -1324,12 +1324,11 @@ class ObjectLiteral final : public AggregateLiteral { ...@@ -1324,12 +1324,11 @@ class ObjectLiteral final : public AggregateLiteral {
bool has_rest_property) bool has_rest_property)
: AggregateLiteral(pos, kObjectLiteral), : AggregateLiteral(pos, kObjectLiteral),
boilerplate_properties_(boilerplate_properties), boilerplate_properties_(boilerplate_properties),
properties_(0, nullptr) { properties_(properties.ToConstVector(), zone) {
bit_field_ |= HasElementsField::encode(false) | bit_field_ |= HasElementsField::encode(false) |
HasRestPropertyField::encode(has_rest_property) | HasRestPropertyField::encode(has_rest_property) |
FastElementsField::encode(false) | FastElementsField::encode(false) |
HasNullPrototypeField::encode(false); HasNullPrototypeField::encode(false);
properties.CopyTo(&properties_, zone);
} }
void InitFlagsForPendingNullPrototype(int i); void InitFlagsForPendingNullPrototype(int i);
...@@ -1398,9 +1397,7 @@ class ArrayLiteral final : public AggregateLiteral { ...@@ -1398,9 +1397,7 @@ class ArrayLiteral final : public AggregateLiteral {
int first_spread_index, int pos) int first_spread_index, int pos)
: AggregateLiteral(pos, kArrayLiteral), : AggregateLiteral(pos, kArrayLiteral),
first_spread_index_(first_spread_index), first_spread_index_(first_spread_index),
values_(0, nullptr) { values_(values.ToConstVector(), zone) {}
values.CopyTo(&values_, zone);
}
int first_spread_index_; int first_spread_index_;
Handle<ArrayBoilerplateDescription> boilerplate_description_; Handle<ArrayBoilerplateDescription> boilerplate_description_;
...@@ -1683,12 +1680,11 @@ class Call final : public Expression { ...@@ -1683,12 +1680,11 @@ class Call final : public Expression {
PossiblyEval possibly_eval, bool optional_chain) PossiblyEval possibly_eval, bool optional_chain)
: Expression(pos, kCall), : Expression(pos, kCall),
expression_(expression), expression_(expression),
arguments_(0, nullptr) { arguments_(arguments.ToConstVector(), zone) {
bit_field_ |= bit_field_ |=
IsPossiblyEvalField::encode(possibly_eval == IS_POSSIBLY_EVAL) | IsPossiblyEvalField::encode(possibly_eval == IS_POSSIBLY_EVAL) |
IsTaggedTemplateField::encode(false) | IsTaggedTemplateField::encode(false) |
IsOptionalChainLinkField::encode(optional_chain); IsOptionalChainLinkField::encode(optional_chain);
arguments.CopyTo(&arguments_, zone);
} }
Call(Zone* zone, Expression* expression, Call(Zone* zone, Expression* expression,
...@@ -1696,11 +1692,10 @@ class Call final : public Expression { ...@@ -1696,11 +1692,10 @@ class Call final : public Expression {
TaggedTemplateTag tag) TaggedTemplateTag tag)
: Expression(pos, kCall), : Expression(pos, kCall),
expression_(expression), expression_(expression),
arguments_(0, nullptr) { arguments_(arguments.ToConstVector(), zone) {
bit_field_ |= IsPossiblyEvalField::encode(false) | bit_field_ |= IsPossiblyEvalField::encode(false) |
IsTaggedTemplateField::encode(true) | IsTaggedTemplateField::encode(true) |
IsOptionalChainLinkField::encode(false); IsOptionalChainLinkField::encode(false);
arguments.CopyTo(&arguments_, zone);
} }
using IsPossiblyEvalField = Expression::NextBitField<bool, 1>; using IsPossiblyEvalField = Expression::NextBitField<bool, 1>;
...@@ -1729,9 +1724,7 @@ class CallNew final : public Expression { ...@@ -1729,9 +1724,7 @@ class CallNew final : public Expression {
const ScopedPtrList<Expression>& arguments, int pos) const ScopedPtrList<Expression>& arguments, int pos)
: Expression(pos, kCallNew), : Expression(pos, kCallNew),
expression_(expression), expression_(expression),
arguments_(0, nullptr) { arguments_(arguments.ToConstVector(), zone) {}
arguments.CopyTo(&arguments_, zone);
}
Expression* expression_; Expression* expression_;
ZonePtrList<Expression> arguments_; ZonePtrList<Expression> arguments_;
...@@ -1765,17 +1758,13 @@ class CallRuntime final : public Expression { ...@@ -1765,17 +1758,13 @@ class CallRuntime final : public Expression {
const ScopedPtrList<Expression>& arguments, int pos) const ScopedPtrList<Expression>& arguments, int pos)
: Expression(pos, kCallRuntime), : Expression(pos, kCallRuntime),
function_(function), function_(function),
arguments_(0, nullptr) { arguments_(arguments.ToConstVector(), zone) {}
arguments.CopyTo(&arguments_, zone);
}
CallRuntime(Zone* zone, int context_index, CallRuntime(Zone* zone, int context_index,
const ScopedPtrList<Expression>& arguments, int pos) const ScopedPtrList<Expression>& arguments, int pos)
: Expression(pos, kCallRuntime), : Expression(pos, kCallRuntime),
context_index_(context_index), context_index_(context_index),
function_(nullptr), function_(nullptr),
arguments_(0, nullptr) { arguments_(arguments.ToConstVector(), zone) {}
arguments.CopyTo(&arguments_, zone);
}
int context_index_; int context_index_;
const Runtime::Function* function_; const Runtime::Function* function_;
...@@ -2307,7 +2296,7 @@ class FunctionLiteral final : public Expression { ...@@ -2307,7 +2296,7 @@ class FunctionLiteral final : public Expression {
function_literal_id_(function_literal_id), function_literal_id_(function_literal_id),
raw_name_(name), raw_name_(name),
scope_(scope), scope_(scope),
body_(0, nullptr), body_(body.ToConstVector(), zone),
raw_inferred_name_(ast_value_factory->empty_cons_string()), raw_inferred_name_(ast_value_factory->empty_cons_string()),
produced_preparse_data_(produced_preparse_data) { produced_preparse_data_(produced_preparse_data) {
bit_field_ |= FunctionSyntaxKindBits::encode(function_syntax_kind) | bit_field_ |= FunctionSyntaxKindBits::encode(function_syntax_kind) |
...@@ -2319,7 +2308,6 @@ class FunctionLiteral final : public Expression { ...@@ -2319,7 +2308,6 @@ class FunctionLiteral final : public Expression {
HasBracesField::encode(has_braces) | HasBracesField::encode(has_braces) |
OneshotIIFEBit::encode(false); OneshotIIFEBit::encode(false);
if (eager_compile_hint == kShouldEagerCompile) SetShouldEagerCompile(); if (eager_compile_hint == kShouldEagerCompile) SetShouldEagerCompile();
body.CopyTo(&body_, zone);
} }
using FunctionSyntaxKindBits = using FunctionSyntaxKindBits =
......
...@@ -2913,8 +2913,8 @@ void BytecodeGenerator::BuildCreateArrayLiteral( ...@@ -2913,8 +2913,8 @@ void BytecodeGenerator::BuildCreateArrayLiteral(
Register array = register_allocator()->NewRegister(); Register array = register_allocator()->NewRegister();
SharedFeedbackSlot element_slot(feedback_spec(), SharedFeedbackSlot element_slot(feedback_spec(),
FeedbackSlotKind::kStoreInArrayLiteral); FeedbackSlotKind::kStoreInArrayLiteral);
ZonePtrList<Expression>::iterator current = elements->begin(); ZonePtrList<Expression>::const_iterator current = elements->begin();
ZonePtrList<Expression>::iterator end = elements->end(); ZonePtrList<Expression>::const_iterator end = elements->end();
bool is_empty = elements->is_empty(); bool is_empty = elements->is_empty();
if (!is_empty && (*current)->IsSpread()) { if (!is_empty && (*current)->IsSpread()) {
...@@ -2976,7 +2976,7 @@ void BytecodeGenerator::BuildCreateArrayLiteral( ...@@ -2976,7 +2976,7 @@ void BytecodeGenerator::BuildCreateArrayLiteral(
// index, into the initial array (the remaining elements will be inserted // index, into the initial array (the remaining elements will be inserted
// below). // below).
DCHECK_EQ(current, elements->begin()); DCHECK_EQ(current, elements->begin());
ZonePtrList<Expression>::iterator first_spread_or_end = ZonePtrList<Expression>::const_iterator first_spread_or_end =
expr->first_spread_index() >= 0 ? current + expr->first_spread_index() expr->first_spread_index() >= 0 ? current + expr->first_spread_index()
: end; : end;
int array_index = 0; int array_index = 0;
......
...@@ -3191,7 +3191,7 @@ Expression* Parser::CloseTemplateLiteral(TemplateLiteralState* state, int start, ...@@ -3191,7 +3191,7 @@ Expression* Parser::CloseTemplateLiteral(TemplateLiteralState* state, int start,
// Call TagFn // Call TagFn
ScopedPtrList<Expression> call_args(pointer_buffer()); ScopedPtrList<Expression> call_args(pointer_buffer());
call_args.Add(template_object); call_args.Add(template_object);
call_args.AddAll(*expressions); call_args.AddAll(expressions->ToConstVector());
return factory()->NewTaggedTemplate(tag, call_args, pos); return factory()->NewTaggedTemplate(tag, call_args, pos);
} }
} }
......
...@@ -17,6 +17,7 @@ ...@@ -17,6 +17,7 @@
#include "src/parsing/preparser.h" #include "src/parsing/preparser.h"
#include "src/roots/roots.h" #include "src/roots/roots.h"
#include "src/zone/zone-list-inl.h" // crbug.com/v8/8816 #include "src/zone/zone-list-inl.h" // crbug.com/v8/8816
#include "src/zone/zone-utils.h"
namespace v8 { namespace v8 {
namespace internal { namespace internal {
...@@ -254,7 +255,8 @@ void PreparseDataBuilder::AddChild(PreparseDataBuilder* child) { ...@@ -254,7 +255,8 @@ void PreparseDataBuilder::AddChild(PreparseDataBuilder* child) {
void PreparseDataBuilder::FinalizeChildren(Zone* zone) { void PreparseDataBuilder::FinalizeChildren(Zone* zone) {
DCHECK(!finalized_children_); DCHECK(!finalized_children_);
Vector<PreparseDataBuilder*> children = children_buffer_.CopyTo(zone); Vector<PreparseDataBuilder*> children =
CloneVector(zone, children_buffer_.ToConstVector());
children_buffer_.Rewind(); children_buffer_.Rewind();
children_ = children; children_ = children;
#ifdef DEBUG #ifdef DEBUG
......
...@@ -10,8 +10,8 @@ ...@@ -10,8 +10,8 @@
#include "src/common/globals.h" #include "src/common/globals.h"
#include "src/handles/handles.h" #include "src/handles/handles.h"
#include "src/handles/maybe-handles.h" #include "src/handles/maybe-handles.h"
#include "src/utils/scoped-list.h"
#include "src/utils/vector.h" #include "src/utils/vector.h"
#include "src/zone/scoped-list.h"
#include "src/zone/zone-chunk-list.h" #include "src/zone/zone-chunk-list.h"
#include "src/zone/zone-containers.h" #include "src/zone/zone-containers.h"
......
...@@ -2,14 +2,13 @@ ...@@ -2,14 +2,13 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
#ifndef V8_ZONE_SCOPED_LIST_H_ #ifndef V8_UTILS_SCOPED_LIST_H_
#define V8_ZONE_SCOPED_LIST_H_ #define V8_UTILS_SCOPED_LIST_H_
#include <type_traits> #include <type_traits>
#include <vector> #include <vector>
#include "src/base/logging.h" #include "src/base/logging.h"
#include "src/zone/zone.h"
namespace v8 { namespace v8 {
namespace internal { namespace internal {
...@@ -24,15 +23,14 @@ class ZoneList; ...@@ -24,15 +23,14 @@ class ZoneList;
// re-used between ScopedLists. Note that a ScopedList in an outer scope cannot // re-used between ScopedLists. Note that a ScopedList in an outer scope cannot
// add any entries if there is a ScopedList with the same backing in an inner // add any entries if there is a ScopedList with the same backing in an inner
// scope. // scope.
//
// TODO(ishell): move header to src/utils/ once zone dependency is resolved.
template <typename T, typename TBacking = T> template <typename T, typename TBacking = T>
class ScopedList final { class ScopedList final {
// The backing can either be the same type as the list type, or, for pointers, // The backing can either be the same type as the list type, or, for pointers,
// we additionally allow a void* backing store. // we additionally allow a void* backing store.
STATIC_ASSERT((std::is_same<TBacking, T>::value) || static_assert((std::is_same<TBacking, T>::value) ||
(std::is_same<TBacking, void*>::value && (std::is_same<TBacking, void*>::value &&
std::is_pointer<T>::value)); std::is_pointer<T>::value),
"Incompatible combination of T and TBacking types");
public: public:
explicit ScopedList(std::vector<TBacking>* buffer) explicit ScopedList(std::vector<TBacking>* buffer)
...@@ -69,22 +67,9 @@ class ScopedList final { ...@@ -69,22 +67,9 @@ class ScopedList final {
return *reinterpret_cast<T*>(&buffer_[index]); return *reinterpret_cast<T*>(&buffer_[index]);
} }
void CopyTo(ZoneList<T>* target, Zone* zone) const { Vector<const T> ToConstVector() const {
DCHECK_LE(end_, buffer_.size()); T* data = reinterpret_cast<T*>(buffer_.data() + start_);
// Make sure we don't reference absent elements below. return Vector<const T>(data, length());
if (length() == 0) return;
target->Initialize(length(), zone);
T* data = reinterpret_cast<T*>(&buffer_[start_]);
target->AddAll(Vector<T>(data, length()), zone);
}
Vector<T> CopyTo(Zone* zone) {
DCHECK_LE(end_, buffer_.size());
T* data = zone->NewArray<T>(length());
if (length() != 0) {
MemCopy(data, &buffer_[start_], length() * sizeof(T));
}
return Vector<T>(data, length());
} }
void Add(const T& value) { void Add(const T& value) {
...@@ -93,7 +78,7 @@ class ScopedList final { ...@@ -93,7 +78,7 @@ class ScopedList final {
++end_; ++end_;
} }
void AddAll(const ZoneList<T>& list) { void AddAll(const Vector<const T>& list) {
DCHECK_EQ(buffer_.size(), end_); DCHECK_EQ(buffer_.size(), end_);
buffer_.reserve(buffer_.size() + list.length()); buffer_.reserve(buffer_.size() + list.length());
for (int i = 0; i < list.length(); i++) { for (int i = 0; i < list.length(); i++) {
...@@ -103,10 +88,17 @@ class ScopedList final { ...@@ -103,10 +88,17 @@ class ScopedList final {
} }
using iterator = T*; using iterator = T*;
inline iterator begin() const { using const_iterator = const T*;
inline iterator begin() {
return reinterpret_cast<T*>(buffer_.data() + start_); return reinterpret_cast<T*>(buffer_.data() + start_);
} }
inline iterator end() const { inline const_iterator begin() const {
return reinterpret_cast<T*>(buffer_.data() + start_);
}
inline iterator end() { return reinterpret_cast<T*>(buffer_.data() + end_); }
inline const_iterator end() const {
return reinterpret_cast<T*>(buffer_.data() + end_); return reinterpret_cast<T*>(buffer_.data() + end_);
} }
...@@ -122,4 +114,4 @@ using ScopedPtrList = ScopedList<T*, void*>; ...@@ -122,4 +114,4 @@ using ScopedPtrList = ScopedList<T*, void*>;
} // namespace internal } // namespace internal
} // namespace v8 } // namespace v8
#endif // V8_ZONE_SCOPED_LIST_H_ #endif // V8_UTILS_SCOPED_LIST_H_
...@@ -28,7 +28,7 @@ void ZoneList<T>::AddAll(const ZoneList<T>& other, Zone* zone) { ...@@ -28,7 +28,7 @@ void ZoneList<T>::AddAll(const ZoneList<T>& other, Zone* zone) {
} }
template <typename T> template <typename T>
void ZoneList<T>::AddAll(const Vector<T>& other, Zone* zone) { void ZoneList<T>::AddAll(const Vector<const T>& other, Zone* zone) {
int result_length = length_ + other.length(); int result_length = length_ + other.length();
if (capacity_ < result_length) Resize(result_length, zone); if (capacity_ < result_length) Resize(result_length, zone);
if (std::is_fundamental<T>()) { if (std::is_fundamental<T>()) {
......
...@@ -5,8 +5,6 @@ ...@@ -5,8 +5,6 @@
#ifndef V8_ZONE_ZONE_LIST_H_ #ifndef V8_ZONE_ZONE_LIST_H_
#define V8_ZONE_ZONE_LIST_H_ #define V8_ZONE_ZONE_LIST_H_
#include <initializer_list>
#include "src/base/logging.h" #include "src/base/logging.h"
#include "src/zone/zone-fwd.h" #include "src/zone/zone-fwd.h"
#include "src/zone/zone.h" #include "src/zone/zone.h"
...@@ -32,18 +30,43 @@ class ZoneList final : public ZoneObject { ...@@ -32,18 +30,43 @@ class ZoneList final : public ZoneObject {
public: public:
// Construct a new ZoneList with the given capacity; the length is // Construct a new ZoneList with the given capacity; the length is
// always zero. The capacity must be non-negative. // always zero. The capacity must be non-negative.
ZoneList(int capacity, Zone* zone) { Initialize(capacity, zone); } ZoneList(int capacity, Zone* zone) : capacity_(capacity) {
DCHECK_GE(capacity, 0);
data_ = (capacity_ > 0) ? zone->NewArray<T>(capacity_) : nullptr;
}
// Construct a new ZoneList by copying the elements of the given ZoneList. // Construct a new ZoneList by copying the elements of the given ZoneList.
ZoneList(const ZoneList<T>& other, Zone* zone) { ZoneList(const ZoneList<T>& other, Zone* zone)
Initialize(other.length(), zone); : ZoneList(other.length(), zone) {
AddAll(other, zone); AddAll(other, zone);
} }
// Construct a new ZoneList by copying the elements of the given vector.
ZoneList(const Vector<const T>& other, Zone* zone)
: ZoneList(other.length(), zone) {
AddAll(other, zone);
}
ZoneList(ZoneList<T>&& other) V8_NOEXCEPT { *this = std::move(other); }
// The ZoneList objects are usually allocated as a fields in other // The ZoneList objects are usually allocated as a fields in other
// zone-allocated objects for which destructors are not called anyway, so // zone-allocated objects for which destructors are not called anyway, so
// we are not going to clear the memory here as well. // we are not going to clear the memory here as well.
~ZoneList() = default; ~ZoneList() = default;
ZoneList& operator=(ZoneList&& other) V8_NOEXCEPT {
// We don't have a Zone object, so we'll have to drop the data_ array.
// If this assert ever fails, consider calling Clear(Zone*) or
// DropAndClear() before the move assignment to make it explicit what's
// happenning with the lvalue.
DCHECK_NULL(data_);
data_ = other.data_;
capacity_ = other.capacity_;
length_ = other.length_;
other.DropAndClear();
return *this;
}
// Returns a reference to the element at index i. This reference is not safe // Returns a reference to the element at index i. This reference is not safe
// to use after operations that can change the list's backing store // to use after operations that can change the list's backing store
// (e.g. Add). // (e.g. Add).
...@@ -57,8 +80,12 @@ class ZoneList final : public ZoneObject { ...@@ -57,8 +80,12 @@ class ZoneList final : public ZoneObject {
inline T& first() const { return at(0); } inline T& first() const { return at(0); }
using iterator = T*; using iterator = T*;
inline iterator begin() const { return &data_[0]; } inline iterator begin() { return &data_[0]; }
inline iterator end() const { return &data_[length_]; } inline iterator end() { return &data_[length_]; }
using const_iterator = const T*;
inline const_iterator begin() const { return &data_[0]; }
inline const_iterator end() const { return &data_[length_]; }
V8_INLINE bool is_empty() const { return length_ == 0; } V8_INLINE bool is_empty() const { return length_ == 0; }
V8_INLINE int length() const { return length_; } V8_INLINE int length() const { return length_; }
...@@ -74,23 +101,13 @@ class ZoneList final : public ZoneObject { ...@@ -74,23 +101,13 @@ class ZoneList final : public ZoneObject {
return Vector<const T>(data_, length_); return Vector<const T>(data_, length_);
} }
// TODO(v8:10572): remove this method in favor of more flexible constructor,
// allowing initialization from provided iterators.
V8_INLINE void Initialize(int capacity, Zone* zone) {
DCHECK_GE(capacity, 0);
DCHECK_NULL(data_);
capacity_ = capacity;
data_ = (capacity_ > 0) ? zone->NewArray<T>(capacity_) : nullptr;
length_ = 0;
}
// Adds a copy of the given 'element' to the end of the list, // Adds a copy of the given 'element' to the end of the list,
// expanding the list if necessary. // expanding the list if necessary.
void Add(const T& element, Zone* zone); void Add(const T& element, Zone* zone);
// Add all the elements from the argument list to this list. // Add all the elements from the argument list to this list.
void AddAll(const ZoneList<T>& other, Zone* zone); void AddAll(const ZoneList<T>& other, Zone* zone);
// Add all the elements from the vector to this list. // Add all the elements from the vector to this list.
void AddAll(const Vector<T>& other, Zone* zone); void AddAll(const Vector<const T>& other, Zone* zone);
// Inserts the element at the specific index. // Inserts the element at the specific index.
void InsertAt(int index, const T& element, Zone* zone); void InsertAt(int index, const T& element, Zone* zone);
......
// Copyright 2020 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_ZONE_ZONE_UTILS_H_
#define V8_ZONE_ZONE_UTILS_H_
#include <algorithm>
#include <type_traits>
#include "src/utils/vector.h"
#include "src/zone/zone.h"
namespace v8 {
namespace internal {
template <typename T>
Vector<T> CloneVector(Zone* zone, const Vector<const T>& other) {
int length = other.length();
if (length == 0) return Vector<T>();
T* data = zone->NewArray<T>(length);
if (std::is_fundamental<T>()) {
MemCopy(data, other.data(), length * sizeof(T));
} else {
std::copy(other.begin(), other.end(), data);
}
return Vector<T>(data, length);
}
} // namespace internal
} // namespace v8
#endif // V8_ZONE_ZONE_UTILS_H_
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment