Commit 690d52af authored by Peter Marshall's avatar Peter Marshall Committed by Commit Bot

[cleanup] Remove List.

ZoneList still used List as a base class, so this CL merges the two
classes together. We also remove unused functions in List and ZoneList.

We keep the inline header but move it to src/zone/zone-list-inl.h. The
includes that use this header are still quite tangled, but we can fix
that later.

Bug: v8:6333
Cq-Include-Trybots: master.tryserver.v8:v8_linux_noi18n_rel_ng
Change-Id: Ia809813834b2328ff616623f8a843812a1eb42a7
Reviewed-on: https://chromium-review.googlesource.com/681658
Commit-Queue: Peter Marshall <petermarshall@chromium.org>
Reviewed-by: 's avatarMichael Starzinger <mstarzinger@chromium.org>
Cr-Commit-Position: refs/heads/master@{#48200}
parent 7e4fc163
......@@ -1747,8 +1747,6 @@ v8_source_set("v8_base") {
"src/layout-descriptor-inl.h",
"src/layout-descriptor.cc",
"src/layout-descriptor.h",
"src/list-inl.h",
"src/list.h",
"src/locked-queue-inl.h",
"src/locked-queue.h",
"src/log-inl.h",
......@@ -2099,6 +2097,7 @@ v8_source_set("v8_base") {
"src/zone/zone-chunk-list.h",
"src/zone/zone-containers.h",
"src/zone/zone-handle-set.h",
"src/zone/zone-list-inl.h",
"src/zone/zone-segment.cc",
"src/zone/zone-segment.h",
"src/zone/zone.cc",
......
......@@ -2,6 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include <algorithm>
#include "src/asmjs/switch-logic.h"
namespace v8 {
......
......@@ -6,7 +6,7 @@
#include "src/builtins/builtins.h"
#include "src/code-stub-assembler.h"
#include "src/frame-constants.h"
#include "src/list-inl.h" // TODO(mstarzinger): Temporary cycle breaker.
#include "src/zone/zone-list-inl.h" // TODO(mstarzinger): Temporary cycle breaker.
namespace v8 {
namespace internal {
......
......@@ -8,7 +8,7 @@
#include "src/builtins/builtins-utils-gen.h"
#include "src/code-stub-assembler.h"
#include "src/list-inl.h" // TODO(mstarzinger): Temporary cycle breaker.
#include "src/zone/zone-list-inl.h" // TODO(mstarzinger): Temporary cycle breaker.
namespace v8 {
namespace internal {
......
......@@ -6,7 +6,7 @@
#include "src/builtins/builtins.h"
#include "src/code-factory.h"
#include "src/code-stub-assembler.h"
#include "src/list-inl.h" // TODO(mstarzinger): Temporary cycle breaker.
#include "src/zone/zone-list-inl.h" // TODO(mstarzinger): Temporary cycle breaker.
namespace v8 {
namespace internal {
......
......@@ -9,7 +9,7 @@
#include "src/compiler/node-matchers.h"
#include "src/compiler/operator-properties.h"
#include "src/compiler/simplified-operator.h"
#include "src/list-inl.h" // TODO(mstarzinger): Fix zone-handle-set.h instead!
#include "src/zone/zone-list-inl.h" // TODO(mstarzinger): Fix zone-handle-set.h instead!
#ifdef DEBUG
#define TRACE(...) \
......
......@@ -2,6 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include <algorithm>
#include "src/compiler/zone-stats.h"
namespace v8 {
......
......@@ -18,7 +18,6 @@
#include "src/heap/spaces-inl.h"
#include "src/heap/store-buffer.h"
#include "src/isolate.h"
#include "src/list-inl.h"
#include "src/log.h"
#include "src/msan.h"
#include "src/objects-inl.h"
......@@ -26,6 +25,7 @@
#include "src/objects/script-inl.h"
#include "src/profiler/heap-profiler.h"
#include "src/string-hasher.h"
#include "src/zone/zone-list-inl.h"
namespace v8 {
namespace internal {
......
......@@ -5,6 +5,8 @@
#ifndef V8_INTERPRETER_BYTECODE_LABEL_H_
#define V8_INTERPRETER_BYTECODE_LABEL_H_
#include <algorithm>
#include "src/zone/zone-containers.h"
namespace v8 {
......
// Copyright 2011 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_LIST_H_
#define V8_LIST_H_
#include <algorithm>
#include "src/checks.h"
#include "src/vector.h"
namespace v8 {
namespace internal {
template<typename T> class Vector;
// ----------------------------------------------------------------------------
// The list is a template for very light-weight lists. We are not
// using the STL because we want full control over space and speed of
// the code. This implementation is based on code by Robert Griesemer
// and Rob Pike.
//
// The list is parameterized by the type of its elements (T) and by an
// allocation policy (P). The policy is used for allocating lists in
// the C free store or the zone; see zone.h.
// Forward defined as
// template <typename T,
// class AllocationPolicy = FreeStoreAllocationPolicy> class List;
template <typename T, class AllocationPolicy>
class List {
public:
explicit List(AllocationPolicy allocator = AllocationPolicy()) {
Initialize(0, allocator);
}
INLINE(explicit List(int capacity,
AllocationPolicy allocator = AllocationPolicy())) {
Initialize(capacity, allocator);
}
INLINE(~List()) { DeleteData(data_); }
// Deallocates memory used by the list and leaves the list in a consistent
// empty state.
void Free() {
DeleteData(data_);
Initialize(0);
}
INLINE(void* operator new(size_t size,
AllocationPolicy allocator = AllocationPolicy())) {
return allocator.New(static_cast<int>(size));
}
INLINE(void operator delete(void* p)) {
AllocationPolicy::Delete(p);
}
// Please the MSVC compiler. We should never have to execute this.
INLINE(void operator delete(void* p, AllocationPolicy allocator)) {
UNREACHABLE();
}
// 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 (e.g. Add).
inline T& operator[](int i) const {
DCHECK_LE(0, i);
DCHECK_GT(static_cast<unsigned>(length_), static_cast<unsigned>(i));
return data_[i];
}
inline T& at(int i) const { return operator[](i); }
inline T& last() const { return at(length_ - 1); }
inline T& first() const { return at(0); }
typedef T* iterator;
inline iterator begin() const { return &data_[0]; }
inline iterator end() const { return &data_[length_]; }
INLINE(bool is_empty() const) { return length_ == 0; }
INLINE(int length() const) { return length_; }
INLINE(int capacity() const) { return capacity_; }
Vector<T> ToVector() const { return Vector<T>(data_, length_); }
Vector<const T> ToConstVector() const {
return Vector<const T>(data_, length_);
}
// Adds a copy of the given 'element' to the end of the list,
// expanding the list if necessary.
void Add(const T& element, AllocationPolicy allocator = AllocationPolicy());
// Add all the elements from the argument list to this list.
void AddAll(const List<T, AllocationPolicy>& other,
AllocationPolicy allocator = AllocationPolicy());
// Add all the elements from the vector to this list.
void AddAll(const Vector<T>& other,
AllocationPolicy allocator = AllocationPolicy());
// Inserts the element at the specific index.
void InsertAt(int index, const T& element,
AllocationPolicy allocator = AllocationPolicy());
// Overwrites the element at the specific index.
void Set(int index, const T& element);
// Added 'count' elements with the value 'value' and returns a
// vector that allows access to the elements. The vector is valid
// until the next change is made to this list.
Vector<T> AddBlock(T value, int count,
AllocationPolicy allocator = AllocationPolicy());
// Removes the i'th element without deleting it even if T is a
// pointer type; moves all elements above i "down". Returns the
// removed element. This function's complexity is linear in the
// size of the list.
T Remove(int i);
// Remove the given element from the list. Returns whether or not
// the input is included in the list in the first place.
bool RemoveElement(const T& elm);
// Removes the last element without deleting it even if T is a
// pointer type. Returns the removed element.
INLINE(T RemoveLast()) { return Remove(length_ - 1); }
// Deletes current list contents and allocates space for 'length' elements.
INLINE(void Allocate(int length,
AllocationPolicy allocator = AllocationPolicy()));
// Clears the list by freeing the storage memory. If you want to keep the
// memory, use Rewind(0) instead. Be aware, that even if T is a
// pointer type, clearing the list doesn't delete the entries.
INLINE(void Clear());
// Drops all but the first 'pos' elements from the list.
INLINE(void Rewind(int pos));
// Drop the last 'count' elements from the list.
INLINE(void RewindBy(int count)) { Rewind(length_ - count); }
// Swaps the contents of the two lists.
INLINE(void Swap(List<T, AllocationPolicy>* list));
// Halve the capacity if fill level is less than a quarter.
INLINE(void Trim(AllocationPolicy allocator = AllocationPolicy()));
inline bool Contains(const T& elm) const;
int CountOccurrences(const T& elm, int start, int end) const;
// Iterate through all list entries, starting at index 0.
void Iterate(void (*callback)(T* x));
template<class Visitor>
void Iterate(Visitor* visitor);
// Sort all list entries (using QuickSort)
template <typename CompareFunction>
void Sort(CompareFunction cmp, size_t start, size_t length);
template <typename CompareFunction>
void Sort(CompareFunction cmp);
void Sort();
template <typename CompareFunction>
void StableSort(CompareFunction cmp, size_t start, size_t length);
template <typename CompareFunction>
void StableSort(CompareFunction cmp);
void StableSort();
INLINE(void Initialize(int capacity,
AllocationPolicy allocator = AllocationPolicy())) {
DCHECK(capacity >= 0);
data_ = (capacity > 0) ? NewData(capacity, allocator) : NULL;
capacity_ = capacity;
length_ = 0;
}
private:
T* data_;
int capacity_;
int length_;
INLINE(T* NewData(int n, AllocationPolicy allocator)) {
return static_cast<T*>(allocator.New(n * sizeof(T)));
}
INLINE(void DeleteData(T* data)) {
AllocationPolicy::Delete(data);
}
// Increase the capacity of a full list, and add an element.
// List must be full already.
void ResizeAdd(const T& element, AllocationPolicy allocator);
// Inlined implementation of ResizeAdd, shared by inlined and
// non-inlined versions of ResizeAdd.
void ResizeAddInternal(const T& element, AllocationPolicy allocator);
// Resize the list.
void Resize(int new_capacity, AllocationPolicy allocator);
DISALLOW_COPY_AND_ASSIGN(List);
};
} // namespace internal
} // namespace v8
#endif // V8_LIST_H_
......@@ -5,6 +5,8 @@
#ifndef V8_SPLAY_TREE_INL_H_
#define V8_SPLAY_TREE_INL_H_
#include <vector>
#include "src/splay-tree.h"
namespace v8 {
......@@ -278,13 +280,13 @@ template <typename Config, class Allocator> template <class Callback>
void SplayTree<Config, Allocator>::ForEachNode(Callback* callback) {
if (root_ == NULL) return;
// Pre-allocate some space for tiny trees.
List<Node*, Allocator> nodes_to_visit(10, allocator_);
nodes_to_visit.Add(root_, allocator_);
int pos = 0;
while (pos < nodes_to_visit.length()) {
std::vector<Node*> nodes_to_visit;
nodes_to_visit.push_back(root_);
size_t pos = 0;
while (pos < nodes_to_visit.size()) {
Node* node = nodes_to_visit[pos++];
if (node->left() != NULL) nodes_to_visit.Add(node->left(), allocator_);
if (node->right() != NULL) nodes_to_visit.Add(node->right(), allocator_);
if (node->left() != NULL) nodes_to_visit.push_back(node->left());
if (node->right() != NULL) nodes_to_visit.push_back(node->right());
callback->Call(node);
}
}
......
......@@ -1127,8 +1127,6 @@
'layout-descriptor-inl.h',
'layout-descriptor.cc',
'layout-descriptor.h',
'list-inl.h',
'list.h',
'locked-queue-inl.h',
'locked-queue.h',
'log-inl.h',
......@@ -1486,6 +1484,7 @@
'zone/zone-allocator.h',
'zone/zone-containers.h',
'zone/zone-handle-set.h',
'zone/zone-list-inl.h',
],
'conditions': [
['want_separate_host_toolset==1', {
......
// Copyright 2006-2009 the V8 project authors. All rights reserved.
// 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_LIST_INL_H_
#define V8_LIST_INL_H_
#ifndef V8_ZONE_ZONE_LIST_INL_H_
#define V8_ZONE_ZONE_LIST_INL_H_
#include "src/list.h"
#include "src/zone/zone.h"
#include "src/base/macros.h"
#include "src/base/platform/platform.h"
......@@ -14,27 +14,25 @@
namespace v8 {
namespace internal {
template<typename T, class P>
void List<T, P>::Add(const T& element, P alloc) {
template <typename T>
void ZoneList<T>::Add(const T& element, Zone* zone) {
if (length_ < capacity_) {
data_[length_++] = element;
} else {
List<T, P>::ResizeAdd(element, alloc);
ZoneList<T>::ResizeAdd(element, ZoneAllocationPolicy(zone));
}
}
template<typename T, class P>
void List<T, P>::AddAll(const List<T, P>& other, P alloc) {
AddAll(other.ToVector(), alloc);
template <typename T>
void ZoneList<T>::AddAll(const ZoneList<T>& other, Zone* zone) {
AddAll(other.ToVector(), zone);
}
template<typename T, class P>
void List<T, P>::AddAll(const Vector<T>& other, P alloc) {
template <typename T>
void ZoneList<T>::AddAll(const Vector<T>& other, Zone* zone) {
int result_length = length_ + other.length();
if (capacity_ < result_length) Resize(result_length, alloc);
if (capacity_ < result_length)
Resize(result_length, ZoneAllocationPolicy(zone));
if (std::is_fundamental<T>()) {
memcpy(data_ + length_, other.start(), sizeof(*data_) * other.length());
} else {
......@@ -43,17 +41,16 @@ void List<T, P>::AddAll(const Vector<T>& other, P alloc) {
length_ = result_length;
}
// Use two layers of inlining so that the non-inlined function can
// use the same implementation as the inlined version.
template<typename T, class P>
void List<T, P>::ResizeAdd(const T& element, P alloc) {
template <typename T>
void ZoneList<T>::ResizeAdd(const T& element, ZoneAllocationPolicy alloc) {
ResizeAddInternal(element, alloc);
}
template<typename T, class P>
void List<T, P>::ResizeAddInternal(const T& element, P alloc) {
template <typename T>
void ZoneList<T>::ResizeAddInternal(const T& element,
ZoneAllocationPolicy alloc) {
DCHECK(length_ >= capacity_);
// Grow the list capacity by 100%, but make sure to let it grow
// even when the capacity is zero (possible initial case).
......@@ -65,46 +62,41 @@ void List<T, P>::ResizeAddInternal(const T& element, P alloc) {
data_[length_++] = temp;
}
template<typename T, class P>
void List<T, P>::Resize(int new_capacity, P alloc) {
template <typename T>
void ZoneList<T>::Resize(int new_capacity, ZoneAllocationPolicy alloc) {
DCHECK_LE(length_, new_capacity);
T* new_data = NewData(new_capacity, alloc);
MemCopy(new_data, data_, length_ * sizeof(T));
List<T, P>::DeleteData(data_);
ZoneList<T>::DeleteData(data_);
data_ = new_data;
capacity_ = new_capacity;
}
template<typename T, class P>
Vector<T> List<T, P>::AddBlock(T value, int count, P alloc) {
template <typename T>
Vector<T> ZoneList<T>::AddBlock(T value, int count, Zone* zone) {
int start = length_;
for (int i = 0; i < count; i++) Add(value, alloc);
for (int i = 0; i < count; i++) Add(value, zone);
return Vector<T>(&data_[start], count);
}
template<typename T, class P>
void List<T, P>::Set(int index, const T& elm) {
template <typename T>
void ZoneList<T>::Set(int index, const T& elm) {
DCHECK(index >= 0 && index <= length_);
data_[index] = elm;
}
template<typename T, class P>
void List<T, P>::InsertAt(int index, const T& elm, P alloc) {
template <typename T>
void ZoneList<T>::InsertAt(int index, const T& elm, Zone* zone) {
DCHECK(index >= 0 && index <= length_);
Add(elm, alloc);
Add(elm, zone);
for (int i = length_ - 1; i > index; --i) {
data_[i] = data_[i - 1];
}
data_[index] = elm;
}
template<typename T, class P>
T List<T, P>::Remove(int i) {
template <typename T>
T ZoneList<T>::Remove(int i) {
T element = at(i);
length_--;
while (i < length_) {
......@@ -114,35 +106,8 @@ T List<T, P>::Remove(int i) {
return element;
}
template<typename T, class P>
bool List<T, P>::RemoveElement(const T& elm) {
for (int i = 0; i < length_; i++) {
if (data_[i] == elm) {
Remove(i);
return true;
}
}
return false;
}
template <typename T, class P>
void List<T, P>::Swap(List<T, P>* list) {
std::swap(data_, list->data_);
std::swap(length_, list->length_);
std::swap(capacity_, list->capacity_);
}
template<typename T, class P>
void List<T, P>::Allocate(int length, P allocator) {
DeleteData(data_);
Initialize(length, allocator);
length_ = length;
}
template<typename T, class P>
void List<T, P>::Clear() {
template <typename T>
void ZoneList<T>::Clear() {
DeleteData(data_);
// We don't call Initialize(0) since that requires passing a Zone,
// which we don't really need.
......@@ -151,101 +116,49 @@ void List<T, P>::Clear() {
length_ = 0;
}
template<typename T, class P>
void List<T, P>::Rewind(int pos) {
template <typename T>
void ZoneList<T>::Rewind(int pos) {
DCHECK(0 <= pos && pos <= length_);
length_ = pos;
}
template<typename T, class P>
void List<T, P>::Trim(P alloc) {
if (length_ < capacity_ / 4) {
Resize(capacity_ / 2, alloc);
}
}
template<typename T, class P>
void List<T, P>::Iterate(void (*callback)(T* x)) {
for (int i = 0; i < length_; i++) callback(&data_[i]);
}
template<typename T, class P>
template<class Visitor>
void List<T, P>::Iterate(Visitor* visitor) {
template <typename T>
template <class Visitor>
void ZoneList<T>::Iterate(Visitor* visitor) {
for (int i = 0; i < length_; i++) visitor->Apply(&data_[i]);
}
template<typename T, class P>
bool List<T, P>::Contains(const T& elm) const {
template <typename T>
bool ZoneList<T>::Contains(const T& elm) const {
for (int i = 0; i < length_; i++) {
if (data_[i] == elm)
return true;
if (data_[i] == elm) return true;
}
return false;
}
template<typename T, class P>
int List<T, P>::CountOccurrences(const T& elm, int start, int end) const {
int result = 0;
for (int i = start; i <= end; i++) {
if (data_[i] == elm) ++result;
}
return result;
}
template <typename T, class P>
template <typename CompareFunction>
void List<T, P>::Sort(CompareFunction cmp) {
Sort(cmp, 0, length_);
}
template <typename T, class P>
template <typename T>
template <typename CompareFunction>
void List<T, P>::Sort(CompareFunction cmp, size_t s, size_t l) {
ToVector().Sort(cmp, s, l);
void ZoneList<T>::Sort(CompareFunction cmp) {
ToVector().Sort(cmp, 0, length_);
#ifdef DEBUG
for (size_t i = s + 1; i < l; i++) DCHECK(cmp(&data_[i - 1], &data_[i]) <= 0);
for (int i = 1; i < length_; i++) {
DCHECK_LE(cmp(&data_[i - 1], &data_[i]), 0);
}
#endif
}
template<typename T, class P>
void List<T, P>::Sort() {
ToVector().Sort();
}
template <typename T, class P>
template <typename T>
template <typename CompareFunction>
void List<T, P>::StableSort(CompareFunction cmp) {
StableSort(cmp, 0, length_);
}
template <typename T, class P>
template <typename CompareFunction>
void List<T, P>::StableSort(CompareFunction cmp, size_t s, size_t l) {
void ZoneList<T>::StableSort(CompareFunction cmp, size_t s, size_t l) {
ToVector().StableSort(cmp, s, l);
#ifdef DEBUG
for (size_t i = s + 1; i < l; i++) DCHECK(cmp(&data_[i - 1], &data_[i]) <= 0);
for (size_t i = s + 1; i < l; i++) {
DCHECK_LE(cmp(&data_[i - 1], &data_[i]), 0);
}
#endif
}
template <typename T, class P>
void List<T, P>::StableSort() {
ToVector().StableSort();
}
} // namespace internal
} // namespace v8
#endif // V8_LIST_INL_H_
#endif // V8_ZONE_ZONE_LIST_INL_H_
......@@ -10,7 +10,6 @@
#include "src/base/hashmap.h"
#include "src/base/logging.h"
#include "src/globals.h"
#include "src/list.h"
#include "src/splay-tree.h"
#include "src/zone/accounting-allocator.h"
......@@ -144,63 +143,146 @@ class ZoneAllocationPolicy final {
Zone* zone_;
};
template <typename T>
class Vector;
// ZoneLists are growable lists with constant-time access to the
// elements. The list itself and all its elements are allocated in the
// Zone. ZoneLists cannot be deleted individually; you can delete all
// objects in the Zone by calling Zone::DeleteAll().
template <typename T>
class ZoneList final : public List<T, ZoneAllocationPolicy> {
class ZoneList final {
public:
// Construct a new ZoneList with the given capacity; the length is
// always zero. The capacity must be non-negative.
ZoneList(int capacity, Zone* zone)
: List<T, ZoneAllocationPolicy>(capacity, ZoneAllocationPolicy(zone)) {}
ZoneList(int capacity, Zone* zone) { Initialize(capacity, zone); }
// Construct a new ZoneList from a std::initializer_list
ZoneList(std::initializer_list<T> list, Zone* zone)
: List<T, ZoneAllocationPolicy>(static_cast<int>(list.size()),
ZoneAllocationPolicy(zone)) {
ZoneList(std::initializer_list<T> list, Zone* zone) {
Initialize(static_cast<int>(list.size()), zone);
for (auto& i : list) Add(i, zone);
}
void* operator new(size_t size, Zone* zone) { return zone->New(size); }
// Construct a new ZoneList by copying the elements of the given ZoneList.
ZoneList(const ZoneList<T>& other, Zone* zone)
: List<T, ZoneAllocationPolicy>(other.length(),
ZoneAllocationPolicy(zone)) {
ZoneList(const ZoneList<T>& other, Zone* zone) {
Initialize(other.length(), zone);
AddAll(other, zone);
}
// We add some convenience wrappers so that we can pass in a Zone
// instead of a (less convenient) ZoneAllocationPolicy.
void Add(const T& element, Zone* zone) {
List<T, ZoneAllocationPolicy>::Add(element, ZoneAllocationPolicy(zone));
}
void AddAll(const List<T, ZoneAllocationPolicy>& other, Zone* zone) {
List<T, ZoneAllocationPolicy>::AddAll(other, ZoneAllocationPolicy(zone));
}
void AddAll(const Vector<T>& other, Zone* zone) {
List<T, ZoneAllocationPolicy>::AddAll(other, ZoneAllocationPolicy(zone));
}
void InsertAt(int index, const T& element, Zone* zone) {
List<T, ZoneAllocationPolicy>::InsertAt(index, element,
ZoneAllocationPolicy(zone));
INLINE(~ZoneList()) { DeleteData(data_); }
// Please the MSVC compiler. We should never have to execute this.
INLINE(void operator delete(void* p, ZoneAllocationPolicy allocator)) {
UNREACHABLE();
}
Vector<T> AddBlock(T value, int count, Zone* zone) {
return List<T, ZoneAllocationPolicy>::AddBlock(value, count,
ZoneAllocationPolicy(zone));
void* operator new(size_t size, Zone* zone) { return zone->New(size); }
// 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
// (e.g. Add).
inline T& operator[](int i) const {
DCHECK_LE(0, i);
DCHECK_GT(static_cast<unsigned>(length_), static_cast<unsigned>(i));
return data_[i];
}
void Allocate(int length, Zone* zone) {
List<T, ZoneAllocationPolicy>::Allocate(length, ZoneAllocationPolicy(zone));
inline T& at(int i) const { return operator[](i); }
inline T& last() const { return at(length_ - 1); }
inline T& first() const { return at(0); }
typedef T* iterator;
inline iterator begin() const { return &data_[0]; }
inline iterator end() const { return &data_[length_]; }
INLINE(bool is_empty() const) { return length_ == 0; }
INLINE(int length() const) { return length_; }
INLINE(int capacity() const) { return capacity_; }
Vector<T> ToVector() const { return Vector<T>(data_, length_); }
Vector<const T> ToConstVector() const {
return Vector<const T>(data_, length_);
}
void Initialize(int capacity, Zone* zone) {
List<T, ZoneAllocationPolicy>::Initialize(capacity,
ZoneAllocationPolicy(zone));
INLINE(void Initialize(int capacity, Zone* zone)) {
DCHECK_GE(capacity, 0);
data_ =
(capacity > 0) ? NewData(capacity, ZoneAllocationPolicy(zone)) : NULL;
capacity_ = capacity;
length_ = 0;
}
// Adds a copy of the given 'element' to the end of the list,
// expanding the list if necessary.
void Add(const T& element, Zone* zone);
// Add all the elements from the argument list to this list.
void AddAll(const ZoneList<T>& other, Zone* zone);
// Add all the elements from the vector to this list.
void AddAll(const Vector<T>& other, Zone* zone);
// Inserts the element at the specific index.
void InsertAt(int index, const T& element, Zone* zone);
// Added 'count' elements with the value 'value' and returns a
// vector that allows access to the elements. The vector is valid
// until the next change is made to this list.
Vector<T> AddBlock(T value, int count, Zone* zone);
// Overwrites the element at the specific index.
void Set(int index, const T& element);
// Removes the i'th element without deleting it even if T is a
// pointer type; moves all elements above i "down". Returns the
// removed element. This function's complexity is linear in the
// size of the list.
T Remove(int i);
// Removes the last element without deleting it even if T is a
// pointer type. Returns the removed element.
INLINE(T RemoveLast()) { return Remove(length_ - 1); }
// Clears the list by freeing the storage memory. If you want to keep the
// memory, use Rewind(0) instead. Be aware, that even if T is a
// pointer type, clearing the list doesn't delete the entries.
INLINE(void Clear());
// Drops all but the first 'pos' elements from the list.
INLINE(void Rewind(int pos));
inline bool Contains(const T& elm) const;
// Iterate through all list entries, starting at index 0.
template <class Visitor>
void Iterate(Visitor* visitor);
// Sort all list entries (using QuickSort)
template <typename CompareFunction>
void Sort(CompareFunction cmp);
template <typename CompareFunction>
void StableSort(CompareFunction cmp, size_t start, size_t length);
void operator delete(void* pointer) { UNREACHABLE(); }
void operator delete(void* pointer, Zone* zone) { UNREACHABLE(); }
private:
T* data_;
int capacity_;
int length_;
INLINE(T* NewData(int n, ZoneAllocationPolicy allocator)) {
return static_cast<T*>(allocator.New(n * sizeof(T)));
}
INLINE(void DeleteData(T* data)) { ZoneAllocationPolicy::Delete(data); }
// Increase the capacity of a full list, and add an element.
// List must be full already.
void ResizeAdd(const T& element, ZoneAllocationPolicy allocator);
// Inlined implementation of ResizeAdd, shared by inlined and
// non-inlined versions of ResizeAdd.
void ResizeAddInternal(const T& element, ZoneAllocationPolicy allocator);
// Resize the list.
void Resize(int new_capacity, ZoneAllocationPolicy allocator);
DISALLOW_COPY_AND_ASSIGN(ZoneList);
};
// A zone splay tree. The config type parameter encapsulates the
......
......@@ -178,7 +178,6 @@ v8_source_set("cctest_sources") {
"test-identity-map.cc",
"test-inobject-slack-tracking.cc",
"test-intl.cc",
"test-list.cc",
"test-liveedit.cc",
"test-lockers.cc",
"test-log.cc",
......
......@@ -168,7 +168,6 @@
'test-identity-map.cc',
'test-intl.cc',
'test-inobject-slack-tracking.cc',
'test-list.cc',
'test-liveedit.cc',
'test-lockers.cc',
'test-log.cc',
......
......@@ -6667,19 +6667,19 @@ TEST(DebugEvaluateNoSideEffect) {
LocalContext env;
i::Isolate* isolate = CcTest::i_isolate();
i::HandleScope scope(isolate);
i::List<i::Handle<i::JSFunction>> list;
std::vector<i::Handle<i::JSFunction>> all_functions;
{
i::HeapIterator iterator(isolate->heap());
while (i::HeapObject* obj = iterator.next()) {
if (!obj->IsJSFunction()) continue;
i::JSFunction* fun = i::JSFunction::cast(obj);
list.Add(i::Handle<i::JSFunction>(fun));
all_functions.emplace_back(fun);
}
}
// Perform side effect check on all built-in functions. The side effect check
// itself contains additional sanity checks.
for (i::Handle<i::JSFunction> fun : list) {
for (i::Handle<i::JSFunction> fun : all_functions) {
bool failed = false;
{
i::NoSideEffectScope scope(isolate, true);
......
// Copyright 2011 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following
// disclaimer in the documentation and/or other materials provided
// with the distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <stdlib.h>
#include <string.h>
#include "src/list-inl.h"
#include "src/list.h"
#include "src/v8.h"
#include "test/cctest/cctest.h"
namespace v8 {
namespace internal {
// Use a testing allocator that clears memory before deletion.
class ZeroingAllocationPolicy {
public:
void* New(size_t size) {
// Stash the size in the first word to use for Delete.
size_t true_size = size + sizeof(size_t);
size_t* result = reinterpret_cast<size_t*>(malloc(true_size));
if (result == NULL) return result;
*result = true_size;
return result + 1;
}
static void Delete(void* ptr) {
size_t* true_ptr = reinterpret_cast<size_t*>(ptr) - 1;
memset(true_ptr, 0, *true_ptr);
free(true_ptr);
}
};
// Check that we can add (a reference to) an element of the list
// itself.
TEST(ListAdd) {
// Add elements to the list to grow it to its capacity.
List<int, ZeroingAllocationPolicy> list(4);
list.Add(1);
list.Add(2);
list.Add(3);
list.Add(4);
// Add an existing element, the backing store should have to grow.
list.Add(list[0]);
CHECK_EQ(1, list[4]);
}
// Test that we can add all elements from a list to another list.
TEST(ListAddAll) {
List<int, ZeroingAllocationPolicy> list(4);
list.Add(0);
list.Add(1);
list.Add(2);
CHECK_EQ(3, list.length());
for (int i = 0; i < 3; i++) {
CHECK_EQ(i, list[i]);
}
List<int, ZeroingAllocationPolicy> other_list(4);
// Add no elements to list since other_list is empty.
list.AddAll(other_list);
CHECK_EQ(3, list.length());
for (int i = 0; i < 3; i++) {
CHECK_EQ(i, list[i]);
}
// Add three elements to other_list.
other_list.Add(0);
other_list.Add(1);
other_list.Add(2);
// Copy the three elements from other_list to list.
list.AddAll(other_list);
CHECK_EQ(6, list.length());
for (int i = 0; i < 6; i++) {
CHECK_EQ(i % 3, list[i]);
}
}
TEST(RemoveLast) {
List<int> list(4);
CHECK_EQ(0, list.length());
list.Add(1);
CHECK_EQ(1, list.length());
CHECK_EQ(1, list.last());
list.RemoveLast();
CHECK_EQ(0, list.length());
list.Add(2);
list.Add(3);
CHECK_EQ(2, list.length());
CHECK_EQ(3, list.last());
list.RemoveLast();
CHECK_EQ(1, list.length());
CHECK_EQ(2, list.last());
list.RemoveLast();
CHECK_EQ(0, list.length());
const int kElements = 100;
for (int i = 0; i < kElements; i++) list.Add(i);
for (int j = kElements - 1; j >= 0; j--) {
CHECK_EQ(j + 1, list.length());
CHECK_EQ(j, list.last());
list.RemoveLast();
CHECK_EQ(j, list.length());
}
}
TEST(Allocate) {
List<int> list(4);
list.Add(1);
CHECK_EQ(1, list.length());
list.Allocate(100);
CHECK_EQ(100, list.length());
CHECK_LE(100, list.capacity());
list[99] = 123;
CHECK_EQ(123, list[99]);
}
TEST(Clear) {
List<int> list(4);
CHECK_EQ(0, list.length());
for (int i = 0; i < 4; ++i) list.Add(i);
CHECK_EQ(4, list.length());
list.Clear();
CHECK_EQ(0, list.length());
}
TEST(DeleteEmpty) {
{
List<int>* list = new List<int>(0);
delete list;
}
{
List<int> list(0);
}
}
} // namespace internal
} // namespace v8
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