8049864: TestParallelHeapSizeFlags fails with unexpected heap size

Tue, 24 Jun 2014 15:50:50 +0200

author
ehelin
date
Tue, 24 Jun 2014 15:50:50 +0200
changeset 7778
c2ce24504334
parent 7777
340ca8812af9
child 7779
cc5c3ef1f03a

8049864: TestParallelHeapSizeFlags fails with unexpected heap size
Reviewed-by: sjohanss, jmasa

src/share/vm/gc_implementation/parallelScavenge/generationSizer.cpp file | annotate | diff | comparison | revisions
src/share/vm/gc_implementation/parallelScavenge/parMarkBitMap.cpp file | annotate | diff | comparison | revisions
src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp file | annotate | diff | comparison | revisions
src/share/vm/memory/heap.cpp file | annotate | diff | comparison | revisions
src/share/vm/prims/jni.cpp file | annotate | diff | comparison | revisions
src/share/vm/runtime/os.cpp file | annotate | diff | comparison | revisions
src/share/vm/runtime/os.hpp file | annotate | diff | comparison | revisions
src/share/vm/runtime/virtualspace.cpp file | annotate | diff | comparison | revisions
     1.1 --- a/src/share/vm/gc_implementation/parallelScavenge/generationSizer.cpp	Thu Dec 18 09:37:02 2014 +0100
     1.2 +++ b/src/share/vm/gc_implementation/parallelScavenge/generationSizer.cpp	Tue Jun 24 15:50:50 2014 +0200
     1.3 @@ -66,9 +66,10 @@
     1.4  
     1.5  void GenerationSizer::initialize_size_info() {
     1.6    trace_gen_sizes("ps heap raw");
     1.7 -  const size_t page_sz = os::page_size_for_region(_min_heap_byte_size,
     1.8 -                                                  _max_heap_byte_size,
     1.9 -                                                  8);
    1.10 +  const size_t max_page_sz = os::page_size_for_region(_max_heap_byte_size, 8);
    1.11 +  const size_t min_pages = 4; // 1 for eden + 1 for each survivor + 1 for old
    1.12 +  const size_t min_page_sz = os::page_size_for_region(_min_heap_byte_size, min_pages);
    1.13 +  const size_t page_sz = MIN2(max_page_sz, min_page_sz);
    1.14  
    1.15    // Can a page size be something else than a power of two?
    1.16    assert(is_power_of_2((intptr_t)page_sz), "must be a power of 2");
     2.1 --- a/src/share/vm/gc_implementation/parallelScavenge/parMarkBitMap.cpp	Thu Dec 18 09:37:02 2014 +0100
     2.2 +++ b/src/share/vm/gc_implementation/parallelScavenge/parMarkBitMap.cpp	Tue Jun 24 15:50:50 2014 +0200
     2.3 @@ -55,7 +55,7 @@
     2.4  
     2.5    const size_t words = bits / BitsPerWord;
     2.6    const size_t raw_bytes = words * sizeof(idx_t);
     2.7 -  const size_t page_sz = os::page_size_for_region(raw_bytes, raw_bytes, 10);
     2.8 +  const size_t page_sz = os::page_size_for_region(raw_bytes, 10);
     2.9    const size_t granularity = os::vm_allocation_granularity();
    2.10    _reserved_byte_size = align_size_up(raw_bytes, MAX2(page_sz, granularity));
    2.11  
     3.1 --- a/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp	Thu Dec 18 09:37:02 2014 +0100
     3.2 +++ b/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp	Tue Jun 24 15:50:50 2014 +0200
     3.3 @@ -401,7 +401,7 @@
     3.4  ParallelCompactData::create_vspace(size_t count, size_t element_size)
     3.5  {
     3.6    const size_t raw_bytes = count * element_size;
     3.7 -  const size_t page_sz = os::page_size_for_region(raw_bytes, raw_bytes, 10);
     3.8 +  const size_t page_sz = os::page_size_for_region(raw_bytes, 10);
     3.9    const size_t granularity = os::vm_allocation_granularity();
    3.10    _reserved_byte_size = align_size_up(raw_bytes, MAX2(page_sz, granularity));
    3.11  
     4.1 --- a/src/share/vm/memory/heap.cpp	Thu Dec 18 09:37:02 2014 +0100
     4.2 +++ b/src/share/vm/memory/heap.cpp	Tue Jun 24 15:50:50 2014 +0200
     4.3 @@ -97,9 +97,13 @@
     4.4    _log2_segment_size = exact_log2(segment_size);
     4.5  
     4.6    // Reserve and initialize space for _memory.
     4.7 -  const size_t page_size = os::can_execute_large_page_memory() ?
     4.8 -          os::page_size_for_region(committed_size, reserved_size, 8) :
     4.9 -          os::vm_page_size();
    4.10 +  size_t page_size = os::vm_page_size();
    4.11 +  if (os::can_execute_large_page_memory()) {
    4.12 +    const size_t min_pages = 8;
    4.13 +    page_size = MIN2(os::page_size_for_region(committed_size, min_pages),
    4.14 +                     os::page_size_for_region(reserved_size, min_pages));
    4.15 +  }
    4.16 +
    4.17    const size_t granularity = os::vm_allocation_granularity();
    4.18    const size_t r_align = MAX2(page_size, granularity);
    4.19    const size_t r_size = align_size_up(reserved_size, r_align);
     5.1 --- a/src/share/vm/prims/jni.cpp	Thu Dec 18 09:37:02 2014 +0100
     5.2 +++ b/src/share/vm/prims/jni.cpp	Tue Jun 24 15:50:50 2014 +0200
     5.3 @@ -5071,6 +5071,7 @@
     5.4    unit_test_function_call
     5.5  
     5.6  // Forward declaration
     5.7 +void TestOS_test();
     5.8  void TestReservedSpace_test();
     5.9  void TestReserveMemorySpecial_test();
    5.10  void TestVirtualSpace_test();
    5.11 @@ -5092,6 +5093,7 @@
    5.12  void execute_internal_vm_tests() {
    5.13    if (ExecuteInternalVMTests) {
    5.14      tty->print_cr("Running internal VM tests");
    5.15 +    run_unit_test(TestOS_test());
    5.16      run_unit_test(TestReservedSpace_test());
    5.17      run_unit_test(TestReserveMemorySpecial_test());
    5.18      run_unit_test(TestVirtualSpace_test());
     6.1 --- a/src/share/vm/runtime/os.cpp	Thu Dec 18 09:37:02 2014 +0100
     6.2 +++ b/src/share/vm/runtime/os.cpp	Tue Jun 24 15:50:50 2014 +0200
     6.3 @@ -1315,24 +1315,15 @@
     6.4    return (sp > (stack_limit + reserved_area));
     6.5  }
     6.6  
     6.7 -size_t os::page_size_for_region(size_t region_min_size, size_t region_max_size,
     6.8 -                                uint min_pages)
     6.9 -{
    6.10 +size_t os::page_size_for_region(size_t region_size, size_t min_pages) {
    6.11    assert(min_pages > 0, "sanity");
    6.12    if (UseLargePages) {
    6.13 -    const size_t max_page_size = region_max_size / min_pages;
    6.14 +    const size_t max_page_size = region_size / min_pages;
    6.15  
    6.16 -    for (unsigned int i = 0; _page_sizes[i] != 0; ++i) {
    6.17 -      const size_t sz = _page_sizes[i];
    6.18 -      const size_t mask = sz - 1;
    6.19 -      if ((region_min_size & mask) == 0 && (region_max_size & mask) == 0) {
    6.20 -        // The largest page size with no fragmentation.
    6.21 -        return sz;
    6.22 -      }
    6.23 -
    6.24 -      if (sz <= max_page_size) {
    6.25 -        // The largest page size that satisfies the min_pages requirement.
    6.26 -        return sz;
    6.27 +    for (size_t i = 0; _page_sizes[i] != 0; ++i) {
    6.28 +      const size_t page_size = _page_sizes[i];
    6.29 +      if (page_size <= max_page_size && is_size_aligned(region_size, page_size)) {
    6.30 +        return page_size;
    6.31        }
    6.32      }
    6.33    }
    6.34 @@ -1574,3 +1565,63 @@
    6.35    return result;
    6.36  }
    6.37  #endif
    6.38 +
    6.39 +/////////////// Unit tests ///////////////
    6.40 +
    6.41 +#ifndef PRODUCT
    6.42 +
    6.43 +#define assert_eq(a,b) assert(a == b, err_msg(SIZE_FORMAT " != " SIZE_FORMAT, a, b))
    6.44 +
    6.45 +class TestOS : AllStatic {
    6.46 +  static size_t small_page_size() {
    6.47 +    return os::vm_page_size();
    6.48 +  }
    6.49 +
    6.50 +  static size_t large_page_size() {
    6.51 +    const size_t large_page_size_example = 4 * M;
    6.52 +    return os::page_size_for_region(large_page_size_example, 1);
    6.53 +  }
    6.54 +
    6.55 +  static void test_page_size_for_region() {
    6.56 +    if (UseLargePages) {
    6.57 +      const size_t small_page = small_page_size();
    6.58 +      const size_t large_page = large_page_size();
    6.59 +
    6.60 +      if (large_page > small_page) {
    6.61 +        size_t num_small_pages_in_large = large_page / small_page;
    6.62 +        size_t page = os::page_size_for_region(large_page, num_small_pages_in_large);
    6.63 +
    6.64 +        assert_eq(page, small_page);
    6.65 +      }
    6.66 +    }
    6.67 +  }
    6.68 +
    6.69 +  static void test_page_size_for_region_alignment() {
    6.70 +    if (UseLargePages) {
    6.71 +      const size_t small_page = small_page_size();
    6.72 +      const size_t large_page = large_page_size();
    6.73 +      if (large_page > small_page) {
    6.74 +        const size_t unaligned_region = large_page + 17;
    6.75 +        size_t page = os::page_size_for_region(unaligned_region, 1);
    6.76 +        assert_eq(page, small_page);
    6.77 +
    6.78 +        const size_t num_pages = 5;
    6.79 +        const size_t aligned_region = large_page * num_pages;
    6.80 +        page = os::page_size_for_region(aligned_region, num_pages);
    6.81 +        assert_eq(page, large_page);
    6.82 +      }
    6.83 +    }
    6.84 +  }
    6.85 +
    6.86 + public:
    6.87 +  static void run_tests() {
    6.88 +    test_page_size_for_region();
    6.89 +    test_page_size_for_region_alignment();
    6.90 +  }
    6.91 +};
    6.92 +
    6.93 +void TestOS_test() {
    6.94 +  TestOS::run_tests();
    6.95 +}
    6.96 +
    6.97 +#endif // PRODUCT
     7.1 --- a/src/share/vm/runtime/os.hpp	Thu Dec 18 09:37:02 2014 +0100
     7.2 +++ b/src/share/vm/runtime/os.hpp	Tue Jun 24 15:50:50 2014 +0200
     7.3 @@ -265,19 +265,11 @@
     7.4    // Return the default page size.
     7.5    static int    vm_page_size();
     7.6  
     7.7 -  // Return the page size to use for a region of memory.  The min_pages argument
     7.8 -  // is a hint intended to limit fragmentation; it says the returned page size
     7.9 -  // should be <= region_max_size / min_pages.  Because min_pages is a hint,
    7.10 -  // this routine may return a size larger than region_max_size / min_pages.
    7.11 -  //
    7.12 -  // The current implementation ignores min_pages if a larger page size is an
    7.13 -  // exact multiple of both region_min_size and region_max_size.  This allows
    7.14 -  // larger pages to be used when doing so would not cause fragmentation; in
    7.15 -  // particular, a single page can be used when region_min_size ==
    7.16 -  // region_max_size == a supported page size.
    7.17 -  static size_t page_size_for_region(size_t region_min_size,
    7.18 -                                     size_t region_max_size,
    7.19 -                                     uint min_pages);
    7.20 +  // Returns the page size to use for a region of memory.
    7.21 +  // region_size / min_pages will always be greater than or equal to the
    7.22 +  // returned value.
    7.23 +  static size_t page_size_for_region(size_t region_size, size_t min_pages);
    7.24 +
    7.25    // Return the largest page size that can be used
    7.26    static size_t max_page_size() {
    7.27      // The _page_sizes array is sorted in descending order.
     8.1 --- a/src/share/vm/runtime/virtualspace.cpp	Thu Dec 18 09:37:02 2014 +0100
     8.2 +++ b/src/share/vm/runtime/virtualspace.cpp	Tue Jun 24 15:50:50 2014 +0200
     8.3 @@ -53,7 +53,7 @@
     8.4  }
     8.5  
     8.6  ReservedSpace::ReservedSpace(size_t size) {
     8.7 -  size_t page_size = os::page_size_for_region(size, size, 1);
     8.8 +  size_t page_size = os::page_size_for_region(size, 1);
     8.9    bool large_pages = page_size != (size_t)os::vm_page_size();
    8.10    // Don't force the alignment to be large page aligned,
    8.11    // since that will waste memory.
    8.12 @@ -372,7 +372,7 @@
    8.13  
    8.14  
    8.15  bool VirtualSpace::initialize(ReservedSpace rs, size_t committed_size) {
    8.16 -  const size_t max_commit_granularity = os::page_size_for_region(rs.size(), rs.size(), 1);
    8.17 +  const size_t max_commit_granularity = os::page_size_for_region(rs.size(), 1);
    8.18    return initialize_with_granularity(rs, committed_size, max_commit_granularity);
    8.19  }
    8.20  
    8.21 @@ -995,7 +995,7 @@
    8.22      case Disable:
    8.23        return vs.initialize_with_granularity(rs, 0, os::vm_page_size());
    8.24      case Commit:
    8.25 -      return vs.initialize_with_granularity(rs, 0, os::page_size_for_region(rs.size(), rs.size(), 1));
    8.26 +      return vs.initialize_with_granularity(rs, 0, os::page_size_for_region(rs.size(), 1));
    8.27      }
    8.28    }
    8.29  

mercurial