# HG changeset patch # User ehelin # Date 1404301972 -7200 # Node ID 3924abbe7bc9865643b73507fcbaf6f6b6f7fff6 # Parent 6db782823853b661dcf4fff836ba258b496c207f# Parent 8b8061f353ee8d1d575f83a2c8f2bd7f38a3c81f Merge diff -r 6db782823853 -r 3924abbe7bc9 hotspot/src/share/vm/gc_implementation/parallelScavenge/generationSizer.cpp --- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/generationSizer.cpp Thu Jun 26 18:55:29 2014 -0700 +++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/generationSizer.cpp Wed Jul 02 13:52:52 2014 +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"); diff -r 6db782823853 -r 3924abbe7bc9 hotspot/src/share/vm/gc_implementation/parallelScavenge/parMarkBitMap.cpp --- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/parMarkBitMap.cpp Thu Jun 26 18:55:29 2014 -0700 +++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/parMarkBitMap.cpp Wed Jul 02 13:52:52 2014 +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)); diff -r 6db782823853 -r 3924abbe7bc9 hotspot/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp --- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp Thu Jun 26 18:55:29 2014 -0700 +++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp Wed Jul 02 13:52:52 2014 +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)); diff -r 6db782823853 -r 3924abbe7bc9 hotspot/src/share/vm/memory/heap.cpp --- a/hotspot/src/share/vm/memory/heap.cpp Thu Jun 26 18:55:29 2014 -0700 +++ b/hotspot/src/share/vm/memory/heap.cpp Wed Jul 02 13:52:52 2014 +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); diff -r 6db782823853 -r 3924abbe7bc9 hotspot/src/share/vm/prims/jni.cpp --- a/hotspot/src/share/vm/prims/jni.cpp Thu Jun 26 18:55:29 2014 -0700 +++ b/hotspot/src/share/vm/prims/jni.cpp Wed Jul 02 13:52:52 2014 +0200 @@ -3865,7 +3865,6 @@ unit_test_function_call // Forward declaration -void TestOS_test(); void TestReservedSpace_test(); void TestReserveMemorySpecial_test(); void TestVirtualSpace_test(); @@ -3887,7 +3886,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()); diff -r 6db782823853 -r 3924abbe7bc9 hotspot/src/share/vm/runtime/os.cpp --- a/hotspot/src/share/vm/runtime/os.cpp Thu Jun 26 18:55:29 2014 -0700 +++ b/hotspot/src/share/vm/runtime/os.cpp Wed Jul 02 13:52:52 2014 +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 (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; + 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; + } + + 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 diff -r 6db782823853 -r 3924abbe7bc9 hotspot/src/share/vm/runtime/os.hpp --- a/hotspot/src/share/vm/runtime/os.hpp Thu Jun 26 18:55:29 2014 -0700 +++ b/hotspot/src/share/vm/runtime/os.hpp Wed Jul 02 13:52:52 2014 +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. diff -r 6db782823853 -r 3924abbe7bc9 hotspot/src/share/vm/runtime/virtualspace.cpp --- a/hotspot/src/share/vm/runtime/virtualspace.cpp Thu Jun 26 18:55:29 2014 -0700 +++ b/hotspot/src/share/vm/runtime/virtualspace.cpp Wed Jul 02 13:52:52 2014 +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)); } } diff -r 6db782823853 -r 3924abbe7bc9 hotspot/test/gc/arguments/TestParallelHeapSizeFlags.java --- a/hotspot/test/gc/arguments/TestParallelHeapSizeFlags.java Thu Jun 26 18:55:29 2014 -0700 +++ b/hotspot/test/gc/arguments/TestParallelHeapSizeFlags.java Wed Jul 02 13:52:52 2014 +0200 @@ -22,6 +22,7 @@ */ /* + * @ignore 8027915 * @test TestParallelHeapSizeFlags * @key gc * @bug 8006088