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

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

author
tschatzl
date
Fri, 10 Oct 2014 15:51:58 +0200
changeset 7257
e7d0505c8a30
parent 6680
78bbf4d43a14
child 6876
710a3c8b516e
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

tschatzl@5773 1 /*
drchase@6680 2 * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
tschatzl@5773 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
tschatzl@5773 4 *
tschatzl@5773 5 * This code is free software; you can redistribute it and/or modify it
tschatzl@5773 6 * under the terms of the GNU General Public License version 2 only, as
tschatzl@5773 7 * published by the Free Software Foundation.
tschatzl@5773 8 *
tschatzl@5773 9 * This code is distributed in the hope that it will be useful, but WITHOUT
tschatzl@5773 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
tschatzl@5773 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
tschatzl@5773 12 * version 2 for more details (a copy is included in the LICENSE file that
tschatzl@5773 13 * accompanied this code).
tschatzl@5773 14 *
tschatzl@5773 15 * You should have received a copy of the GNU General Public License version
tschatzl@5773 16 * 2 along with this work; if not, write to the Free Software Foundation,
tschatzl@5773 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
tschatzl@5773 18 *
tschatzl@5773 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
tschatzl@5773 20 * or visit www.oracle.com if you need additional information or have any
tschatzl@5773 21 * questions.
tschatzl@5773 22 *
tschatzl@5773 23 */
tschatzl@5773 24
tschatzl@5773 25 #include "precompiled.hpp"
tschatzl@5773 26 #include "gc_implementation/g1/g1BiasedArray.hpp"
tschatzl@6409 27 #include "memory/padded.inline.hpp"
tschatzl@6409 28
tschatzl@6409 29 // Allocate a new array, generic version.
tschatzl@6409 30 address G1BiasedMappedArrayBase::create_new_base_array(size_t length, size_t elem_size) {
tschatzl@6409 31 assert(length > 0, "just checking");
tschatzl@6409 32 assert(elem_size > 0, "just checking");
tschatzl@6409 33 return PaddedPrimitiveArray<u_char, mtGC>::create_unfreeable(length * elem_size);
tschatzl@6409 34 }
tschatzl@5773 35
tschatzl@5773 36 #ifndef PRODUCT
tschatzl@5773 37 void G1BiasedMappedArrayBase::verify_index(idx_t index) const {
tschatzl@5773 38 guarantee(_base != NULL, "Array not initialized");
tschatzl@5773 39 guarantee(index < length(), err_msg("Index out of bounds index: "SIZE_FORMAT" length: "SIZE_FORMAT, index, length()));
tschatzl@5773 40 }
tschatzl@5773 41
tschatzl@5773 42 void G1BiasedMappedArrayBase::verify_biased_index(idx_t biased_index) const {
tschatzl@5773 43 guarantee(_biased_base != NULL, "Array not initialized");
tschatzl@5773 44 guarantee(biased_index >= bias() && biased_index < (bias() + length()),
tschatzl@5773 45 err_msg("Biased index out of bounds, index: "SIZE_FORMAT" bias: "SIZE_FORMAT" length: "SIZE_FORMAT, biased_index, bias(), length()));
tschatzl@5773 46 }
tschatzl@5773 47
tschatzl@5773 48 void G1BiasedMappedArrayBase::verify_biased_index_inclusive_end(idx_t biased_index) const {
tschatzl@5773 49 guarantee(_biased_base != NULL, "Array not initialized");
tschatzl@5773 50 guarantee(biased_index >= bias() && biased_index <= (bias() + length()),
tschatzl@5773 51 err_msg("Biased index out of inclusive bounds, index: "SIZE_FORMAT" bias: "SIZE_FORMAT" length: "SIZE_FORMAT, biased_index, bias(), length()));
tschatzl@5773 52 }
tschatzl@5773 53
tschatzl@5773 54 class TestMappedArray : public G1BiasedMappedArray<int> {
tschatzl@5773 55 protected:
tschatzl@5773 56 virtual int default_value() const { return 0xBAADBABE; }
tschatzl@5773 57 public:
tschatzl@5773 58 static void test_biasedarray() {
tschatzl@5773 59 const size_t REGION_SIZE_IN_WORDS = 512;
tschatzl@5773 60 const size_t NUM_REGIONS = 20;
tschatzl@5773 61 HeapWord* fake_heap = (HeapWord*)LP64_ONLY(0xBAAA00000) NOT_LP64(0xBA000000); // Any value that is non-zero
tschatzl@5773 62
tschatzl@5773 63 TestMappedArray array;
tschatzl@5773 64 array.initialize(fake_heap, fake_heap + REGION_SIZE_IN_WORDS * NUM_REGIONS,
tschatzl@5773 65 REGION_SIZE_IN_WORDS * HeapWordSize);
tschatzl@5773 66 // Check address calculation (bounds)
tschatzl@5773 67 assert(array.bottom_address_mapped() == fake_heap,
drchase@6680 68 err_msg("bottom mapped address should be " PTR_FORMAT ", but is " PTR_FORMAT, p2i(fake_heap), p2i(array.bottom_address_mapped())));
tschatzl@5773 69 assert(array.end_address_mapped() == (fake_heap + REGION_SIZE_IN_WORDS * NUM_REGIONS), "must be");
tschatzl@5773 70
tschatzl@5773 71 int* bottom = array.address_mapped_to(fake_heap);
tschatzl@5773 72 assert((void*)bottom == (void*) array.base(), "must be");
tschatzl@5773 73 int* end = array.address_mapped_to(fake_heap + REGION_SIZE_IN_WORDS * NUM_REGIONS);
tschatzl@5773 74 assert((void*)end == (void*)(array.base() + array.length()), "must be");
tschatzl@5773 75 // The entire array should contain default value elements
tschatzl@5773 76 for (int* current = bottom; current < end; current++) {
tschatzl@5773 77 assert(*current == array.default_value(), "must be");
tschatzl@5773 78 }
tschatzl@5773 79
tschatzl@5773 80 // Test setting values in the table
tschatzl@5773 81
tschatzl@5773 82 HeapWord* region_start_address = fake_heap + REGION_SIZE_IN_WORDS * (NUM_REGIONS / 2);
tschatzl@5773 83 HeapWord* region_end_address = fake_heap + (REGION_SIZE_IN_WORDS * (NUM_REGIONS / 2) + REGION_SIZE_IN_WORDS - 1);
tschatzl@5773 84
tschatzl@5773 85 // Set/get by address tests: invert some value; first retrieve one
tschatzl@5773 86 int actual_value = array.get_by_index(NUM_REGIONS / 2);
tschatzl@5773 87 array.set_by_index(NUM_REGIONS / 2, ~actual_value);
tschatzl@5773 88 // Get the same value by address, should correspond to the start of the "region"
tschatzl@5773 89 int value = array.get_by_address(region_start_address);
tschatzl@5773 90 assert(value == ~actual_value, "must be");
tschatzl@5773 91 // Get the same value by address, at one HeapWord before the start
tschatzl@5773 92 value = array.get_by_address(region_start_address - 1);
tschatzl@5773 93 assert(value == array.default_value(), "must be");
tschatzl@5773 94 // Get the same value by address, at the end of the "region"
tschatzl@5773 95 value = array.get_by_address(region_end_address);
tschatzl@5773 96 assert(value == ~actual_value, "must be");
tschatzl@5773 97 // Make sure the next value maps to another index
tschatzl@5773 98 value = array.get_by_address(region_end_address + 1);
tschatzl@5773 99 assert(value == array.default_value(), "must be");
tschatzl@5773 100
tschatzl@5773 101 // Reset the value in the array
tschatzl@5773 102 array.set_by_address(region_start_address + (region_end_address - region_start_address) / 2, actual_value);
tschatzl@5773 103
tschatzl@5773 104 // The entire array should have the default value again
tschatzl@5773 105 for (int* current = bottom; current < end; current++) {
tschatzl@5773 106 assert(*current == array.default_value(), "must be");
tschatzl@5773 107 }
tschatzl@5773 108
tschatzl@5773 109 // Set/get by index tests: invert some value
tschatzl@5773 110 idx_t index = NUM_REGIONS / 2;
tschatzl@5773 111 actual_value = array.get_by_index(index);
tschatzl@5773 112 array.set_by_index(index, ~actual_value);
tschatzl@5773 113
tschatzl@5773 114 value = array.get_by_index(index);
tschatzl@5773 115 assert(value == ~actual_value, "must be");
tschatzl@5773 116
tschatzl@5773 117 value = array.get_by_index(index - 1);
tschatzl@5773 118 assert(value == array.default_value(), "must be");
tschatzl@5773 119
tschatzl@5773 120 value = array.get_by_index(index + 1);
tschatzl@5773 121 assert(value == array.default_value(), "must be");
tschatzl@5773 122
tschatzl@5773 123 array.set_by_index(0, 0);
tschatzl@5773 124 value = array.get_by_index(0);
tschatzl@5773 125 assert(value == 0, "must be");
tschatzl@5773 126
tschatzl@5773 127 array.set_by_index(array.length() - 1, 0);
tschatzl@5773 128 value = array.get_by_index(array.length() - 1);
tschatzl@5773 129 assert(value == 0, "must be");
tschatzl@5773 130
tschatzl@5773 131 array.set_by_index(index, 0);
tschatzl@5773 132
tschatzl@5773 133 // The array should have three zeros, and default values otherwise
tschatzl@5773 134 size_t num_zeros = 0;
tschatzl@5773 135 for (int* current = bottom; current < end; current++) {
tschatzl@5773 136 assert(*current == array.default_value() || *current == 0, "must be");
tschatzl@5773 137 if (*current == 0) {
tschatzl@5773 138 num_zeros++;
tschatzl@5773 139 }
tschatzl@5773 140 }
tschatzl@5773 141 assert(num_zeros == 3, "must be");
tschatzl@5773 142 }
tschatzl@5773 143 };
tschatzl@5773 144
tschatzl@5773 145 void TestG1BiasedArray_test() {
tschatzl@5773 146 TestMappedArray::test_biasedarray();
tschatzl@5773 147 }
tschatzl@5773 148
tschatzl@5773 149 #endif

mercurial