--- old/src/share/vm/gc_implementation/parallelScavenge/generationSizer.cpp 2014-07-01 16:47:47.970009390 +0200 +++ new/src/share/vm/gc_implementation/parallelScavenge/generationSizer.cpp 2014-07-01 16:47:47.886009391 +0200 @@ -66,10 +66,9 @@ void GenerationSizer::initialize_size_info() { trace_gen_sizes("ps heap raw"); - const size_t max_page_sz = os::page_size_for_region(_max_heap_byte_size, 8); - const size_t min_pages = 4; // 1 for eden + 1 for each survivor + 1 for old - const size_t min_page_sz = os::page_size_for_region(_min_heap_byte_size, min_pages); - const size_t page_sz = MIN2(max_page_sz, min_page_sz); + const size_t page_sz = os::page_size_for_region(_min_heap_byte_size, + _max_heap_byte_size, + 8); // Can a page size be something else than a power of two? assert(is_power_of_2((intptr_t)page_sz), "must be a power of 2"); --- old/src/share/vm/gc_implementation/parallelScavenge/parMarkBitMap.cpp 2014-07-01 16:47:48.434009389 +0200 +++ new/src/share/vm/gc_implementation/parallelScavenge/parMarkBitMap.cpp 2014-07-01 16:47:48.354009389 +0200 @@ -56,7 +56,7 @@ const size_t words = bits / BitsPerWord; const size_t raw_bytes = words * sizeof(idx_t); - const size_t page_sz = os::page_size_for_region(raw_bytes, 10); + const size_t page_sz = os::page_size_for_region(raw_bytes, raw_bytes, 10); const size_t granularity = os::vm_allocation_granularity(); _reserved_byte_size = align_size_up(raw_bytes, MAX2(page_sz, granularity)); --- old/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp 2014-07-01 16:47:48.882009388 +0200 +++ new/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp 2014-07-01 16:47:48.794009388 +0200 @@ -403,7 +403,7 @@ ParallelCompactData::create_vspace(size_t count, size_t element_size) { const size_t raw_bytes = count * element_size; - const size_t page_sz = os::page_size_for_region(raw_bytes, 10); + const size_t page_sz = os::page_size_for_region(raw_bytes, raw_bytes, 10); const size_t granularity = os::vm_allocation_granularity(); _reserved_byte_size = align_size_up(raw_bytes, MAX2(page_sz, granularity)); --- old/src/share/vm/memory/heap.cpp 2014-07-01 16:47:49.314009387 +0200 +++ new/src/share/vm/memory/heap.cpp 2014-07-01 16:47:49.230009387 +0200 @@ -98,13 +98,9 @@ _log2_segment_size = exact_log2(segment_size); // Reserve and initialize space for _memory. - size_t page_size = os::vm_page_size(); - if (os::can_execute_large_page_memory()) { - const size_t min_pages = 8; - page_size = MIN2(os::page_size_for_region(committed_size, min_pages), - os::page_size_for_region(reserved_size, min_pages)); - } - + const size_t page_size = os::can_execute_large_page_memory() ? + os::page_size_for_region(committed_size, reserved_size, 8) : + os::vm_page_size(); const size_t granularity = os::vm_allocation_granularity(); const size_t r_align = MAX2(page_size, granularity); const size_t r_size = align_size_up(reserved_size, r_align); --- old/src/share/vm/prims/jni.cpp 2014-07-01 16:47:49.778009385 +0200 +++ new/src/share/vm/prims/jni.cpp 2014-07-01 16:47:49.694009386 +0200 @@ -3871,7 +3871,6 @@ unit_test_function_call // Forward declaration -void TestOS_test(); void TestReservedSpace_test(); void TestReserveMemorySpecial_test(); void TestVirtualSpace_test(); @@ -3893,7 +3892,6 @@ void execute_internal_vm_tests() { if (ExecuteInternalVMTests) { tty->print_cr("Running internal VM tests"); - run_unit_test(TestOS_test()); run_unit_test(TestReservedSpace_test()); run_unit_test(TestReserveMemorySpecial_test()); run_unit_test(TestVirtualSpace_test()); --- old/src/share/vm/runtime/os.cpp 2014-07-01 16:47:50.250009384 +0200 +++ new/src/share/vm/runtime/os.cpp 2014-07-01 16:47:50.174009384 +0200 @@ -1303,15 +1303,24 @@ return (sp > (stack_limit + reserved_area)); } -size_t os::page_size_for_region(size_t region_size, size_t min_pages) { +size_t os::page_size_for_region(size_t region_min_size, size_t region_max_size, + uint min_pages) +{ assert(min_pages > 0, "sanity"); if (UseLargePages) { - const size_t max_page_size = region_size / min_pages; + const size_t max_page_size = region_max_size / min_pages; + + for (unsigned int i = 0; _page_sizes[i] != 0; ++i) { + const size_t sz = _page_sizes[i]; + const size_t mask = sz - 1; + if ((region_min_size & mask) == 0 && (region_max_size & mask) == 0) { + // The largest page size with no fragmentation. + return sz; + } - for (size_t i = 0; _page_sizes[i] != 0; ++i) { - const size_t page_size = _page_sizes[i]; - if (page_size <= max_page_size && is_size_aligned(region_size, page_size)) { - return page_size; + if (sz <= max_page_size) { + // The largest page size that satisfies the min_pages requirement. + return sz; } } } @@ -1539,63 +1548,3 @@ return result; } #endif - -/////////////// Unit tests /////////////// - -#ifndef PRODUCT - -#define assert_eq(a,b) assert(a == b, err_msg(SIZE_FORMAT " != " SIZE_FORMAT, a, b)) - -class TestOS : AllStatic { - static size_t small_page_size() { - return os::vm_page_size(); - } - - static size_t large_page_size() { - const size_t large_page_size_example = 4 * M; - return os::page_size_for_region(large_page_size_example, 1); - } - - static void test_page_size_for_region() { - if (UseLargePages) { - const size_t small_page = small_page_size(); - const size_t large_page = large_page_size(); - - if (large_page > small_page) { - size_t num_small_pages_in_large = large_page / small_page; - size_t page = os::page_size_for_region(large_page, num_small_pages_in_large); - - assert_eq(page, small_page); - } - } - } - - static void test_page_size_for_region_alignment() { - if (UseLargePages) { - const size_t small_page = small_page_size(); - const size_t large_page = large_page_size(); - if (large_page > small_page) { - const size_t unaligned_region = large_page + 17; - size_t page = os::page_size_for_region(unaligned_region, 1); - assert_eq(page, small_page); - - const size_t num_pages = 5; - const size_t aligned_region = large_page * num_pages; - page = os::page_size_for_region(aligned_region, num_pages); - assert_eq(page, large_page); - } - } - } - - public: - static void run_tests() { - test_page_size_for_region(); - test_page_size_for_region_alignment(); - } -}; - -void TestOS_test() { - TestOS::run_tests(); -} - -#endif // PRODUCT --- old/src/share/vm/runtime/os.hpp 2014-07-01 16:47:50.690009383 +0200 +++ new/src/share/vm/runtime/os.hpp 2014-07-01 16:47:50.602009383 +0200 @@ -253,11 +253,19 @@ // Return the default page size. static int vm_page_size(); - // Returns the page size to use for a region of memory. - // region_size / min_pages will always be greater than or equal to the - // returned value. - static size_t page_size_for_region(size_t region_size, size_t min_pages); - + // Return the page size to use for a region of memory. The min_pages argument + // is a hint intended to limit fragmentation; it says the returned page size + // should be <= region_max_size / min_pages. Because min_pages is a hint, + // this routine may return a size larger than region_max_size / min_pages. + // + // The current implementation ignores min_pages if a larger page size is an + // exact multiple of both region_min_size and region_max_size. This allows + // larger pages to be used when doing so would not cause fragmentation; in + // particular, a single page can be used when region_min_size == + // region_max_size == a supported page size. + static size_t page_size_for_region(size_t region_min_size, + size_t region_max_size, + uint min_pages); // Return the largest page size that can be used static size_t max_page_size() { // The _page_sizes array is sorted in descending order. --- old/src/share/vm/runtime/virtualspace.cpp 2014-07-01 16:47:51.170009382 +0200 +++ new/src/share/vm/runtime/virtualspace.cpp 2014-07-01 16:47:51.086009382 +0200 @@ -53,7 +53,7 @@ } ReservedSpace::ReservedSpace(size_t size) { - size_t page_size = os::page_size_for_region(size, 1); + size_t page_size = os::page_size_for_region(size, size, 1); bool large_pages = page_size != (size_t)os::vm_page_size(); // Don't force the alignment to be large page aligned, // since that will waste memory. @@ -372,7 +372,7 @@ bool VirtualSpace::initialize(ReservedSpace rs, size_t committed_size) { - const size_t max_commit_granularity = os::page_size_for_region(rs.size(), 1); + const size_t max_commit_granularity = os::page_size_for_region(rs.size(), rs.size(), 1); return initialize_with_granularity(rs, committed_size, max_commit_granularity); } @@ -1007,7 +1007,7 @@ case Disable: return vs.initialize_with_granularity(rs, 0, os::vm_page_size()); case Commit: - return vs.initialize_with_granularity(rs, 0, os::page_size_for_region(rs.size(), 1)); + return vs.initialize_with_granularity(rs, 0, os::page_size_for_region(rs.size(), rs.size(), 1)); } } --- old/test/gc/arguments/TestParallelHeapSizeFlags.java 2014-07-01 16:47:51.634009380 +0200 +++ new/test/gc/arguments/TestParallelHeapSizeFlags.java 2014-07-01 16:47:51.550009381 +0200 @@ -22,6 +22,7 @@ */ /* + * @ignore 8027915 * @test TestParallelHeapSizeFlags * @key gc * @bug 8006088