annotate hotspot/src/share/vm/gc_implementation/g1/g1CardCounts.cpp @ 27149:9246fc481aa3

8059758: Footprint regressions with JDK-8038423 Summary: Changes in JDK-8038423 always initialize (zero out) virtual memory used for auxiliary data structures. This causes a footprint regression for G1 in startup benchmarks. This is because they do not touch that memory at all, so the operating system does not actually commit these pages. The fix is to, if the initialization value of the data structures matches the default value of just committed memory (=0), do not do anything. Reviewed-by: jwilhelm, brutisso
author tschatzl
date Thu, 09 Oct 2014 11:40:11 +0200
parents aba6b01cb988
children 7a04e5c250d1
rev   line source
johnc@17327 1 /*
drchase@24424 2 * Copyright (c) 2013, 2014, 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
drchase@24424 34 PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC
drchase@24424 35
tschatzl@27149 36 void G1CardCountsMappingChangedListener::on_commit(uint start_idx, size_t num_regions, bool zero_filled) {
tschatzl@27149 37 if (zero_filled) {
tschatzl@27149 38 return;
tschatzl@27149 39 }
tschatzl@26160 40 MemRegion mr(G1CollectedHeap::heap()->bottom_addr_for_region(start_idx), num_regions * HeapRegion::GrainWords);
tschatzl@26160 41 _counts->clear_range(mr);
tschatzl@26160 42 }
tschatzl@26160 43
johnc@17327 44 void G1CardCounts::clear_range(size_t from_card_num, size_t to_card_num) {
johnc@17327 45 if (has_count_table()) {
johnc@17327 46 assert(from_card_num < to_card_num,
johnc@17327 47 err_msg("Wrong order? from: " SIZE_FORMAT ", to: "SIZE_FORMAT,
johnc@17327 48 from_card_num, to_card_num));
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):
tschatzl@26160 54 _listener(), _g1h(g1h), _card_counts(NULL), _reserved_max_card_num(0) {
tschatzl@26160 55 _listener.set_cardcounts(this);
tschatzl@26160 56 }
johnc@17327 57
tschatzl@26160 58 void G1CardCounts::initialize(G1RegionToSpaceMapper* mapper) {
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
mgerdin@20309 68 _ct_bs = _g1h->g1_barrier_set();
johnc@17327 69 _ct_bot = _ct_bs->byte_for_const(_g1h->reserved_region().start());
johnc@17327 70
tschatzl@26160 71 _card_counts = (jubyte*) mapper->reserved().start();
tschatzl@26160 72 _reserved_max_card_num = mapper->reserved().byte_size();
tschatzl@26160 73 mapper->set_mapping_changed_listener(&_listener);
johnc@17327 74 }
johnc@17327 75 }
johnc@17327 76
johnc@17327 77 uint G1CardCounts::add_card_count(jbyte* card_ptr) {
johnc@17327 78 // Returns the number of times the card has been refined.
johnc@17327 79 // If we failed to reserve/commit the counts table, return 0.
johnc@17327 80 // If card_ptr is beyond the committed end of the counts table,
johnc@17327 81 // return 0.
johnc@17327 82 // Otherwise return the actual count.
johnc@17327 83 // Unless G1ConcRSHotCardLimit has been set appropriately,
johnc@17327 84 // returning 0 will result in the card being considered
johnc@17327 85 // cold and will be refined immediately.
johnc@17327 86 uint count = 0;
johnc@17327 87 if (has_count_table()) {
johnc@17327 88 size_t card_num = ptr_2_card_num(card_ptr);
tschatzl@26160 89 assert(card_num < _reserved_max_card_num,
tschatzl@26160 90 err_msg("Card "SIZE_FORMAT" outside of card counts table (max size "SIZE_FORMAT")",
tschatzl@26160 91 card_num, _reserved_max_card_num));
tschatzl@26160 92 count = (uint) _card_counts[card_num];
tschatzl@26160 93 if (count < G1ConcRSHotCardLimit) {
tschatzl@26160 94 _card_counts[card_num] =
tschatzl@26160 95 (jubyte)(MIN2((uintx)(_card_counts[card_num] + 1), G1ConcRSHotCardLimit));
johnc@17327 96 }
johnc@17327 97 }
johnc@17327 98 return count;
johnc@17327 99 }
johnc@17327 100
johnc@17327 101 bool G1CardCounts::is_hot(uint count) {
johnc@17327 102 return (count >= G1ConcRSHotCardLimit);
johnc@17327 103 }
johnc@17327 104
johnc@17327 105 void G1CardCounts::clear_region(HeapRegion* hr) {
tschatzl@26160 106 MemRegion mr(hr->bottom(), hr->end());
tschatzl@26160 107 clear_range(mr);
tschatzl@26160 108 }
tschatzl@26160 109
tschatzl@26160 110 void G1CardCounts::clear_range(MemRegion mr) {
johnc@17327 111 if (has_count_table()) {
tschatzl@26160 112 const jbyte* from_card_ptr = _ct_bs->byte_for_const(mr.start());
tschatzl@26160 113 // We use the last address in the range as the range could represent the
tschatzl@26160 114 // last region in the heap. In which case trying to find the card will be an
tschatzl@26160 115 // OOB access to the card table.
tschatzl@26160 116 const jbyte* last_card_ptr = _ct_bs->byte_for_const(mr.last());
johnc@17327 117
johnc@17327 118 #ifdef ASSERT
johnc@17327 119 HeapWord* start_addr = _ct_bs->addr_for(from_card_ptr);
tschatzl@26160 120 assert(start_addr == mr.start(), "MemRegion start must be aligned to a card.");
johnc@17327 121 HeapWord* last_addr = _ct_bs->addr_for(last_card_ptr);
tschatzl@26160 122 assert((last_addr + CardTableModRefBS::card_size_in_words) == mr.end(), "MemRegion end must be aligned to a card.");
johnc@17327 123 #endif // ASSERT
johnc@17327 124
johnc@17327 125 // Clear the counts for the (exclusive) card range.
johnc@17327 126 size_t from_card_num = ptr_2_card_num(from_card_ptr);
johnc@17327 127 size_t to_card_num = ptr_2_card_num(last_card_ptr) + 1;
johnc@17327 128 clear_range(from_card_num, to_card_num);
johnc@17327 129 }
johnc@17327 130 }
johnc@17327 131
tschatzl@26160 132 class G1CardCountsClearClosure : public HeapRegionClosure {
tschatzl@26160 133 private:
tschatzl@26160 134 G1CardCounts* _card_counts;
tschatzl@26160 135 public:
tschatzl@26160 136 G1CardCountsClearClosure(G1CardCounts* card_counts) :
tschatzl@26160 137 HeapRegionClosure(), _card_counts(card_counts) { }
tschatzl@26160 138
tschatzl@26160 139
tschatzl@26160 140 virtual bool doHeapRegion(HeapRegion* r) {
tschatzl@26160 141 _card_counts->clear_region(r);
tschatzl@26160 142 return false;
tschatzl@26160 143 }
tschatzl@26160 144 };
tschatzl@26160 145
johnc@17327 146 void G1CardCounts::clear_all() {
johnc@17327 147 assert(SafepointSynchronize::is_at_safepoint(), "don't call this otherwise");
tschatzl@26160 148 G1CardCountsClearClosure cl(this);
tschatzl@26160 149 _g1h->heap_region_iterate(&cl);
johnc@17327 150 }