js/src/jit/InlineList.h

Sat, 03 Jan 2015 20:18:00 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Sat, 03 Jan 2015 20:18:00 +0100
branch
TOR_BUG_3246
changeset 7
129ffea94266
permissions
-rw-r--r--

Conditionally enable double key logic according to:
private browsing mode or privacy.thirdparty.isolate preference and
implement in GetCookieStringCommon and FindCookie where it counts...
With some reservations of how to convince FindCookie users to test
condition and pass a nullptr when disabling double key logic.

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

mercurial