1 /* 2 * Copyright (c) 2016, 2018, 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 25 #ifndef SHARE_VM_JFR_UTILITIES_JFRLISTITERATOR_HPP 26 #define SHARE_VM_JFR_UTILITIES_JFRLISTITERATOR_HPP 27 28 #include "memory/allocation.hpp" 29 30 enum jfr_iter_direction { 31 forward = 1, 32 backward 33 }; 34 35 template <typename Node> 36 class StopOnNullCondition : public AllStatic { 37 public: 38 static bool has_next(const Node* node) { 39 return node != NULL; 40 } 41 }; 42 43 template <typename List, template <typename> class ContinuationPredicate> 44 class Navigator { 45 public: 46 typedef typename List::Node Node; 47 typedef jfr_iter_direction Direction; 48 Navigator(List& list, Direction direction) : 49 _list(list), _node(direction == forward ? list.head() : list.tail()), _direction(direction) {} 50 bool has_next() const { 51 return ContinuationPredicate<Node>::has_next(_node); 52 } 53 54 bool direction_forward() const { 55 return _direction == forward; 56 } 57 58 Node* next() const { 59 assert(_node != NULL, "invariant"); 60 Node* temp = _node; 61 _node = direction_forward() ? (Node*)_node->next() : (Node*)_node->prev(); 62 return temp; 63 } 64 65 void set_direction(Direction direction) { 66 _direction = direction; 67 } 68 69 void reset(Direction direction) { 70 set_direction(direction); 71 _node = direction_forward() ? _list.head() : _list.tail(); 72 } 73 74 private: 75 List& _list; 76 mutable Node* _node; 77 Direction _direction; 78 }; 79 80 template <typename List> 81 class NavigatorStopOnNull : public Navigator<List, StopOnNullCondition> { 82 public: 83 NavigatorStopOnNull(List& list, jfr_iter_direction direction = forward) : Navigator<List, StopOnNullCondition>(list, direction) {} 84 }; 85 86 template<typename List, template <typename> class Navigator, typename AP = StackObj> 87 class IteratorHost : public AP { 88 private: 89 Navigator<List> _navigator; 90 91 public: 92 typedef typename List::Node Node; 93 typedef jfr_iter_direction Direction; 94 IteratorHost(List& list, Direction direction = forward) : AP(), _navigator(list, direction) {} 95 void reset(Direction direction = forward) { _navigator.reset(direction); } 96 bool has_next() const { return _navigator.has_next(); } 97 Node* next() const { return _navigator.next(); } 98 void set_direction(Direction direction) { _navigator.set_direction(direction); } 99 }; 100 101 template<typename List, typename AP = StackObj> 102 class StopOnNullIterator : public IteratorHost<List, NavigatorStopOnNull, AP> { 103 public: 104 StopOnNullIterator(List& list, jfr_iter_direction direction = forward) : IteratorHost<List, NavigatorStopOnNull, AP>(list, direction) {} 105 }; 106 107 #endif // SHARE_VM_JFR_UTILITIES_JFRLISTITERATOR_HPP