comparison src/share/vm/runtime/virtualspace.cpp @ 12834:04b18a42c2f3

8025526: VirtualSpace should support per-instance disabling of large pages Summary: Add a new initialization function to VirtualSpace which allows the caller to override the max commit granularity. Reviewed-by: stefank, ehelin, tschatzl
author mgerdin
date Fri, 04 Oct 2013 13:33:02 +0200
parents 8c5e6482cbfc
children 63a4eb8bcd23 2b8e28fdf503
comparison
equal deleted inserted replaced
12833:8618e0d7735b 12834:04b18a42c2f3
366 _executable = false; 366 _executable = false;
367 } 367 }
368 368
369 369
370 bool VirtualSpace::initialize(ReservedSpace rs, size_t committed_size) { 370 bool VirtualSpace::initialize(ReservedSpace rs, size_t committed_size) {
371 const size_t max_commit_granularity = os::page_size_for_region(rs.size(), rs.size(), 1);
372 return initialize_with_granularity(rs, committed_size, max_commit_granularity);
373 }
374
375 bool VirtualSpace::initialize_with_granularity(ReservedSpace rs, size_t committed_size, size_t max_commit_granularity) {
371 if(!rs.is_reserved()) return false; // allocation failed. 376 if(!rs.is_reserved()) return false; // allocation failed.
372 assert(_low_boundary == NULL, "VirtualSpace already initialized"); 377 assert(_low_boundary == NULL, "VirtualSpace already initialized");
378 assert(max_commit_granularity > 0, "Granularity must be non-zero.");
379
373 _low_boundary = rs.base(); 380 _low_boundary = rs.base();
374 _high_boundary = low_boundary() + rs.size(); 381 _high_boundary = low_boundary() + rs.size();
375 382
376 _low = low_boundary(); 383 _low = low_boundary();
377 _high = low(); 384 _high = low();
388 // boost in many benchmarks when covered by large pages. 395 // boost in many benchmarks when covered by large pages.
389 // 396 //
390 // No attempt is made to force large page alignment at the very top and 397 // No attempt is made to force large page alignment at the very top and
391 // bottom of the space if they are not aligned so already. 398 // bottom of the space if they are not aligned so already.
392 _lower_alignment = os::vm_page_size(); 399 _lower_alignment = os::vm_page_size();
393 _middle_alignment = os::page_size_for_region(rs.size(), rs.size(), 1); 400 _middle_alignment = max_commit_granularity;
394 _upper_alignment = os::vm_page_size(); 401 _upper_alignment = os::vm_page_size();
395 402
396 // End of each region 403 // End of each region
397 _lower_high_boundary = (char*) round_to((intptr_t) low_boundary(), middle_alignment()); 404 _lower_high_boundary = (char*) round_to((intptr_t) low_boundary(), middle_alignment());
398 _middle_high_boundary = (char*) round_down((intptr_t) high_boundary(), middle_alignment()); 405 _middle_high_boundary = (char*) round_down((intptr_t) high_boundary(), middle_alignment());
964 err_msg("'" #value1 "': " SIZE_FORMAT " '" \ 971 err_msg("'" #value1 "': " SIZE_FORMAT " '" \
965 #value2 "': " SIZE_FORMAT, value1, value2)); 972 #value2 "': " SIZE_FORMAT, value1, value2));
966 973
967 974
968 class TestVirtualSpace : AllStatic { 975 class TestVirtualSpace : AllStatic {
976 enum TestLargePages {
977 Default,
978 Disable,
979 Reserve,
980 Commit
981 };
982
983 static ReservedSpace reserve_memory(size_t reserve_size_aligned, TestLargePages mode) {
984 switch(mode) {
985 default:
986 case Default:
987 case Reserve:
988 return ReservedSpace(reserve_size_aligned);
989 case Disable:
990 case Commit:
991 return ReservedSpace(reserve_size_aligned,
992 os::vm_allocation_granularity(),
993 /* large */ false, /* exec */ false);
994 }
995 }
996
997 static bool initialize_virtual_space(VirtualSpace& vs, ReservedSpace rs, TestLargePages mode) {
998 switch(mode) {
999 default:
1000 case Default:
1001 case Reserve:
1002 return vs.initialize(rs, 0);
1003 case Disable:
1004 return vs.initialize_with_granularity(rs, 0, os::vm_page_size());
1005 case Commit:
1006 return vs.initialize_with_granularity(rs, 0, os::page_size_for_region(rs.size(), rs.size(), 1));
1007 }
1008 }
1009
969 public: 1010 public:
970 static void test_virtual_space_actual_committed_space(size_t reserve_size, size_t commit_size) { 1011 static void test_virtual_space_actual_committed_space(size_t reserve_size, size_t commit_size,
1012 TestLargePages mode = Default) {
971 size_t granularity = os::vm_allocation_granularity(); 1013 size_t granularity = os::vm_allocation_granularity();
972 size_t reserve_size_aligned = align_size_up(reserve_size, granularity); 1014 size_t reserve_size_aligned = align_size_up(reserve_size, granularity);
973 1015
974 ReservedSpace reserved(reserve_size_aligned); 1016 ReservedSpace reserved = reserve_memory(reserve_size_aligned, mode);
975 1017
976 assert(reserved.is_reserved(), "Must be"); 1018 assert(reserved.is_reserved(), "Must be");
977 1019
978 VirtualSpace vs; 1020 VirtualSpace vs;
979 bool initialized = vs.initialize(reserved, 0); 1021 bool initialized = initialize_virtual_space(vs, reserved, mode);
980 assert(initialized, "Failed to initialize VirtualSpace"); 1022 assert(initialized, "Failed to initialize VirtualSpace");
981 1023
982 vs.expand_by(commit_size, false); 1024 vs.expand_by(commit_size, false);
983 1025
984 if (vs.special()) { 1026 if (vs.special()) {
985 assert_equals(vs.actual_committed_size(), reserve_size_aligned); 1027 assert_equals(vs.actual_committed_size(), reserve_size_aligned);
986 } else { 1028 } else {
987 assert_ge(vs.actual_committed_size(), commit_size); 1029 assert_ge(vs.actual_committed_size(), commit_size);
988 // Approximate the commit granularity. 1030 // Approximate the commit granularity.
989 size_t commit_granularity = UseLargePages ? os::large_page_size() : os::vm_page_size(); 1031 // Make sure that we don't commit using large pages
1032 // if large pages has been disabled for this VirtualSpace.
1033 size_t commit_granularity = (mode == Disable || !UseLargePages) ?
1034 os::vm_page_size() : os::large_page_size();
990 assert_lt(vs.actual_committed_size(), commit_size + commit_granularity); 1035 assert_lt(vs.actual_committed_size(), commit_size + commit_granularity);
991 } 1036 }
992 1037
993 reserved.release(); 1038 reserved.release();
994 } 1039 }
1040 test_virtual_space_actual_committed_space(10 * M, 2 * M); 1085 test_virtual_space_actual_committed_space(10 * M, 2 * M);
1041 test_virtual_space_actual_committed_space(10 * M, 5 * M); 1086 test_virtual_space_actual_committed_space(10 * M, 5 * M);
1042 test_virtual_space_actual_committed_space(10 * M, 10 * M); 1087 test_virtual_space_actual_committed_space(10 * M, 10 * M);
1043 } 1088 }
1044 1089
1090 static void test_virtual_space_disable_large_pages() {
1091 if (!UseLargePages) {
1092 return;
1093 }
1094 // These test cases verify that if we force VirtualSpace to disable large pages
1095 test_virtual_space_actual_committed_space(10 * M, 0, Disable);
1096 test_virtual_space_actual_committed_space(10 * M, 4 * K, Disable);
1097 test_virtual_space_actual_committed_space(10 * M, 8 * K, Disable);
1098 test_virtual_space_actual_committed_space(10 * M, 1 * M, Disable);
1099 test_virtual_space_actual_committed_space(10 * M, 2 * M, Disable);
1100 test_virtual_space_actual_committed_space(10 * M, 5 * M, Disable);
1101 test_virtual_space_actual_committed_space(10 * M, 10 * M, Disable);
1102
1103 test_virtual_space_actual_committed_space(10 * M, 0, Reserve);
1104 test_virtual_space_actual_committed_space(10 * M, 4 * K, Reserve);
1105 test_virtual_space_actual_committed_space(10 * M, 8 * K, Reserve);
1106 test_virtual_space_actual_committed_space(10 * M, 1 * M, Reserve);
1107 test_virtual_space_actual_committed_space(10 * M, 2 * M, Reserve);
1108 test_virtual_space_actual_committed_space(10 * M, 5 * M, Reserve);
1109 test_virtual_space_actual_committed_space(10 * M, 10 * M, Reserve);
1110
1111 test_virtual_space_actual_committed_space(10 * M, 0, Commit);
1112 test_virtual_space_actual_committed_space(10 * M, 4 * K, Commit);
1113 test_virtual_space_actual_committed_space(10 * M, 8 * K, Commit);
1114 test_virtual_space_actual_committed_space(10 * M, 1 * M, Commit);
1115 test_virtual_space_actual_committed_space(10 * M, 2 * M, Commit);
1116 test_virtual_space_actual_committed_space(10 * M, 5 * M, Commit);
1117 test_virtual_space_actual_committed_space(10 * M, 10 * M, Commit);
1118 }
1119
1045 static void test_virtual_space() { 1120 static void test_virtual_space() {
1046 test_virtual_space_actual_committed_space(); 1121 test_virtual_space_actual_committed_space();
1047 test_virtual_space_actual_committed_space_one_large_page(); 1122 test_virtual_space_actual_committed_space_one_large_page();
1123 test_virtual_space_disable_large_pages();
1048 } 1124 }
1049 }; 1125 };
1050 1126
1051 void TestVirtualSpace_test() { 1127 void TestVirtualSpace_test() {
1052 TestVirtualSpace::test_virtual_space(); 1128 TestVirtualSpace::test_virtual_space();