8066875: VirtualSpace does not use large pages

Fri, 16 Jan 2015 10:29:12 +0100

author
ehelin
date
Fri, 16 Jan 2015 10:29:12 +0100
changeset 7780
5788dbd1f2d6
parent 7779
cc5c3ef1f03a
child 7781
33e421924c67

8066875: VirtualSpace does not use large pages
Reviewed-by: stefank, tschatzl, anoll, thartmann

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/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	Wed Nov 26 10:32:21 2014 -0800
     1.2 +++ b/src/share/vm/gc_implementation/parallelScavenge/generationSizer.cpp	Fri Jan 16 10:29:12 2015 +0100
     1.3 @@ -66,9 +66,9 @@
     1.4  
     1.5  void GenerationSizer::initialize_size_info() {
     1.6    trace_gen_sizes("ps heap raw");
     1.7 -  const size_t max_page_sz = os::page_size_for_region(_max_heap_byte_size, 8);
     1.8 +  const size_t max_page_sz = os::page_size_for_region_aligned(_max_heap_byte_size, 8);
     1.9    const size_t min_pages = 4; // 1 for eden + 1 for each survivor + 1 for old
    1.10 -  const size_t min_page_sz = os::page_size_for_region(_min_heap_byte_size, min_pages);
    1.11 +  const size_t min_page_sz = os::page_size_for_region_aligned(_min_heap_byte_size, min_pages);
    1.12    const size_t page_sz = MIN2(max_page_sz, min_page_sz);
    1.13  
    1.14    // Can a page size be something else than a power of two?
     2.1 --- a/src/share/vm/gc_implementation/parallelScavenge/parMarkBitMap.cpp	Wed Nov 26 10:32:21 2014 -0800
     2.2 +++ b/src/share/vm/gc_implementation/parallelScavenge/parMarkBitMap.cpp	Fri Jan 16 10:29:12 2015 +0100
     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, 10);
     2.8 +  const size_t page_sz = os::page_size_for_region_aligned(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	Wed Nov 26 10:32:21 2014 -0800
     3.2 +++ b/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp	Fri Jan 16 10:29:12 2015 +0100
     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, 10);
     3.8 +  const size_t page_sz = os::page_size_for_region_aligned(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	Wed Nov 26 10:32:21 2014 -0800
     4.2 +++ b/src/share/vm/memory/heap.cpp	Fri Jan 16 10:29:12 2015 +0100
     4.3 @@ -100,8 +100,8 @@
     4.4    size_t page_size = os::vm_page_size();
     4.5    if (os::can_execute_large_page_memory()) {
     4.6      const size_t min_pages = 8;
     4.7 -    page_size = MIN2(os::page_size_for_region(committed_size, min_pages),
     4.8 -                     os::page_size_for_region(reserved_size, min_pages));
     4.9 +    page_size = MIN2(os::page_size_for_region_aligned(committed_size, min_pages),
    4.10 +                     os::page_size_for_region_aligned(reserved_size, min_pages));
    4.11    }
    4.12  
    4.13    const size_t granularity = os::vm_allocation_granularity();
     5.1 --- a/src/share/vm/runtime/os.cpp	Wed Nov 26 10:32:21 2014 -0800
     5.2 +++ b/src/share/vm/runtime/os.cpp	Fri Jan 16 10:29:12 2015 +0100
     5.3 @@ -1315,15 +1315,17 @@
     5.4    return (sp > (stack_limit + reserved_area));
     5.5  }
     5.6  
     5.7 -size_t os::page_size_for_region(size_t region_size, size_t min_pages) {
     5.8 +size_t os::page_size_for_region(size_t region_size, size_t min_pages, bool must_be_aligned) {
     5.9    assert(min_pages > 0, "sanity");
    5.10    if (UseLargePages) {
    5.11      const size_t max_page_size = region_size / min_pages;
    5.12  
    5.13      for (size_t i = 0; _page_sizes[i] != 0; ++i) {
    5.14        const size_t page_size = _page_sizes[i];
    5.15 -      if (page_size <= max_page_size && is_size_aligned(region_size, page_size)) {
    5.16 -        return page_size;
    5.17 +      if (page_size <= max_page_size) {
    5.18 +        if (!must_be_aligned || is_size_aligned(region_size, page_size)) {
    5.19 +          return page_size;
    5.20 +        }
    5.21        }
    5.22      }
    5.23    }
    5.24 @@ -1331,6 +1333,14 @@
    5.25    return vm_page_size();
    5.26  }
    5.27  
    5.28 +size_t os::page_size_for_region_aligned(size_t region_size, size_t min_pages) {
    5.29 +  return page_size_for_region(region_size, min_pages, true);
    5.30 +}
    5.31 +
    5.32 +size_t os::page_size_for_region_unaligned(size_t region_size, size_t min_pages) {
    5.33 +  return page_size_for_region(region_size, min_pages, false);
    5.34 +}
    5.35 +
    5.36  #ifndef PRODUCT
    5.37  void os::trace_page_sizes(const char* str, const size_t* page_sizes, int count)
    5.38  {
    5.39 @@ -1579,17 +1589,17 @@
    5.40  
    5.41    static size_t large_page_size() {
    5.42      const size_t large_page_size_example = 4 * M;
    5.43 -    return os::page_size_for_region(large_page_size_example, 1);
    5.44 +    return os::page_size_for_region_aligned(large_page_size_example, 1);
    5.45    }
    5.46  
    5.47 -  static void test_page_size_for_region() {
    5.48 +  static void test_page_size_for_region_aligned() {
    5.49      if (UseLargePages) {
    5.50        const size_t small_page = small_page_size();
    5.51        const size_t large_page = large_page_size();
    5.52  
    5.53        if (large_page > small_page) {
    5.54          size_t num_small_pages_in_large = large_page / small_page;
    5.55 -        size_t page = os::page_size_for_region(large_page, num_small_pages_in_large);
    5.56 +        size_t page = os::page_size_for_region_aligned(large_page, num_small_pages_in_large);
    5.57  
    5.58          assert_eq(page, small_page);
    5.59        }
    5.60 @@ -1602,21 +1612,53 @@
    5.61        const size_t large_page = large_page_size();
    5.62        if (large_page > small_page) {
    5.63          const size_t unaligned_region = large_page + 17;
    5.64 -        size_t page = os::page_size_for_region(unaligned_region, 1);
    5.65 +        size_t page = os::page_size_for_region_aligned(unaligned_region, 1);
    5.66          assert_eq(page, small_page);
    5.67  
    5.68          const size_t num_pages = 5;
    5.69          const size_t aligned_region = large_page * num_pages;
    5.70 -        page = os::page_size_for_region(aligned_region, num_pages);
    5.71 +        page = os::page_size_for_region_aligned(aligned_region, num_pages);
    5.72          assert_eq(page, large_page);
    5.73        }
    5.74      }
    5.75    }
    5.76  
    5.77 +  static void test_page_size_for_region_unaligned() {
    5.78 +    if (UseLargePages) {
    5.79 +      // Given exact page size, should return that page size.
    5.80 +      for (size_t i = 0; os::_page_sizes[i] != 0; i++) {
    5.81 +        size_t expected = os::_page_sizes[i];
    5.82 +        size_t actual = os::page_size_for_region_unaligned(expected, 1);
    5.83 +        assert_eq(expected, actual);
    5.84 +      }
    5.85 +
    5.86 +      // Given slightly larger size than a page size, return the page size.
    5.87 +      for (size_t i = 0; os::_page_sizes[i] != 0; i++) {
    5.88 +        size_t expected = os::_page_sizes[i];
    5.89 +        size_t actual = os::page_size_for_region_unaligned(expected + 17, 1);
    5.90 +        assert_eq(expected, actual);
    5.91 +      }
    5.92 +
    5.93 +      // Given a slightly smaller size than a page size,
    5.94 +      // return the next smaller page size.
    5.95 +      if (os::_page_sizes[1] > os::_page_sizes[0]) {
    5.96 +        size_t expected = os::_page_sizes[0];
    5.97 +        size_t actual = os::page_size_for_region_unaligned(os::_page_sizes[1] - 17, 1);
    5.98 +        assert_eq(actual, expected);
    5.99 +      }
   5.100 +
   5.101 +      // Return small page size for values less than a small page.
   5.102 +      size_t small_page = small_page_size();
   5.103 +      size_t actual = os::page_size_for_region_unaligned(small_page - 17, 1);
   5.104 +      assert_eq(small_page, actual);
   5.105 +    }
   5.106 +  }
   5.107 +
   5.108   public:
   5.109    static void run_tests() {
   5.110 -    test_page_size_for_region();
   5.111 +    test_page_size_for_region_aligned();
   5.112      test_page_size_for_region_alignment();
   5.113 +    test_page_size_for_region_unaligned();
   5.114    }
   5.115  };
   5.116  
     6.1 --- a/src/share/vm/runtime/os.hpp	Wed Nov 26 10:32:21 2014 -0800
     6.2 +++ b/src/share/vm/runtime/os.hpp	Fri Jan 16 10:29:12 2015 +0100
     6.3 @@ -149,6 +149,7 @@
     6.4    static void   pd_free_memory(char *addr, size_t bytes, size_t alignment_hint);
     6.5    static void   pd_realign_memory(char *addr, size_t bytes, size_t alignment_hint);
     6.6  
     6.7 +  static size_t page_size_for_region(size_t region_size, size_t min_pages, bool must_be_aligned);
     6.8  
     6.9   public:
    6.10    static void init(void);                      // Called before command line parsing
    6.11 @@ -267,8 +268,13 @@
    6.12  
    6.13    // Returns the page size to use for a region of memory.
    6.14    // region_size / min_pages will always be greater than or equal to the
    6.15 -  // returned value.
    6.16 -  static size_t page_size_for_region(size_t region_size, size_t min_pages);
    6.17 +  // returned value. The returned value will divide region_size.
    6.18 +  static size_t page_size_for_region_aligned(size_t region_size, size_t min_pages);
    6.19 +
    6.20 +  // Returns the page size to use for a region of memory.
    6.21 +  // region_size / min_pages will always be greater than or equal to the
    6.22 +  // returned value. The returned value might not divide region_size.
    6.23 +  static size_t page_size_for_region_unaligned(size_t region_size, size_t min_pages);
    6.24  
    6.25    // Return the largest page size that can be used
    6.26    static size_t max_page_size() {
     7.1 --- a/src/share/vm/runtime/virtualspace.cpp	Wed Nov 26 10:32:21 2014 -0800
     7.2 +++ b/src/share/vm/runtime/virtualspace.cpp	Fri Jan 16 10:29:12 2015 +0100
     7.3 @@ -53,7 +53,8 @@
     7.4  }
     7.5  
     7.6  ReservedSpace::ReservedSpace(size_t size) {
     7.7 -  size_t page_size = os::page_size_for_region(size, 1);
     7.8 +  // Want to use large pages where possible and pad with small pages.
     7.9 +  size_t page_size = os::page_size_for_region_unaligned(size, 1);
    7.10    bool large_pages = page_size != (size_t)os::vm_page_size();
    7.11    // Don't force the alignment to be large page aligned,
    7.12    // since that will waste memory.
    7.13 @@ -372,7 +373,7 @@
    7.14  
    7.15  
    7.16  bool VirtualSpace::initialize(ReservedSpace rs, size_t committed_size) {
    7.17 -  const size_t max_commit_granularity = os::page_size_for_region(rs.size(), 1);
    7.18 +  const size_t max_commit_granularity = os::page_size_for_region_unaligned(rs.size(), 1);
    7.19    return initialize_with_granularity(rs, committed_size, max_commit_granularity);
    7.20  }
    7.21  
    7.22 @@ -995,7 +996,7 @@
    7.23      case Disable:
    7.24        return vs.initialize_with_granularity(rs, 0, os::vm_page_size());
    7.25      case Commit:
    7.26 -      return vs.initialize_with_granularity(rs, 0, os::page_size_for_region(rs.size(), 1));
    7.27 +      return vs.initialize_with_granularity(rs, 0, os::page_size_for_region_unaligned(rs.size(), 1));
    7.28      }
    7.29    }
    7.30  

mercurial