Tue, 24 Jun 2014 15:50:50 +0200
8049864: TestParallelHeapSizeFlags fails with unexpected heap size
Reviewed-by: sjohanss, jmasa
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