V8 Project
small-pointer-list.h
Go to the documentation of this file.
1 // Copyright 2011 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef V8_SMALL_POINTER_LIST_H_
6 #define V8_SMALL_POINTER_LIST_H_
7 
8 #include "src/base/logging.h"
9 #include "src/globals.h"
10 #include "src/zone.h"
11 
12 namespace v8 {
13 namespace internal {
14 
15 // SmallPointerList is a list optimized for storing no or just a
16 // single value. When more values are given it falls back to ZoneList.
17 //
18 // The interface tries to be as close to List from list.h as possible.
19 template <typename T>
21  public:
23 
24  SmallPointerList(int capacity, Zone* zone) : data_(kEmptyTag) {
25  Reserve(capacity, zone);
26  }
27 
28  void Reserve(int capacity, Zone* zone) {
29  if (capacity < 2) return;
30  if ((data_ & kTagMask) == kListTag) {
31  if (list()->capacity() >= capacity) return;
32  int old_length = list()->length();
33  list()->AddBlock(NULL, capacity - list()->capacity(), zone);
34  list()->Rewind(old_length);
35  return;
36  }
37  PointerList* list = new(zone) PointerList(capacity, zone);
38  if ((data_ & kTagMask) == kSingletonTag) {
39  list->Add(single_value(), zone);
40  }
41  DCHECK(IsAligned(reinterpret_cast<intptr_t>(list), kPointerAlignment));
42  data_ = reinterpret_cast<intptr_t>(list) | kListTag;
43  }
44 
45  void Clear() {
46  data_ = kEmptyTag;
47  }
48 
49  void Sort() {
50  if ((data_ & kTagMask) == kListTag) {
52  }
53  }
54 
55  bool is_empty() const { return length() == 0; }
56 
57  int length() const {
58  if ((data_ & kTagMask) == kEmptyTag) return 0;
59  if ((data_ & kTagMask) == kSingletonTag) return 1;
60  return list()->length();
61  }
62 
63  void Add(T* pointer, Zone* zone) {
64  DCHECK(IsAligned(reinterpret_cast<intptr_t>(pointer), kPointerAlignment));
65  if ((data_ & kTagMask) == kEmptyTag) {
66  data_ = reinterpret_cast<intptr_t>(pointer) | kSingletonTag;
67  return;
68  }
69  if ((data_ & kTagMask) == kSingletonTag) {
70  PointerList* list = new(zone) PointerList(2, zone);
71  list->Add(single_value(), zone);
72  list->Add(pointer, zone);
73  DCHECK(IsAligned(reinterpret_cast<intptr_t>(list), kPointerAlignment));
74  data_ = reinterpret_cast<intptr_t>(list) | kListTag;
75  return;
76  }
77  list()->Add(pointer, zone);
78  }
79 
80  // Note: returns T* and not T*& (unlike List from list.h).
81  // This makes the implementation simpler and more const correct.
82  T* at(int i) const {
84  if ((data_ & kTagMask) == kSingletonTag) {
85  DCHECK(i == 0);
86  return single_value();
87  }
88  return list()->at(i);
89  }
90 
91  // See the note above.
92  T* operator[](int i) const { return at(i); }
93 
94  // Remove the given element from the list (if present).
95  void RemoveElement(T* pointer) {
96  if ((data_ & kTagMask) == kEmptyTag) return;
97  if ((data_ & kTagMask) == kSingletonTag) {
98  if (pointer == single_value()) {
99  data_ = kEmptyTag;
100  }
101  return;
102  }
103  list()->RemoveElement(pointer);
104  }
105 
107  DCHECK((data_ & kTagMask) != kEmptyTag);
108  if ((data_ & kTagMask) == kSingletonTag) {
109  T* result = single_value();
110  data_ = kEmptyTag;
111  return result;
112  }
113  return list()->RemoveLast();
114  }
115 
116  void Rewind(int pos) {
117  if ((data_ & kTagMask) == kEmptyTag) {
118  DCHECK(pos == 0);
119  return;
120  }
121  if ((data_ & kTagMask) == kSingletonTag) {
122  DCHECK(pos == 0 || pos == 1);
123  if (pos == 0) {
124  data_ = kEmptyTag;
125  }
126  return;
127  }
128  list()->Rewind(pos);
129  }
130 
131  int CountOccurrences(T* pointer, int start, int end) const {
132  if ((data_ & kTagMask) == kEmptyTag) return 0;
133  if ((data_ & kTagMask) == kSingletonTag) {
134  if (start == 0 && end >= 0) {
135  return (single_value() == pointer) ? 1 : 0;
136  }
137  return 0;
138  }
139  return list()->CountOccurrences(pointer, start, end);
140  }
141 
142  private:
144 
145  static int compare_value(T* const* a, T* const* b) {
146  return Compare<T>(**a, **b);
147  }
148 
149  static const intptr_t kEmptyTag = 1;
150  static const intptr_t kSingletonTag = 0;
151  static const intptr_t kListTag = 2;
152  static const intptr_t kTagMask = 3;
153  static const intptr_t kValueMask = ~kTagMask;
154 
156 
157  T* single_value() const {
160  return reinterpret_cast<T*>(data_);
161  }
162 
163  PointerList* list() const {
164  DCHECK((data_ & kTagMask) == kListTag);
165  return reinterpret_cast<PointerList*>(data_ & kValueMask);
166  }
167 
168  intptr_t data_;
169 
171 };
172 
173 } } // namespace v8::internal
174 
175 #endif // V8_SMALL_POINTER_LIST_H_
void Add(const T &element, AllocationPolicy allocator=AllocationPolicy())
Definition: list-inl.h:17
bool RemoveElement(const T &elm)
Definition: list-inl.h:115
T & at(int i) const
Definition: list.h:69
int CountOccurrences(const T &elm, int start, int end) const
Definition: list-inl.h:184
void Sort(int(*cmp)(const T *x, const T *y))
Definition: list-inl.h:194
Vector< T > AddBlock(T value, int count, AllocationPolicy allocator=AllocationPolicy())
Definition: list-inl.h:77
STATIC_ASSERT(kTagMask+1<=kPointerAlignment)
SmallPointerList(int capacity, Zone *zone)
void Reserve(int capacity, Zone *zone)
int CountOccurrences(T *pointer, int start, int end) const
void Add(T *pointer, Zone *zone)
DISALLOW_COPY_AND_ASSIGN(SmallPointerList)
static const intptr_t kValueMask
static int compare_value(T *const *a, T *const *b)
static const intptr_t kSingletonTag
enable harmony numeric enable harmony object literal extensions Optimize object Array DOM strings and string trace pretenuring decisions of HAllocate instructions Enables optimizations which favor memory size over execution speed maximum source size in bytes considered for a single inlining maximum cumulative number of AST nodes considered for inlining trace the tracking of allocation sites deoptimize every n garbage collections perform array bounds checks elimination analyze liveness of environment slots and zap dead values flushes the cache of optimized code for closures on every GC allow uint32 values on optimize frames if they are used only in safe operations track concurrent recompilation artificial compilation delay in ms do not emit check maps for constant values that have a leaf deoptimize the optimized code if the layout of the maps changes enable context specialization in TurboFan execution budget before interrupt is triggered max percentage of megamorphic generic ICs to allow optimization enable use of SAHF instruction if enable use of VFP3 instructions if available enable use of NEON instructions if enable use of SDIV and UDIV instructions if enable use of MLS instructions if enable loading bit constant by means of movw movt instruction enable unaligned accesses for enable use of d16 d31 registers on ARM this requires VFP3 force all emitted branches to be in long enable alignment of csp to bytes on platforms which prefer the register to always be NULL
#define DCHECK(condition)
Definition: logging.h:205
bool IsAligned(T value, U alignment)
Definition: utils.h:123
const intptr_t kPointerAlignment
Definition: globals.h:230
Debugger support for the V8 JavaScript engine.
Definition: accessors.cc:20
#define T(name, string, precedence)
Definition: token.cc:25