blob: 83e5f4594ee5ae0bbdd0ac8d9f7337701c58a0c3 [file] [log] [blame]
Ben Murdoch257744e2011-11-30 15:57:28 +00001// Copyright 2011 the V8 project authors. All rights reserved.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
Steve Blocka7e24c12009-10-30 11:49:00 +00004
5#ifndef V8_LIST_H_
6#define V8_LIST_H_
7
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00008#include <algorithm>
9
Ben Murdochb8a8cc12014-11-26 15:28:44 +000010#include "src/checks.h"
11#include "src/utils.h"
Ben Murdoch257744e2011-11-30 15:57:28 +000012
Steve Blocka7e24c12009-10-30 11:49:00 +000013namespace v8 {
14namespace internal {
15
Ben Murdochb8a8cc12014-11-26 15:28:44 +000016template<typename T> class Vector;
Steve Blocka7e24c12009-10-30 11:49:00 +000017
18// ----------------------------------------------------------------------------
19// The list is a template for very light-weight lists. We are not
20// using the STL because we want full control over space and speed of
21// the code. This implementation is based on code by Robert Griesemer
22// and Rob Pike.
23//
24// The list is parameterized by the type of its elements (T) and by an
25// allocation policy (P). The policy is used for allocating lists in
26// the C free store or the zone; see zone.h.
27
28// Forward defined as
Ben Murdochb8a8cc12014-11-26 15:28:44 +000029// template <typename T,
30// class AllocationPolicy = FreeStoreAllocationPolicy> class List;
31template <typename T, class AllocationPolicy>
Steve Blocka7e24c12009-10-30 11:49:00 +000032class List {
33 public:
Ben Murdochb8a8cc12014-11-26 15:28:44 +000034 explicit List(AllocationPolicy allocator = AllocationPolicy()) {
35 Initialize(0, allocator);
36 }
37 INLINE(explicit List(int capacity,
38 AllocationPolicy allocator = AllocationPolicy())) {
39 Initialize(capacity, allocator);
40 }
Steve Blocka7e24c12009-10-30 11:49:00 +000041 INLINE(~List()) { DeleteData(data_); }
42
43 // Deallocates memory used by the list and leaves the list in a consistent
44 // empty state.
45 void Free() {
46 DeleteData(data_);
47 Initialize(0);
48 }
49
Ben Murdochb8a8cc12014-11-26 15:28:44 +000050 INLINE(void* operator new(size_t size,
51 AllocationPolicy allocator = AllocationPolicy())) {
52 return allocator.New(static_cast<int>(size));
Steve Blockd0582a62009-12-15 09:54:21 +000053 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +000054 INLINE(void operator delete(void* p)) {
55 AllocationPolicy::Delete(p);
56 }
57
58 // Please the MSVC compiler. We should never have to execute this.
59 INLINE(void operator delete(void* p, AllocationPolicy allocator)) {
60 UNREACHABLE();
61 }
Steve Blocka7e24c12009-10-30 11:49:00 +000062
63 // Returns a reference to the element at index i. This reference is
64 // not safe to use after operations that can change the list's
Ben Murdoch3ef787d2012-04-12 10:51:47 +010065 // backing store (e.g. Add).
Kristian Monsen0d5e1162010-09-30 15:31:59 +010066 inline T& operator[](int i) const {
Ben Murdochb8a8cc12014-11-26 15:28:44 +000067 DCHECK(0 <= i);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000068 SLOW_DCHECK(static_cast<unsigned>(i) < static_cast<unsigned>(length_));
Steve Blocka7e24c12009-10-30 11:49:00 +000069 return data_[i];
70 }
Kristian Monsen0d5e1162010-09-30 15:31:59 +010071 inline T& at(int i) const { return operator[](i); }
Steve Blocka7e24c12009-10-30 11:49:00 +000072 inline T& last() const { return at(length_ - 1); }
73 inline T& first() const { return at(0); }
74
Ben Murdochb8a8cc12014-11-26 15:28:44 +000075 typedef T* iterator;
76 inline iterator begin() const { return &data_[0]; }
77 inline iterator end() const { return &data_[length_]; }
78
Steve Blocka7e24c12009-10-30 11:49:00 +000079 INLINE(bool is_empty() const) { return length_ == 0; }
80 INLINE(int length() const) { return length_; }
81 INLINE(int capacity() const) { return capacity_; }
82
Ben Murdoch257744e2011-11-30 15:57:28 +000083 Vector<T> ToVector() const { return Vector<T>(data_, length_); }
Steve Blocka7e24c12009-10-30 11:49:00 +000084
Emily Bernierd0a1eb72015-03-24 16:35:39 -040085 Vector<const T> ToConstVector() const {
86 return Vector<const T>(data_, length_);
87 }
Steve Blocka7e24c12009-10-30 11:49:00 +000088
89 // Adds a copy of the given 'element' to the end of the list,
90 // expanding the list if necessary.
Ben Murdochb8a8cc12014-11-26 15:28:44 +000091 void Add(const T& element, AllocationPolicy allocator = AllocationPolicy());
Steve Blocka7e24c12009-10-30 11:49:00 +000092
93 // Add all the elements from the argument list to this list.
Ben Murdochb8a8cc12014-11-26 15:28:44 +000094 void AddAll(const List<T, AllocationPolicy>& other,
95 AllocationPolicy allocator = AllocationPolicy());
Steve Blocka7e24c12009-10-30 11:49:00 +000096
Ben Murdoch257744e2011-11-30 15:57:28 +000097 // Add all the elements from the vector to this list.
Ben Murdochb8a8cc12014-11-26 15:28:44 +000098 void AddAll(const Vector<T>& other,
99 AllocationPolicy allocator = AllocationPolicy());
Ben Murdoch257744e2011-11-30 15:57:28 +0000100
Ben Murdochb0fe1622011-05-05 13:52:32 +0100101 // Inserts the element at the specific index.
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000102 void InsertAt(int index, const T& element,
103 AllocationPolicy allocator = AllocationPolicy());
104
105 // Overwrites the element at the specific index.
106 void Set(int index, const T& element);
Ben Murdochb0fe1622011-05-05 13:52:32 +0100107
Steve Blocka7e24c12009-10-30 11:49:00 +0000108 // Added 'count' elements with the value 'value' and returns a
109 // vector that allows access to the elements. The vector is valid
110 // until the next change is made to this list.
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000111 Vector<T> AddBlock(T value, int count,
112 AllocationPolicy allocator = AllocationPolicy());
Steve Blocka7e24c12009-10-30 11:49:00 +0000113
114 // Removes the i'th element without deleting it even if T is a
115 // pointer type; moves all elements above i "down". Returns the
116 // removed element. This function's complexity is linear in the
117 // size of the list.
118 T Remove(int i);
119
Ben Murdochb0fe1622011-05-05 13:52:32 +0100120 // Remove the given element from the list. Returns whether or not
121 // the input is included in the list in the first place.
122 bool RemoveElement(const T& elm);
123
Steve Blocka7e24c12009-10-30 11:49:00 +0000124 // Removes the last element without deleting it even if T is a
125 // pointer type. Returns the removed element.
126 INLINE(T RemoveLast()) { return Remove(length_ - 1); }
127
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000128 // Deletes current list contents and allocates space for 'length' elements.
129 INLINE(void Allocate(int length,
130 AllocationPolicy allocator = AllocationPolicy()));
131
Steve Blocka7e24c12009-10-30 11:49:00 +0000132 // Clears the list by setting the length to zero. Even if T is a
133 // pointer type, clearing the list doesn't delete the entries.
134 INLINE(void Clear());
135
136 // Drops all but the first 'pos' elements from the list.
137 INLINE(void Rewind(int pos));
138
Ben Murdochb0fe1622011-05-05 13:52:32 +0100139 // Drop the last 'count' elements from the list.
140 INLINE(void RewindBy(int count)) { Rewind(length_ - count); }
141
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000142 // Swaps the contents of the two lists.
143 INLINE(void Swap(List<T, AllocationPolicy>* list));
144
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000145 // Halve the capacity if fill level is less than a quarter.
146 INLINE(void Trim(AllocationPolicy allocator = AllocationPolicy()));
147
Ben Murdochb0fe1622011-05-05 13:52:32 +0100148 bool Contains(const T& elm) const;
149 int CountOccurrences(const T& elm, int start, int end) const;
Steve Blocka7e24c12009-10-30 11:49:00 +0000150
151 // Iterate through all list entries, starting at index 0.
152 void Iterate(void (*callback)(T* x));
Iain Merrick75681382010-08-19 15:07:18 +0100153 template<class Visitor>
154 void Iterate(Visitor* visitor);
Steve Blocka7e24c12009-10-30 11:49:00 +0000155
156 // Sort all list entries (using QuickSort)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000157 template <typename CompareFunction>
158 void Sort(CompareFunction cmp, size_t start, size_t length);
159 template <typename CompareFunction>
160 void Sort(CompareFunction cmp);
Steve Blocka7e24c12009-10-30 11:49:00 +0000161 void Sort();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000162 template <typename CompareFunction>
163 void StableSort(CompareFunction cmp, size_t start, size_t length);
164 template <typename CompareFunction>
165 void StableSort(CompareFunction cmp);
166 void StableSort();
Steve Blocka7e24c12009-10-30 11:49:00 +0000167
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000168 INLINE(void Initialize(int capacity,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000169 AllocationPolicy allocator = AllocationPolicy())) {
170 DCHECK(capacity >= 0);
171 data_ = (capacity > 0) ? NewData(capacity, allocator) : NULL;
172 capacity_ = capacity;
173 length_ = 0;
174 }
Steve Blocka7e24c12009-10-30 11:49:00 +0000175
176 private:
177 T* data_;
178 int capacity_;
179 int length_;
180
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000181 INLINE(T* NewData(int n, AllocationPolicy allocator)) {
182 return static_cast<T*>(allocator.New(n * sizeof(T)));
183 }
184 INLINE(void DeleteData(T* data)) {
185 AllocationPolicy::Delete(data);
186 }
Steve Blocka7e24c12009-10-30 11:49:00 +0000187
188 // Increase the capacity of a full list, and add an element.
189 // List must be full already.
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000190 void ResizeAdd(const T& element, AllocationPolicy allocator);
Steve Blocka7e24c12009-10-30 11:49:00 +0000191
192 // Inlined implementation of ResizeAdd, shared by inlined and
193 // non-inlined versions of ResizeAdd.
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000194 void ResizeAddInternal(const T& element, AllocationPolicy allocator);
Steve Blocka7e24c12009-10-30 11:49:00 +0000195
196 // Resize the list.
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000197 void Resize(int new_capacity, AllocationPolicy allocator);
Steve Blocka7e24c12009-10-30 11:49:00 +0000198
199 DISALLOW_COPY_AND_ASSIGN(List);
200};
201
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000202
203template<typename T, class P>
204size_t GetMemoryUsedByList(const List<T, P>& list) {
205 return list.length() * sizeof(T) + sizeof(list);
206}
207
208
Ben Murdoch257744e2011-11-30 15:57:28 +0000209class Map;
Ben Murdoch097c5b22016-05-18 11:27:45 +0100210class FieldType;
Ben Murdoch257744e2011-11-30 15:57:28 +0000211class Code;
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100212template<typename T> class Handle;
Ben Murdoch257744e2011-11-30 15:57:28 +0000213typedef List<Map*> MapList;
214typedef List<Code*> CodeList;
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100215typedef List<Handle<Map> > MapHandleList;
Ben Murdoch097c5b22016-05-18 11:27:45 +0100216typedef List<Handle<FieldType> > TypeHandleList;
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100217typedef List<Handle<Code> > CodeHandleList;
Ben Murdoch257744e2011-11-30 15:57:28 +0000218
Ben Murdoch589d6972011-11-30 16:04:58 +0000219// Perform binary search for an element in an already sorted
220// list. Returns the index of the element of -1 if it was not found.
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000221// |cmp| is a predicate that takes a pointer to an element of the List
222// and returns +1 if it is greater, -1 if it is less than the element
223// being searched.
224template <typename T, class P>
225int SortedListBSearch(const List<T>& list, P cmp);
Ben Murdoch589d6972011-11-30 16:04:58 +0000226template <typename T>
227int SortedListBSearch(const List<T>& list, T elem);
228
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100229
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000230} // namespace internal
231} // namespace v8
Steve Blocka7e24c12009-10-30 11:49:00 +0000232
Ben Murdoch589d6972011-11-30 16:04:58 +0000233
Steve Blocka7e24c12009-10-30 11:49:00 +0000234#endif // V8_LIST_H_