src/share/vm/gc_implementation/g1/g1CardCounts.cpp

Fri, 10 Oct 2014 15:51:58 +0200

author
tschatzl
date
Fri, 10 Oct 2014 15:51:58 +0200
changeset 7257
e7d0505c8a30
parent 7051
1f1d373cd044
child 7535
7ae4e26cb1e0
child 9327
f96fcd9e1e1b
permissions
-rw-r--r--

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

johnc@5078 1 /*
drchase@6680 2 * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
johnc@5078 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
johnc@5078 4 *
johnc@5078 5 * This code is free software; you can redistribute it and/or modify it
johnc@5078 6 * under the terms of the GNU General Public License version 2 only, as
johnc@5078 7 * published by the Free Software Foundation.
johnc@5078 8 *
johnc@5078 9 * This code is distributed in the hope that it will be useful, but WITHOUT
johnc@5078 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
johnc@5078 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
johnc@5078 12 * version 2 for more details (a copy is included in the LICENSE file that
johnc@5078 13 * accompanied this code).
johnc@5078 14 *
johnc@5078 15 * You should have received a copy of the GNU General Public License version
johnc@5078 16 * 2 along with this work; if not, write to the Free Software Foundation,
johnc@5078 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
johnc@5078 18 *
johnc@5078 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
johnc@5078 20 * or visit www.oracle.com if you need additional information or have any
johnc@5078 21 * questions.
johnc@5078 22 *
johnc@5078 23 */
johnc@5078 24
johnc@5078 25 #include "precompiled.hpp"
johnc@5078 26 #include "gc_implementation/g1/g1CardCounts.hpp"
johnc@5078 27 #include "gc_implementation/g1/g1CollectedHeap.inline.hpp"
johnc@5078 28 #include "gc_implementation/g1/g1CollectorPolicy.hpp"
johnc@5078 29 #include "gc_implementation/g1/g1GCPhaseTimes.hpp"
johnc@5078 30 #include "memory/cardTableModRefBS.hpp"
johnc@5078 31 #include "services/memTracker.hpp"
johnc@5078 32 #include "utilities/copy.hpp"
johnc@5078 33
drchase@6680 34 PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC
drchase@6680 35
tschatzl@7257 36 void G1CardCountsMappingChangedListener::on_commit(uint start_idx, size_t num_regions, bool zero_filled) {
tschatzl@7257 37 if (zero_filled) {
tschatzl@7257 38 return;
tschatzl@7257 39 }
tschatzl@7051 40 MemRegion mr(G1CollectedHeap::heap()->bottom_addr_for_region(start_idx), num_regions * HeapRegion::GrainWords);
tschatzl@7051 41 _counts->clear_range(mr);
tschatzl@7051 42 }
tschatzl@7051 43
johnc@5078 44 void G1CardCounts::clear_range(size_t from_card_num, size_t to_card_num) {
johnc@5078 45 if (has_count_table()) {
johnc@5078 46 assert(from_card_num < to_card_num,
johnc@5078 47 err_msg("Wrong order? from: " SIZE_FORMAT ", to: "SIZE_FORMAT,
johnc@5078 48 from_card_num, to_card_num));
johnc@5078 49 Copy::fill_to_bytes(&_card_counts[from_card_num], (to_card_num - from_card_num));
johnc@5078 50 }
johnc@5078 51 }
johnc@5078 52
johnc@5078 53 G1CardCounts::G1CardCounts(G1CollectedHeap *g1h):
tschatzl@7051 54 _listener(), _g1h(g1h), _card_counts(NULL), _reserved_max_card_num(0) {
tschatzl@7051 55 _listener.set_cardcounts(this);
tschatzl@7051 56 }
johnc@5078 57
tschatzl@7051 58 void G1CardCounts::initialize(G1RegionToSpaceMapper* mapper) {
johnc@5078 59 assert(_g1h->max_capacity() > 0, "initialization order");
johnc@5078 60 assert(_g1h->capacity() == 0, "initialization order");
johnc@5078 61
johnc@5078 62 if (G1ConcRSHotCardLimit > 0) {
johnc@5078 63 // The max value we can store in the counts table is
johnc@5078 64 // max_jubyte. Guarantee the value of the hot
johnc@5078 65 // threshold limit is no more than this.
johnc@5078 66 guarantee(G1ConcRSHotCardLimit <= max_jubyte, "sanity");
johnc@5078 67
mgerdin@5811 68 _ct_bs = _g1h->g1_barrier_set();
johnc@5078 69 _ct_bot = _ct_bs->byte_for_const(_g1h->reserved_region().start());
johnc@5078 70
tschatzl@7051 71 _card_counts = (jubyte*) mapper->reserved().start();
tschatzl@7051 72 _reserved_max_card_num = mapper->reserved().byte_size();
tschatzl@7051 73 mapper->set_mapping_changed_listener(&_listener);
johnc@5078 74 }
johnc@5078 75 }
johnc@5078 76
johnc@5078 77 uint G1CardCounts::add_card_count(jbyte* card_ptr) {
johnc@5078 78 // Returns the number of times the card has been refined.
johnc@5078 79 // If we failed to reserve/commit the counts table, return 0.
johnc@5078 80 // If card_ptr is beyond the committed end of the counts table,
johnc@5078 81 // return 0.
johnc@5078 82 // Otherwise return the actual count.
johnc@5078 83 // Unless G1ConcRSHotCardLimit has been set appropriately,
johnc@5078 84 // returning 0 will result in the card being considered
johnc@5078 85 // cold and will be refined immediately.
johnc@5078 86 uint count = 0;
johnc@5078 87 if (has_count_table()) {
johnc@5078 88 size_t card_num = ptr_2_card_num(card_ptr);
tschatzl@7051 89 assert(card_num < _reserved_max_card_num,
tschatzl@7051 90 err_msg("Card "SIZE_FORMAT" outside of card counts table (max size "SIZE_FORMAT")",
tschatzl@7051 91 card_num, _reserved_max_card_num));
tschatzl@7051 92 count = (uint) _card_counts[card_num];
tschatzl@7051 93 if (count < G1ConcRSHotCardLimit) {
tschatzl@7051 94 _card_counts[card_num] =
tschatzl@7051 95 (jubyte)(MIN2((uintx)(_card_counts[card_num] + 1), G1ConcRSHotCardLimit));
johnc@5078 96 }
johnc@5078 97 }
johnc@5078 98 return count;
johnc@5078 99 }
johnc@5078 100
johnc@5078 101 bool G1CardCounts::is_hot(uint count) {
johnc@5078 102 return (count >= G1ConcRSHotCardLimit);
johnc@5078 103 }
johnc@5078 104
johnc@5078 105 void G1CardCounts::clear_region(HeapRegion* hr) {
tschatzl@7051 106 MemRegion mr(hr->bottom(), hr->end());
tschatzl@7051 107 clear_range(mr);
tschatzl@7051 108 }
tschatzl@7051 109
tschatzl@7051 110 void G1CardCounts::clear_range(MemRegion mr) {
johnc@5078 111 if (has_count_table()) {
tschatzl@7051 112 const jbyte* from_card_ptr = _ct_bs->byte_for_const(mr.start());
tschatzl@7051 113 // We use the last address in the range as the range could represent the
tschatzl@7051 114 // last region in the heap. In which case trying to find the card will be an
tschatzl@7051 115 // OOB access to the card table.
tschatzl@7051 116 const jbyte* last_card_ptr = _ct_bs->byte_for_const(mr.last());
johnc@5078 117
johnc@5078 118 #ifdef ASSERT
johnc@5078 119 HeapWord* start_addr = _ct_bs->addr_for(from_card_ptr);
tschatzl@7051 120 assert(start_addr == mr.start(), "MemRegion start must be aligned to a card.");
johnc@5078 121 HeapWord* last_addr = _ct_bs->addr_for(last_card_ptr);
tschatzl@7051 122 assert((last_addr + CardTableModRefBS::card_size_in_words) == mr.end(), "MemRegion end must be aligned to a card.");
johnc@5078 123 #endif // ASSERT
johnc@5078 124
johnc@5078 125 // Clear the counts for the (exclusive) card range.
johnc@5078 126 size_t from_card_num = ptr_2_card_num(from_card_ptr);
johnc@5078 127 size_t to_card_num = ptr_2_card_num(last_card_ptr) + 1;
johnc@5078 128 clear_range(from_card_num, to_card_num);
johnc@5078 129 }
johnc@5078 130 }
johnc@5078 131
tschatzl@7051 132 class G1CardCountsClearClosure : public HeapRegionClosure {
tschatzl@7051 133 private:
tschatzl@7051 134 G1CardCounts* _card_counts;
tschatzl@7051 135 public:
tschatzl@7051 136 G1CardCountsClearClosure(G1CardCounts* card_counts) :
tschatzl@7051 137 HeapRegionClosure(), _card_counts(card_counts) { }
tschatzl@7051 138
tschatzl@7051 139
tschatzl@7051 140 virtual bool doHeapRegion(HeapRegion* r) {
tschatzl@7051 141 _card_counts->clear_region(r);
tschatzl@7051 142 return false;
tschatzl@7051 143 }
tschatzl@7051 144 };
tschatzl@7051 145
johnc@5078 146 void G1CardCounts::clear_all() {
johnc@5078 147 assert(SafepointSynchronize::is_at_safepoint(), "don't call this otherwise");
tschatzl@7051 148 G1CardCountsClearClosure cl(this);
tschatzl@7051 149 _g1h->heap_region_iterate(&cl);
johnc@5078 150 }

mercurial