1 /*
2 * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
81 }
82
83 bool PSVirtualSpace::expand_by(size_t bytes) {
84 assert(is_aligned(bytes), "arg not aligned");
85 DEBUG_ONLY(PSVirtualSpaceVerifier this_verifier(this));
86
87 if (uncommitted_size() < bytes) {
88 return false;
89 }
90
91 char* const base_addr = committed_high_addr();
92 bool result = special() ||
93 os::commit_memory(base_addr, bytes, alignment(), !ExecMem);
94 if (result) {
95 _committed_high_addr += bytes;
96 }
97
98 return result;
99 }
100
101 bool PSVirtualSpace::shrink_by(size_t bytes) {
102 assert(is_aligned(bytes), "arg not aligned");
103 DEBUG_ONLY(PSVirtualSpaceVerifier this_verifier(this));
104
105 if (committed_size() < bytes) {
106 return false;
107 }
108
109 char* const base_addr = committed_high_addr() - bytes;
110 bool result = special() || os::uncommit_memory(base_addr, bytes);
111 if (result) {
112 _committed_high_addr -= bytes;
113 }
114
115 return result;
116 }
117
118 size_t
119 PSVirtualSpace::expand_into(PSVirtualSpace* other_space, size_t bytes) {
120 assert(is_aligned(bytes), "arg not aligned");
156 } else {
157 return bytes - bytes_needed;
158 }
159 }
160
161 // Finally take from the already committed region in the other space.
162 tmp_bytes = bytes_needed;
163 if (tmp_bytes > 0) {
164 // Reduce both committed and reserved in the other space.
165 other_space->set_committed(other_space->committed_low_addr() + tmp_bytes,
166 other_space->committed_high_addr());
167 other_space->set_reserved(other_space->reserved_low_addr() + tmp_bytes,
168 other_space->reserved_high_addr(),
169 other_space->special());
170
171 // Grow both reserved and committed in this space.
172 _reserved_high_addr += tmp_bytes;
173 _committed_high_addr += tmp_bytes;
174 }
175
176 return bytes;
177 }
178
179 #ifndef PRODUCT
180 bool PSVirtualSpace::is_aligned(size_t value, size_t align) {
181 const size_t tmp_value = value + align - 1;
182 const size_t mask = ~(align - 1);
183 return (tmp_value & mask) == value;
184 }
185
186 bool PSVirtualSpace::is_aligned(size_t value) const {
187 return is_aligned(value, alignment());
188 }
189
190 bool PSVirtualSpace::is_aligned(char* value) const {
191 return is_aligned((size_t)value);
192 }
193
194 void PSVirtualSpace::verify() const {
195 assert(is_aligned(alignment(), os::vm_page_size()), "bad alignment");
|
1 /*
2 * Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
81 }
82
83 bool PSVirtualSpace::expand_by(size_t bytes) {
84 assert(is_aligned(bytes), "arg not aligned");
85 DEBUG_ONLY(PSVirtualSpaceVerifier this_verifier(this));
86
87 if (uncommitted_size() < bytes) {
88 return false;
89 }
90
91 char* const base_addr = committed_high_addr();
92 bool result = special() ||
93 os::commit_memory(base_addr, bytes, alignment(), !ExecMem);
94 if (result) {
95 _committed_high_addr += bytes;
96 }
97
98 return result;
99 }
100
101 bool PSVirtualSpace::expand_by(size_t bytes, int fd) {
102 assert(is_aligned(bytes), "arg not aligned");
103 DEBUG_ONLY(PSVirtualSpaceVerifier this_verifier(this));
104 if (uncommitted_size() < bytes) {
105 return false;
106 }
107 char* const base_addr = committed_high_addr();
108 bool commit_result = os::commit_memory(base_addr, bytes, alignment(), !ExecMem, fd, committed_size());
109 bool result = special() || commit_result;
110 if (result) {
111 _committed_high_addr += bytes;
112 }
113 return result;
114 }
115
116 bool PSVirtualSpace::shrink_by(size_t bytes) {
117 assert(is_aligned(bytes), "arg not aligned");
118 DEBUG_ONLY(PSVirtualSpaceVerifier this_verifier(this));
119
120 if (committed_size() < bytes) {
121 return false;
122 }
123
124 char* const base_addr = committed_high_addr() - bytes;
125 bool result = special() || os::uncommit_memory(base_addr, bytes);
126 if (result) {
127 _committed_high_addr -= bytes;
128 }
129
130 return result;
131 }
132
133 size_t
134 PSVirtualSpace::expand_into(PSVirtualSpace* other_space, size_t bytes) {
135 assert(is_aligned(bytes), "arg not aligned");
171 } else {
172 return bytes - bytes_needed;
173 }
174 }
175
176 // Finally take from the already committed region in the other space.
177 tmp_bytes = bytes_needed;
178 if (tmp_bytes > 0) {
179 // Reduce both committed and reserved in the other space.
180 other_space->set_committed(other_space->committed_low_addr() + tmp_bytes,
181 other_space->committed_high_addr());
182 other_space->set_reserved(other_space->reserved_low_addr() + tmp_bytes,
183 other_space->reserved_high_addr(),
184 other_space->special());
185
186 // Grow both reserved and committed in this space.
187 _reserved_high_addr += tmp_bytes;
188 _committed_high_addr += tmp_bytes;
189 }
190
191 return bytes;
192 }
193
194 size_t
195 PSVirtualSpace::expand_into(PSVirtualSpace* other_space, size_t bytes, int fd) {
196 assert(is_aligned(bytes), "arg not aligned");
197 assert(grows_up(), "this space must grow up");
198 assert(other_space->grows_down(), "other space must grow down");
199 assert(reserved_high_addr() == other_space->reserved_low_addr(),
200 "spaces not contiguous");
201 assert(special() == other_space->special(), "one space is special, the other is not");
202 DEBUG_ONLY(PSVirtualSpaceVerifier this_verifier(this));
203 DEBUG_ONLY(PSVirtualSpaceVerifier other_verifier(other_space));
204
205 size_t bytes_needed = bytes;
206
207 // First use the uncommitted region in this space.
208 size_t tmp_bytes = MIN2(uncommitted_size(), bytes_needed);
209 if (tmp_bytes > 0) {
210 if (expand_by(tmp_bytes)) {
211 bytes_needed -= tmp_bytes;
212 } else {
213 return 0;
214 }
215 }
216
217 // Next take from the uncommitted region in the other space, and commit it.
218 tmp_bytes = MIN2(other_space->uncommitted_size(), bytes_needed);
219 if (tmp_bytes > 0) {
220 char* const commit_base = committed_high_addr();
221 if (other_space->special() ||
222 os::commit_memory(commit_base, tmp_bytes, alignment(), !ExecMem, fd, committed_size())) {
223 // Reduce the reserved region in the other space.
224 other_space->set_reserved(other_space->reserved_low_addr() + tmp_bytes,
225 other_space->reserved_high_addr(),
226 other_space->special());
227
228 // Grow both reserved and committed in this space.
229 _reserved_high_addr += tmp_bytes;
230 _committed_high_addr += tmp_bytes;
231 bytes_needed -= tmp_bytes;
232 } else {
233 return bytes - bytes_needed;
234 }
235 }
236
237 // Finally take from the already committed region in the other space.
238 tmp_bytes = bytes_needed;
239 if (tmp_bytes > 0) {
240 // Reduce both committed and reserved in the other space.
241 other_space->set_committed(other_space->committed_low_addr() + tmp_bytes,
242 other_space->committed_high_addr());
243 other_space->set_reserved(other_space->reserved_low_addr() + tmp_bytes,
244 other_space->reserved_high_addr(),
245 other_space->special());
246
247 // Grow both reserved and committed in this space.
248 _reserved_high_addr += tmp_bytes;
249 _committed_high_addr += tmp_bytes;
250 }
251 return bytes;
252 }
253
254 #ifndef PRODUCT
255 bool PSVirtualSpace::is_aligned(size_t value, size_t align) {
256 const size_t tmp_value = value + align - 1;
257 const size_t mask = ~(align - 1);
258 return (tmp_value & mask) == value;
259 }
260
261 bool PSVirtualSpace::is_aligned(size_t value) const {
262 return is_aligned(value, alignment());
263 }
264
265 bool PSVirtualSpace::is_aligned(char* value) const {
266 return is_aligned((size_t)value);
267 }
268
269 void PSVirtualSpace::verify() const {
270 assert(is_aligned(alignment(), os::vm_page_size()), "bad alignment");
|