1 /* 2 * Copyright (c) 2019, 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_GC_SHARED_OOPSTORAGESET_HPP 26 #define SHARE_GC_SHARED_OOPSTORAGESET_HPP 27 28 #include "memory/allocation.hpp" 29 #include "utilities/debug.hpp" 30 #include "utilities/globalDefinitions.hpp" 31 #include "utilities/macros.hpp" 32 33 class OopStorage; 34 35 class OopStorageSet : public AllStatic { 36 private: 37 friend void oopstorage_init(); 38 39 enum { 40 singular_index, // For singular iterator. 41 42 all_start, 43 44 // Strong 45 strong_start = all_start, 46 jni_global_index = strong_start, 47 vm_global_index, 48 strong_end, 49 50 // Weak 51 weak_start = strong_end, 52 jni_weak_index = weak_start, 53 vm_weak_index, 54 string_table_weak_index, 55 resolved_method_table_weak_index, 56 weak_end, 57 58 all_end = weak_end 59 }; 60 61 static OopStorage* storages[all_end]; 62 63 static void verify_initialized(uint index) NOT_DEBUG_RETURN; 64 65 static OopStorage* storage(uint index) { 66 verify_initialized(index); 67 return storages[index]; 68 } 69 70 static void initialize(); 71 72 public: 73 class Iterator; 74 75 static const uint strong_count = (strong_end - strong_start); 76 static const uint weak_count = (weak_end - weak_start); 77 static const uint all_count = (all_end - all_start); 78 79 static Iterator strong_iterator(); 80 static Iterator weak_iterator(); 81 static Iterator all_iterator(); 82 83 // Strong 84 static OopStorage* jni_global() { return storage(jni_global_index); } 85 static OopStorage* vm_global() { return storage(vm_global_index); } 86 87 // Weak 88 static OopStorage* jni_weak() { return storage(jni_weak_index); } 89 static OopStorage* vm_weak() { return storage(vm_weak_index); } 90 91 static OopStorage* string_table_weak() { 92 return storage(string_table_weak_index); 93 } 94 95 static OopStorage* resolved_method_table_weak() { 96 return storage(resolved_method_table_weak_index); 97 } 98 99 template <typename Closure> 100 static void strong_oops_do(Closure* cl); 101 }; 102 103 class OopStorageSet::Iterator { 104 friend class OopStorageSet; 105 106 enum Category { singular, strong, weak, all }; 107 108 uint _index; 109 uint _limit; 110 DEBUG_ONLY(Category _category;) 111 112 Iterator(uint index, uint limit, Category category) : 113 _index(index), _limit(limit) DEBUG_ONLY(COMMA _category(category)) {} 114 115 void verify_nonsingular() const NOT_DEBUG_RETURN; 116 void verify_category_match(const Iterator& other) const NOT_DEBUG_RETURN; 117 void verify_dereferenceable() const NOT_DEBUG_RETURN; 118 119 public: 120 // Construct a singular iterator for later assignment. The only valid 121 // operations are destruction and assignment. 122 Iterator() : 123 _index(singular_index), 124 _limit(singular_index) 125 DEBUG_ONLY(COMMA _category(singular)) {} 126 127 bool is_end() const { 128 verify_nonsingular(); 129 return _index == _limit; 130 } 131 132 bool operator==(const Iterator& other) const { 133 verify_category_match(other); 134 return _index == other._index; 135 } 136 137 bool operator!=(const Iterator& other) const { 138 return !operator==(other); 139 } 140 141 OopStorage* operator*() const { 142 verify_dereferenceable(); 143 return storage(_index); 144 } 145 146 OopStorage* operator->() const { 147 return operator*(); 148 } 149 150 Iterator& operator++() { 151 verify_dereferenceable(); 152 ++_index; 153 return *this; 154 } 155 156 Iterator operator++(int) { 157 Iterator result = *this; 158 operator++(); 159 return result; 160 } 161 162 Iterator begin() const { 163 verify_nonsingular(); 164 return *this; 165 } 166 167 Iterator end() const { 168 verify_nonsingular(); 169 Iterator result = *this; 170 result._index = _limit; 171 return result; 172 } 173 }; 174 175 inline OopStorageSet::Iterator OopStorageSet::strong_iterator() { 176 return Iterator(strong_start, strong_end, Iterator::strong); 177 } 178 179 inline OopStorageSet::Iterator OopStorageSet::weak_iterator() { 180 return Iterator(weak_start, weak_end, Iterator::weak); 181 } 182 183 inline OopStorageSet::Iterator OopStorageSet::all_iterator() { 184 return Iterator(all_start, all_end, Iterator::all); 185 } 186 187 #endif // SHARE_GC_SHARED_OOPSTORAGESET_HPP