1 /* 2 * Copyright (c) 2011, 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_GC_G1_HEAPREGIONSET_HPP 26 #define SHARE_VM_GC_G1_HEAPREGIONSET_HPP 27 28 #include "gc/g1/heapRegion.hpp" 29 #include "utilities/macros.hpp" 30 31 #define assert_heap_region_set(p, message) \ 32 do { \ 33 assert((p), "[%s] %s ln: %u", \ 34 name(), message, length()); \ 35 } while (0) 36 37 #define guarantee_heap_region_set(p, message) \ 38 do { \ 39 guarantee((p), "[%s] %s ln: %u", \ 40 name(), message, length()); \ 41 } while (0) 42 43 #define assert_free_region_list(p, message) \ 44 do { \ 45 assert((p), "[%s] %s ln: %u hd: " PTR_FORMAT " tl: " PTR_FORMAT, \ 46 name(), message, length(), p2i(_head), p2i(_tail)); \ 47 } while (0) 48 49 50 class HRSMtSafeChecker : public CHeapObj<mtGC> { 51 public: 52 virtual void check() = 0; 53 }; 54 55 class MasterFreeRegionListMtSafeChecker : public HRSMtSafeChecker { public: void check(); }; 56 class HumongousRegionSetMtSafeChecker : public HRSMtSafeChecker { public: void check(); }; 57 class OldRegionSetMtSafeChecker : public HRSMtSafeChecker { public: void check(); }; 58 59 // Base class for all the classes that represent heap region sets. It 60 // contains the basic attributes that each set needs to maintain 61 // (e.g., length, region num, used bytes sum) plus any shared 62 // functionality (e.g., verification). 63 64 class HeapRegionSetBase { 65 friend class VMStructs; 66 private: 67 bool _is_humongous; 68 bool _is_free; 69 HRSMtSafeChecker* _mt_safety_checker; 70 71 protected: 72 // The number of regions in to the set. 73 uint _length; 74 75 const char* _name; 76 77 bool _verify_in_progress; 78 79 // verify_region() is used to ensure that the contents of a region 80 // added to / removed from a set are consistent. 81 void verify_region(HeapRegion* hr) PRODUCT_RETURN; 82 83 // Indicates whether all regions in the set should be humongous or 84 // not. Only used during verification. 85 bool regions_humongous() { return _is_humongous; } 86 87 // Indicates whether all regions in the set should be free or 88 // not. Only used during verification. 89 bool regions_free() { return _is_free; } 90 91 void check_mt_safety() { 92 if (_mt_safety_checker != NULL) { 93 _mt_safety_checker->check(); 94 } 95 } 96 97 HeapRegionSetBase(const char* name, bool humongous, bool free, HRSMtSafeChecker* mt_safety_checker); 98 99 public: 100 const char* name() { return _name; } 101 102 uint length() const { return _length; } 103 104 bool is_empty() { return _length == 0; } 105 106 // It updates the fields of the set to reflect hr being added to 107 // the set and tags the region appropriately. 108 inline void add(HeapRegion* hr); 109 110 // It updates the fields of the set to reflect hr being removed 111 // from the set and tags the region appropriately. 112 inline void remove(HeapRegion* hr); 113 114 virtual void verify(); 115 void verify_start(); 116 void verify_next_region(HeapRegion* hr); 117 void verify_end(); 118 119 void verify_optional() { DEBUG_ONLY(verify();) } 120 121 virtual void print_on(outputStream* out, bool print_contents = false); 122 }; 123 124 #define hrs_assert_sets_match(_set1_, _set2_) \ 125 do { \ 126 assert(((_set1_)->regions_humongous() == (_set2_)->regions_humongous()) && \ 127 ((_set1_)->regions_free() == (_set2_)->regions_free()), \ 128 "the contents of set %s and set %s should match", \ 129 (_set1_)->name(), \ 130 (_set2_)->name()); \ 131 } while (0) 132 133 // This class represents heap region sets whose members are not 134 // explicitly tracked. It's helpful to group regions using such sets 135 // so that we can reason about all the region groups in the heap using 136 // the same interface (namely, the HeapRegionSetBase API). 137 138 class HeapRegionSet : public HeapRegionSetBase { 139 public: 140 HeapRegionSet(const char* name, bool humongous, HRSMtSafeChecker* mt_safety_checker): 141 HeapRegionSetBase(name, humongous, false /* free */, mt_safety_checker) { } 142 143 void bulk_remove(const uint removed) { 144 _length -= removed; 145 } 146 }; 147 148 // A set that links all the regions added to it in a doubly-linked 149 // sorted list. We should try to avoid doing operations that iterate over 150 // such lists in performance critical paths. Typically we should 151 // add / remove one region at a time or concatenate two lists. 152 153 class FreeRegionListIterator; 154 155 class FreeRegionList : public HeapRegionSetBase { 156 friend class FreeRegionListIterator; 157 158 private: 159 HeapRegion* _head; 160 HeapRegion* _tail; 161 162 // _last is used to keep track of where we added an element the last 163 // time. It helps to improve performance when adding several ordered items in a row. 164 HeapRegion* _last; 165 166 static uint _unrealistically_long_length; 167 168 inline HeapRegion* remove_from_head_impl(); 169 inline HeapRegion* remove_from_tail_impl(); 170 171 protected: 172 // See the comment for HeapRegionSetBase::clear() 173 virtual void clear(); 174 175 public: 176 FreeRegionList(const char* name, HRSMtSafeChecker* mt_safety_checker = NULL): 177 HeapRegionSetBase(name, false /* humongous */, true /* empty */, mt_safety_checker) { 178 clear(); 179 } 180 181 void verify_list(); 182 183 #ifdef ASSERT 184 bool contains(HeapRegion* hr) const { 185 return hr->containing_set() == this; 186 } 187 #endif 188 189 static void set_unrealistically_long_length(uint len); 190 191 // Add hr to the list. The region should not be a member of another set. 192 // Assumes that the list is ordered and will preserve that order. The order 193 // is determined by hrm_index. 194 inline void add_ordered(HeapRegion* hr); 195 inline HeapRegion* show_tail() { return _tail; } 196 // Removes from head or tail based on the given argument. 197 HeapRegion* remove_region(bool from_head); 198 199 // Merge two ordered lists. The result is also ordered. The order is 200 // determined by hrm_index. 201 void add_ordered(FreeRegionList* from_list); 202 203 // It empties the list by removing all regions from it. 204 void remove_all(); 205 206 // Remove all (contiguous) regions from first to first + num_regions -1 from 207 // this list. 208 // Num_regions must be > 1. 209 void remove_starting_at(HeapRegion* first, uint num_regions); 210 211 virtual void verify(); 212 }; 213 214 // Iterator class that provides a convenient way to iterate over the 215 // regions of a FreeRegionList. 216 217 class FreeRegionListIterator : public StackObj { 218 private: 219 FreeRegionList* _list; 220 HeapRegion* _curr; 221 222 public: 223 bool more_available() { 224 return _curr != NULL; 225 } 226 227 HeapRegion* get_next() { 228 assert(more_available(), 229 "get_next() should be called when more regions are available"); 230 231 // If we are going to introduce a count in the iterator we should 232 // do the "cycle" check. 233 234 HeapRegion* hr = _curr; 235 _list->verify_region(hr); 236 _curr = hr->next(); 237 return hr; 238 } 239 240 FreeRegionListIterator(FreeRegionList* list) : _curr(NULL), _list(list) { 241 _curr = list->_head; 242 } 243 }; 244 245 #endif // SHARE_VM_GC_G1_HEAPREGIONSET_HPP