--- old/src/share/vm/runtime/virtualspace.cpp Thu Jun 17 20:39:44 2010 +++ new/src/share/vm/runtime/virtualspace.cpp Thu Jun 17 20:39:44 2010 @@ -129,6 +129,10 @@ assert((suffix_align & prefix_align - 1) == 0, "suffix_align not divisible by prefix_align"); + // Assert that if noaccess_prefix is used, it is the same as prefix_align. + assert(noaccess_prefix == 0 || + noaccess_prefix == prefix_align, "noaccess prefix wrong"); + // Add in noaccess_prefix to prefix_size; const size_t adjusted_prefix_size = prefix_size + noaccess_prefix; const size_t size = adjusted_prefix_size + suffix_size; @@ -150,15 +154,26 @@ _noaccess_prefix = 0; _executable = false; - // Assert that if noaccess_prefix is used, it is the same as prefix_align. - assert(noaccess_prefix == 0 || - noaccess_prefix == prefix_align, "noaccess prefix wrong"); - // Optimistically try to reserve the exact size needed. char* addr; if (requested_address != 0) { - addr = os::attempt_reserve_memory_at(size, - requested_address-noaccess_prefix); + requested_address -= noaccess_prefix; // adjust address + assert(requested_address != NULL, "huge noaccess prefix?"); + addr = os::attempt_reserve_memory_at(size, requested_address); + if (addr != NULL && addr != requested_address) { + // Different reserve address may be acceptable in other cases + // but for compressed oops heap should be at requested address. + assert(UseCompressedOops, "currently requested address used only for compressed oops"); + if (PrintCompressedOopsMode) { + tty->cr(); + tty->print_cr("Reserved memory at not requested address: " PTR_FORMAT " vs " PTR_FORMAT, addr, requested_address); + } + // OS ignored requested address. Try different address. + if (!os::release_memory(addr, size)) { + fatal("os::release_memory failed"); + } + addr = NULL; + } } else { addr = os::reserve_memory(size, NULL, prefix_align); } @@ -222,11 +237,30 @@ bool special = large && !os::can_commit_large_page_memory(); char* base = NULL; + if (requested_address != 0) { + requested_address -= noaccess_prefix; // adjust requested address + assert(requested_address != NULL, "huge noaccess prefix?"); + } + if (special) { base = os::reserve_memory_special(size, requested_address, executable); if (base != NULL) { + if (requested_address != NULL && base != requested_address) { + // Different reserve address may be acceptable in other cases + // but for compressed oops heap should be at requested address. + assert(UseCompressedOops, "currently requested address used only for compressed oops"); + if (PrintCompressedOopsMode) { + tty->cr(); + tty->print_cr("Reserved shared memory at not requested address: " PTR_FORMAT " vs " PTR_FORMAT, base, requested_address); + } + // OS ignored requested address. Try different address. + if (!os::release_memory_special(base, size)) { + fatal("os::release_memory failed"); + } + return; + } // Check alignment constraints if (alignment > 0) { assert((uintptr_t) base % alignment == 0, @@ -235,6 +269,13 @@ _special = true; } else { // failed; try to reserve regular memory below + if (UseLargePages && (!FLAG_IS_DEFAULT(UseLargePages) || + !FLAG_IS_DEFAULT(LargePageSizeInBytes))) { + if (PrintCompressedOopsMode) { + tty->cr(); + tty->print_cr("Reserve regular memory without large pages."); + } + } } } @@ -248,8 +289,19 @@ // important. If available space is not detected, return NULL. if (requested_address != 0) { - base = os::attempt_reserve_memory_at(size, - requested_address-noaccess_prefix); + base = os::attempt_reserve_memory_at(size, requested_address); + if (base != NULL && base != requested_address) { + assert(UseCompressedOops, "currently requested address used only for compressed oops"); + if (PrintCompressedOopsMode) { + tty->cr(); + tty->print_cr("Reserved memory at not requested address: " PTR_FORMAT " vs " PTR_FORMAT, base, requested_address); + } + // OS ignored requested address. Try different address. + if (!os::release_memory(base, size)) { + fatal("os::release_memory failed"); + } + base = NULL; + } } else { base = os::reserve_memory(size, NULL, alignment); } @@ -365,9 +417,19 @@ } void ReservedSpace::protect_noaccess_prefix(const size_t size) { - // If there is noaccess prefix, return. - if (_noaccess_prefix == 0) return; + // If there is no noaccess prefix, return. + if (_noaccess_prefix == 0) { + assert(_base == NULL || // failed reserve case + !UseCompressedOops || (size_t(_base + _size) <= OopEncodingHeapMax) || + !Universe::narrow_oop_use_implicit_null_checks(), + "noaccess_prefix should be used with non zero based compressed oops"); + return; + } + assert(_base != NULL && + UseCompressedOops && (size_t(_base + _size) > OopEncodingHeapMax) && + Universe::narrow_oop_use_implicit_null_checks(), + "noaccess_prefix should be used only with non zero based compressed oops"); assert(_noaccess_prefix >= (size_t)os::vm_page_size(), "must be at least page size big"); @@ -377,6 +439,10 @@ _special)) { fatal("cannot protect protection page"); } + if (PrintCompressedOopsMode) { + tty->cr(); + tty->print_cr("Protected page at the reserved heap base: " PTR_FORMAT " / " INTX_FORMAT " bytes", _base, _noaccess_prefix); + } _base += _noaccess_prefix; _size -= _noaccess_prefix;