Revision f230a1cf deps/v8/src/unique.h
deps/v8/src/unique.h | ||
---|---|---|
29 | 29 |
#define V8_HYDROGEN_UNIQUE_H_ |
30 | 30 |
|
31 | 31 |
#include "handles.h" |
32 |
#include "objects.h" |
|
32 | 33 |
#include "utils.h" |
33 | 34 |
#include "zone.h" |
34 | 35 |
|
... | ... | |
53 | 54 |
template <typename T> |
54 | 55 |
class Unique V8_FINAL { |
55 | 56 |
public: |
56 |
// TODO(titzer): make private and introduce some builder/owner class.
|
|
57 |
// TODO(titzer): make private and introduce a uniqueness scope.
|
|
57 | 58 |
explicit Unique(Handle<T> handle) { |
58 | 59 |
if (handle.is_null()) { |
59 | 60 |
raw_address_ = NULL; |
60 | 61 |
} else { |
62 |
// This is a best-effort check to prevent comparing Unique<T>'s created |
|
63 |
// in different GC eras; we require heap allocation to be disallowed at |
|
64 |
// creation time. |
|
65 |
// NOTE: we currently consider maps to be non-movable, so no special |
|
66 |
// assurance is required for creating a Unique<Map>. |
|
67 |
// TODO(titzer): other immortable immovable objects are also fine. |
|
68 |
ASSERT(!AllowHeapAllocation::IsAllowed() || handle->IsMap()); |
|
61 | 69 |
raw_address_ = reinterpret_cast<Address>(*handle); |
62 |
ASSERT_NE(raw_address_, NULL); |
|
70 |
ASSERT_NE(raw_address_, NULL); // Non-null should imply non-zero address.
|
|
63 | 71 |
} |
64 | 72 |
handle_ = handle; |
65 | 73 |
} |
66 | 74 |
|
75 |
// TODO(titzer): this is a hack to migrate to Unique<T> incrementally. |
|
76 |
Unique(Address raw_address, Handle<T> handle) |
|
77 |
: raw_address_(raw_address), handle_(handle) { } |
|
78 |
|
|
67 | 79 |
// Constructor for handling automatic up casting. |
68 |
// Ex. Unique<JSFunction> can be passed when Unique<Object> is expected.
|
|
80 |
// Eg. Unique<JSFunction> can be passed when Unique<Object> is expected.
|
|
69 | 81 |
template <class S> Unique(Unique<S> uniq) { |
70 | 82 |
#ifdef DEBUG |
71 | 83 |
T* a = NULL; |
... | ... | |
74 | 86 |
USE(a); |
75 | 87 |
#endif |
76 | 88 |
raw_address_ = uniq.raw_address_; |
77 |
handle_ = uniq.handle_; // Creates a new handle sharing the same location.
|
|
89 |
handle_ = uniq.handle_; |
|
78 | 90 |
} |
79 | 91 |
|
80 | 92 |
template <typename U> |
81 |
bool operator==(const Unique<U>& other) const { |
|
93 |
inline bool operator==(const Unique<U>& other) const { |
|
94 |
ASSERT(IsInitialized() && other.IsInitialized()); |
|
82 | 95 |
return raw_address_ == other.raw_address_; |
83 | 96 |
} |
84 | 97 |
|
85 | 98 |
template <typename U> |
86 |
bool operator!=(const Unique<U>& other) const { |
|
99 |
inline bool operator!=(const Unique<U>& other) const { |
|
100 |
ASSERT(IsInitialized() && other.IsInitialized()); |
|
87 | 101 |
return raw_address_ != other.raw_address_; |
88 | 102 |
} |
89 | 103 |
|
90 |
intptr_t Hashcode() const { |
|
104 |
inline intptr_t Hashcode() const { |
|
105 |
ASSERT(IsInitialized()); |
|
91 | 106 |
return reinterpret_cast<intptr_t>(raw_address_); |
92 | 107 |
} |
93 | 108 |
|
94 |
bool IsNull() { |
|
109 |
inline bool IsNull() const { |
|
110 |
ASSERT(IsInitialized()); |
|
95 | 111 |
return raw_address_ == NULL; |
96 | 112 |
} |
97 | 113 |
|
98 |
// Don't do this unless you have access to the heap! |
|
99 |
// No, seriously! You can compare and hash and set-ify uniques that were |
|
100 |
// all created at the same time; please don't dereference. |
|
101 |
Handle<T> handle() { |
|
114 |
inline bool IsKnownGlobal(void* global) const { |
|
115 |
ASSERT(IsInitialized()); |
|
116 |
return raw_address_ == reinterpret_cast<Address>(global); |
|
117 |
} |
|
118 |
|
|
119 |
inline Handle<T> handle() const { |
|
102 | 120 |
return handle_; |
103 | 121 |
} |
104 | 122 |
|
123 |
template <class S> static Unique<T> cast(Unique<S> that) { |
|
124 |
return Unique<T>(that.raw_address_, Handle<T>::cast(that.handle_)); |
|
125 |
} |
|
126 |
|
|
127 |
inline bool IsInitialized() const { |
|
128 |
return raw_address_ != NULL || handle_.is_null(); |
|
129 |
} |
|
130 |
|
|
131 |
// TODO(titzer): this is a hack to migrate to Unique<T> incrementally. |
|
132 |
static Unique<T> CreateUninitialized(Handle<T> handle) { |
|
133 |
return Unique<T>(reinterpret_cast<Address>(NULL), handle); |
|
134 |
} |
|
135 |
|
|
136 |
static Unique<T> CreateImmovable(Handle<T> handle) { |
|
137 |
return Unique<T>(reinterpret_cast<Address>(*handle), handle); |
|
138 |
} |
|
139 |
|
|
105 | 140 |
friend class UniqueSet<T>; // Uses internal details for speed. |
106 | 141 |
template <class U> |
107 | 142 |
friend class Unique; // For comparing raw_address values. |
... | ... | |
120 | 155 |
|
121 | 156 |
// Add a new element to this unique set. Mutates this set. O(|this|). |
122 | 157 |
void Add(Unique<T> uniq, Zone* zone) { |
158 |
ASSERT(uniq.IsInitialized()); |
|
123 | 159 |
// Keep the set sorted by the {raw_address} of the unique elements. |
124 | 160 |
for (int i = 0; i < size_; i++) { |
125 | 161 |
if (array_[i] == uniq) return; |
... | ... | |
137 | 173 |
array_[size_++] = uniq; |
138 | 174 |
} |
139 | 175 |
|
176 |
// Remove an element from this set. Mutates this set. O(|this|) |
|
177 |
void Remove(Unique<T> uniq) { |
|
178 |
for (int i = 0; i < size_; i++) { |
|
179 |
if (array_[i] == uniq) { |
|
180 |
while (++i < size_) array_[i - 1] = array_[i]; |
|
181 |
size_--; |
|
182 |
return; |
|
183 |
} |
|
184 |
} |
|
185 |
} |
|
186 |
|
|
140 | 187 |
// Compare this set against another set. O(|this|). |
141 |
bool Equals(UniqueSet<T>* that) { |
|
188 |
bool Equals(UniqueSet<T>* that) const {
|
|
142 | 189 |
if (that->size_ != this->size_) return false; |
143 | 190 |
for (int i = 0; i < this->size_; i++) { |
144 | 191 |
if (this->array_[i] != that->array_[i]) return false; |
... | ... | |
146 | 193 |
return true; |
147 | 194 |
} |
148 | 195 |
|
196 |
// Check whether this set contains the given element. O(|this|) |
|
197 |
// TODO(titzer): use binary search for large sets to make this O(log|this|) |
|
198 |
template <typename U> |
|
199 |
bool Contains(Unique<U> elem) const { |
|
200 |
for (int i = 0; i < size_; i++) { |
|
201 |
if (this->array_[i] == elem) return true; |
|
202 |
} |
|
203 |
return false; |
|
204 |
} |
|
205 |
|
|
149 | 206 |
// Check if this set is a subset of the given set. O(|this| + |that|). |
150 |
bool IsSubset(UniqueSet<T>* that) { |
|
207 |
bool IsSubset(UniqueSet<T>* that) const {
|
|
151 | 208 |
if (that->size_ < this->size_) return false; |
152 | 209 |
int j = 0; |
153 | 210 |
for (int i = 0; i < this->size_; i++) { |
... | ... | |
163 | 220 |
|
164 | 221 |
// Returns a new set representing the intersection of this set and the other. |
165 | 222 |
// O(|this| + |that|). |
166 |
UniqueSet<T>* Intersect(UniqueSet<T>* that, Zone* zone) { |
|
223 |
UniqueSet<T>* Intersect(UniqueSet<T>* that, Zone* zone) const {
|
|
167 | 224 |
if (that->size_ == 0 || this->size_ == 0) return new(zone) UniqueSet<T>(); |
168 | 225 |
|
169 | 226 |
UniqueSet<T>* out = new(zone) UniqueSet<T>(); |
... | ... | |
190 | 247 |
|
191 | 248 |
// Returns a new set representing the union of this set and the other. |
192 | 249 |
// O(|this| + |that|). |
193 |
UniqueSet<T>* Union(UniqueSet<T>* that, Zone* zone) { |
|
250 |
UniqueSet<T>* Union(UniqueSet<T>* that, Zone* zone) const {
|
|
194 | 251 |
if (that->size_ == 0) return this->Copy(zone); |
195 | 252 |
if (this->size_ == 0) return that->Copy(zone); |
196 | 253 |
|
... | ... | |
222 | 279 |
} |
223 | 280 |
|
224 | 281 |
// Makes an exact copy of this set. O(|this| + |that|). |
225 |
UniqueSet<T>* Copy(Zone* zone) { |
|
282 |
UniqueSet<T>* Copy(Zone* zone) const {
|
|
226 | 283 |
UniqueSet<T>* copy = new(zone) UniqueSet<T>(); |
227 | 284 |
copy->size_ = this->size_; |
228 | 285 |
copy->capacity_ = this->size_; |
... | ... | |
231 | 288 |
return copy; |
232 | 289 |
} |
233 | 290 |
|
234 |
inline int size() { |
|
291 |
void Clear() { |
|
292 |
size_ = 0; |
|
293 |
} |
|
294 |
|
|
295 |
inline int size() const { |
|
235 | 296 |
return size_; |
236 | 297 |
} |
237 | 298 |
|
299 |
inline Unique<T> at(int index) const { |
|
300 |
ASSERT(index >= 0 && index < size_); |
|
301 |
return array_[index]; |
|
302 |
} |
|
303 |
|
|
238 | 304 |
private: |
239 | 305 |
// These sets should be small, since operations are implemented with simple |
240 | 306 |
// linear algorithms. Enforce a maximum size. |
Also available in: Unified diff