Mercurial > hg > truffle
comparison src/share/vm/runtime/virtualspace.cpp @ 14422:2b8e28fdf503
Merge
author | kvn |
---|---|
date | Tue, 05 Nov 2013 17:38:04 -0800 |
parents | e2722a66aba7 04b18a42c2f3 |
children | 8a9bb7821e28 78bbf4d43a14 |
comparison
equal
deleted
inserted
replaced
14421:3068270ba476 | 14422:2b8e28fdf503 |
---|---|
369 _executable = false; | 369 _executable = false; |
370 } | 370 } |
371 | 371 |
372 | 372 |
373 bool VirtualSpace::initialize(ReservedSpace rs, size_t committed_size) { | 373 bool VirtualSpace::initialize(ReservedSpace rs, size_t committed_size) { |
374 const size_t max_commit_granularity = os::page_size_for_region(rs.size(), rs.size(), 1); | |
375 return initialize_with_granularity(rs, committed_size, max_commit_granularity); | |
376 } | |
377 | |
378 bool VirtualSpace::initialize_with_granularity(ReservedSpace rs, size_t committed_size, size_t max_commit_granularity) { | |
374 if(!rs.is_reserved()) return false; // allocation failed. | 379 if(!rs.is_reserved()) return false; // allocation failed. |
375 assert(_low_boundary == NULL, "VirtualSpace already initialized"); | 380 assert(_low_boundary == NULL, "VirtualSpace already initialized"); |
381 assert(max_commit_granularity > 0, "Granularity must be non-zero."); | |
382 | |
376 _low_boundary = rs.base(); | 383 _low_boundary = rs.base(); |
377 _high_boundary = low_boundary() + rs.size(); | 384 _high_boundary = low_boundary() + rs.size(); |
378 | 385 |
379 _low = low_boundary(); | 386 _low = low_boundary(); |
380 _high = low(); | 387 _high = low(); |
391 // boost in many benchmarks when covered by large pages. | 398 // boost in many benchmarks when covered by large pages. |
392 // | 399 // |
393 // No attempt is made to force large page alignment at the very top and | 400 // No attempt is made to force large page alignment at the very top and |
394 // bottom of the space if they are not aligned so already. | 401 // bottom of the space if they are not aligned so already. |
395 _lower_alignment = os::vm_page_size(); | 402 _lower_alignment = os::vm_page_size(); |
396 _middle_alignment = os::page_size_for_region(rs.size(), rs.size(), 1); | 403 _middle_alignment = max_commit_granularity; |
397 _upper_alignment = os::vm_page_size(); | 404 _upper_alignment = os::vm_page_size(); |
398 | 405 |
399 // End of each region | 406 // End of each region |
400 _lower_high_boundary = (char*) round_to((intptr_t) low_boundary(), middle_alignment()); | 407 _lower_high_boundary = (char*) round_to((intptr_t) low_boundary(), middle_alignment()); |
401 _middle_high_boundary = (char*) round_down((intptr_t) high_boundary(), middle_alignment()); | 408 _middle_high_boundary = (char*) round_down((intptr_t) high_boundary(), middle_alignment()); |
454 | 461 |
455 size_t VirtualSpace::uncommitted_size() const { | 462 size_t VirtualSpace::uncommitted_size() const { |
456 return reserved_size() - committed_size(); | 463 return reserved_size() - committed_size(); |
457 } | 464 } |
458 | 465 |
466 size_t VirtualSpace::actual_committed_size() const { | |
467 // Special VirtualSpaces commit all reserved space up front. | |
468 if (special()) { | |
469 return reserved_size(); | |
470 } | |
471 | |
472 size_t committed_low = pointer_delta(_lower_high, _low_boundary, sizeof(char)); | |
473 size_t committed_middle = pointer_delta(_middle_high, _lower_high_boundary, sizeof(char)); | |
474 size_t committed_high = pointer_delta(_upper_high, _middle_high_boundary, sizeof(char)); | |
475 | |
476 #ifdef ASSERT | |
477 size_t lower = pointer_delta(_lower_high_boundary, _low_boundary, sizeof(char)); | |
478 size_t middle = pointer_delta(_middle_high_boundary, _lower_high_boundary, sizeof(char)); | |
479 size_t upper = pointer_delta(_upper_high_boundary, _middle_high_boundary, sizeof(char)); | |
480 | |
481 if (committed_high > 0) { | |
482 assert(committed_low == lower, "Must be"); | |
483 assert(committed_middle == middle, "Must be"); | |
484 } | |
485 | |
486 if (committed_middle > 0) { | |
487 assert(committed_low == lower, "Must be"); | |
488 } | |
489 if (committed_middle < middle) { | |
490 assert(committed_high == 0, "Must be"); | |
491 } | |
492 | |
493 if (committed_low < lower) { | |
494 assert(committed_high == 0, "Must be"); | |
495 assert(committed_middle == 0, "Must be"); | |
496 } | |
497 #endif | |
498 | |
499 return committed_low + committed_middle + committed_high; | |
500 } | |
501 | |
459 | 502 |
460 bool VirtualSpace::contains(const void* p) const { | 503 bool VirtualSpace::contains(const void* p) const { |
461 return low() <= (const char*) p && (const char*) p < high(); | 504 return low() <= (const char*) p && (const char*) p < high(); |
462 } | 505 } |
463 | 506 |
719 assert(low_boundary() <= lower_high_boundary(), "lower high boundary"); | 762 assert(low_boundary() <= lower_high_boundary(), "lower high boundary"); |
720 assert(upper_high_boundary() <= high_boundary(), "upper high boundary"); | 763 assert(upper_high_boundary() <= high_boundary(), "upper high boundary"); |
721 assert(high() <= upper_high(), "upper high"); | 764 assert(high() <= upper_high(), "upper high"); |
722 } | 765 } |
723 | 766 |
767 void VirtualSpace::print_on(outputStream* out) { | |
768 out->print ("Virtual space:"); | |
769 if (special()) out->print(" (pinned in memory)"); | |
770 out->cr(); | |
771 out->print_cr(" - committed: " SIZE_FORMAT, committed_size()); | |
772 out->print_cr(" - reserved: " SIZE_FORMAT, reserved_size()); | |
773 out->print_cr(" - [low, high]: [" INTPTR_FORMAT ", " INTPTR_FORMAT "]", low(), high()); | |
774 out->print_cr(" - [low_b, high_b]: [" INTPTR_FORMAT ", " INTPTR_FORMAT "]", low_boundary(), high_boundary()); | |
775 } | |
776 | |
724 void VirtualSpace::print() { | 777 void VirtualSpace::print() { |
725 tty->print ("Virtual space:"); | 778 print_on(tty); |
726 if (special()) tty->print(" (pinned in memory)"); | 779 } |
727 tty->cr(); | |
728 tty->print_cr(" - committed: " SIZE_FORMAT, committed_size()); | |
729 tty->print_cr(" - reserved: " SIZE_FORMAT, reserved_size()); | |
730 tty->print_cr(" - [low, high]: [" INTPTR_FORMAT ", " INTPTR_FORMAT "]", low(), high()); | |
731 tty->print_cr(" - [low_b, high_b]: [" INTPTR_FORMAT ", " INTPTR_FORMAT "]", low_boundary(), high_boundary()); | |
732 } | |
733 | |
734 | 780 |
735 /////////////// Unit tests /////////////// | 781 /////////////// Unit tests /////////////// |
736 | 782 |
737 #ifndef PRODUCT | 783 #ifndef PRODUCT |
738 | 784 |
911 | 957 |
912 void TestReservedSpace_test() { | 958 void TestReservedSpace_test() { |
913 TestReservedSpace::test_reserved_space(); | 959 TestReservedSpace::test_reserved_space(); |
914 } | 960 } |
915 | 961 |
962 #define assert_equals(actual, expected) \ | |
963 assert(actual == expected, \ | |
964 err_msg("Got " SIZE_FORMAT " expected " \ | |
965 SIZE_FORMAT, actual, expected)); | |
966 | |
967 #define assert_ge(value1, value2) \ | |
968 assert(value1 >= value2, \ | |
969 err_msg("'" #value1 "': " SIZE_FORMAT " '" \ | |
970 #value2 "': " SIZE_FORMAT, value1, value2)); | |
971 | |
972 #define assert_lt(value1, value2) \ | |
973 assert(value1 < value2, \ | |
974 err_msg("'" #value1 "': " SIZE_FORMAT " '" \ | |
975 #value2 "': " SIZE_FORMAT, value1, value2)); | |
976 | |
977 | |
978 class TestVirtualSpace : AllStatic { | |
979 enum TestLargePages { | |
980 Default, | |
981 Disable, | |
982 Reserve, | |
983 Commit | |
984 }; | |
985 | |
986 static ReservedSpace reserve_memory(size_t reserve_size_aligned, TestLargePages mode) { | |
987 switch(mode) { | |
988 default: | |
989 case Default: | |
990 case Reserve: | |
991 return ReservedSpace(reserve_size_aligned); | |
992 case Disable: | |
993 case Commit: | |
994 return ReservedSpace(reserve_size_aligned, | |
995 os::vm_allocation_granularity(), | |
996 /* large */ false, /* exec */ false); | |
997 } | |
998 } | |
999 | |
1000 static bool initialize_virtual_space(VirtualSpace& vs, ReservedSpace rs, TestLargePages mode) { | |
1001 switch(mode) { | |
1002 default: | |
1003 case Default: | |
1004 case Reserve: | |
1005 return vs.initialize(rs, 0); | |
1006 case Disable: | |
1007 return vs.initialize_with_granularity(rs, 0, os::vm_page_size()); | |
1008 case Commit: | |
1009 return vs.initialize_with_granularity(rs, 0, os::page_size_for_region(rs.size(), rs.size(), 1)); | |
1010 } | |
1011 } | |
1012 | |
1013 public: | |
1014 static void test_virtual_space_actual_committed_space(size_t reserve_size, size_t commit_size, | |
1015 TestLargePages mode = Default) { | |
1016 size_t granularity = os::vm_allocation_granularity(); | |
1017 size_t reserve_size_aligned = align_size_up(reserve_size, granularity); | |
1018 | |
1019 ReservedSpace reserved = reserve_memory(reserve_size_aligned, mode); | |
1020 | |
1021 assert(reserved.is_reserved(), "Must be"); | |
1022 | |
1023 VirtualSpace vs; | |
1024 bool initialized = initialize_virtual_space(vs, reserved, mode); | |
1025 assert(initialized, "Failed to initialize VirtualSpace"); | |
1026 | |
1027 vs.expand_by(commit_size, false); | |
1028 | |
1029 if (vs.special()) { | |
1030 assert_equals(vs.actual_committed_size(), reserve_size_aligned); | |
1031 } else { | |
1032 assert_ge(vs.actual_committed_size(), commit_size); | |
1033 // Approximate the commit granularity. | |
1034 // Make sure that we don't commit using large pages | |
1035 // if large pages has been disabled for this VirtualSpace. | |
1036 size_t commit_granularity = (mode == Disable || !UseLargePages) ? | |
1037 os::vm_page_size() : os::large_page_size(); | |
1038 assert_lt(vs.actual_committed_size(), commit_size + commit_granularity); | |
1039 } | |
1040 | |
1041 reserved.release(); | |
1042 } | |
1043 | |
1044 static void test_virtual_space_actual_committed_space_one_large_page() { | |
1045 if (!UseLargePages) { | |
1046 return; | |
1047 } | |
1048 | |
1049 size_t large_page_size = os::large_page_size(); | |
1050 | |
1051 ReservedSpace reserved(large_page_size, large_page_size, true, false); | |
1052 | |
1053 assert(reserved.is_reserved(), "Must be"); | |
1054 | |
1055 VirtualSpace vs; | |
1056 bool initialized = vs.initialize(reserved, 0); | |
1057 assert(initialized, "Failed to initialize VirtualSpace"); | |
1058 | |
1059 vs.expand_by(large_page_size, false); | |
1060 | |
1061 assert_equals(vs.actual_committed_size(), large_page_size); | |
1062 | |
1063 reserved.release(); | |
1064 } | |
1065 | |
1066 static void test_virtual_space_actual_committed_space() { | |
1067 test_virtual_space_actual_committed_space(4 * K, 0); | |
1068 test_virtual_space_actual_committed_space(4 * K, 4 * K); | |
1069 test_virtual_space_actual_committed_space(8 * K, 0); | |
1070 test_virtual_space_actual_committed_space(8 * K, 4 * K); | |
1071 test_virtual_space_actual_committed_space(8 * K, 8 * K); | |
1072 test_virtual_space_actual_committed_space(12 * K, 0); | |
1073 test_virtual_space_actual_committed_space(12 * K, 4 * K); | |
1074 test_virtual_space_actual_committed_space(12 * K, 8 * K); | |
1075 test_virtual_space_actual_committed_space(12 * K, 12 * K); | |
1076 test_virtual_space_actual_committed_space(64 * K, 0); | |
1077 test_virtual_space_actual_committed_space(64 * K, 32 * K); | |
1078 test_virtual_space_actual_committed_space(64 * K, 64 * K); | |
1079 test_virtual_space_actual_committed_space(2 * M, 0); | |
1080 test_virtual_space_actual_committed_space(2 * M, 4 * K); | |
1081 test_virtual_space_actual_committed_space(2 * M, 64 * K); | |
1082 test_virtual_space_actual_committed_space(2 * M, 1 * M); | |
1083 test_virtual_space_actual_committed_space(2 * M, 2 * M); | |
1084 test_virtual_space_actual_committed_space(10 * M, 0); | |
1085 test_virtual_space_actual_committed_space(10 * M, 4 * K); | |
1086 test_virtual_space_actual_committed_space(10 * M, 8 * K); | |
1087 test_virtual_space_actual_committed_space(10 * M, 1 * M); | |
1088 test_virtual_space_actual_committed_space(10 * M, 2 * M); | |
1089 test_virtual_space_actual_committed_space(10 * M, 5 * M); | |
1090 test_virtual_space_actual_committed_space(10 * M, 10 * M); | |
1091 } | |
1092 | |
1093 static void test_virtual_space_disable_large_pages() { | |
1094 if (!UseLargePages) { | |
1095 return; | |
1096 } | |
1097 // These test cases verify that if we force VirtualSpace to disable large pages | |
1098 test_virtual_space_actual_committed_space(10 * M, 0, Disable); | |
1099 test_virtual_space_actual_committed_space(10 * M, 4 * K, Disable); | |
1100 test_virtual_space_actual_committed_space(10 * M, 8 * K, Disable); | |
1101 test_virtual_space_actual_committed_space(10 * M, 1 * M, Disable); | |
1102 test_virtual_space_actual_committed_space(10 * M, 2 * M, Disable); | |
1103 test_virtual_space_actual_committed_space(10 * M, 5 * M, Disable); | |
1104 test_virtual_space_actual_committed_space(10 * M, 10 * M, Disable); | |
1105 | |
1106 test_virtual_space_actual_committed_space(10 * M, 0, Reserve); | |
1107 test_virtual_space_actual_committed_space(10 * M, 4 * K, Reserve); | |
1108 test_virtual_space_actual_committed_space(10 * M, 8 * K, Reserve); | |
1109 test_virtual_space_actual_committed_space(10 * M, 1 * M, Reserve); | |
1110 test_virtual_space_actual_committed_space(10 * M, 2 * M, Reserve); | |
1111 test_virtual_space_actual_committed_space(10 * M, 5 * M, Reserve); | |
1112 test_virtual_space_actual_committed_space(10 * M, 10 * M, Reserve); | |
1113 | |
1114 test_virtual_space_actual_committed_space(10 * M, 0, Commit); | |
1115 test_virtual_space_actual_committed_space(10 * M, 4 * K, Commit); | |
1116 test_virtual_space_actual_committed_space(10 * M, 8 * K, Commit); | |
1117 test_virtual_space_actual_committed_space(10 * M, 1 * M, Commit); | |
1118 test_virtual_space_actual_committed_space(10 * M, 2 * M, Commit); | |
1119 test_virtual_space_actual_committed_space(10 * M, 5 * M, Commit); | |
1120 test_virtual_space_actual_committed_space(10 * M, 10 * M, Commit); | |
1121 } | |
1122 | |
1123 static void test_virtual_space() { | |
1124 test_virtual_space_actual_committed_space(); | |
1125 test_virtual_space_actual_committed_space_one_large_page(); | |
1126 test_virtual_space_disable_large_pages(); | |
1127 } | |
1128 }; | |
1129 | |
1130 void TestVirtualSpace_test() { | |
1131 TestVirtualSpace::test_virtual_space(); | |
1132 } | |
1133 | |
916 #endif // PRODUCT | 1134 #endif // PRODUCT |
917 | 1135 |
918 #endif | 1136 #endif |