js/src/jit/InlineList.h

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

michael@0 1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
michael@0 2 * vim: set ts=8 sts=4 et sw=4 tw=99:
michael@0 3 * This Source Code Form is subject to the terms of the Mozilla Public
michael@0 4 * License, v. 2.0. If a copy of the MPL was not distributed with this
michael@0 5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 6
michael@0 7 #ifndef jit_InlineList_h
michael@0 8 #define jit_InlineList_h
michael@0 9
michael@0 10 #include "jsutil.h"
michael@0 11
michael@0 12 namespace js {
michael@0 13
michael@0 14 template <typename T> class InlineForwardList;
michael@0 15 template <typename T> class InlineForwardListIterator;
michael@0 16
michael@0 17 template <typename T>
michael@0 18 class InlineForwardListNode
michael@0 19 {
michael@0 20 public:
michael@0 21 InlineForwardListNode() : next(nullptr)
michael@0 22 { }
michael@0 23 InlineForwardListNode(InlineForwardListNode<T> *n) : next(n)
michael@0 24 { }
michael@0 25
michael@0 26 protected:
michael@0 27 friend class InlineForwardList<T>;
michael@0 28 friend class InlineForwardListIterator<T>;
michael@0 29
michael@0 30 InlineForwardListNode<T> *next;
michael@0 31 };
michael@0 32
michael@0 33 template <typename T>
michael@0 34 class InlineForwardList : protected InlineForwardListNode<T>
michael@0 35 {
michael@0 36 friend class InlineForwardListIterator<T>;
michael@0 37
michael@0 38 typedef InlineForwardListNode<T> Node;
michael@0 39
michael@0 40 Node *tail_;
michael@0 41 #ifdef DEBUG
michael@0 42 int modifyCount_;
michael@0 43 #endif
michael@0 44
michael@0 45 InlineForwardList<T> *thisFromConstructor() {
michael@0 46 return this;
michael@0 47 }
michael@0 48
michael@0 49 public:
michael@0 50 InlineForwardList()
michael@0 51 : tail_(thisFromConstructor())
michael@0 52 {
michael@0 53 #ifdef DEBUG
michael@0 54 modifyCount_ = 0;
michael@0 55 #endif
michael@0 56 }
michael@0 57
michael@0 58 public:
michael@0 59 typedef InlineForwardListIterator<T> iterator;
michael@0 60
michael@0 61 public:
michael@0 62 iterator begin() const {
michael@0 63 return iterator(this);
michael@0 64 }
michael@0 65 iterator end() const {
michael@0 66 return iterator(nullptr);
michael@0 67 }
michael@0 68 iterator removeAt(iterator &where) {
michael@0 69 iterator iter(where);
michael@0 70 iter++;
michael@0 71 iter.prev = where.prev;
michael@0 72 #ifdef DEBUG
michael@0 73 iter.modifyCount_++;
michael@0 74 #endif
michael@0 75
michael@0 76 // Once the element 'where' points at has been removed, it is no longer
michael@0 77 // safe to do any operations that would touch 'iter', as the element
michael@0 78 // may be added to another list, etc. This nullptr ensures that any
michael@0 79 // improper uses of this function will fail quickly and loudly.
michael@0 80 removeAfter(where.prev, where.iter);
michael@0 81 where.prev = where.iter = nullptr;
michael@0 82
michael@0 83 return iter;
michael@0 84 }
michael@0 85 void pushFront(Node *t) {
michael@0 86 insertAfter(this, t);
michael@0 87 }
michael@0 88 void pushBack(Node *t) {
michael@0 89 #ifdef DEBUG
michael@0 90 modifyCount_++;
michael@0 91 #endif
michael@0 92 tail_->next = t;
michael@0 93 t->next = nullptr;
michael@0 94 tail_ = t;
michael@0 95 }
michael@0 96 T *popFront() {
michael@0 97 JS_ASSERT(!empty());
michael@0 98 T* result = static_cast<T *>(this->next);
michael@0 99 removeAfter(this, result);
michael@0 100 return result;
michael@0 101 }
michael@0 102 T *back() {
michael@0 103 JS_ASSERT(!empty());
michael@0 104 return static_cast<T *>(tail_);
michael@0 105 }
michael@0 106 void insertAfter(Node *at, Node *item) {
michael@0 107 #ifdef DEBUG
michael@0 108 modifyCount_++;
michael@0 109 #endif
michael@0 110 if (at == tail_)
michael@0 111 tail_ = item;
michael@0 112 item->next = at->next;
michael@0 113 at->next = item;
michael@0 114 }
michael@0 115 void removeAfter(Node *at, Node *item) {
michael@0 116 #ifdef DEBUG
michael@0 117 modifyCount_++;
michael@0 118 #endif
michael@0 119 if (item == tail_)
michael@0 120 tail_ = at;
michael@0 121 JS_ASSERT(at->next == item);
michael@0 122 at->next = item->next;
michael@0 123 }
michael@0 124 void splitAfter(Node *at, InlineForwardList<T> *to) {
michael@0 125 JS_ASSERT(to->empty());
michael@0 126 if (!at)
michael@0 127 at = this;
michael@0 128 if (at == tail_)
michael@0 129 return;
michael@0 130 #ifdef DEBUG
michael@0 131 modifyCount_++;
michael@0 132 #endif
michael@0 133 to->next = at->next;
michael@0 134 to->tail_ = tail_;
michael@0 135 tail_ = at;
michael@0 136 at->next = nullptr;
michael@0 137 }
michael@0 138 bool empty() const {
michael@0 139 return tail_ == this;
michael@0 140 }
michael@0 141 void clear() {
michael@0 142 this->next = nullptr;
michael@0 143 tail_ = this;
michael@0 144 #ifdef DEBUG
michael@0 145 modifyCount_ = 0;
michael@0 146 #endif
michael@0 147 }
michael@0 148 };
michael@0 149
michael@0 150 template <typename T>
michael@0 151 class InlineForwardListIterator
michael@0 152 {
michael@0 153 private:
michael@0 154 friend class InlineForwardList<T>;
michael@0 155
michael@0 156 typedef InlineForwardListNode<T> Node;
michael@0 157
michael@0 158 InlineForwardListIterator<T>(const InlineForwardList<T> *owner)
michael@0 159 : prev(const_cast<Node *>(static_cast<const Node *>(owner))),
michael@0 160 iter(owner ? owner->next : nullptr)
michael@0 161 #ifdef DEBUG
michael@0 162 , owner_(owner),
michael@0 163 modifyCount_(owner ? owner->modifyCount_ : 0)
michael@0 164 #endif
michael@0 165 { }
michael@0 166
michael@0 167 public:
michael@0 168 InlineForwardListIterator<T> & operator ++() {
michael@0 169 JS_ASSERT(modifyCount_ == owner_->modifyCount_);
michael@0 170 prev = iter;
michael@0 171 iter = iter->next;
michael@0 172 return *this;
michael@0 173 }
michael@0 174 InlineForwardListIterator<T> operator ++(int) {
michael@0 175 JS_ASSERT(modifyCount_ == owner_->modifyCount_);
michael@0 176 InlineForwardListIterator<T> old(*this);
michael@0 177 prev = iter;
michael@0 178 iter = iter->next;
michael@0 179 return old;
michael@0 180 }
michael@0 181 T * operator *() const {
michael@0 182 JS_ASSERT(modifyCount_ == owner_->modifyCount_);
michael@0 183 return static_cast<T *>(iter);
michael@0 184 }
michael@0 185 T * operator ->() const {
michael@0 186 JS_ASSERT(modifyCount_ == owner_->modifyCount_);
michael@0 187 return static_cast<T *>(iter);
michael@0 188 }
michael@0 189 bool operator !=(const InlineForwardListIterator<T> &where) const {
michael@0 190 return iter != where.iter;
michael@0 191 }
michael@0 192 bool operator ==(const InlineForwardListIterator<T> &where) const {
michael@0 193 return iter == where.iter;
michael@0 194 }
michael@0 195
michael@0 196 private:
michael@0 197 Node *prev;
michael@0 198 Node *iter;
michael@0 199
michael@0 200 #ifdef DEBUG
michael@0 201 const InlineForwardList<T> *owner_;
michael@0 202 int modifyCount_;
michael@0 203 #endif
michael@0 204 };
michael@0 205
michael@0 206 template <typename T> class InlineList;
michael@0 207 template <typename T> class InlineListIterator;
michael@0 208 template <typename T> class InlineListReverseIterator;
michael@0 209
michael@0 210 template <typename T>
michael@0 211 class InlineListNode : public InlineForwardListNode<T>
michael@0 212 {
michael@0 213 public:
michael@0 214 InlineListNode() : InlineForwardListNode<T>(nullptr), prev(nullptr)
michael@0 215 { }
michael@0 216 InlineListNode(InlineListNode<T> *n, InlineListNode<T> *p)
michael@0 217 : InlineForwardListNode<T>(n),
michael@0 218 prev(p)
michael@0 219 { }
michael@0 220
michael@0 221 protected:
michael@0 222 friend class InlineList<T>;
michael@0 223 friend class InlineListIterator<T>;
michael@0 224 friend class InlineListReverseIterator<T>;
michael@0 225
michael@0 226 InlineListNode<T> *prev;
michael@0 227 };
michael@0 228
michael@0 229 template <typename T>
michael@0 230 class InlineList : protected InlineListNode<T>
michael@0 231 {
michael@0 232 typedef InlineListNode<T> Node;
michael@0 233
michael@0 234 public:
michael@0 235 InlineList() : InlineListNode<T>(MOZ_THIS_IN_INITIALIZER_LIST(), MOZ_THIS_IN_INITIALIZER_LIST())
michael@0 236 { }
michael@0 237
michael@0 238 public:
michael@0 239 typedef InlineListIterator<T> iterator;
michael@0 240 typedef InlineListReverseIterator<T> reverse_iterator;
michael@0 241
michael@0 242 public:
michael@0 243 iterator begin() const {
michael@0 244 return iterator(static_cast<Node *>(this->next));
michael@0 245 }
michael@0 246 iterator begin(Node *t) const {
michael@0 247 return iterator(t);
michael@0 248 }
michael@0 249 iterator end() const {
michael@0 250 return iterator(this);
michael@0 251 }
michael@0 252 reverse_iterator rbegin() const {
michael@0 253 return reverse_iterator(this->prev);
michael@0 254 }
michael@0 255 reverse_iterator rbegin(Node *t) const {
michael@0 256 return reverse_iterator(t);
michael@0 257 }
michael@0 258 reverse_iterator rend() const {
michael@0 259 return reverse_iterator(this);
michael@0 260 }
michael@0 261 template <typename itertype>
michael@0 262 itertype removeAt(itertype &where) {
michael@0 263 itertype iter(where);
michael@0 264 iter++;
michael@0 265
michael@0 266 // Once the element 'where' points at has been removed, it is no longer
michael@0 267 // safe to do any operations that would touch 'iter', as the element
michael@0 268 // may be added to another list, etc. This nullptr ensures that any
michael@0 269 // improper uses of this function will fail quickly and loudly.
michael@0 270 remove(where.iter);
michael@0 271 where.iter = nullptr;
michael@0 272
michael@0 273 return iter;
michael@0 274 }
michael@0 275 void pushFront(Node *t) {
michael@0 276 insertAfter(this, t);
michael@0 277 }
michael@0 278 void pushBack(Node *t) {
michael@0 279 insertBefore(this, t);
michael@0 280 }
michael@0 281 T *popFront() {
michael@0 282 JS_ASSERT(!empty());
michael@0 283 T *t = static_cast<T *>(this->next);
michael@0 284 remove(t);
michael@0 285 return t;
michael@0 286 }
michael@0 287 T *popBack() {
michael@0 288 JS_ASSERT(!empty());
michael@0 289 T *t = static_cast<T *>(this->prev);
michael@0 290 remove(t);
michael@0 291 return t;
michael@0 292 }
michael@0 293 T *peekBack() const {
michael@0 294 iterator iter = end();
michael@0 295 iter--;
michael@0 296 return *iter;
michael@0 297 }
michael@0 298 void insertBefore(Node *at, Node *item) {
michael@0 299 item->next = at;
michael@0 300 item->prev = at->prev;
michael@0 301 at->prev->next = item;
michael@0 302 at->prev = item;
michael@0 303 }
michael@0 304 void insertAfter(Node *at, Node *item) {
michael@0 305 item->next = at->next;
michael@0 306 item->prev = at;
michael@0 307 static_cast<Node *>(at->next)->prev = item;
michael@0 308 at->next = item;
michael@0 309 }
michael@0 310 void remove(Node *t) {
michael@0 311 t->prev->next = t->next;
michael@0 312 static_cast<Node *>(t->next)->prev = t->prev;
michael@0 313 t->next = t->prev = nullptr;
michael@0 314 }
michael@0 315 void clear() {
michael@0 316 this->next = this->prev = this;
michael@0 317 }
michael@0 318 bool empty() const {
michael@0 319 return begin() == end();
michael@0 320 }
michael@0 321 };
michael@0 322
michael@0 323 template <typename T>
michael@0 324 class InlineListIterator
michael@0 325 {
michael@0 326 private:
michael@0 327 friend class InlineList<T>;
michael@0 328
michael@0 329 typedef InlineListNode<T> Node;
michael@0 330
michael@0 331 InlineListIterator(const Node *iter)
michael@0 332 : iter(const_cast<Node *>(iter))
michael@0 333 { }
michael@0 334
michael@0 335 public:
michael@0 336 InlineListIterator<T> & operator ++() {
michael@0 337 iter = static_cast<Node *>(iter->next);
michael@0 338 return *this;
michael@0 339 }
michael@0 340 InlineListIterator<T> operator ++(int) {
michael@0 341 InlineListIterator<T> old(*this);
michael@0 342 iter = static_cast<Node *>(iter->next);
michael@0 343 return old;
michael@0 344 }
michael@0 345 InlineListIterator<T> operator --(int) {
michael@0 346 InlineListIterator<T> old(*this);
michael@0 347 iter = iter->prev;
michael@0 348 return old;
michael@0 349 }
michael@0 350 T * operator *() const {
michael@0 351 return static_cast<T *>(iter);
michael@0 352 }
michael@0 353 T * operator ->() const {
michael@0 354 return static_cast<T *>(iter);
michael@0 355 }
michael@0 356 bool operator !=(const InlineListIterator<T> &where) const {
michael@0 357 return iter != where.iter;
michael@0 358 }
michael@0 359 bool operator ==(const InlineListIterator<T> &where) const {
michael@0 360 return iter == where.iter;
michael@0 361 }
michael@0 362
michael@0 363 private:
michael@0 364 Node *iter;
michael@0 365 };
michael@0 366
michael@0 367 template <typename T>
michael@0 368 class InlineListReverseIterator
michael@0 369 {
michael@0 370 private:
michael@0 371 friend class InlineList<T>;
michael@0 372
michael@0 373 typedef InlineListNode<T> Node;
michael@0 374
michael@0 375 InlineListReverseIterator(const Node *iter)
michael@0 376 : iter(const_cast<Node *>(iter))
michael@0 377 { }
michael@0 378
michael@0 379 public:
michael@0 380 InlineListReverseIterator<T> & operator ++() {
michael@0 381 iter = iter->prev;
michael@0 382 return *this;
michael@0 383 }
michael@0 384 InlineListReverseIterator<T> operator ++(int) {
michael@0 385 InlineListReverseIterator<T> old(*this);
michael@0 386 iter = iter->prev;
michael@0 387 return old;
michael@0 388 }
michael@0 389 T * operator *() {
michael@0 390 return static_cast<T *>(iter);
michael@0 391 }
michael@0 392 T * operator ->() {
michael@0 393 return static_cast<T *>(iter);
michael@0 394 }
michael@0 395 bool operator !=(const InlineListReverseIterator<T> &where) const {
michael@0 396 return iter != where.iter;
michael@0 397 }
michael@0 398 bool operator ==(const InlineListReverseIterator<T> &where) const {
michael@0 399 return iter == where.iter;
michael@0 400 }
michael@0 401
michael@0 402 private:
michael@0 403 Node *iter;
michael@0 404 };
michael@0 405
michael@0 406 /* This list type is more or less exactly an InlineForwardList without a sentinel
michael@0 407 * node. It is useful in cases where you are doing algorithms that deal with many
michael@0 408 * merging singleton lists, rather than often empty ones.
michael@0 409 */
michael@0 410 template <typename T> class InlineConcatListIterator;
michael@0 411 template <typename T>
michael@0 412 class InlineConcatList
michael@0 413 {
michael@0 414 private:
michael@0 415 typedef InlineConcatList<T> Node;
michael@0 416
michael@0 417 InlineConcatList<T> *thisFromConstructor() {
michael@0 418 return this;
michael@0 419 }
michael@0 420
michael@0 421 public:
michael@0 422 InlineConcatList() : next(nullptr), tail(thisFromConstructor())
michael@0 423 { }
michael@0 424
michael@0 425 typedef InlineConcatListIterator<T> iterator;
michael@0 426
michael@0 427 iterator begin() const {
michael@0 428 return iterator(this);
michael@0 429 }
michael@0 430
michael@0 431 iterator end() const {
michael@0 432 return iterator(nullptr);
michael@0 433 }
michael@0 434
michael@0 435 void append(InlineConcatList<T> *adding)
michael@0 436 {
michael@0 437 JS_ASSERT(tail);
michael@0 438 JS_ASSERT(!tail->next);
michael@0 439 JS_ASSERT(adding->tail);
michael@0 440 JS_ASSERT(!adding->tail->next);
michael@0 441
michael@0 442 tail->next = adding;
michael@0 443 tail = adding->tail;
michael@0 444 adding->tail = nullptr;
michael@0 445 }
michael@0 446
michael@0 447 protected:
michael@0 448 friend class InlineConcatListIterator<T>;
michael@0 449 Node *next;
michael@0 450 Node *tail;
michael@0 451 };
michael@0 452
michael@0 453 template <typename T>
michael@0 454 class InlineConcatListIterator
michael@0 455 {
michael@0 456 private:
michael@0 457 friend class InlineConcatList<T>;
michael@0 458
michael@0 459 typedef InlineConcatList<T> Node;
michael@0 460
michael@0 461 InlineConcatListIterator(const Node *iter)
michael@0 462 : iter(const_cast<Node *>(iter))
michael@0 463 { }
michael@0 464
michael@0 465 public:
michael@0 466 InlineConcatListIterator<T> & operator ++() {
michael@0 467 iter = iter->next;
michael@0 468 return *iter;
michael@0 469 }
michael@0 470 InlineConcatListIterator<T> operator ++(int) {
michael@0 471 InlineConcatListIterator<T> old(*this);
michael@0 472 iter = static_cast<Node *>(iter->next);
michael@0 473 return old;
michael@0 474 }
michael@0 475 T * operator *() const {
michael@0 476 return static_cast<T *>(iter);
michael@0 477 }
michael@0 478 T * operator ->() const {
michael@0 479 return static_cast<T *>(iter);
michael@0 480 }
michael@0 481 bool operator !=(const InlineConcatListIterator<T> &where) const {
michael@0 482 return iter != where.iter;
michael@0 483 }
michael@0 484 bool operator ==(const InlineConcatListIterator<T> &where) const {
michael@0 485 return iter == where.iter;
michael@0 486 }
michael@0 487
michael@0 488 private:
michael@0 489 Node *iter;
michael@0 490 };
michael@0 491
michael@0 492 } // namespace js
michael@0 493
michael@0 494 #endif /* jit_InlineList_h */

mercurial