src/share/vm/runtime/virtualspace.cpp

changeset 672
1fdb98a17101
parent 435
a61af66fc99e
child 760
93befa083681
child 791
1ee8caae33af
     1.1 --- a/src/share/vm/runtime/virtualspace.cpp	Fri Jul 11 01:14:44 2008 -0700
     1.2 +++ b/src/share/vm/runtime/virtualspace.cpp	Sat Jul 19 17:38:22 2008 -0400
     1.3 @@ -28,12 +28,15 @@
     1.4  
     1.5  // ReservedSpace
     1.6  ReservedSpace::ReservedSpace(size_t size) {
     1.7 -  initialize(size, 0, false, NULL);
     1.8 +  initialize(size, 0, false, NULL, 0);
     1.9  }
    1.10  
    1.11  ReservedSpace::ReservedSpace(size_t size, size_t alignment,
    1.12 -                             bool large, char* requested_address) {
    1.13 -  initialize(size, alignment, large, requested_address);
    1.14 +                             bool large,
    1.15 +                             char* requested_address,
    1.16 +                             const size_t noaccess_prefix) {
    1.17 +  initialize(size+noaccess_prefix, alignment, large, requested_address,
    1.18 +             noaccess_prefix);
    1.19  }
    1.20  
    1.21  char *
    1.22 @@ -105,7 +108,8 @@
    1.23  ReservedSpace::ReservedSpace(const size_t prefix_size,
    1.24                               const size_t prefix_align,
    1.25                               const size_t suffix_size,
    1.26 -                             const size_t suffix_align)
    1.27 +                             const size_t suffix_align,
    1.28 +                             const size_t noaccess_prefix)
    1.29  {
    1.30    assert(prefix_size != 0, "sanity");
    1.31    assert(prefix_align != 0, "sanity");
    1.32 @@ -118,12 +122,16 @@
    1.33    assert((suffix_align & prefix_align - 1) == 0,
    1.34      "suffix_align not divisible by prefix_align");
    1.35  
    1.36 +  // Add in noaccess_prefix to prefix_size;
    1.37 +  const size_t adjusted_prefix_size = prefix_size + noaccess_prefix;
    1.38 +  const size_t size = adjusted_prefix_size + suffix_size;
    1.39 +
    1.40    // On systems where the entire region has to be reserved and committed up
    1.41    // front, the compound alignment normally done by this method is unnecessary.
    1.42    const bool try_reserve_special = UseLargePages &&
    1.43      prefix_align == os::large_page_size();
    1.44    if (!os::can_commit_large_page_memory() && try_reserve_special) {
    1.45 -    initialize(prefix_size + suffix_size, prefix_align, true);
    1.46 +    initialize(size, prefix_align, true, NULL, noaccess_prefix);
    1.47      return;
    1.48    }
    1.49  
    1.50 @@ -131,15 +139,19 @@
    1.51    _size = 0;
    1.52    _alignment = 0;
    1.53    _special = false;
    1.54 +  _noaccess_prefix = 0;
    1.55 +
    1.56 +  // Assert that if noaccess_prefix is used, it is the same as prefix_align.
    1.57 +  assert(noaccess_prefix == 0 ||
    1.58 +         noaccess_prefix == prefix_align, "noaccess prefix wrong");
    1.59  
    1.60    // Optimistically try to reserve the exact size needed.
    1.61 -  const size_t size = prefix_size + suffix_size;
    1.62    char* addr = os::reserve_memory(size, NULL, prefix_align);
    1.63    if (addr == NULL) return;
    1.64  
    1.65    // Check whether the result has the needed alignment (unlikely unless
    1.66    // prefix_align == suffix_align).
    1.67 -  const size_t ofs = size_t(addr) + prefix_size & suffix_align - 1;
    1.68 +  const size_t ofs = size_t(addr) + adjusted_prefix_size & suffix_align - 1;
    1.69    if (ofs != 0) {
    1.70      // Wrong alignment.  Release, allocate more space and do manual alignment.
    1.71      //
    1.72 @@ -153,11 +165,11 @@
    1.73      }
    1.74  
    1.75      const size_t extra = MAX2(ofs, suffix_align - ofs);
    1.76 -    addr = reserve_and_align(size + extra, prefix_size, prefix_align,
    1.77 +    addr = reserve_and_align(size + extra, adjusted_prefix_size, prefix_align,
    1.78                               suffix_size, suffix_align);
    1.79      if (addr == NULL) {
    1.80        // Try an even larger region.  If this fails, address space is exhausted.
    1.81 -      addr = reserve_and_align(size + suffix_align, prefix_size,
    1.82 +      addr = reserve_and_align(size + suffix_align, adjusted_prefix_size,
    1.83                                 prefix_align, suffix_size, suffix_align);
    1.84      }
    1.85    }
    1.86 @@ -165,10 +177,12 @@
    1.87    _base = addr;
    1.88    _size = size;
    1.89    _alignment = prefix_align;
    1.90 +  _noaccess_prefix = noaccess_prefix;
    1.91  }
    1.92  
    1.93  void ReservedSpace::initialize(size_t size, size_t alignment, bool large,
    1.94 -                               char* requested_address) {
    1.95 +                               char* requested_address,
    1.96 +                               const size_t noaccess_prefix) {
    1.97    const size_t granularity = os::vm_allocation_granularity();
    1.98    assert((size & granularity - 1) == 0,
    1.99           "size not aligned to os::vm_allocation_granularity()");
   1.100 @@ -181,6 +195,7 @@
   1.101    _size = 0;
   1.102    _special = false;
   1.103    _alignment = 0;
   1.104 +  _noaccess_prefix = 0;
   1.105    if (size == 0) {
   1.106      return;
   1.107    }
   1.108 @@ -220,7 +235,8 @@
   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, requested_address);
   1.113 +      base = os::attempt_reserve_memory_at(size,
   1.114 +                                           requested_address-noaccess_prefix);
   1.115      } else {
   1.116        base = os::reserve_memory(size, NULL, alignment);
   1.117      }
   1.118 @@ -259,6 +275,11 @@
   1.119    _base = base;
   1.120    _size = size;
   1.121    _alignment = MAX2(alignment, (size_t) os::vm_page_size());
   1.122 +  _noaccess_prefix = noaccess_prefix;
   1.123 +
   1.124 +  // Assert that if noaccess_prefix is used, it is the same as alignment.
   1.125 +  assert(noaccess_prefix == 0 ||
   1.126 +         noaccess_prefix == _alignment, "noaccess prefix wrong");
   1.127  
   1.128    assert(markOopDesc::encode_pointer_as_mark(_base)->decode_pointer() == _base,
   1.129           "area must be distinguisable from marks for mark-sweep");
   1.130 @@ -274,6 +295,7 @@
   1.131    _base = base;
   1.132    _size = size;
   1.133    _alignment = alignment;
   1.134 +  _noaccess_prefix = 0;
   1.135    _special = special;
   1.136  }
   1.137  
   1.138 @@ -320,17 +342,58 @@
   1.139  
   1.140  void ReservedSpace::release() {
   1.141    if (is_reserved()) {
   1.142 +    char *real_base = _base - _noaccess_prefix;
   1.143 +    const size_t real_size = _size + _noaccess_prefix;
   1.144      if (special()) {
   1.145 -      os::release_memory_special(_base, _size);
   1.146 +      os::release_memory_special(real_base, real_size);
   1.147      } else{
   1.148 -      os::release_memory(_base, _size);
   1.149 +      os::release_memory(real_base, real_size);
   1.150      }
   1.151      _base = NULL;
   1.152      _size = 0;
   1.153 +    _noaccess_prefix = 0;
   1.154      _special = false;
   1.155    }
   1.156  }
   1.157  
   1.158 +void ReservedSpace::protect_noaccess_prefix(const size_t size) {
   1.159 +  // If there is noaccess prefix, return.
   1.160 +  if (_noaccess_prefix == 0) return;
   1.161 +
   1.162 +  assert(_noaccess_prefix >= (size_t)os::vm_page_size(),
   1.163 +         "must be at least page size big");
   1.164 +
   1.165 +  // Protect memory at the base of the allocated region.
   1.166 +  // If special, the page was committed (only matters on windows)
   1.167 +  if (!os::protect_memory(_base, _noaccess_prefix, os::MEM_PROT_NONE,
   1.168 +                          _special)) {
   1.169 +    fatal("cannot protect protection page");
   1.170 +  }
   1.171 +
   1.172 +  _base += _noaccess_prefix;
   1.173 +  _size -= _noaccess_prefix;
   1.174 +  assert((size == _size) && ((uintptr_t)_base % _alignment == 0),
   1.175 +         "must be exactly of required size and alignment");
   1.176 +}
   1.177 +
   1.178 +ReservedHeapSpace::ReservedHeapSpace(size_t size, size_t alignment,
   1.179 +                                     bool large, char* requested_address) :
   1.180 +  ReservedSpace(size, alignment, large,
   1.181 +                requested_address,
   1.182 +                UseCompressedOops ? lcm(os::vm_page_size(), alignment) : 0) {
   1.183 +  // Only reserved space for the java heap should have a noaccess_prefix
   1.184 +  // if using compressed oops.
   1.185 +  protect_noaccess_prefix(size);
   1.186 +}
   1.187 +
   1.188 +ReservedHeapSpace::ReservedHeapSpace(const size_t prefix_size,
   1.189 +                                     const size_t prefix_align,
   1.190 +                                     const size_t suffix_size,
   1.191 +                                     const size_t suffix_align) :
   1.192 +  ReservedSpace(prefix_size, prefix_align, suffix_size, suffix_align,
   1.193 +                UseCompressedOops ? lcm(os::vm_page_size(), prefix_align) : 0) {
   1.194 +  protect_noaccess_prefix(prefix_size+suffix_size);
   1.195 +}
   1.196  
   1.197  // VirtualSpace
   1.198  
   1.199 @@ -348,6 +411,7 @@
   1.200    _lower_alignment        = 0;
   1.201    _middle_alignment       = 0;
   1.202    _upper_alignment        = 0;
   1.203 +  _special                = false;
   1.204  }
   1.205  
   1.206  
   1.207 @@ -402,7 +466,8 @@
   1.208  
   1.209  
   1.210  void VirtualSpace::release() {
   1.211 -  (void)os::release_memory(low_boundary(), reserved_size());
   1.212 +  // This does not release memory it never reserved.
   1.213 +  // Caller must release via rs.release();
   1.214    _low_boundary           = NULL;
   1.215    _high_boundary          = NULL;
   1.216    _low                    = NULL;

mercurial