1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/share/vm/gc_implementation/g1/heapRegionSet.hpp Wed Jan 19 19:30:42 2011 -0500 1.3 @@ -0,0 +1,346 @@ 1.4 +/* 1.5 + * copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. 1.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 1.7 + * 1.8 + * This code is free software; you can redistribute it and/or modify it 1.9 + * under the terms of the GNU General Public License version 2 only, as 1.10 + * published by the Free Software Foundation. 1.11 + * 1.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 1.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 1.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 1.15 + * version 2 for more details (a copy is included in the LICENSE file that 1.16 + * accompanied this code). 1.17 + * 1.18 + * You should have received a copy of the GNU General Public License version 1.19 + * 2 along with this work; if not, write to the Free Software Foundation, 1.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 1.21 + * 1.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 1.23 + * or visit www.oracle.com if you need additional information or have any 1.24 + * questions. 1.25 + * 1.26 + */ 1.27 + 1.28 +#ifndef SHARE_VM_GC_IMPLEMENTATION_G1_HEAPREGIONSET_HPP 1.29 +#define SHARE_VM_GC_IMPLEMENTATION_G1_HEAPREGIONSET_HPP 1.30 + 1.31 +#include "gc_implementation/g1/heapRegion.hpp" 1.32 + 1.33 +// Large buffer for some cases where the output might be larger than normal. 1.34 +#define HRL_ERR_MSG_BUFSZ 512 1.35 +typedef FormatBuffer<HRL_ERR_MSG_BUFSZ> hrl_err_msg; 1.36 + 1.37 +// Set verification will be forced either if someone defines 1.38 +// HEAP_REGION_SET_FORCE_VERIFY to be 1, or in builds in which 1.39 +// asserts are compiled in. 1.40 +#ifndef HEAP_REGION_SET_FORCE_VERIFY 1.41 +#define HEAP_REGION_SET_FORCE_VERIFY defined(ASSERT) 1.42 +#endif // HEAP_REGION_SET_FORCE_VERIFY 1.43 + 1.44 +//////////////////// HeapRegionSetBase //////////////////// 1.45 + 1.46 +// Base class for all the classes that represent heap region sets. It 1.47 +// contains the basic attributes that each set needs to maintain 1.48 +// (e.g., length, region num, used bytes sum) plus any shared 1.49 +// functionality (e.g., verification). 1.50 + 1.51 +class hrl_ext_msg; 1.52 + 1.53 +class HeapRegionSetBase VALUE_OBJ_CLASS_SPEC { 1.54 + friend class hrl_ext_msg; 1.55 + 1.56 +protected: 1.57 + static size_t calculate_region_num(HeapRegion* hr); 1.58 + 1.59 + static size_t _unrealistically_long_length; 1.60 + 1.61 + // The number of regions added to the set. If the set contains 1.62 + // only humongous regions, this reflects only 'starts humongous' 1.63 + // regions and does not include 'continues humongous' ones. 1.64 + size_t _length; 1.65 + 1.66 + // The total number of regions represented by the set. If the set 1.67 + // does not contain humongous regions, this should be the same as 1.68 + // _length. If the set contains only humongous regions, this will 1.69 + // include the 'continues humongous' regions. 1.70 + size_t _region_num; 1.71 + 1.72 + // We don't keep track of the total capacity explicitly, we instead 1.73 + // recalculate it based on _region_num and the heap region size. 1.74 + 1.75 + // The sum of used bytes in the all the regions in the set. 1.76 + size_t _total_used_bytes; 1.77 + 1.78 + const char* _name; 1.79 + 1.80 + bool _verify_in_progress; 1.81 + size_t _calc_length; 1.82 + size_t _calc_region_num; 1.83 + size_t _calc_total_capacity_bytes; 1.84 + size_t _calc_total_used_bytes; 1.85 + 1.86 + // verify_region() is used to ensure that the contents of a region 1.87 + // added to / removed from a set are consistent. Different sets 1.88 + // make different assumptions about the regions added to them. So 1.89 + // each set can override verify_region_extra(), which is called 1.90 + // from verify_region(), and do any extra verification it needs to 1.91 + // perform in that. 1.92 + virtual const char* verify_region_extra(HeapRegion* hr) { return NULL; } 1.93 + bool verify_region(HeapRegion* hr, 1.94 + HeapRegionSetBase* expected_containing_set); 1.95 + 1.96 + // Indicates whether all regions in the set should be humongous or 1.97 + // not. Only used during verification. 1.98 + virtual bool regions_humongous() = 0; 1.99 + 1.100 + // Indicates whether all regions in the set should be empty or 1.101 + // not. Only used during verification. 1.102 + virtual bool regions_empty() = 0; 1.103 + 1.104 + // Subclasses can optionally override this to do MT safety protocol 1.105 + // checks. It is called in an assert from all methods that perform 1.106 + // updates on the set (and subclasses should also call it too). 1.107 + virtual bool check_mt_safety() { return true; } 1.108 + 1.109 + // fill_in_ext_msg() writes the the values of the set's attributes 1.110 + // in the custom err_msg (hrl_ext_msg). fill_in_ext_msg_extra() 1.111 + // allows subclasses to append further information. 1.112 + virtual void fill_in_ext_msg_extra(hrl_ext_msg* msg) { } 1.113 + void fill_in_ext_msg(hrl_ext_msg* msg, const char* message); 1.114 + 1.115 + // It updates the fields of the set to reflect hr being added to 1.116 + // the set. 1.117 + inline void update_for_addition(HeapRegion* hr); 1.118 + 1.119 + // It updates the fields of the set to reflect hr being added to 1.120 + // the set and tags the region appropriately. 1.121 + inline void add_internal(HeapRegion* hr); 1.122 + 1.123 + // It updates the fields of the set to reflect hr being removed 1.124 + // from the set. 1.125 + inline void update_for_removal(HeapRegion* hr); 1.126 + 1.127 + // It updates the fields of the set to reflect hr being removed 1.128 + // from the set and tags the region appropriately. 1.129 + inline void remove_internal(HeapRegion* hr); 1.130 + 1.131 + // It clears all the fields of the sets. Note: it will not iterate 1.132 + // over the set and remove regions from it. It assumes that the 1.133 + // caller has already done so. It will literally just clear the fields. 1.134 + virtual void clear(); 1.135 + 1.136 + HeapRegionSetBase(const char* name); 1.137 + 1.138 +public: 1.139 + static void set_unrealistically_long_length(size_t len); 1.140 + 1.141 + const char* name() { return _name; } 1.142 + 1.143 + size_t length() { return _length; } 1.144 + 1.145 + bool is_empty() { return _length == 0; } 1.146 + 1.147 + size_t region_num() { return _region_num; } 1.148 + 1.149 + size_t total_capacity_bytes() { 1.150 + return region_num() << HeapRegion::LogOfHRGrainBytes; 1.151 + } 1.152 + 1.153 + size_t total_used_bytes() { return _total_used_bytes; } 1.154 + 1.155 + virtual void verify(); 1.156 + void verify_start(); 1.157 + void verify_next_region(HeapRegion* hr); 1.158 + void verify_end(); 1.159 + 1.160 +#if HEAP_REGION_SET_FORCE_VERIFY 1.161 + void verify_optional() { 1.162 + verify(); 1.163 + } 1.164 +#else // HEAP_REGION_SET_FORCE_VERIFY 1.165 + void verify_optional() { } 1.166 +#endif // HEAP_REGION_SET_FORCE_VERIFY 1.167 + 1.168 + virtual void print_on(outputStream* out, bool print_contents = false); 1.169 +}; 1.170 + 1.171 +// Customized err_msg for heap region sets. Apart from a 1.172 +// assert/guarantee-specific message it also prints out the values of 1.173 +// the fields of the associated set. This can be very helpful in 1.174 +// diagnosing failures. 1.175 + 1.176 +class hrl_ext_msg : public hrl_err_msg { 1.177 +public: 1.178 + hrl_ext_msg(HeapRegionSetBase* set, const char* message) : hrl_err_msg("") { 1.179 + set->fill_in_ext_msg(this, message); 1.180 + } 1.181 +}; 1.182 + 1.183 +// These two macros are provided for convenience, to keep the uses of 1.184 +// these two asserts a bit more concise. 1.185 + 1.186 +#define hrl_assert_mt_safety_ok(_set_) \ 1.187 + do { \ 1.188 + assert((_set_)->check_mt_safety(), hrl_ext_msg((_set_), "MT safety")); \ 1.189 + } while (0) 1.190 + 1.191 +#define hrl_assert_region_ok(_set_, _hr_, _expected_) \ 1.192 + do { \ 1.193 + assert((_set_)->verify_region((_hr_), (_expected_)), \ 1.194 + hrl_ext_msg((_set_), "region verification")); \ 1.195 + } while (0) 1.196 + 1.197 +//////////////////// HeapRegionSet //////////////////// 1.198 + 1.199 +#define hrl_assert_sets_match(_set1_, _set2_) \ 1.200 + do { \ 1.201 + assert(((_set1_)->regions_humongous() == \ 1.202 + (_set2_)->regions_humongous()) && \ 1.203 + ((_set1_)->regions_empty() == (_set2_)->regions_empty()), \ 1.204 + hrl_err_msg("the contents of set %s and set %s should match", \ 1.205 + (_set1_)->name(), (_set2_)->name())); \ 1.206 + } while (0) 1.207 + 1.208 +// This class represents heap region sets whose members are not 1.209 +// explicitly tracked. It's helpful to group regions using such sets 1.210 +// so that we can reason about all the region groups in the heap using 1.211 +// the same interface (namely, the HeapRegionSetBase API). 1.212 + 1.213 +class HeapRegionSet : public HeapRegionSetBase { 1.214 +protected: 1.215 + virtual const char* verify_region_extra(HeapRegion* hr) { 1.216 + if (hr->next() != NULL) { 1.217 + return "next() should always be NULL as we do not link the regions"; 1.218 + } 1.219 + 1.220 + return HeapRegionSetBase::verify_region_extra(hr); 1.221 + } 1.222 + 1.223 + HeapRegionSet(const char* name) : HeapRegionSetBase(name) { 1.224 + clear(); 1.225 + } 1.226 + 1.227 +public: 1.228 + // It adds hr to the set. The region should not be a member of 1.229 + // another set. 1.230 + inline void add(HeapRegion* hr); 1.231 + 1.232 + // It removes hr from the set. The region should be a member of 1.233 + // this set. 1.234 + inline void remove(HeapRegion* hr); 1.235 + 1.236 + // It removes a region from the set. Instead of updating the fields 1.237 + // of the set to reflect this removal, it accumulates the updates 1.238 + // in proxy_set. The idea is that proxy_set is thread-local to 1.239 + // avoid multiple threads updating the fields of the set 1.240 + // concurrently and having to synchronize. The method 1.241 + // update_from_proxy() will update the fields of the set from the 1.242 + // proxy_set. 1.243 + inline void remove_with_proxy(HeapRegion* hr, HeapRegionSet* proxy_set); 1.244 + 1.245 + // After multiple calls to remove_with_proxy() the updates to the 1.246 + // fields of the set are accumulated in proxy_set. This call 1.247 + // updates the fields of the set from proxy_set. 1.248 + void update_from_proxy(HeapRegionSet* proxy_set); 1.249 +}; 1.250 + 1.251 +//////////////////// HeapRegionLinkedList //////////////////// 1.252 + 1.253 +// A set that links all the regions added to it in a singly-linked 1.254 +// list. We should try to avoid doing operations that iterate over 1.255 +// such lists in performance critical paths. Typically we should 1.256 +// add / remove one region at a time or concatenate two lists. All 1.257 +// those operations are done in constant time. 1.258 + 1.259 +class HeapRegionLinkedListIterator; 1.260 + 1.261 +class HeapRegionLinkedList : public HeapRegionSetBase { 1.262 + friend class HeapRegionLinkedListIterator; 1.263 + 1.264 +private: 1.265 + HeapRegion* _head; 1.266 + HeapRegion* _tail; 1.267 + 1.268 + // These are provided for use by the friend classes. 1.269 + HeapRegion* head() { return _head; } 1.270 + HeapRegion* tail() { return _tail; } 1.271 + 1.272 +protected: 1.273 + virtual void fill_in_ext_msg_extra(hrl_ext_msg* msg); 1.274 + 1.275 + // See the comment for HeapRegionSetBase::clear() 1.276 + virtual void clear(); 1.277 + 1.278 + HeapRegionLinkedList(const char* name) : HeapRegionSetBase(name) { 1.279 + clear(); 1.280 + } 1.281 + 1.282 +public: 1.283 + // It adds hr to the list as the new tail. The region should not be 1.284 + // a member of another set. 1.285 + inline void add_as_tail(HeapRegion* hr); 1.286 + 1.287 + // It removes and returns the head of the list. It assumes that the 1.288 + // list is not empty so it will return a non-NULL value. 1.289 + inline HeapRegion* remove_head(); 1.290 + 1.291 + // Convenience method. 1.292 + inline HeapRegion* remove_head_or_null(); 1.293 + 1.294 + // It moves the regions from from_list to this list and empties 1.295 + // from_list. The new regions will appear in the same order as they 1.296 + // were in from_list and be linked in the end of this list. 1.297 + void add_as_tail(HeapRegionLinkedList* from_list); 1.298 + 1.299 + // It empties the list by removing all regions from it. 1.300 + void remove_all(); 1.301 + 1.302 + // It removes all regions in the list that are pending for removal 1.303 + // (i.e., they have been tagged with "pending_removal"). The list 1.304 + // must not be empty, target_count should reflect the exact number 1.305 + // of regions that are pending for removal in the list, and 1.306 + // target_count should be > 1 (currently, we never need to remove a 1.307 + // single region using this). 1.308 + void remove_all_pending(size_t target_count); 1.309 + 1.310 + virtual void verify(); 1.311 + 1.312 + virtual void print_on(outputStream* out, bool print_contents = false); 1.313 +}; 1.314 + 1.315 +//////////////////// HeapRegionLinkedList //////////////////// 1.316 + 1.317 +// Iterator class that provides a convenient way to iterator over the 1.318 +// regions in a HeapRegionLinkedList instance. 1.319 + 1.320 +class HeapRegionLinkedListIterator : public StackObj { 1.321 +private: 1.322 + HeapRegionLinkedList* _list; 1.323 + HeapRegion* _curr; 1.324 + 1.325 +public: 1.326 + bool more_available() { 1.327 + return _curr != NULL; 1.328 + } 1.329 + 1.330 + HeapRegion* get_next() { 1.331 + assert(more_available(), 1.332 + "get_next() should be called when more regions are available"); 1.333 + 1.334 + // If we are going to introduce a count in the iterator we should 1.335 + // do the "cycle" check. 1.336 + 1.337 + HeapRegion* hr = _curr; 1.338 + assert(_list->verify_region(hr, _list), "region verification"); 1.339 + _curr = hr->next(); 1.340 + return hr; 1.341 + } 1.342 + 1.343 + HeapRegionLinkedListIterator(HeapRegionLinkedList* list) 1.344 + : _curr(NULL), _list(list) { 1.345 + _curr = list->head(); 1.346 + } 1.347 +}; 1.348 + 1.349 +#endif // SHARE_VM_GC_IMPLEMENTATION_G1_HEAPREGIONSET_HPP