src/hotspot/share/gc/z/zList.hpp
changeset 50525 767cdb97f103
child 50875 2217b2fc29ea
equal deleted inserted replaced
50524:04f4e983c2f7 50525:767cdb97f103
       
     1 /*
       
     2  * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
       
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
       
     4  *
       
     5  * This code is free software; you can redistribute it and/or modify it
       
     6  * under the terms of the GNU General Public License version 2 only, as
       
     7  * published by the Free Software Foundation.
       
     8  *
       
     9  * This code is distributed in the hope that it will be useful, but WITHOUT
       
    10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
       
    11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
       
    12  * version 2 for more details (a copy is included in the LICENSE file that
       
    13  * accompanied this code).
       
    14  *
       
    15  * You should have received a copy of the GNU General Public License version
       
    16  * 2 along with this work; if not, write to the Free Software Foundation,
       
    17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
       
    18  *
       
    19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
       
    20  * or visit www.oracle.com if you need additional information or have any
       
    21  * questions.
       
    22  */
       
    23 
       
    24 #ifndef SHARE_GC_Z_ZLIST_HPP
       
    25 #define SHARE_GC_Z_ZLIST_HPP
       
    26 
       
    27 #include "memory/allocation.hpp"
       
    28 #include "utilities/debug.hpp"
       
    29 
       
    30 template <typename T> class ZList;
       
    31 
       
    32 // Element in a double linked list
       
    33 template <typename T>
       
    34 class ZListNode {
       
    35   friend class ZList<T>;
       
    36 
       
    37 private:
       
    38   ZListNode* _next;
       
    39   ZListNode* _prev;
       
    40 
       
    41   ZListNode(ZListNode* next, ZListNode* prev) :
       
    42       _next(next),
       
    43       _prev(prev) {}
       
    44 
       
    45   void set_unused() {
       
    46     _next = NULL;
       
    47     _prev = NULL;
       
    48   }
       
    49 
       
    50 public:
       
    51   ZListNode() {
       
    52     set_unused();
       
    53   }
       
    54 
       
    55   ~ZListNode() {
       
    56     set_unused();
       
    57   }
       
    58 
       
    59   bool is_unused() const {
       
    60     return _next == NULL && _prev == NULL;
       
    61   }
       
    62 };
       
    63 
       
    64 // Double-linked list
       
    65 template <typename T>
       
    66 class ZList {
       
    67 private:
       
    68   ZListNode<T> _head;
       
    69   size_t       _size;
       
    70 
       
    71   // Passing by value and assignment is not allowed
       
    72   ZList(const ZList<T>& list);
       
    73   ZList<T>& operator=(const ZList<T>& list);
       
    74 
       
    75   void verify() const {
       
    76     assert(_head._next->_prev == &_head, "List corrupt");
       
    77     assert(_head._prev->_next == &_head, "List corrupt");
       
    78   }
       
    79 
       
    80   void insert(ZListNode<T>* before, ZListNode<T>* node) {
       
    81     verify();
       
    82 
       
    83     assert(node->is_unused(), "Already in a list");
       
    84     node->_prev = before;
       
    85     node->_next = before->_next;
       
    86     before->_next = node;
       
    87     node->_next->_prev = node;
       
    88 
       
    89     _size++;
       
    90   }
       
    91 
       
    92   ZListNode<T>* cast_to_inner(T* elem) const {
       
    93     return &elem->_node;
       
    94   }
       
    95 
       
    96   T* cast_to_outer(ZListNode<T>* node) const {
       
    97     return (T*)((uintptr_t)node - offset_of(T, _node));
       
    98   }
       
    99 
       
   100 public:
       
   101   ZList() :
       
   102       _head(&_head, &_head),
       
   103       _size(0) {
       
   104     verify();
       
   105   }
       
   106 
       
   107   size_t size() const {
       
   108     verify();
       
   109     return _size;
       
   110   }
       
   111 
       
   112   bool is_empty() const {
       
   113     return _size == 0;
       
   114   }
       
   115 
       
   116   T* first() const {
       
   117     return is_empty() ? NULL : cast_to_outer(_head._next);
       
   118   }
       
   119 
       
   120   T* last() const {
       
   121     return is_empty() ? NULL : cast_to_outer(_head._prev);
       
   122   }
       
   123 
       
   124   T* next(T* elem) const {
       
   125     verify();
       
   126     ZListNode<T>* next = cast_to_inner(elem)->_next;
       
   127     return (next == &_head) ? NULL : cast_to_outer(next);
       
   128   }
       
   129 
       
   130   T* prev(T* elem) const {
       
   131     verify();
       
   132     ZListNode<T>* prev = cast_to_inner(elem)->_prev;
       
   133     return (prev == &_head) ? NULL : cast_to_outer(prev);
       
   134   }
       
   135 
       
   136   void insert_first(T* elem) {
       
   137     insert(&_head, cast_to_inner(elem));
       
   138   }
       
   139 
       
   140   void insert_last(T* elem) {
       
   141     insert(_head._prev, cast_to_inner(elem));
       
   142   }
       
   143 
       
   144   void insert_before(T* before, T* elem) {
       
   145     insert(cast_to_inner(before)->_prev, cast_to_inner(elem));
       
   146   }
       
   147 
       
   148   void insert_after(T* after, T* elem) {
       
   149     insert(cast_to_inner(after), cast_to_inner(elem));
       
   150   }
       
   151 
       
   152   void remove(T* elem) {
       
   153     verify();
       
   154 
       
   155     ZListNode<T>* const node = cast_to_inner(elem);
       
   156     assert(!node->is_unused(), "Not in a list");
       
   157 
       
   158     ZListNode<T>* const next = node->_next;
       
   159     ZListNode<T>* const prev = node->_prev;
       
   160     assert(next->_prev == node, "List corrupt");
       
   161     assert(prev->_next == node, "List corrupt");
       
   162 
       
   163     prev->_next = next;
       
   164     next->_prev = prev;
       
   165     node->set_unused();
       
   166 
       
   167     _size--;
       
   168   }
       
   169 
       
   170   T* remove_first() {
       
   171     T* elem = first();
       
   172     if (elem != NULL) {
       
   173       remove(elem);
       
   174     }
       
   175 
       
   176     return elem;
       
   177   }
       
   178 
       
   179   T* remove_last() {
       
   180     T* elem = last();
       
   181     if (elem != NULL) {
       
   182       remove(elem);
       
   183     }
       
   184 
       
   185     return elem;
       
   186   }
       
   187 
       
   188   void transfer(ZList<T>* list) {
       
   189     verify();
       
   190 
       
   191     if (!list->is_empty()) {
       
   192       list->_head._next->_prev = _head._prev;
       
   193       list->_head._prev->_next = _head._prev->_next;
       
   194 
       
   195       _head._prev->_next = list->_head._next;
       
   196       _head._prev = list->_head._prev;
       
   197 
       
   198       list->_head._next = &list->_head;
       
   199       list->_head._prev = &list->_head;
       
   200 
       
   201       _size += list->_size;
       
   202       list->_size = 0;
       
   203 
       
   204       list->verify();
       
   205       verify();
       
   206     }
       
   207   }
       
   208 };
       
   209 
       
   210 template <typename T, bool forward>
       
   211 class ZListIteratorImpl : public StackObj {
       
   212 private:
       
   213   ZList<T>* const _list;
       
   214   T*              _next;
       
   215 
       
   216 public:
       
   217   ZListIteratorImpl(ZList<T>* list);
       
   218 
       
   219   bool next(T** elem);
       
   220 };
       
   221 
       
   222 // Iterator types
       
   223 #define ZLIST_FORWARD        true
       
   224 #define ZLIST_REVERSE        false
       
   225 
       
   226 template <typename T>
       
   227 class ZListIterator : public ZListIteratorImpl<T, ZLIST_FORWARD> {
       
   228 public:
       
   229   ZListIterator(ZList<T>* list) :
       
   230       ZListIteratorImpl<T, ZLIST_FORWARD>(list) {}
       
   231 };
       
   232 
       
   233 template <typename T>
       
   234 class ZListReverseIterator : public ZListIteratorImpl<T, ZLIST_REVERSE> {
       
   235 public:
       
   236   ZListReverseIterator(ZList<T>* list) :
       
   237       ZListIteratorImpl<T, ZLIST_REVERSE>(list) {}
       
   238 };
       
   239 
       
   240 #endif // SHARE_GC_Z_ZLIST_HPP