annotate src/share/vm/gc_implementation/g1/g1PageBasedVirtualSpace.cpp @ 20338:8d5f66b42c53

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