1.1 --- a/src/share/vm/gc_implementation/g1/heapRegionSet.cpp Mon Mar 24 09:14:14 2014 -0700 1.2 +++ b/src/share/vm/gc_implementation/g1/heapRegionSet.cpp Fri Feb 28 15:27:09 2014 +0100 1.3 @@ -1,5 +1,5 @@ 1.4 /* 1.5 - * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved. 1.6 + * Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved. 1.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 1.8 * 1.9 * This code is free software; you can redistribute it and/or modify it 1.10 @@ -135,9 +135,11 @@ 1.11 assert(length() > 0 && _tail != NULL, hrs_ext_msg(this, "invariant")); 1.12 if (as_head) { 1.13 from_list->_tail->set_next(_head); 1.14 + _head->set_prev(from_list->_tail); 1.15 _head = from_list->_head; 1.16 } else { 1.17 _tail->set_next(from_list->_head); 1.18 + from_list->_head->set_prev(_tail); 1.19 _tail = from_list->_tail; 1.20 } 1.21 } 1.22 @@ -167,6 +169,7 @@ 1.23 1.24 HeapRegion* next = curr->next(); 1.25 curr->set_next(NULL); 1.26 + curr->set_prev(NULL); 1.27 curr->set_containing_set(NULL); 1.28 curr = next; 1.29 } 1.30 @@ -175,6 +178,74 @@ 1.31 verify_optional(); 1.32 } 1.33 1.34 +void FreeRegionList::add_ordered(FreeRegionList* from_list) { 1.35 + check_mt_safety(); 1.36 + from_list->check_mt_safety(); 1.37 + 1.38 + verify_optional(); 1.39 + from_list->verify_optional(); 1.40 + 1.41 + if (from_list->is_empty()) { 1.42 + return; 1.43 + } 1.44 + 1.45 + if (is_empty()) { 1.46 + add_as_head(from_list); 1.47 + return; 1.48 + } 1.49 + 1.50 + #ifdef ASSERT 1.51 + FreeRegionListIterator iter(from_list); 1.52 + while (iter.more_available()) { 1.53 + HeapRegion* hr = iter.get_next(); 1.54 + // In set_containing_set() we check that we either set the value 1.55 + // from NULL to non-NULL or vice versa to catch bugs. So, we have 1.56 + // to NULL it first before setting it to the value. 1.57 + hr->set_containing_set(NULL); 1.58 + hr->set_containing_set(this); 1.59 + } 1.60 + #endif // ASSERT 1.61 + 1.62 + HeapRegion* curr_to = _head; 1.63 + HeapRegion* curr_from = from_list->_head; 1.64 + 1.65 + while (curr_from != NULL) { 1.66 + while (curr_to != NULL && curr_to->hrs_index() < curr_from->hrs_index()) { 1.67 + curr_to = curr_to->next(); 1.68 + } 1.69 + 1.70 + if (curr_to == NULL) { 1.71 + // The rest of the from list should be added as tail 1.72 + _tail->set_next(curr_from); 1.73 + curr_from->set_prev(_tail); 1.74 + curr_from = NULL; 1.75 + } else { 1.76 + HeapRegion* next_from = curr_from->next(); 1.77 + 1.78 + curr_from->set_next(curr_to); 1.79 + curr_from->set_prev(curr_to->prev()); 1.80 + if (curr_to->prev() == NULL) { 1.81 + _head = curr_from; 1.82 + } else { 1.83 + curr_to->prev()->set_next(curr_from); 1.84 + } 1.85 + curr_to->set_prev(curr_from); 1.86 + 1.87 + curr_from = next_from; 1.88 + } 1.89 + } 1.90 + 1.91 + if (_tail->hrs_index() < from_list->_tail->hrs_index()) { 1.92 + _tail = from_list->_tail; 1.93 + } 1.94 + 1.95 + _count.increment(from_list->length(), from_list->total_capacity_bytes()); 1.96 + from_list->clear(); 1.97 + 1.98 + verify_optional(); 1.99 + from_list->verify_optional(); 1.100 +} 1.101 + 1.102 void FreeRegionList::remove_all_pending(uint target_count) { 1.103 check_mt_safety(); 1.104 assert(target_count > 1, hrs_ext_msg(this, "pre-condition")); 1.105 @@ -184,11 +255,11 @@ 1.106 DEBUG_ONLY(uint old_length = length();) 1.107 1.108 HeapRegion* curr = _head; 1.109 - HeapRegion* prev = NULL; 1.110 uint count = 0; 1.111 while (curr != NULL) { 1.112 verify_region(curr); 1.113 HeapRegion* next = curr->next(); 1.114 + HeapRegion* prev = curr->prev(); 1.115 1.116 if (curr->pending_removal()) { 1.117 assert(count < target_count, 1.118 @@ -208,9 +279,14 @@ 1.119 _tail = prev; 1.120 } else { 1.121 assert(_tail != curr, hrs_ext_msg(this, "invariant")); 1.122 + next->set_prev(prev); 1.123 + } 1.124 + if (_last = curr) { 1.125 + _last = NULL; 1.126 } 1.127 1.128 curr->set_next(NULL); 1.129 + curr->set_prev(NULL); 1.130 remove(curr); 1.131 curr->set_pending_removal(false); 1.132 1.133 @@ -221,8 +297,6 @@ 1.134 // carry on iterating to make sure there are not more regions 1.135 // tagged with pending removal. 1.136 DEBUG_ONLY(if (count == target_count) break;) 1.137 - } else { 1.138 - prev = curr; 1.139 } 1.140 curr = next; 1.141 } 1.142 @@ -255,6 +329,7 @@ 1.143 _count = HeapRegionSetCount(); 1.144 _head = NULL; 1.145 _tail = NULL; 1.146 + _last = NULL; 1.147 } 1.148 1.149 void FreeRegionList::print_on(outputStream* out, bool print_contents) { 1.150 @@ -279,6 +354,9 @@ 1.151 HeapRegion* prev0 = NULL; 1.152 uint count = 0; 1.153 size_t capacity = 0; 1.154 + uint last_index = 0; 1.155 + 1.156 + guarantee(_head == NULL || _head->prev() == NULL, "_head should not have a prev"); 1.157 while (curr != NULL) { 1.158 verify_region(curr); 1.159 1.160 @@ -286,6 +364,12 @@ 1.161 guarantee(count < _unrealistically_long_length, 1.162 hrs_err_msg("[%s] the calculated length: %u seems very long, is there maybe a cycle? curr: "PTR_FORMAT" prev0: "PTR_FORMAT" " "prev1: "PTR_FORMAT" length: %u", name(), count, curr, prev0, prev1, length())); 1.163 1.164 + if (curr->next() != NULL) { 1.165 + guarantee(curr->next()->prev() == curr, "Next or prev pointers messed up"); 1.166 + } 1.167 + guarantee(curr->hrs_index() == 0 || curr->hrs_index() > last_index, "List should be sorted"); 1.168 + last_index = curr->hrs_index(); 1.169 + 1.170 capacity += curr->capacity(); 1.171 1.172 prev1 = prev0; 1.173 @@ -294,7 +378,7 @@ 1.174 } 1.175 1.176 guarantee(tail() == prev0, err_msg("Expected %s to end with %u but it ended with %u.", name(), tail()->hrs_index(), prev0->hrs_index())); 1.177 - 1.178 + guarantee(_tail == NULL || _tail->next() == NULL, "_tail should not have a next"); 1.179 guarantee(length() == count, err_msg("%s count mismatch. Expected %u, actual %u.", name(), length(), count)); 1.180 guarantee(total_capacity_bytes() == capacity, err_msg("%s capacity mismatch. Expected " SIZE_FORMAT ", actual " SIZE_FORMAT, 1.181 name(), total_capacity_bytes(), capacity));