src/share/vm/runtime/virtualspace.cpp

changeset 1973
5f249b390094
parent 1907
c18cbe5936b8
child 2314
f95d63e2154a
     1.1 --- a/src/share/vm/runtime/virtualspace.cpp	Tue Jun 22 12:10:07 2010 -0700
     1.2 +++ b/src/share/vm/runtime/virtualspace.cpp	Wed Jun 23 09:40:11 2010 -0700
     1.3 @@ -111,6 +111,35 @@
     1.4    return result;
     1.5  }
     1.6  
     1.7 +// Helper method.
     1.8 +static bool failed_to_reserve_as_requested(char* base, char* requested_address,
     1.9 +                                           const size_t size, bool special)
    1.10 +{
    1.11 +  if (base == requested_address || requested_address == NULL)
    1.12 +    return false; // did not fail
    1.13 +
    1.14 +  if (base != NULL) {
    1.15 +    // Different reserve address may be acceptable in other cases
    1.16 +    // but for compressed oops heap should be at requested address.
    1.17 +    assert(UseCompressedOops, "currently requested address used only for compressed oops");
    1.18 +    if (PrintCompressedOopsMode) {
    1.19 +      tty->cr();
    1.20 +      tty->print_cr("Reserved memory at not requested address: " PTR_FORMAT " vs " PTR_FORMAT, base, requested_address);
    1.21 +    }
    1.22 +    // OS ignored requested address. Try different address.
    1.23 +    if (special) {
    1.24 +      if (!os::release_memory_special(base, size)) {
    1.25 +        fatal("os::release_memory_special failed");
    1.26 +      }
    1.27 +    } else {
    1.28 +      if (!os::release_memory(base, size)) {
    1.29 +        fatal("os::release_memory failed");
    1.30 +      }
    1.31 +    }
    1.32 +  }
    1.33 +  return true;
    1.34 +}
    1.35 +
    1.36  ReservedSpace::ReservedSpace(const size_t prefix_size,
    1.37                               const size_t prefix_align,
    1.38                               const size_t suffix_size,
    1.39 @@ -129,6 +158,10 @@
    1.40    assert((suffix_align & prefix_align - 1) == 0,
    1.41      "suffix_align not divisible by prefix_align");
    1.42  
    1.43 +  // Assert that if noaccess_prefix is used, it is the same as prefix_align.
    1.44 +  assert(noaccess_prefix == 0 ||
    1.45 +         noaccess_prefix == prefix_align, "noaccess prefix wrong");
    1.46 +
    1.47    // Add in noaccess_prefix to prefix_size;
    1.48    const size_t adjusted_prefix_size = prefix_size + noaccess_prefix;
    1.49    const size_t size = adjusted_prefix_size + suffix_size;
    1.50 @@ -150,15 +183,16 @@
    1.51    _noaccess_prefix = 0;
    1.52    _executable = false;
    1.53  
    1.54 -  // Assert that if noaccess_prefix is used, it is the same as prefix_align.
    1.55 -  assert(noaccess_prefix == 0 ||
    1.56 -         noaccess_prefix == prefix_align, "noaccess prefix wrong");
    1.57 -
    1.58    // Optimistically try to reserve the exact size needed.
    1.59    char* addr;
    1.60    if (requested_address != 0) {
    1.61 -    addr = os::attempt_reserve_memory_at(size,
    1.62 -                                         requested_address-noaccess_prefix);
    1.63 +    requested_address -= noaccess_prefix; // adjust address
    1.64 +    assert(requested_address != NULL, "huge noaccess prefix?");
    1.65 +    addr = os::attempt_reserve_memory_at(size, requested_address);
    1.66 +    if (failed_to_reserve_as_requested(addr, requested_address, size, false)) {
    1.67 +      // OS ignored requested address. Try different address.
    1.68 +      addr = NULL;
    1.69 +    }
    1.70    } else {
    1.71      addr = os::reserve_memory(size, NULL, prefix_align);
    1.72    }
    1.73 @@ -222,11 +256,20 @@
    1.74    bool special = large && !os::can_commit_large_page_memory();
    1.75    char* base = NULL;
    1.76  
    1.77 +  if (requested_address != 0) {
    1.78 +    requested_address -= noaccess_prefix; // adjust requested address
    1.79 +    assert(requested_address != NULL, "huge noaccess prefix?");
    1.80 +  }
    1.81 +
    1.82    if (special) {
    1.83  
    1.84      base = os::reserve_memory_special(size, requested_address, executable);
    1.85  
    1.86      if (base != NULL) {
    1.87 +      if (failed_to_reserve_as_requested(base, requested_address, size, true)) {
    1.88 +        // OS ignored requested address. Try different address.
    1.89 +        return;
    1.90 +      }
    1.91        // Check alignment constraints
    1.92        if (alignment > 0) {
    1.93          assert((uintptr_t) base % alignment == 0,
    1.94 @@ -235,6 +278,13 @@
    1.95        _special = true;
    1.96      } else {
    1.97        // failed; try to reserve regular memory below
    1.98 +      if (UseLargePages && (!FLAG_IS_DEFAULT(UseLargePages) ||
    1.99 +                            !FLAG_IS_DEFAULT(LargePageSizeInBytes))) {
   1.100 +        if (PrintCompressedOopsMode) {
   1.101 +          tty->cr();
   1.102 +          tty->print_cr("Reserve regular memory without large pages.");
   1.103 +        }
   1.104 +      }
   1.105      }
   1.106    }
   1.107  
   1.108 @@ -248,8 +298,11 @@
   1.109      // important.  If available space is not detected, return NULL.
   1.110  
   1.111      if (requested_address != 0) {
   1.112 -      base = os::attempt_reserve_memory_at(size,
   1.113 -                                           requested_address-noaccess_prefix);
   1.114 +      base = os::attempt_reserve_memory_at(size, requested_address);
   1.115 +      if (failed_to_reserve_as_requested(base, requested_address, size, false)) {
   1.116 +        // OS ignored requested address. Try different address.
   1.117 +        base = NULL;
   1.118 +      }
   1.119      } else {
   1.120        base = os::reserve_memory(size, NULL, alignment);
   1.121      }
   1.122 @@ -365,7 +418,12 @@
   1.123  }
   1.124  
   1.125  void ReservedSpace::protect_noaccess_prefix(const size_t size) {
   1.126 -  // If there is noaccess prefix, return.
   1.127 +  assert( (_noaccess_prefix != 0) == (UseCompressedOops && _base != NULL &&
   1.128 +                                      (size_t(_base + _size) > OopEncodingHeapMax) &&
   1.129 +                                      Universe::narrow_oop_use_implicit_null_checks()),
   1.130 +         "noaccess_prefix should be used only with non zero based compressed oops");
   1.131 +
   1.132 +  // If there is no noaccess prefix, return.
   1.133    if (_noaccess_prefix == 0) return;
   1.134  
   1.135    assert(_noaccess_prefix >= (size_t)os::vm_page_size(),
   1.136 @@ -377,6 +435,10 @@
   1.137                            _special)) {
   1.138      fatal("cannot protect protection page");
   1.139    }
   1.140 +  if (PrintCompressedOopsMode) {
   1.141 +    tty->cr();
   1.142 +    tty->print_cr("Protected page at the reserved heap base: " PTR_FORMAT " / " INTX_FORMAT " bytes", _base, _noaccess_prefix);
   1.143 +  }
   1.144  
   1.145    _base += _noaccess_prefix;
   1.146    _size -= _noaccess_prefix;

mercurial