hotspot/src/share/vm/runtime/virtualspace.cpp
changeset 2268 bea8be80ec88
parent 2254 f13dda645a4b
child 3261 c7d5aae8d3f7
equal deleted inserted replaced
2267:2e18a3d0155b 2268:bea8be80ec88
    26 #include "incls/_virtualspace.cpp.incl"
    26 #include "incls/_virtualspace.cpp.incl"
    27 
    27 
    28 
    28 
    29 // ReservedSpace
    29 // ReservedSpace
    30 ReservedSpace::ReservedSpace(size_t size) {
    30 ReservedSpace::ReservedSpace(size_t size) {
    31   initialize(size, 0, false, NULL, 0);
    31   initialize(size, 0, false, NULL, 0, false);
    32 }
    32 }
    33 
    33 
    34 ReservedSpace::ReservedSpace(size_t size, size_t alignment,
    34 ReservedSpace::ReservedSpace(size_t size, size_t alignment,
    35                              bool large,
    35                              bool large,
    36                              char* requested_address,
    36                              char* requested_address,
    37                              const size_t noaccess_prefix) {
    37                              const size_t noaccess_prefix) {
    38   initialize(size+noaccess_prefix, alignment, large, requested_address,
    38   initialize(size+noaccess_prefix, alignment, large, requested_address,
    39              noaccess_prefix);
    39              noaccess_prefix, false);
       
    40 }
       
    41 
       
    42 ReservedSpace::ReservedSpace(size_t size, size_t alignment,
       
    43                              bool large,
       
    44                              bool executable) {
       
    45   initialize(size, alignment, large, NULL, 0, executable);
    40 }
    46 }
    41 
    47 
    42 char *
    48 char *
    43 ReservedSpace::align_reserved_region(char* addr, const size_t len,
    49 ReservedSpace::align_reserved_region(char* addr, const size_t len,
    44                                      const size_t prefix_size,
    50                                      const size_t prefix_size,
   130   // On systems where the entire region has to be reserved and committed up
   136   // On systems where the entire region has to be reserved and committed up
   131   // front, the compound alignment normally done by this method is unnecessary.
   137   // front, the compound alignment normally done by this method is unnecessary.
   132   const bool try_reserve_special = UseLargePages &&
   138   const bool try_reserve_special = UseLargePages &&
   133     prefix_align == os::large_page_size();
   139     prefix_align == os::large_page_size();
   134   if (!os::can_commit_large_page_memory() && try_reserve_special) {
   140   if (!os::can_commit_large_page_memory() && try_reserve_special) {
   135     initialize(size, prefix_align, true, requested_address, noaccess_prefix);
   141     initialize(size, prefix_align, true, requested_address, noaccess_prefix,
       
   142                false);
   136     return;
   143     return;
   137   }
   144   }
   138 
   145 
   139   _base = NULL;
   146   _base = NULL;
   140   _size = 0;
   147   _size = 0;
   141   _alignment = 0;
   148   _alignment = 0;
   142   _special = false;
   149   _special = false;
   143   _noaccess_prefix = 0;
   150   _noaccess_prefix = 0;
       
   151   _executable = false;
   144 
   152 
   145   // Assert that if noaccess_prefix is used, it is the same as prefix_align.
   153   // Assert that if noaccess_prefix is used, it is the same as prefix_align.
   146   assert(noaccess_prefix == 0 ||
   154   assert(noaccess_prefix == 0 ||
   147          noaccess_prefix == prefix_align, "noaccess prefix wrong");
   155          noaccess_prefix == prefix_align, "noaccess prefix wrong");
   148 
   156 
   187   _noaccess_prefix = noaccess_prefix;
   195   _noaccess_prefix = noaccess_prefix;
   188 }
   196 }
   189 
   197 
   190 void ReservedSpace::initialize(size_t size, size_t alignment, bool large,
   198 void ReservedSpace::initialize(size_t size, size_t alignment, bool large,
   191                                char* requested_address,
   199                                char* requested_address,
   192                                const size_t noaccess_prefix) {
   200                                const size_t noaccess_prefix,
       
   201                                bool executable) {
   193   const size_t granularity = os::vm_allocation_granularity();
   202   const size_t granularity = os::vm_allocation_granularity();
   194   assert((size & granularity - 1) == 0,
   203   assert((size & granularity - 1) == 0,
   195          "size not aligned to os::vm_allocation_granularity()");
   204          "size not aligned to os::vm_allocation_granularity()");
   196   assert((alignment & granularity - 1) == 0,
   205   assert((alignment & granularity - 1) == 0,
   197          "alignment not aligned to os::vm_allocation_granularity()");
   206          "alignment not aligned to os::vm_allocation_granularity()");
   199          "not a power of 2");
   208          "not a power of 2");
   200 
   209 
   201   _base = NULL;
   210   _base = NULL;
   202   _size = 0;
   211   _size = 0;
   203   _special = false;
   212   _special = false;
       
   213   _executable = executable;
   204   _alignment = 0;
   214   _alignment = 0;
   205   _noaccess_prefix = 0;
   215   _noaccess_prefix = 0;
   206   if (size == 0) {
   216   if (size == 0) {
   207     return;
   217     return;
   208   }
   218   }
   212   bool special = large && !os::can_commit_large_page_memory();
   222   bool special = large && !os::can_commit_large_page_memory();
   213   char* base = NULL;
   223   char* base = NULL;
   214 
   224 
   215   if (special) {
   225   if (special) {
   216 
   226 
   217     base = os::reserve_memory_special(size, requested_address);
   227     base = os::reserve_memory_special(size, requested_address, executable);
   218 
   228 
   219     if (base != NULL) {
   229     if (base != NULL) {
   220       // Check alignment constraints
   230       // Check alignment constraints
   221       if (alignment > 0) {
   231       if (alignment > 0) {
   222         assert((uintptr_t) base % alignment == 0,
   232         assert((uintptr_t) base % alignment == 0,
   282          "area must be distinguisable from marks for mark-sweep");
   292          "area must be distinguisable from marks for mark-sweep");
   283 }
   293 }
   284 
   294 
   285 
   295 
   286 ReservedSpace::ReservedSpace(char* base, size_t size, size_t alignment,
   296 ReservedSpace::ReservedSpace(char* base, size_t size, size_t alignment,
   287                              bool special) {
   297                              bool special, bool executable) {
   288   assert((size % os::vm_allocation_granularity()) == 0,
   298   assert((size % os::vm_allocation_granularity()) == 0,
   289          "size not allocation aligned");
   299          "size not allocation aligned");
   290   _base = base;
   300   _base = base;
   291   _size = size;
   301   _size = size;
   292   _alignment = alignment;
   302   _alignment = alignment;
   293   _noaccess_prefix = 0;
   303   _noaccess_prefix = 0;
   294   _special = special;
   304   _special = special;
       
   305   _executable = executable;
   295 }
   306 }
   296 
   307 
   297 
   308 
   298 ReservedSpace ReservedSpace::first_part(size_t partition_size, size_t alignment,
   309 ReservedSpace ReservedSpace::first_part(size_t partition_size, size_t alignment,
   299                                         bool split, bool realloc) {
   310                                         bool split, bool realloc) {
   300   assert(partition_size <= size(), "partition failed");
   311   assert(partition_size <= size(), "partition failed");
   301   if (split) {
   312   if (split) {
   302     os::split_reserved_memory(_base, _size, partition_size, realloc);
   313     os::split_reserved_memory(base(), size(), partition_size, realloc);
   303   }
   314   }
   304   ReservedSpace result(base(), partition_size, alignment, special());
   315   ReservedSpace result(base(), partition_size, alignment, special(),
       
   316                        executable());
   305   return result;
   317   return result;
   306 }
   318 }
   307 
   319 
   308 
   320 
   309 ReservedSpace
   321 ReservedSpace
   310 ReservedSpace::last_part(size_t partition_size, size_t alignment) {
   322 ReservedSpace::last_part(size_t partition_size, size_t alignment) {
   311   assert(partition_size <= size(), "partition failed");
   323   assert(partition_size <= size(), "partition failed");
   312   ReservedSpace result(base() + partition_size, size() - partition_size,
   324   ReservedSpace result(base() + partition_size, size() - partition_size,
   313                        alignment, special());
   325                        alignment, special(), executable());
   314   return result;
   326   return result;
   315 }
   327 }
   316 
   328 
   317 
   329 
   318 size_t ReservedSpace::page_align_size_up(size_t size) {
   330 size_t ReservedSpace::page_align_size_up(size_t size) {
   346     }
   358     }
   347     _base = NULL;
   359     _base = NULL;
   348     _size = 0;
   360     _size = 0;
   349     _noaccess_prefix = 0;
   361     _noaccess_prefix = 0;
   350     _special = false;
   362     _special = false;
       
   363     _executable = false;
   351   }
   364   }
   352 }
   365 }
   353 
   366 
   354 void ReservedSpace::protect_noaccess_prefix(const size_t size) {
   367 void ReservedSpace::protect_noaccess_prefix(const size_t size) {
   355   // If there is noaccess prefix, return.
   368   // If there is noaccess prefix, return.
   392                 requested_address,
   405                 requested_address,
   393                 (UseCompressedOops && (Universe::narrow_oop_base() != NULL) &&
   406                 (UseCompressedOops && (Universe::narrow_oop_base() != NULL) &&
   394                  Universe::narrow_oop_use_implicit_null_checks()) ?
   407                  Universe::narrow_oop_use_implicit_null_checks()) ?
   395                   lcm(os::vm_page_size(), prefix_align) : 0) {
   408                   lcm(os::vm_page_size(), prefix_align) : 0) {
   396   protect_noaccess_prefix(prefix_size+suffix_size);
   409   protect_noaccess_prefix(prefix_size+suffix_size);
       
   410 }
       
   411 
       
   412 // Reserve space for code segment.  Same as Java heap only we mark this as
       
   413 // executable.
       
   414 ReservedCodeSpace::ReservedCodeSpace(size_t r_size,
       
   415                                      size_t rs_align,
       
   416                                      bool large) :
       
   417   ReservedSpace(r_size, rs_align, large, /*executable*/ true) {
   397 }
   418 }
   398 
   419 
   399 // VirtualSpace
   420 // VirtualSpace
   400 
   421 
   401 VirtualSpace::VirtualSpace() {
   422 VirtualSpace::VirtualSpace() {
   411   _upper_high_boundary    = NULL;
   432   _upper_high_boundary    = NULL;
   412   _lower_alignment        = 0;
   433   _lower_alignment        = 0;
   413   _middle_alignment       = 0;
   434   _middle_alignment       = 0;
   414   _upper_alignment        = 0;
   435   _upper_alignment        = 0;
   415   _special                = false;
   436   _special                = false;
       
   437   _executable             = false;
   416 }
   438 }
   417 
   439 
   418 
   440 
   419 bool VirtualSpace::initialize(ReservedSpace rs, size_t committed_size) {
   441 bool VirtualSpace::initialize(ReservedSpace rs, size_t committed_size) {
   420   if(!rs.is_reserved()) return false;  // allocation failed.
   442   if(!rs.is_reserved()) return false;  // allocation failed.
   424 
   446 
   425   _low = low_boundary();
   447   _low = low_boundary();
   426   _high = low();
   448   _high = low();
   427 
   449 
   428   _special = rs.special();
   450   _special = rs.special();
       
   451   _executable = rs.executable();
   429 
   452 
   430   // When a VirtualSpace begins life at a large size, make all future expansion
   453   // When a VirtualSpace begins life at a large size, make all future expansion
   431   // and shrinking occur aligned to a granularity of large pages.  This avoids
   454   // and shrinking occur aligned to a granularity of large pages.  This avoids
   432   // fragmentation of physical addresses that inhibits the use of large pages
   455   // fragmentation of physical addresses that inhibits the use of large pages
   433   // by the OS virtual memory system.  Empirically,  we see that with a 4MB
   456   // by the OS virtual memory system.  Empirically,  we see that with a 4MB
   481   _upper_high_boundary    = NULL;
   504   _upper_high_boundary    = NULL;
   482   _lower_alignment        = 0;
   505   _lower_alignment        = 0;
   483   _middle_alignment       = 0;
   506   _middle_alignment       = 0;
   484   _upper_alignment        = 0;
   507   _upper_alignment        = 0;
   485   _special                = false;
   508   _special                = false;
       
   509   _executable             = false;
   486 }
   510 }
   487 
   511 
   488 
   512 
   489 size_t VirtualSpace::committed_size() const {
   513 size_t VirtualSpace::committed_size() const {
   490   return pointer_delta(high(), low(), sizeof(char));
   514   return pointer_delta(high(), low(), sizeof(char));
   590   // Commit regions
   614   // Commit regions
   591   if (lower_needs > 0) {
   615   if (lower_needs > 0) {
   592     assert(low_boundary() <= lower_high() &&
   616     assert(low_boundary() <= lower_high() &&
   593            lower_high() + lower_needs <= lower_high_boundary(),
   617            lower_high() + lower_needs <= lower_high_boundary(),
   594            "must not expand beyond region");
   618            "must not expand beyond region");
   595     if (!os::commit_memory(lower_high(), lower_needs)) {
   619     if (!os::commit_memory(lower_high(), lower_needs, _executable)) {
   596       debug_only(warning("os::commit_memory failed"));
   620       debug_only(warning("os::commit_memory failed"));
   597       return false;
   621       return false;
   598     } else {
   622     } else {
   599       _lower_high += lower_needs;
   623       _lower_high += lower_needs;
   600      }
   624      }
   601   }
   625   }
   602   if (middle_needs > 0) {
   626   if (middle_needs > 0) {
   603     assert(lower_high_boundary() <= middle_high() &&
   627     assert(lower_high_boundary() <= middle_high() &&
   604            middle_high() + middle_needs <= middle_high_boundary(),
   628            middle_high() + middle_needs <= middle_high_boundary(),
   605            "must not expand beyond region");
   629            "must not expand beyond region");
   606     if (!os::commit_memory(middle_high(), middle_needs, middle_alignment())) {
   630     if (!os::commit_memory(middle_high(), middle_needs, middle_alignment(),
       
   631                            _executable)) {
   607       debug_only(warning("os::commit_memory failed"));
   632       debug_only(warning("os::commit_memory failed"));
   608       return false;
   633       return false;
   609     }
   634     }
   610     _middle_high += middle_needs;
   635     _middle_high += middle_needs;
   611   }
   636   }
   612   if (upper_needs > 0) {
   637   if (upper_needs > 0) {
   613     assert(middle_high_boundary() <= upper_high() &&
   638     assert(middle_high_boundary() <= upper_high() &&
   614            upper_high() + upper_needs <= upper_high_boundary(),
   639            upper_high() + upper_needs <= upper_high_boundary(),
   615            "must not expand beyond region");
   640            "must not expand beyond region");
   616     if (!os::commit_memory(upper_high(), upper_needs)) {
   641     if (!os::commit_memory(upper_high(), upper_needs, _executable)) {
   617       debug_only(warning("os::commit_memory failed"));
   642       debug_only(warning("os::commit_memory failed"));
   618       return false;
   643       return false;
   619     } else {
   644     } else {
   620       _upper_high += upper_needs;
   645       _upper_high += upper_needs;
   621     }
   646     }