src/hotspot/share/gc/z/zList.inline.hpp
changeset 58708 f74ec3cbfcc0
parent 54834 39ba09047e19
--- a/src/hotspot/share/gc/z/zList.inline.hpp	Mon Oct 21 09:57:26 2019 +0200
+++ b/src/hotspot/share/gc/z/zList.inline.hpp	Mon Oct 21 09:58:07 2019 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -25,14 +25,193 @@
 #define SHARE_GC_Z_ZLIST_INLINE_HPP
 
 #include "gc/z/zList.hpp"
+#include "utilities/debug.hpp"
+
+template <typename T>
+inline ZListNode<T>::ZListNode(ZListNode* next, ZListNode* prev) :
+    _next(next),
+    _prev(prev) {}
+
+template <typename T>
+inline void ZListNode<T>::set_unused() {
+  _next = NULL;
+  _prev = NULL;
+}
+
+template <typename T>
+inline ZListNode<T>::ZListNode() {
+  set_unused();
+}
+
+template <typename T>
+inline ZListNode<T>::~ZListNode() {
+  set_unused();
+}
+
+template <typename T>
+inline bool ZListNode<T>::is_unused() const {
+  return _next == NULL && _prev == NULL;
+}
+
+template <typename T>
+inline void ZList<T>::verify() const {
+  assert(_head._next->_prev == &_head, "List corrupt");
+  assert(_head._prev->_next == &_head, "List corrupt");
+}
+
+template <typename T>
+inline void ZList<T>::insert(ZListNode<T>* before, ZListNode<T>* node) {
+  verify();
+
+  assert(node->is_unused(), "Already in a list");
+  node->_prev = before;
+  node->_next = before->_next;
+  before->_next = node;
+  node->_next->_prev = node;
+
+  _size++;
+}
+
+template <typename T>
+inline ZListNode<T>* ZList<T>::cast_to_inner(T* elem) const {
+  return &elem->_node;
+}
+
+template <typename T>
+inline T* ZList<T>::cast_to_outer(ZListNode<T>* node) const {
+  return (T*)((uintptr_t)node - offset_of(T, _node));
+}
+
+template <typename T>
+inline ZList<T>::ZList() :
+    _head(&_head, &_head),
+    _size(0) {
+  verify();
+}
+
+template <typename T>
+inline size_t ZList<T>::size() const {
+  verify();
+  return _size;
+}
+
+template <typename T>
+inline bool ZList<T>::is_empty() const {
+  return _size == 0;
+}
+
+template <typename T>
+inline T* ZList<T>::first() const {
+  return is_empty() ? NULL : cast_to_outer(_head._next);
+}
+
+template <typename T>
+inline T* ZList<T>::last() const {
+  return is_empty() ? NULL : cast_to_outer(_head._prev);
+}
+
+template <typename T>
+inline T* ZList<T>::next(T* elem) const {
+  verify();
+  ZListNode<T>* next = cast_to_inner(elem)->_next;
+  return (next == &_head) ? NULL : cast_to_outer(next);
+}
+
+template <typename T>
+inline T* ZList<T>::prev(T* elem) const {
+  verify();
+  ZListNode<T>* prev = cast_to_inner(elem)->_prev;
+  return (prev == &_head) ? NULL : cast_to_outer(prev);
+}
+
+template <typename T>
+inline void ZList<T>::insert_first(T* elem) {
+  insert(&_head, cast_to_inner(elem));
+}
+
+template <typename T>
+inline void ZList<T>::insert_last(T* elem) {
+  insert(_head._prev, cast_to_inner(elem));
+}
+
+template <typename T>
+inline void ZList<T>::insert_before(T* before, T* elem) {
+  insert(cast_to_inner(before)->_prev, cast_to_inner(elem));
+}
+
+template <typename T>
+inline void ZList<T>::insert_after(T* after, T* elem) {
+  insert(cast_to_inner(after), cast_to_inner(elem));
+}
+
+template <typename T>
+inline void ZList<T>::remove(T* elem) {
+  verify();
+
+  ZListNode<T>* const node = cast_to_inner(elem);
+  assert(!node->is_unused(), "Not in a list");
+
+  ZListNode<T>* const next = node->_next;
+  ZListNode<T>* const prev = node->_prev;
+  assert(next->_prev == node, "List corrupt");
+  assert(prev->_next == node, "List corrupt");
+
+  prev->_next = next;
+  next->_prev = prev;
+  node->set_unused();
+
+  _size--;
+}
+
+template <typename T>
+inline T* ZList<T>::remove_first() {
+  T* elem = first();
+  if (elem != NULL) {
+    remove(elem);
+  }
+
+  return elem;
+}
+
+template <typename T>
+inline T* ZList<T>::remove_last() {
+  T* elem = last();
+  if (elem != NULL) {
+    remove(elem);
+  }
+
+  return elem;
+}
+
+template <typename T>
+inline void ZList<T>::transfer(ZList<T>* list) {
+  verify();
+
+  if (!list->is_empty()) {
+    list->_head._next->_prev = _head._prev;
+    list->_head._prev->_next = _head._prev->_next;
+
+    _head._prev->_next = list->_head._next;
+    _head._prev = list->_head._prev;
+
+    list->_head._next = &list->_head;
+    list->_head._prev = &list->_head;
+
+    _size += list->_size;
+    list->_size = 0;
+
+    list->verify();
+    verify();
+  }
+}
 
 template <typename T, bool forward>
-ZListIteratorImpl<T, forward>::ZListIteratorImpl(const ZList<T>* list) :
+inline ZListIteratorImpl<T, forward>::ZListIteratorImpl(const ZList<T>* list) :
     _list(list),
     _next(forward ? list->first() : list->last()) {}
 
 template <typename T, bool forward>
-bool ZListIteratorImpl<T, forward>::next(T** elem) {
+inline bool ZListIteratorImpl<T, forward>::next(T** elem) {
   if (_next != NULL) {
     *elem = _next;
     _next = forward ? _list->next(_next) : _list->prev(_next);
@@ -43,4 +222,12 @@
   return false;
 }
 
+template <typename T>
+inline ZListIterator<T>::ZListIterator(const ZList<T>* list) :
+    ZListIteratorImpl<T, ZLIST_FORWARD>(list) {}
+
+template <typename T>
+inline ZListReverseIterator<T>::ZListReverseIterator(const ZList<T>* list) :
+    ZListIteratorImpl<T, ZLIST_REVERSE>(list) {}
+
 #endif // SHARE_GC_Z_ZLIST_INLINE_HPP