Revision f230a1cf deps/v8/src/unique.h

View differences:

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