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