Fri, 08 Oct 2010 09:29:09 -0700
Merge
1 /*
2 * Copyright (c) 1997, 2009, 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 *
23 */
25 #include "incls/_precompiled.incl"
26 #include "incls/_virtualspace.cpp.incl"
29 // ReservedSpace
30 ReservedSpace::ReservedSpace(size_t size) {
31 initialize(size, 0, false, NULL, 0, false);
32 }
34 ReservedSpace::ReservedSpace(size_t size, size_t alignment,
35 bool large,
36 char* requested_address,
37 const size_t noaccess_prefix) {
38 initialize(size+noaccess_prefix, alignment, large, requested_address,
39 noaccess_prefix, false);
40 }
42 ReservedSpace::ReservedSpace(size_t size, size_t alignment,
43 bool large,
44 bool executable) {
45 initialize(size, alignment, large, NULL, 0, executable);
46 }
48 char *
49 ReservedSpace::align_reserved_region(char* addr, const size_t len,
50 const size_t prefix_size,
51 const size_t prefix_align,
52 const size_t suffix_size,
53 const size_t suffix_align)
54 {
55 assert(addr != NULL, "sanity");
56 const size_t required_size = prefix_size + suffix_size;
57 assert(len >= required_size, "len too small");
59 const size_t s = size_t(addr);
60 const size_t beg_ofs = s + prefix_size & suffix_align - 1;
61 const size_t beg_delta = beg_ofs == 0 ? 0 : suffix_align - beg_ofs;
63 if (len < beg_delta + required_size) {
64 return NULL; // Cannot do proper alignment.
65 }
66 const size_t end_delta = len - (beg_delta + required_size);
68 if (beg_delta != 0) {
69 os::release_memory(addr, beg_delta);
70 }
72 if (end_delta != 0) {
73 char* release_addr = (char*) (s + beg_delta + required_size);
74 os::release_memory(release_addr, end_delta);
75 }
77 return (char*) (s + beg_delta);
78 }
80 char* ReservedSpace::reserve_and_align(const size_t reserve_size,
81 const size_t prefix_size,
82 const size_t prefix_align,
83 const size_t suffix_size,
84 const size_t suffix_align)
85 {
86 assert(reserve_size > prefix_size + suffix_size, "should not be here");
88 char* raw_addr = os::reserve_memory(reserve_size, NULL, prefix_align);
89 if (raw_addr == NULL) return NULL;
91 char* result = align_reserved_region(raw_addr, reserve_size, prefix_size,
92 prefix_align, suffix_size,
93 suffix_align);
94 if (result == NULL && !os::release_memory(raw_addr, reserve_size)) {
95 fatal("os::release_memory failed");
96 }
98 #ifdef ASSERT
99 if (result != NULL) {
100 const size_t raw = size_t(raw_addr);
101 const size_t res = size_t(result);
102 assert(res >= raw, "alignment decreased start addr");
103 assert(res + prefix_size + suffix_size <= raw + reserve_size,
104 "alignment increased end addr");
105 assert((res & prefix_align - 1) == 0, "bad alignment of prefix");
106 assert((res + prefix_size & suffix_align - 1) == 0,
107 "bad alignment of suffix");
108 }
109 #endif
111 return result;
112 }
114 // Helper method.
115 static bool failed_to_reserve_as_requested(char* base, char* requested_address,
116 const size_t size, bool special)
117 {
118 if (base == requested_address || requested_address == NULL)
119 return false; // did not fail
121 if (base != NULL) {
122 // Different reserve address may be acceptable in other cases
123 // but for compressed oops heap should be at requested address.
124 assert(UseCompressedOops, "currently requested address used only for compressed oops");
125 if (PrintCompressedOopsMode) {
126 tty->cr();
127 tty->print_cr("Reserved memory at not requested address: " PTR_FORMAT " vs " PTR_FORMAT, base, requested_address);
128 }
129 // OS ignored requested address. Try different address.
130 if (special) {
131 if (!os::release_memory_special(base, size)) {
132 fatal("os::release_memory_special failed");
133 }
134 } else {
135 if (!os::release_memory(base, size)) {
136 fatal("os::release_memory failed");
137 }
138 }
139 }
140 return true;
141 }
143 ReservedSpace::ReservedSpace(const size_t prefix_size,
144 const size_t prefix_align,
145 const size_t suffix_size,
146 const size_t suffix_align,
147 char* requested_address,
148 const size_t noaccess_prefix)
149 {
150 assert(prefix_size != 0, "sanity");
151 assert(prefix_align != 0, "sanity");
152 assert(suffix_size != 0, "sanity");
153 assert(suffix_align != 0, "sanity");
154 assert((prefix_size & prefix_align - 1) == 0,
155 "prefix_size not divisible by prefix_align");
156 assert((suffix_size & suffix_align - 1) == 0,
157 "suffix_size not divisible by suffix_align");
158 assert((suffix_align & prefix_align - 1) == 0,
159 "suffix_align not divisible by prefix_align");
161 // Assert that if noaccess_prefix is used, it is the same as prefix_align.
162 assert(noaccess_prefix == 0 ||
163 noaccess_prefix == prefix_align, "noaccess prefix wrong");
165 // Add in noaccess_prefix to prefix_size;
166 const size_t adjusted_prefix_size = prefix_size + noaccess_prefix;
167 const size_t size = adjusted_prefix_size + suffix_size;
169 // On systems where the entire region has to be reserved and committed up
170 // front, the compound alignment normally done by this method is unnecessary.
171 const bool try_reserve_special = UseLargePages &&
172 prefix_align == os::large_page_size();
173 if (!os::can_commit_large_page_memory() && try_reserve_special) {
174 initialize(size, prefix_align, true, requested_address, noaccess_prefix,
175 false);
176 return;
177 }
179 _base = NULL;
180 _size = 0;
181 _alignment = 0;
182 _special = false;
183 _noaccess_prefix = 0;
184 _executable = false;
186 // Optimistically try to reserve the exact size needed.
187 char* addr;
188 if (requested_address != 0) {
189 requested_address -= noaccess_prefix; // adjust address
190 assert(requested_address != NULL, "huge noaccess prefix?");
191 addr = os::attempt_reserve_memory_at(size, requested_address);
192 if (failed_to_reserve_as_requested(addr, requested_address, size, false)) {
193 // OS ignored requested address. Try different address.
194 addr = NULL;
195 }
196 } else {
197 addr = os::reserve_memory(size, NULL, prefix_align);
198 }
199 if (addr == NULL) return;
201 // Check whether the result has the needed alignment (unlikely unless
202 // prefix_align == suffix_align).
203 const size_t ofs = size_t(addr) + adjusted_prefix_size & suffix_align - 1;
204 if (ofs != 0) {
205 // Wrong alignment. Release, allocate more space and do manual alignment.
206 //
207 // On most operating systems, another allocation with a somewhat larger size
208 // will return an address "close to" that of the previous allocation. The
209 // result is often the same address (if the kernel hands out virtual
210 // addresses from low to high), or an address that is offset by the increase
211 // in size. Exploit that to minimize the amount of extra space requested.
212 if (!os::release_memory(addr, size)) {
213 fatal("os::release_memory failed");
214 }
216 const size_t extra = MAX2(ofs, suffix_align - ofs);
217 addr = reserve_and_align(size + extra, adjusted_prefix_size, prefix_align,
218 suffix_size, suffix_align);
219 if (addr == NULL) {
220 // Try an even larger region. If this fails, address space is exhausted.
221 addr = reserve_and_align(size + suffix_align, adjusted_prefix_size,
222 prefix_align, suffix_size, suffix_align);
223 }
224 }
226 _base = addr;
227 _size = size;
228 _alignment = prefix_align;
229 _noaccess_prefix = noaccess_prefix;
230 }
232 void ReservedSpace::initialize(size_t size, size_t alignment, bool large,
233 char* requested_address,
234 const size_t noaccess_prefix,
235 bool executable) {
236 const size_t granularity = os::vm_allocation_granularity();
237 assert((size & granularity - 1) == 0,
238 "size not aligned to os::vm_allocation_granularity()");
239 assert((alignment & granularity - 1) == 0,
240 "alignment not aligned to os::vm_allocation_granularity()");
241 assert(alignment == 0 || is_power_of_2((intptr_t)alignment),
242 "not a power of 2");
244 _base = NULL;
245 _size = 0;
246 _special = false;
247 _executable = executable;
248 _alignment = 0;
249 _noaccess_prefix = 0;
250 if (size == 0) {
251 return;
252 }
254 // If OS doesn't support demand paging for large page memory, we need
255 // to use reserve_memory_special() to reserve and pin the entire region.
256 bool special = large && !os::can_commit_large_page_memory();
257 char* base = NULL;
259 if (requested_address != 0) {
260 requested_address -= noaccess_prefix; // adjust requested address
261 assert(requested_address != NULL, "huge noaccess prefix?");
262 }
264 if (special) {
266 base = os::reserve_memory_special(size, requested_address, executable);
268 if (base != NULL) {
269 if (failed_to_reserve_as_requested(base, requested_address, size, true)) {
270 // OS ignored requested address. Try different address.
271 return;
272 }
273 // Check alignment constraints
274 if (alignment > 0) {
275 assert((uintptr_t) base % alignment == 0,
276 "Large pages returned a non-aligned address");
277 }
278 _special = true;
279 } else {
280 // failed; try to reserve regular memory below
281 if (UseLargePages && (!FLAG_IS_DEFAULT(UseLargePages) ||
282 !FLAG_IS_DEFAULT(LargePageSizeInBytes))) {
283 if (PrintCompressedOopsMode) {
284 tty->cr();
285 tty->print_cr("Reserve regular memory without large pages.");
286 }
287 }
288 }
289 }
291 if (base == NULL) {
292 // Optimistically assume that the OSes returns an aligned base pointer.
293 // When reserving a large address range, most OSes seem to align to at
294 // least 64K.
296 // If the memory was requested at a particular address, use
297 // os::attempt_reserve_memory_at() to avoid over mapping something
298 // important. If available space is not detected, return NULL.
300 if (requested_address != 0) {
301 base = os::attempt_reserve_memory_at(size, requested_address);
302 if (failed_to_reserve_as_requested(base, requested_address, size, false)) {
303 // OS ignored requested address. Try different address.
304 base = NULL;
305 }
306 } else {
307 base = os::reserve_memory(size, NULL, alignment);
308 }
310 if (base == NULL) return;
312 // Check alignment constraints
313 if (alignment > 0 && ((size_t)base & alignment - 1) != 0) {
314 // Base not aligned, retry
315 if (!os::release_memory(base, size)) fatal("os::release_memory failed");
316 // Reserve size large enough to do manual alignment and
317 // increase size to a multiple of the desired alignment
318 size = align_size_up(size, alignment);
319 size_t extra_size = size + alignment;
320 do {
321 char* extra_base = os::reserve_memory(extra_size, NULL, alignment);
322 if (extra_base == NULL) return;
323 // Do manual alignement
324 base = (char*) align_size_up((uintptr_t) extra_base, alignment);
325 assert(base >= extra_base, "just checking");
326 // Re-reserve the region at the aligned base address.
327 os::release_memory(extra_base, extra_size);
328 base = os::reserve_memory(size, base);
329 } while (base == NULL);
330 }
331 }
332 // Done
333 _base = base;
334 _size = size;
335 _alignment = MAX2(alignment, (size_t) os::vm_page_size());
336 _noaccess_prefix = noaccess_prefix;
338 // Assert that if noaccess_prefix is used, it is the same as alignment.
339 assert(noaccess_prefix == 0 ||
340 noaccess_prefix == _alignment, "noaccess prefix wrong");
342 assert(markOopDesc::encode_pointer_as_mark(_base)->decode_pointer() == _base,
343 "area must be distinguisable from marks for mark-sweep");
344 assert(markOopDesc::encode_pointer_as_mark(&_base[size])->decode_pointer() == &_base[size],
345 "area must be distinguisable from marks for mark-sweep");
346 }
349 ReservedSpace::ReservedSpace(char* base, size_t size, size_t alignment,
350 bool special, bool executable) {
351 assert((size % os::vm_allocation_granularity()) == 0,
352 "size not allocation aligned");
353 _base = base;
354 _size = size;
355 _alignment = alignment;
356 _noaccess_prefix = 0;
357 _special = special;
358 _executable = executable;
359 }
362 ReservedSpace ReservedSpace::first_part(size_t partition_size, size_t alignment,
363 bool split, bool realloc) {
364 assert(partition_size <= size(), "partition failed");
365 if (split) {
366 os::split_reserved_memory(base(), size(), partition_size, realloc);
367 }
368 ReservedSpace result(base(), partition_size, alignment, special(),
369 executable());
370 return result;
371 }
374 ReservedSpace
375 ReservedSpace::last_part(size_t partition_size, size_t alignment) {
376 assert(partition_size <= size(), "partition failed");
377 ReservedSpace result(base() + partition_size, size() - partition_size,
378 alignment, special(), executable());
379 return result;
380 }
383 size_t ReservedSpace::page_align_size_up(size_t size) {
384 return align_size_up(size, os::vm_page_size());
385 }
388 size_t ReservedSpace::page_align_size_down(size_t size) {
389 return align_size_down(size, os::vm_page_size());
390 }
393 size_t ReservedSpace::allocation_align_size_up(size_t size) {
394 return align_size_up(size, os::vm_allocation_granularity());
395 }
398 size_t ReservedSpace::allocation_align_size_down(size_t size) {
399 return align_size_down(size, os::vm_allocation_granularity());
400 }
403 void ReservedSpace::release() {
404 if (is_reserved()) {
405 char *real_base = _base - _noaccess_prefix;
406 const size_t real_size = _size + _noaccess_prefix;
407 if (special()) {
408 os::release_memory_special(real_base, real_size);
409 } else{
410 os::release_memory(real_base, real_size);
411 }
412 _base = NULL;
413 _size = 0;
414 _noaccess_prefix = 0;
415 _special = false;
416 _executable = false;
417 }
418 }
420 void ReservedSpace::protect_noaccess_prefix(const size_t size) {
421 assert( (_noaccess_prefix != 0) == (UseCompressedOops && _base != NULL &&
422 (size_t(_base + _size) > OopEncodingHeapMax) &&
423 Universe::narrow_oop_use_implicit_null_checks()),
424 "noaccess_prefix should be used only with non zero based compressed oops");
426 // If there is no noaccess prefix, return.
427 if (_noaccess_prefix == 0) return;
429 assert(_noaccess_prefix >= (size_t)os::vm_page_size(),
430 "must be at least page size big");
432 // Protect memory at the base of the allocated region.
433 // If special, the page was committed (only matters on windows)
434 if (!os::protect_memory(_base, _noaccess_prefix, os::MEM_PROT_NONE,
435 _special)) {
436 fatal("cannot protect protection page");
437 }
438 if (PrintCompressedOopsMode) {
439 tty->cr();
440 tty->print_cr("Protected page at the reserved heap base: " PTR_FORMAT " / " INTX_FORMAT " bytes", _base, _noaccess_prefix);
441 }
443 _base += _noaccess_prefix;
444 _size -= _noaccess_prefix;
445 assert((size == _size) && ((uintptr_t)_base % _alignment == 0),
446 "must be exactly of required size and alignment");
447 }
449 ReservedHeapSpace::ReservedHeapSpace(size_t size, size_t alignment,
450 bool large, char* requested_address) :
451 ReservedSpace(size, alignment, large,
452 requested_address,
453 (UseCompressedOops && (Universe::narrow_oop_base() != NULL) &&
454 Universe::narrow_oop_use_implicit_null_checks()) ?
455 lcm(os::vm_page_size(), alignment) : 0) {
456 // Only reserved space for the java heap should have a noaccess_prefix
457 // if using compressed oops.
458 protect_noaccess_prefix(size);
459 }
461 ReservedHeapSpace::ReservedHeapSpace(const size_t prefix_size,
462 const size_t prefix_align,
463 const size_t suffix_size,
464 const size_t suffix_align,
465 char* requested_address) :
466 ReservedSpace(prefix_size, prefix_align, suffix_size, suffix_align,
467 requested_address,
468 (UseCompressedOops && (Universe::narrow_oop_base() != NULL) &&
469 Universe::narrow_oop_use_implicit_null_checks()) ?
470 lcm(os::vm_page_size(), prefix_align) : 0) {
471 protect_noaccess_prefix(prefix_size+suffix_size);
472 }
474 // Reserve space for code segment. Same as Java heap only we mark this as
475 // executable.
476 ReservedCodeSpace::ReservedCodeSpace(size_t r_size,
477 size_t rs_align,
478 bool large) :
479 ReservedSpace(r_size, rs_align, large, /*executable*/ true) {
480 }
482 // VirtualSpace
484 VirtualSpace::VirtualSpace() {
485 _low_boundary = NULL;
486 _high_boundary = NULL;
487 _low = NULL;
488 _high = NULL;
489 _lower_high = NULL;
490 _middle_high = NULL;
491 _upper_high = NULL;
492 _lower_high_boundary = NULL;
493 _middle_high_boundary = NULL;
494 _upper_high_boundary = NULL;
495 _lower_alignment = 0;
496 _middle_alignment = 0;
497 _upper_alignment = 0;
498 _special = false;
499 _executable = false;
500 }
503 bool VirtualSpace::initialize(ReservedSpace rs, size_t committed_size) {
504 if(!rs.is_reserved()) return false; // allocation failed.
505 assert(_low_boundary == NULL, "VirtualSpace already initialized");
506 _low_boundary = rs.base();
507 _high_boundary = low_boundary() + rs.size();
509 _low = low_boundary();
510 _high = low();
512 _special = rs.special();
513 _executable = rs.executable();
515 // When a VirtualSpace begins life at a large size, make all future expansion
516 // and shrinking occur aligned to a granularity of large pages. This avoids
517 // fragmentation of physical addresses that inhibits the use of large pages
518 // by the OS virtual memory system. Empirically, we see that with a 4MB
519 // page size, the only spaces that get handled this way are codecache and
520 // the heap itself, both of which provide a substantial performance
521 // boost in many benchmarks when covered by large pages.
522 //
523 // No attempt is made to force large page alignment at the very top and
524 // bottom of the space if they are not aligned so already.
525 _lower_alignment = os::vm_page_size();
526 _middle_alignment = os::page_size_for_region(rs.size(), rs.size(), 1);
527 _upper_alignment = os::vm_page_size();
529 // End of each region
530 _lower_high_boundary = (char*) round_to((intptr_t) low_boundary(), middle_alignment());
531 _middle_high_boundary = (char*) round_down((intptr_t) high_boundary(), middle_alignment());
532 _upper_high_boundary = high_boundary();
534 // High address of each region
535 _lower_high = low_boundary();
536 _middle_high = lower_high_boundary();
537 _upper_high = middle_high_boundary();
539 // commit to initial size
540 if (committed_size > 0) {
541 if (!expand_by(committed_size)) {
542 return false;
543 }
544 }
545 return true;
546 }
549 VirtualSpace::~VirtualSpace() {
550 release();
551 }
554 void VirtualSpace::release() {
555 // This does not release memory it never reserved.
556 // Caller must release via rs.release();
557 _low_boundary = NULL;
558 _high_boundary = NULL;
559 _low = NULL;
560 _high = NULL;
561 _lower_high = NULL;
562 _middle_high = NULL;
563 _upper_high = NULL;
564 _lower_high_boundary = NULL;
565 _middle_high_boundary = NULL;
566 _upper_high_boundary = NULL;
567 _lower_alignment = 0;
568 _middle_alignment = 0;
569 _upper_alignment = 0;
570 _special = false;
571 _executable = false;
572 }
575 size_t VirtualSpace::committed_size() const {
576 return pointer_delta(high(), low(), sizeof(char));
577 }
580 size_t VirtualSpace::reserved_size() const {
581 return pointer_delta(high_boundary(), low_boundary(), sizeof(char));
582 }
585 size_t VirtualSpace::uncommitted_size() const {
586 return reserved_size() - committed_size();
587 }
590 bool VirtualSpace::contains(const void* p) const {
591 return low() <= (const char*) p && (const char*) p < high();
592 }
594 /*
595 First we need to determine if a particular virtual space is using large
596 pages. This is done at the initialize function and only virtual spaces
597 that are larger than LargePageSizeInBytes use large pages. Once we
598 have determined this, all expand_by and shrink_by calls must grow and
599 shrink by large page size chunks. If a particular request
600 is within the current large page, the call to commit and uncommit memory
601 can be ignored. In the case that the low and high boundaries of this
602 space is not large page aligned, the pages leading to the first large
603 page address and the pages after the last large page address must be
604 allocated with default pages.
605 */
606 bool VirtualSpace::expand_by(size_t bytes, bool pre_touch) {
607 if (uncommitted_size() < bytes) return false;
609 if (special()) {
610 // don't commit memory if the entire space is pinned in memory
611 _high += bytes;
612 return true;
613 }
615 char* previous_high = high();
616 char* unaligned_new_high = high() + bytes;
617 assert(unaligned_new_high <= high_boundary(),
618 "cannot expand by more than upper boundary");
620 // Calculate where the new high for each of the regions should be. If
621 // the low_boundary() and high_boundary() are LargePageSizeInBytes aligned
622 // then the unaligned lower and upper new highs would be the
623 // lower_high() and upper_high() respectively.
624 char* unaligned_lower_new_high =
625 MIN2(unaligned_new_high, lower_high_boundary());
626 char* unaligned_middle_new_high =
627 MIN2(unaligned_new_high, middle_high_boundary());
628 char* unaligned_upper_new_high =
629 MIN2(unaligned_new_high, upper_high_boundary());
631 // Align the new highs based on the regions alignment. lower and upper
632 // alignment will always be default page size. middle alignment will be
633 // LargePageSizeInBytes if the actual size of the virtual space is in
634 // fact larger than LargePageSizeInBytes.
635 char* aligned_lower_new_high =
636 (char*) round_to((intptr_t) unaligned_lower_new_high, lower_alignment());
637 char* aligned_middle_new_high =
638 (char*) round_to((intptr_t) unaligned_middle_new_high, middle_alignment());
639 char* aligned_upper_new_high =
640 (char*) round_to((intptr_t) unaligned_upper_new_high, upper_alignment());
642 // Determine which regions need to grow in this expand_by call.
643 // If you are growing in the lower region, high() must be in that
644 // region so calcuate the size based on high(). For the middle and
645 // upper regions, determine the starting point of growth based on the
646 // location of high(). By getting the MAX of the region's low address
647 // (or the prevoius region's high address) and high(), we can tell if it
648 // is an intra or inter region growth.
649 size_t lower_needs = 0;
650 if (aligned_lower_new_high > lower_high()) {
651 lower_needs =
652 pointer_delta(aligned_lower_new_high, lower_high(), sizeof(char));
653 }
654 size_t middle_needs = 0;
655 if (aligned_middle_new_high > middle_high()) {
656 middle_needs =
657 pointer_delta(aligned_middle_new_high, middle_high(), sizeof(char));
658 }
659 size_t upper_needs = 0;
660 if (aligned_upper_new_high > upper_high()) {
661 upper_needs =
662 pointer_delta(aligned_upper_new_high, upper_high(), sizeof(char));
663 }
665 // Check contiguity.
666 assert(low_boundary() <= lower_high() &&
667 lower_high() <= lower_high_boundary(),
668 "high address must be contained within the region");
669 assert(lower_high_boundary() <= middle_high() &&
670 middle_high() <= middle_high_boundary(),
671 "high address must be contained within the region");
672 assert(middle_high_boundary() <= upper_high() &&
673 upper_high() <= upper_high_boundary(),
674 "high address must be contained within the region");
676 // Commit regions
677 if (lower_needs > 0) {
678 assert(low_boundary() <= lower_high() &&
679 lower_high() + lower_needs <= lower_high_boundary(),
680 "must not expand beyond region");
681 if (!os::commit_memory(lower_high(), lower_needs, _executable)) {
682 debug_only(warning("os::commit_memory failed"));
683 return false;
684 } else {
685 _lower_high += lower_needs;
686 }
687 }
688 if (middle_needs > 0) {
689 assert(lower_high_boundary() <= middle_high() &&
690 middle_high() + middle_needs <= middle_high_boundary(),
691 "must not expand beyond region");
692 if (!os::commit_memory(middle_high(), middle_needs, middle_alignment(),
693 _executable)) {
694 debug_only(warning("os::commit_memory failed"));
695 return false;
696 }
697 _middle_high += middle_needs;
698 }
699 if (upper_needs > 0) {
700 assert(middle_high_boundary() <= upper_high() &&
701 upper_high() + upper_needs <= upper_high_boundary(),
702 "must not expand beyond region");
703 if (!os::commit_memory(upper_high(), upper_needs, _executable)) {
704 debug_only(warning("os::commit_memory failed"));
705 return false;
706 } else {
707 _upper_high += upper_needs;
708 }
709 }
711 if (pre_touch || AlwaysPreTouch) {
712 int vm_ps = os::vm_page_size();
713 for (char* curr = previous_high;
714 curr < unaligned_new_high;
715 curr += vm_ps) {
716 // Note the use of a write here; originally we tried just a read, but
717 // since the value read was unused, the optimizer removed the read.
718 // If we ever have a concurrent touchahead thread, we'll want to use
719 // a read, to avoid the potential of overwriting data (if a mutator
720 // thread beats the touchahead thread to a page). There are various
721 // ways of making sure this read is not optimized away: for example,
722 // generating the code for a read procedure at runtime.
723 *curr = 0;
724 }
725 }
727 _high += bytes;
728 return true;
729 }
731 // A page is uncommitted if the contents of the entire page is deemed unusable.
732 // Continue to decrement the high() pointer until it reaches a page boundary
733 // in which case that particular page can now be uncommitted.
734 void VirtualSpace::shrink_by(size_t size) {
735 if (committed_size() < size)
736 fatal("Cannot shrink virtual space to negative size");
738 if (special()) {
739 // don't uncommit if the entire space is pinned in memory
740 _high -= size;
741 return;
742 }
744 char* unaligned_new_high = high() - size;
745 assert(unaligned_new_high >= low_boundary(), "cannot shrink past lower boundary");
747 // Calculate new unaligned address
748 char* unaligned_upper_new_high =
749 MAX2(unaligned_new_high, middle_high_boundary());
750 char* unaligned_middle_new_high =
751 MAX2(unaligned_new_high, lower_high_boundary());
752 char* unaligned_lower_new_high =
753 MAX2(unaligned_new_high, low_boundary());
755 // Align address to region's alignment
756 char* aligned_upper_new_high =
757 (char*) round_to((intptr_t) unaligned_upper_new_high, upper_alignment());
758 char* aligned_middle_new_high =
759 (char*) round_to((intptr_t) unaligned_middle_new_high, middle_alignment());
760 char* aligned_lower_new_high =
761 (char*) round_to((intptr_t) unaligned_lower_new_high, lower_alignment());
763 // Determine which regions need to shrink
764 size_t upper_needs = 0;
765 if (aligned_upper_new_high < upper_high()) {
766 upper_needs =
767 pointer_delta(upper_high(), aligned_upper_new_high, sizeof(char));
768 }
769 size_t middle_needs = 0;
770 if (aligned_middle_new_high < middle_high()) {
771 middle_needs =
772 pointer_delta(middle_high(), aligned_middle_new_high, sizeof(char));
773 }
774 size_t lower_needs = 0;
775 if (aligned_lower_new_high < lower_high()) {
776 lower_needs =
777 pointer_delta(lower_high(), aligned_lower_new_high, sizeof(char));
778 }
780 // Check contiguity.
781 assert(middle_high_boundary() <= upper_high() &&
782 upper_high() <= upper_high_boundary(),
783 "high address must be contained within the region");
784 assert(lower_high_boundary() <= middle_high() &&
785 middle_high() <= middle_high_boundary(),
786 "high address must be contained within the region");
787 assert(low_boundary() <= lower_high() &&
788 lower_high() <= lower_high_boundary(),
789 "high address must be contained within the region");
791 // Uncommit
792 if (upper_needs > 0) {
793 assert(middle_high_boundary() <= aligned_upper_new_high &&
794 aligned_upper_new_high + upper_needs <= upper_high_boundary(),
795 "must not shrink beyond region");
796 if (!os::uncommit_memory(aligned_upper_new_high, upper_needs)) {
797 debug_only(warning("os::uncommit_memory failed"));
798 return;
799 } else {
800 _upper_high -= upper_needs;
801 }
802 }
803 if (middle_needs > 0) {
804 assert(lower_high_boundary() <= aligned_middle_new_high &&
805 aligned_middle_new_high + middle_needs <= middle_high_boundary(),
806 "must not shrink beyond region");
807 if (!os::uncommit_memory(aligned_middle_new_high, middle_needs)) {
808 debug_only(warning("os::uncommit_memory failed"));
809 return;
810 } else {
811 _middle_high -= middle_needs;
812 }
813 }
814 if (lower_needs > 0) {
815 assert(low_boundary() <= aligned_lower_new_high &&
816 aligned_lower_new_high + lower_needs <= lower_high_boundary(),
817 "must not shrink beyond region");
818 if (!os::uncommit_memory(aligned_lower_new_high, lower_needs)) {
819 debug_only(warning("os::uncommit_memory failed"));
820 return;
821 } else {
822 _lower_high -= lower_needs;
823 }
824 }
826 _high -= size;
827 }
829 #ifndef PRODUCT
830 void VirtualSpace::check_for_contiguity() {
831 // Check contiguity.
832 assert(low_boundary() <= lower_high() &&
833 lower_high() <= lower_high_boundary(),
834 "high address must be contained within the region");
835 assert(lower_high_boundary() <= middle_high() &&
836 middle_high() <= middle_high_boundary(),
837 "high address must be contained within the region");
838 assert(middle_high_boundary() <= upper_high() &&
839 upper_high() <= upper_high_boundary(),
840 "high address must be contained within the region");
841 assert(low() >= low_boundary(), "low");
842 assert(low_boundary() <= lower_high_boundary(), "lower high boundary");
843 assert(upper_high_boundary() <= high_boundary(), "upper high boundary");
844 assert(high() <= upper_high(), "upper high");
845 }
847 void VirtualSpace::print() {
848 tty->print ("Virtual space:");
849 if (special()) tty->print(" (pinned in memory)");
850 tty->cr();
851 tty->print_cr(" - committed: %ld", committed_size());
852 tty->print_cr(" - reserved: %ld", reserved_size());
853 tty->print_cr(" - [low, high]: [" INTPTR_FORMAT ", " INTPTR_FORMAT "]", low(), high());
854 tty->print_cr(" - [low_b, high_b]: [" INTPTR_FORMAT ", " INTPTR_FORMAT "]", low_boundary(), high_boundary());
855 }
857 #endif