diff -r 000000000000 -r 6474c204b198 js/src/jit/InlineList.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/js/src/jit/InlineList.h Wed Dec 31 06:09:35 2014 +0100 @@ -0,0 +1,494 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * vim: set ts=8 sts=4 et sw=4 tw=99: + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef jit_InlineList_h +#define jit_InlineList_h + +#include "jsutil.h" + +namespace js { + +template class InlineForwardList; +template class InlineForwardListIterator; + +template +class InlineForwardListNode +{ + public: + InlineForwardListNode() : next(nullptr) + { } + InlineForwardListNode(InlineForwardListNode *n) : next(n) + { } + + protected: + friend class InlineForwardList; + friend class InlineForwardListIterator; + + InlineForwardListNode *next; +}; + +template +class InlineForwardList : protected InlineForwardListNode +{ + friend class InlineForwardListIterator; + + typedef InlineForwardListNode Node; + + Node *tail_; +#ifdef DEBUG + int modifyCount_; +#endif + + InlineForwardList *thisFromConstructor() { + return this; + } + + public: + InlineForwardList() + : tail_(thisFromConstructor()) + { +#ifdef DEBUG + modifyCount_ = 0; +#endif + } + + public: + typedef InlineForwardListIterator iterator; + + public: + iterator begin() const { + return iterator(this); + } + iterator end() const { + return iterator(nullptr); + } + iterator removeAt(iterator &where) { + iterator iter(where); + iter++; + iter.prev = where.prev; +#ifdef DEBUG + iter.modifyCount_++; +#endif + + // Once the element 'where' points at has been removed, it is no longer + // safe to do any operations that would touch 'iter', as the element + // may be added to another list, etc. This nullptr ensures that any + // improper uses of this function will fail quickly and loudly. + removeAfter(where.prev, where.iter); + where.prev = where.iter = nullptr; + + return iter; + } + void pushFront(Node *t) { + insertAfter(this, t); + } + void pushBack(Node *t) { +#ifdef DEBUG + modifyCount_++; +#endif + tail_->next = t; + t->next = nullptr; + tail_ = t; + } + T *popFront() { + JS_ASSERT(!empty()); + T* result = static_cast(this->next); + removeAfter(this, result); + return result; + } + T *back() { + JS_ASSERT(!empty()); + return static_cast(tail_); + } + void insertAfter(Node *at, Node *item) { +#ifdef DEBUG + modifyCount_++; +#endif + if (at == tail_) + tail_ = item; + item->next = at->next; + at->next = item; + } + void removeAfter(Node *at, Node *item) { +#ifdef DEBUG + modifyCount_++; +#endif + if (item == tail_) + tail_ = at; + JS_ASSERT(at->next == item); + at->next = item->next; + } + void splitAfter(Node *at, InlineForwardList *to) { + JS_ASSERT(to->empty()); + if (!at) + at = this; + if (at == tail_) + return; +#ifdef DEBUG + modifyCount_++; +#endif + to->next = at->next; + to->tail_ = tail_; + tail_ = at; + at->next = nullptr; + } + bool empty() const { + return tail_ == this; + } + void clear() { + this->next = nullptr; + tail_ = this; +#ifdef DEBUG + modifyCount_ = 0; +#endif + } +}; + +template +class InlineForwardListIterator +{ +private: + friend class InlineForwardList; + + typedef InlineForwardListNode Node; + + InlineForwardListIterator(const InlineForwardList *owner) + : prev(const_cast(static_cast(owner))), + iter(owner ? owner->next : nullptr) +#ifdef DEBUG + , owner_(owner), + modifyCount_(owner ? owner->modifyCount_ : 0) +#endif + { } + +public: + InlineForwardListIterator & operator ++() { + JS_ASSERT(modifyCount_ == owner_->modifyCount_); + prev = iter; + iter = iter->next; + return *this; + } + InlineForwardListIterator operator ++(int) { + JS_ASSERT(modifyCount_ == owner_->modifyCount_); + InlineForwardListIterator old(*this); + prev = iter; + iter = iter->next; + return old; + } + T * operator *() const { + JS_ASSERT(modifyCount_ == owner_->modifyCount_); + return static_cast(iter); + } + T * operator ->() const { + JS_ASSERT(modifyCount_ == owner_->modifyCount_); + return static_cast(iter); + } + bool operator !=(const InlineForwardListIterator &where) const { + return iter != where.iter; + } + bool operator ==(const InlineForwardListIterator &where) const { + return iter == where.iter; + } + +private: + Node *prev; + Node *iter; + +#ifdef DEBUG + const InlineForwardList *owner_; + int modifyCount_; +#endif +}; + +template class InlineList; +template class InlineListIterator; +template class InlineListReverseIterator; + +template +class InlineListNode : public InlineForwardListNode +{ + public: + InlineListNode() : InlineForwardListNode(nullptr), prev(nullptr) + { } + InlineListNode(InlineListNode *n, InlineListNode *p) + : InlineForwardListNode(n), + prev(p) + { } + + protected: + friend class InlineList; + friend class InlineListIterator; + friend class InlineListReverseIterator; + + InlineListNode *prev; +}; + +template +class InlineList : protected InlineListNode +{ + typedef InlineListNode Node; + + public: + InlineList() : InlineListNode(MOZ_THIS_IN_INITIALIZER_LIST(), MOZ_THIS_IN_INITIALIZER_LIST()) + { } + + public: + typedef InlineListIterator iterator; + typedef InlineListReverseIterator reverse_iterator; + + public: + iterator begin() const { + return iterator(static_cast(this->next)); + } + iterator begin(Node *t) const { + return iterator(t); + } + iterator end() const { + return iterator(this); + } + reverse_iterator rbegin() const { + return reverse_iterator(this->prev); + } + reverse_iterator rbegin(Node *t) const { + return reverse_iterator(t); + } + reverse_iterator rend() const { + return reverse_iterator(this); + } + template + itertype removeAt(itertype &where) { + itertype iter(where); + iter++; + + // Once the element 'where' points at has been removed, it is no longer + // safe to do any operations that would touch 'iter', as the element + // may be added to another list, etc. This nullptr ensures that any + // improper uses of this function will fail quickly and loudly. + remove(where.iter); + where.iter = nullptr; + + return iter; + } + void pushFront(Node *t) { + insertAfter(this, t); + } + void pushBack(Node *t) { + insertBefore(this, t); + } + T *popFront() { + JS_ASSERT(!empty()); + T *t = static_cast(this->next); + remove(t); + return t; + } + T *popBack() { + JS_ASSERT(!empty()); + T *t = static_cast(this->prev); + remove(t); + return t; + } + T *peekBack() const { + iterator iter = end(); + iter--; + return *iter; + } + void insertBefore(Node *at, Node *item) { + item->next = at; + item->prev = at->prev; + at->prev->next = item; + at->prev = item; + } + void insertAfter(Node *at, Node *item) { + item->next = at->next; + item->prev = at; + static_cast(at->next)->prev = item; + at->next = item; + } + void remove(Node *t) { + t->prev->next = t->next; + static_cast(t->next)->prev = t->prev; + t->next = t->prev = nullptr; + } + void clear() { + this->next = this->prev = this; + } + bool empty() const { + return begin() == end(); + } +}; + +template +class InlineListIterator +{ + private: + friend class InlineList; + + typedef InlineListNode Node; + + InlineListIterator(const Node *iter) + : iter(const_cast(iter)) + { } + + public: + InlineListIterator & operator ++() { + iter = static_cast(iter->next); + return *this; + } + InlineListIterator operator ++(int) { + InlineListIterator old(*this); + iter = static_cast(iter->next); + return old; + } + InlineListIterator operator --(int) { + InlineListIterator old(*this); + iter = iter->prev; + return old; + } + T * operator *() const { + return static_cast(iter); + } + T * operator ->() const { + return static_cast(iter); + } + bool operator !=(const InlineListIterator &where) const { + return iter != where.iter; + } + bool operator ==(const InlineListIterator &where) const { + return iter == where.iter; + } + + private: + Node *iter; +}; + +template +class InlineListReverseIterator +{ + private: + friend class InlineList; + + typedef InlineListNode Node; + + InlineListReverseIterator(const Node *iter) + : iter(const_cast(iter)) + { } + + public: + InlineListReverseIterator & operator ++() { + iter = iter->prev; + return *this; + } + InlineListReverseIterator operator ++(int) { + InlineListReverseIterator old(*this); + iter = iter->prev; + return old; + } + T * operator *() { + return static_cast(iter); + } + T * operator ->() { + return static_cast(iter); + } + bool operator !=(const InlineListReverseIterator &where) const { + return iter != where.iter; + } + bool operator ==(const InlineListReverseIterator &where) const { + return iter == where.iter; + } + + private: + Node *iter; +}; + +/* This list type is more or less exactly an InlineForwardList without a sentinel + * node. It is useful in cases where you are doing algorithms that deal with many + * merging singleton lists, rather than often empty ones. + */ +template class InlineConcatListIterator; +template +class InlineConcatList +{ + private: + typedef InlineConcatList Node; + + InlineConcatList *thisFromConstructor() { + return this; + } + + public: + InlineConcatList() : next(nullptr), tail(thisFromConstructor()) + { } + + typedef InlineConcatListIterator iterator; + + iterator begin() const { + return iterator(this); + } + + iterator end() const { + return iterator(nullptr); + } + + void append(InlineConcatList *adding) + { + JS_ASSERT(tail); + JS_ASSERT(!tail->next); + JS_ASSERT(adding->tail); + JS_ASSERT(!adding->tail->next); + + tail->next = adding; + tail = adding->tail; + adding->tail = nullptr; + } + + protected: + friend class InlineConcatListIterator; + Node *next; + Node *tail; +}; + +template +class InlineConcatListIterator +{ + private: + friend class InlineConcatList; + + typedef InlineConcatList Node; + + InlineConcatListIterator(const Node *iter) + : iter(const_cast(iter)) + { } + + public: + InlineConcatListIterator & operator ++() { + iter = iter->next; + return *iter; + } + InlineConcatListIterator operator ++(int) { + InlineConcatListIterator old(*this); + iter = static_cast(iter->next); + return old; + } + T * operator *() const { + return static_cast(iter); + } + T * operator ->() const { + return static_cast(iter); + } + bool operator !=(const InlineConcatListIterator &where) const { + return iter != where.iter; + } + bool operator ==(const InlineConcatListIterator &where) const { + return iter == where.iter; + } + + private: + Node *iter; +}; + +} // namespace js + +#endif /* jit_InlineList_h */