annotate hotspot/src/share/vm/gc_implementation/g1/g1CardCounts.cpp @ 17327:4bd0581aa231

7176479: G1: JVM crashes on T5-8 system with 1.5 TB heap Summary: Refactor G1's hot card cache and card counts table into their own files. Simplify the card counts table, including removing the encoding of the card index in each entry. The card counts table now has a 1:1 correspondence with the cards spanned by heap. Space for the card counts table is reserved from virtual memory (rather than C heap) during JVM startup and is committed/expanded when the heap is expanded. Changes were also reviewed-by Vitaly Davidovich. Reviewed-by: tschatzl, jmasa
author johnc
date Thu, 09 May 2013 11:16:39 -0700
parents
children 156f30e1d09a
rev   line source
johnc@17327 1 /*
johnc@17327 2 * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
johnc@17327 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
johnc@17327 4 *
johnc@17327 5 * This code is free software; you can redistribute it and/or modify it
johnc@17327 6 * under the terms of the GNU General Public License version 2 only, as
johnc@17327 7 * published by the Free Software Foundation.
johnc@17327 8 *
johnc@17327 9 * This code is distributed in the hope that it will be useful, but WITHOUT
johnc@17327 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
johnc@17327 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
johnc@17327 12 * version 2 for more details (a copy is included in the LICENSE file that
johnc@17327 13 * accompanied this code).
johnc@17327 14 *
johnc@17327 15 * You should have received a copy of the GNU General Public License version
johnc@17327 16 * 2 along with this work; if not, write to the Free Software Foundation,
johnc@17327 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
johnc@17327 18 *
johnc@17327 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
johnc@17327 20 * or visit www.oracle.com if you need additional information or have any
johnc@17327 21 * questions.
johnc@17327 22 *
johnc@17327 23 */
johnc@17327 24
johnc@17327 25 #include "precompiled.hpp"
johnc@17327 26 #include "gc_implementation/g1/g1CardCounts.hpp"
johnc@17327 27 #include "gc_implementation/g1/g1CollectedHeap.inline.hpp"
johnc@17327 28 #include "gc_implementation/g1/g1CollectorPolicy.hpp"
johnc@17327 29 #include "gc_implementation/g1/g1GCPhaseTimes.hpp"
johnc@17327 30 #include "memory/cardTableModRefBS.hpp"
johnc@17327 31 #include "services/memTracker.hpp"
johnc@17327 32 #include "utilities/copy.hpp"
johnc@17327 33
johnc@17327 34 void G1CardCounts::clear_range(size_t from_card_num, size_t to_card_num) {
johnc@17327 35 if (has_count_table()) {
johnc@17327 36 check_card_num(from_card_num,
johnc@17327 37 err_msg("from card num out of range: "SIZE_FORMAT, from_card_num));
johnc@17327 38 assert(from_card_num < to_card_num,
johnc@17327 39 err_msg("Wrong order? from: " SIZE_FORMAT ", to: "SIZE_FORMAT,
johnc@17327 40 from_card_num, to_card_num));
johnc@17327 41 assert(to_card_num <= _committed_max_card_num,
johnc@17327 42 err_msg("to card num out of range: "
johnc@17327 43 "to: "SIZE_FORMAT ", "
johnc@17327 44 "max: "SIZE_FORMAT,
johnc@17327 45 to_card_num, _committed_max_card_num));
johnc@17327 46
johnc@17327 47 to_card_num = MIN2(_committed_max_card_num, to_card_num);
johnc@17327 48
johnc@17327 49 Copy::fill_to_bytes(&_card_counts[from_card_num], (to_card_num - from_card_num));
johnc@17327 50 }
johnc@17327 51 }
johnc@17327 52
johnc@17327 53 G1CardCounts::G1CardCounts(G1CollectedHeap *g1h):
johnc@17327 54 _g1h(g1h), _card_counts(NULL),
johnc@17327 55 _reserved_max_card_num(0), _committed_max_card_num(0),
johnc@17327 56 _committed_size(0) {}
johnc@17327 57
johnc@17327 58 void G1CardCounts::initialize() {
johnc@17327 59 assert(_g1h->max_capacity() > 0, "initialization order");
johnc@17327 60 assert(_g1h->capacity() == 0, "initialization order");
johnc@17327 61
johnc@17327 62 if (G1ConcRSHotCardLimit > 0) {
johnc@17327 63 // The max value we can store in the counts table is
johnc@17327 64 // max_jubyte. Guarantee the value of the hot
johnc@17327 65 // threshold limit is no more than this.
johnc@17327 66 guarantee(G1ConcRSHotCardLimit <= max_jubyte, "sanity");
johnc@17327 67
johnc@17327 68 ModRefBarrierSet* bs = _g1h->mr_bs();
johnc@17327 69 guarantee(bs->is_a(BarrierSet::CardTableModRef), "Precondition");
johnc@17327 70 _ct_bs = (CardTableModRefBS*)bs;
johnc@17327 71 _ct_bot = _ct_bs->byte_for_const(_g1h->reserved_region().start());
johnc@17327 72
johnc@17327 73 // Allocate/Reserve the counts table
johnc@17327 74 size_t reserved_bytes = _g1h->max_capacity();
johnc@17327 75 _reserved_max_card_num = reserved_bytes >> CardTableModRefBS::card_shift;
johnc@17327 76
johnc@17327 77 size_t reserved_size = _reserved_max_card_num * sizeof(jbyte);
johnc@17327 78 ReservedSpace rs(ReservedSpace::allocation_align_size_up(reserved_size));
johnc@17327 79 if (!rs.is_reserved()) {
johnc@17327 80 warning("Could not reserve enough space for the card counts table");
johnc@17327 81 guarantee(!has_reserved_count_table(), "should be NULL");
johnc@17327 82 return;
johnc@17327 83 }
johnc@17327 84
johnc@17327 85 MemTracker::record_virtual_memory_type((address)rs.base(), mtGC);
johnc@17327 86
johnc@17327 87 _card_counts_storage.initialize(rs, 0);
johnc@17327 88 _card_counts = (jubyte*) _card_counts_storage.low();
johnc@17327 89 }
johnc@17327 90 }
johnc@17327 91
johnc@17327 92 void G1CardCounts::resize(size_t heap_capacity) {
johnc@17327 93 // Expand the card counts table to handle a heap with the given capacity.
johnc@17327 94
johnc@17327 95 if (!has_reserved_count_table()) {
johnc@17327 96 // Don't expand if we failed to reserve the card counts table.
johnc@17327 97 return;
johnc@17327 98 }
johnc@17327 99
johnc@17327 100 assert(_committed_size ==
johnc@17327 101 ReservedSpace::allocation_align_size_up(_committed_size),
johnc@17327 102 err_msg("Unaligned? committed_size: " SIZE_FORMAT, _committed_size));
johnc@17327 103
johnc@17327 104 // Verify that the committed space for the card counts
johnc@17327 105 // matches our committed max card num.
johnc@17327 106 size_t prev_committed_size = _committed_size;
johnc@17327 107 size_t prev_committed_card_num = prev_committed_size / sizeof(jbyte);
johnc@17327 108 assert(prev_committed_card_num == _committed_max_card_num,
johnc@17327 109 err_msg("Card mismatch: "
johnc@17327 110 "prev: " SIZE_FORMAT ", "
johnc@17327 111 "committed: "SIZE_FORMAT,
johnc@17327 112 prev_committed_card_num, _committed_max_card_num));
johnc@17327 113
johnc@17327 114 size_t new_size = (heap_capacity >> CardTableModRefBS::card_shift) * sizeof(jbyte);
johnc@17327 115 size_t new_committed_size = ReservedSpace::allocation_align_size_up(new_size);
johnc@17327 116 size_t new_committed_card_num =
johnc@17327 117 MIN2(_reserved_max_card_num, new_committed_size / sizeof(jbyte));
johnc@17327 118
johnc@17327 119 if (_committed_max_card_num < new_committed_card_num) {
johnc@17327 120 // we need to expand the backing store for the card counts
johnc@17327 121 size_t expand_size = new_committed_size - prev_committed_size;
johnc@17327 122
johnc@17327 123 if (!_card_counts_storage.expand_by(expand_size)) {
johnc@17327 124 warning("Card counts table backing store commit failure");
johnc@17327 125 return;
johnc@17327 126 }
johnc@17327 127 assert(_card_counts_storage.committed_size() == new_committed_size,
johnc@17327 128 "expansion commit failure");
johnc@17327 129
johnc@17327 130 _committed_size = new_committed_size;
johnc@17327 131 _committed_max_card_num = new_committed_card_num;
johnc@17327 132
johnc@17327 133 clear_range(prev_committed_card_num, _committed_max_card_num);
johnc@17327 134 }
johnc@17327 135 }
johnc@17327 136
johnc@17327 137 uint G1CardCounts::add_card_count(jbyte* card_ptr) {
johnc@17327 138 // Returns the number of times the card has been refined.
johnc@17327 139 // If we failed to reserve/commit the counts table, return 0.
johnc@17327 140 // If card_ptr is beyond the committed end of the counts table,
johnc@17327 141 // return 0.
johnc@17327 142 // Otherwise return the actual count.
johnc@17327 143 // Unless G1ConcRSHotCardLimit has been set appropriately,
johnc@17327 144 // returning 0 will result in the card being considered
johnc@17327 145 // cold and will be refined immediately.
johnc@17327 146 uint count = 0;
johnc@17327 147 if (has_count_table()) {
johnc@17327 148 size_t card_num = ptr_2_card_num(card_ptr);
johnc@17327 149 if (card_num < _committed_max_card_num) {
johnc@17327 150 count = (uint) _card_counts[card_num];
johnc@17327 151 if (count < G1ConcRSHotCardLimit) {
johnc@17327 152 _card_counts[card_num] += 1;
johnc@17327 153 }
johnc@17327 154 assert(_card_counts[card_num] <= G1ConcRSHotCardLimit,
johnc@17327 155 err_msg("Refinement count overflow? "
johnc@17327 156 "new count: "UINT32_FORMAT,
johnc@17327 157 (uint) _card_counts[card_num]));
johnc@17327 158 }
johnc@17327 159 }
johnc@17327 160 return count;
johnc@17327 161 }
johnc@17327 162
johnc@17327 163 bool G1CardCounts::is_hot(uint count) {
johnc@17327 164 return (count >= G1ConcRSHotCardLimit);
johnc@17327 165 }
johnc@17327 166
johnc@17327 167 void G1CardCounts::clear_region(HeapRegion* hr) {
johnc@17327 168 assert(!hr->isHumongous(), "Should have been cleared");
johnc@17327 169 if (has_count_table()) {
johnc@17327 170 HeapWord* bottom = hr->bottom();
johnc@17327 171
johnc@17327 172 // We use the last address in hr as hr could be the
johnc@17327 173 // last region in the heap. In which case trying to find
johnc@17327 174 // the card for hr->end() will be an OOB accesss to the
johnc@17327 175 // card table.
johnc@17327 176 HeapWord* last = hr->end() - 1;
johnc@17327 177 assert(_g1h->g1_committed().contains(last),
johnc@17327 178 err_msg("last not in committed: "
johnc@17327 179 "last: " PTR_FORMAT ", "
johnc@17327 180 "committed: [" PTR_FORMAT ", " PTR_FORMAT ")",
johnc@17327 181 last,
johnc@17327 182 _g1h->g1_committed().start(),
johnc@17327 183 _g1h->g1_committed().end()));
johnc@17327 184
johnc@17327 185 const jbyte* from_card_ptr = _ct_bs->byte_for_const(bottom);
johnc@17327 186 const jbyte* last_card_ptr = _ct_bs->byte_for_const(last);
johnc@17327 187
johnc@17327 188 #ifdef ASSERT
johnc@17327 189 HeapWord* start_addr = _ct_bs->addr_for(from_card_ptr);
johnc@17327 190 assert(start_addr == hr->bottom(), "alignment");
johnc@17327 191 HeapWord* last_addr = _ct_bs->addr_for(last_card_ptr);
johnc@17327 192 assert((last_addr + CardTableModRefBS::card_size_in_words) == hr->end(), "alignment");
johnc@17327 193 #endif // ASSERT
johnc@17327 194
johnc@17327 195 // Clear the counts for the (exclusive) card range.
johnc@17327 196 size_t from_card_num = ptr_2_card_num(from_card_ptr);
johnc@17327 197 size_t to_card_num = ptr_2_card_num(last_card_ptr) + 1;
johnc@17327 198 clear_range(from_card_num, to_card_num);
johnc@17327 199 }
johnc@17327 200 }
johnc@17327 201
johnc@17327 202 void G1CardCounts::clear_all() {
johnc@17327 203 assert(SafepointSynchronize::is_at_safepoint(), "don't call this otherwise");
johnc@17327 204 clear_range((size_t)0, _committed_max_card_num);
johnc@17327 205 }
johnc@17327 206
johnc@17327 207 G1CardCounts::~G1CardCounts() {
johnc@17327 208 if (has_reserved_count_table()) {
johnc@17327 209 _card_counts_storage.release();
johnc@17327 210 }
johnc@17327 211 }
johnc@17327 212