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

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

author
tschatzl
date
Fri, 10 Oct 2014 15:51:58 +0200
changeset 7257
e7d0505c8a30
parent 7052
8d5f66b42c53
child 7509
ae52ee069062
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@7051 1 /*
tschatzl@7051 2 * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
tschatzl@7051 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
tschatzl@7051 4 *
tschatzl@7051 5 * This code is free software; you can redistribute it and/or modify it
tschatzl@7051 6 * under the terms of the GNU General Public License version 2 only, as
tschatzl@7051 7 * published by the Free Software Foundation.
tschatzl@7051 8 *
tschatzl@7051 9 * This code is distributed in the hope that it will be useful, but WITHOUT
tschatzl@7051 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
tschatzl@7051 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
tschatzl@7051 12 * version 2 for more details (a copy is included in the LICENSE file that
tschatzl@7051 13 * accompanied this code).
tschatzl@7051 14 *
tschatzl@7051 15 * You should have received a copy of the GNU General Public License version
tschatzl@7051 16 * 2 along with this work; if not, write to the Free Software Foundation,
tschatzl@7051 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
tschatzl@7051 18 *
tschatzl@7051 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
tschatzl@7051 20 * or visit www.oracle.com if you need additional information or have any
tschatzl@7051 21 * questions.
tschatzl@7051 22 *
tschatzl@7051 23 */
tschatzl@7051 24
tschatzl@7051 25 #include "precompiled.hpp"
tschatzl@7051 26 #include "gc_implementation/g1/g1PageBasedVirtualSpace.hpp"
tschatzl@7051 27 #include "oops/markOop.hpp"
tschatzl@7051 28 #include "oops/oop.inline.hpp"
tschatzl@7051 29 #include "services/memTracker.hpp"
tschatzl@7051 30 #ifdef TARGET_OS_FAMILY_linux
tschatzl@7051 31 # include "os_linux.inline.hpp"
tschatzl@7051 32 #endif
tschatzl@7051 33 #ifdef TARGET_OS_FAMILY_solaris
tschatzl@7051 34 # include "os_solaris.inline.hpp"
tschatzl@7051 35 #endif
tschatzl@7051 36 #ifdef TARGET_OS_FAMILY_windows
tschatzl@7051 37 # include "os_windows.inline.hpp"
tschatzl@7051 38 #endif
tschatzl@7051 39 #ifdef TARGET_OS_FAMILY_aix
tschatzl@7051 40 # include "os_aix.inline.hpp"
tschatzl@7051 41 #endif
tschatzl@7051 42 #ifdef TARGET_OS_FAMILY_bsd
tschatzl@7051 43 # include "os_bsd.inline.hpp"
tschatzl@7051 44 #endif
tschatzl@7051 45 #include "utilities/bitMap.inline.hpp"
tschatzl@7051 46
tschatzl@7051 47 G1PageBasedVirtualSpace::G1PageBasedVirtualSpace() : _low_boundary(NULL),
tschatzl@7051 48 _high_boundary(NULL), _committed(), _page_size(0), _special(false), _executable(false) {
tschatzl@7051 49 }
tschatzl@7051 50
tschatzl@7051 51 bool G1PageBasedVirtualSpace::initialize_with_granularity(ReservedSpace rs, size_t page_size) {
tschatzl@7051 52 if (!rs.is_reserved()) {
tschatzl@7051 53 return false; // Allocation failed.
tschatzl@7051 54 }
tschatzl@7051 55 assert(_low_boundary == NULL, "VirtualSpace already initialized");
tschatzl@7051 56 assert(page_size > 0, "Granularity must be non-zero.");
tschatzl@7051 57
tschatzl@7051 58 _low_boundary = rs.base();
tschatzl@7051 59 _high_boundary = _low_boundary + rs.size();
tschatzl@7051 60
tschatzl@7051 61 _special = rs.special();
tschatzl@7051 62 _executable = rs.executable();
tschatzl@7051 63
tschatzl@7051 64 _page_size = page_size;
tschatzl@7051 65
tschatzl@7051 66 assert(_committed.size() == 0, "virtual space initialized more than once");
tschatzl@7051 67 uintx size_in_bits = rs.size() / page_size;
tschatzl@7051 68 _committed.resize(size_in_bits, /* in_resource_area */ false);
tschatzl@7051 69
tschatzl@7051 70 return true;
tschatzl@7051 71 }
tschatzl@7051 72
tschatzl@7051 73
tschatzl@7051 74 G1PageBasedVirtualSpace::~G1PageBasedVirtualSpace() {
tschatzl@7051 75 release();
tschatzl@7051 76 }
tschatzl@7051 77
tschatzl@7051 78 void G1PageBasedVirtualSpace::release() {
tschatzl@7051 79 // This does not release memory it never reserved.
tschatzl@7051 80 // Caller must release via rs.release();
tschatzl@7051 81 _low_boundary = NULL;
tschatzl@7051 82 _high_boundary = NULL;
tschatzl@7051 83 _special = false;
tschatzl@7051 84 _executable = false;
tschatzl@7051 85 _page_size = 0;
tschatzl@7051 86 _committed.resize(0, false);
tschatzl@7051 87 }
tschatzl@7051 88
tschatzl@7051 89 size_t G1PageBasedVirtualSpace::committed_size() const {
tschatzl@7051 90 return _committed.count_one_bits() * _page_size;
tschatzl@7051 91 }
tschatzl@7051 92
tschatzl@7051 93 size_t G1PageBasedVirtualSpace::reserved_size() const {
tschatzl@7051 94 return pointer_delta(_high_boundary, _low_boundary, sizeof(char));
tschatzl@7051 95 }
tschatzl@7051 96
tschatzl@7051 97 size_t G1PageBasedVirtualSpace::uncommitted_size() const {
tschatzl@7051 98 return reserved_size() - committed_size();
tschatzl@7051 99 }
tschatzl@7051 100
tschatzl@7051 101 uintptr_t G1PageBasedVirtualSpace::addr_to_page_index(char* addr) const {
tschatzl@7051 102 return (addr - _low_boundary) / _page_size;
tschatzl@7051 103 }
tschatzl@7051 104
tschatzl@7051 105 bool G1PageBasedVirtualSpace::is_area_committed(uintptr_t start, size_t size_in_pages) const {
tschatzl@7051 106 uintptr_t end = start + size_in_pages;
tschatzl@7051 107 return _committed.get_next_zero_offset(start, end) >= end;
tschatzl@7051 108 }
tschatzl@7051 109
tschatzl@7051 110 bool G1PageBasedVirtualSpace::is_area_uncommitted(uintptr_t start, size_t size_in_pages) const {
tschatzl@7051 111 uintptr_t end = start + size_in_pages;
tschatzl@7051 112 return _committed.get_next_one_offset(start, end) >= end;
tschatzl@7051 113 }
tschatzl@7051 114
tschatzl@7051 115 char* G1PageBasedVirtualSpace::page_start(uintptr_t index) {
tschatzl@7051 116 return _low_boundary + index * _page_size;
tschatzl@7051 117 }
tschatzl@7051 118
tschatzl@7051 119 size_t G1PageBasedVirtualSpace::byte_size_for_pages(size_t num) {
tschatzl@7051 120 return num * _page_size;
tschatzl@7051 121 }
tschatzl@7051 122
tschatzl@7051 123 MemRegion G1PageBasedVirtualSpace::commit(uintptr_t start, size_t size_in_pages) {
tschatzl@7051 124 // We need to make sure to commit all pages covered by the given area.
tschatzl@7051 125 guarantee(is_area_uncommitted(start, size_in_pages), "Specified area is not uncommitted");
tschatzl@7051 126
tschatzl@7051 127 if (!_special) {
tschatzl@7051 128 os::commit_memory_or_exit(page_start(start), byte_size_for_pages(size_in_pages), _executable,
tschatzl@7051 129 err_msg("Failed to commit pages from "SIZE_FORMAT" of length "SIZE_FORMAT, start, size_in_pages));
tschatzl@7051 130 }
tschatzl@7051 131 _committed.set_range(start, start + size_in_pages);
tschatzl@7051 132
tschatzl@7051 133 MemRegion result((HeapWord*)page_start(start), byte_size_for_pages(size_in_pages) / HeapWordSize);
tschatzl@7051 134 return result;
tschatzl@7051 135 }
tschatzl@7051 136
tschatzl@7051 137 MemRegion G1PageBasedVirtualSpace::uncommit(uintptr_t start, size_t size_in_pages) {
tschatzl@7051 138 guarantee(is_area_committed(start, size_in_pages), "checking");
tschatzl@7051 139
tschatzl@7051 140 if (!_special) {
tschatzl@7051 141 os::uncommit_memory(page_start(start), byte_size_for_pages(size_in_pages));
tschatzl@7051 142 }
tschatzl@7051 143
tschatzl@7051 144 _committed.clear_range(start, start + size_in_pages);
tschatzl@7051 145
tschatzl@7051 146 MemRegion result((HeapWord*)page_start(start), byte_size_for_pages(size_in_pages) / HeapWordSize);
tschatzl@7051 147 return result;
tschatzl@7051 148 }
tschatzl@7051 149
tschatzl@7051 150 bool G1PageBasedVirtualSpace::contains(const void* p) const {
tschatzl@7051 151 return _low_boundary <= (const char*) p && (const char*) p < _high_boundary;
tschatzl@7051 152 }
tschatzl@7051 153
tschatzl@7051 154 #ifndef PRODUCT
tschatzl@7051 155 void G1PageBasedVirtualSpace::print_on(outputStream* out) {
tschatzl@7051 156 out->print ("Virtual space:");
tschatzl@7051 157 if (special()) out->print(" (pinned in memory)");
tschatzl@7051 158 out->cr();
tschatzl@7051 159 out->print_cr(" - committed: " SIZE_FORMAT, committed_size());
tschatzl@7051 160 out->print_cr(" - reserved: " SIZE_FORMAT, reserved_size());
tschatzl@7051 161 out->print_cr(" - [low_b, high_b]: [" INTPTR_FORMAT ", " INTPTR_FORMAT "]", p2i(_low_boundary), p2i(_high_boundary));
tschatzl@7051 162 }
tschatzl@7051 163
tschatzl@7051 164 void G1PageBasedVirtualSpace::print() {
tschatzl@7051 165 print_on(tty);
tschatzl@7051 166 }
tschatzl@7051 167 #endif

mercurial