comparison src/share/vm/runtime/virtualspace.cpp @ 12355:cefad50507d8

Merge with hs25-b53
author Gilles Duboscq <duboscq@ssw.jku.at>
date Fri, 11 Oct 2013 10:38:03 +0200
parents 8c5e6482cbfc
children 04b18a42c2f3
comparison
equal deleted inserted replaced
12058:ccb4f2af2319 12355:cefad50507d8
40 # include "os_bsd.inline.hpp" 40 # include "os_bsd.inline.hpp"
41 #endif 41 #endif
42 42
43 43
44 // ReservedSpace 44 // ReservedSpace
45
46 // Dummy constructor
47 ReservedSpace::ReservedSpace() : _base(NULL), _size(0), _noaccess_prefix(0),
48 _alignment(0), _special(false), _executable(false) {
49 }
50
45 ReservedSpace::ReservedSpace(size_t size) { 51 ReservedSpace::ReservedSpace(size_t size) {
46 initialize(size, 0, false, NULL, 0, false); 52 size_t page_size = os::page_size_for_region(size, size, 1);
53 bool large_pages = page_size != (size_t)os::vm_page_size();
54 // Don't force the alignment to be large page aligned,
55 // since that will waste memory.
56 size_t alignment = os::vm_allocation_granularity();
57 initialize(size, alignment, large_pages, NULL, 0, false);
47 } 58 }
48 59
49 ReservedSpace::ReservedSpace(size_t size, size_t alignment, 60 ReservedSpace::ReservedSpace(size_t size, size_t alignment,
50 bool large, 61 bool large,
51 char* requested_address, 62 char* requested_address,
127 assert(requested_address != NULL, "huge noaccess prefix?"); 138 assert(requested_address != NULL, "huge noaccess prefix?");
128 } 139 }
129 140
130 if (special) { 141 if (special) {
131 142
132 base = os::reserve_memory_special(size, requested_address, executable); 143 base = os::reserve_memory_special(size, alignment, requested_address, executable);
133 144
134 if (base != NULL) { 145 if (base != NULL) {
135 if (failed_to_reserve_as_requested(base, requested_address, size, true)) { 146 if (failed_to_reserve_as_requested(base, requested_address, size, true)) {
136 // OS ignored requested address. Try different address. 147 // OS ignored requested address. Try different address.
137 return; 148 return;
138 } 149 }
139 // Check alignment constraints 150 // Check alignment constraints.
140 assert((uintptr_t) base % alignment == 0, 151 assert((uintptr_t) base % alignment == 0,
141 "Large pages returned a non-aligned address"); 152 err_msg("Large pages returned a non-aligned address, base: "
153 PTR_FORMAT " alignment: " PTR_FORMAT,
154 base, (void*)(uintptr_t)alignment));
142 _special = true; 155 _special = true;
143 } else { 156 } else {
144 // failed; try to reserve regular memory below 157 // failed; try to reserve regular memory below
145 if (UseLargePages && (!FLAG_IS_DEFAULT(UseLargePages) || 158 if (UseLargePages && (!FLAG_IS_DEFAULT(UseLargePages) ||
146 !FLAG_IS_DEFAULT(LargePageSizeInBytes))) { 159 !FLAG_IS_DEFAULT(LargePageSizeInBytes))) {
438 451
439 size_t VirtualSpace::uncommitted_size() const { 452 size_t VirtualSpace::uncommitted_size() const {
440 return reserved_size() - committed_size(); 453 return reserved_size() - committed_size();
441 } 454 }
442 455
456 size_t VirtualSpace::actual_committed_size() const {
457 // Special VirtualSpaces commit all reserved space up front.
458 if (special()) {
459 return reserved_size();
460 }
461
462 size_t committed_low = pointer_delta(_lower_high, _low_boundary, sizeof(char));
463 size_t committed_middle = pointer_delta(_middle_high, _lower_high_boundary, sizeof(char));
464 size_t committed_high = pointer_delta(_upper_high, _middle_high_boundary, sizeof(char));
465
466 #ifdef ASSERT
467 size_t lower = pointer_delta(_lower_high_boundary, _low_boundary, sizeof(char));
468 size_t middle = pointer_delta(_middle_high_boundary, _lower_high_boundary, sizeof(char));
469 size_t upper = pointer_delta(_upper_high_boundary, _middle_high_boundary, sizeof(char));
470
471 if (committed_high > 0) {
472 assert(committed_low == lower, "Must be");
473 assert(committed_middle == middle, "Must be");
474 }
475
476 if (committed_middle > 0) {
477 assert(committed_low == lower, "Must be");
478 }
479 if (committed_middle < middle) {
480 assert(committed_high == 0, "Must be");
481 }
482
483 if (committed_low < lower) {
484 assert(committed_high == 0, "Must be");
485 assert(committed_middle == 0, "Must be");
486 }
487 #endif
488
489 return committed_low + committed_middle + committed_high;
490 }
491
443 492
444 bool VirtualSpace::contains(const void* p) const { 493 bool VirtualSpace::contains(const void* p) const {
445 return low() <= (const char*) p && (const char*) p < high(); 494 return low() <= (const char*) p && (const char*) p < high();
446 } 495 }
447 496
703 assert(low_boundary() <= lower_high_boundary(), "lower high boundary"); 752 assert(low_boundary() <= lower_high_boundary(), "lower high boundary");
704 assert(upper_high_boundary() <= high_boundary(), "upper high boundary"); 753 assert(upper_high_boundary() <= high_boundary(), "upper high boundary");
705 assert(high() <= upper_high(), "upper high"); 754 assert(high() <= upper_high(), "upper high");
706 } 755 }
707 756
757 void VirtualSpace::print_on(outputStream* out) {
758 out->print ("Virtual space:");
759 if (special()) out->print(" (pinned in memory)");
760 out->cr();
761 out->print_cr(" - committed: " SIZE_FORMAT, committed_size());
762 out->print_cr(" - reserved: " SIZE_FORMAT, reserved_size());
763 out->print_cr(" - [low, high]: [" INTPTR_FORMAT ", " INTPTR_FORMAT "]", low(), high());
764 out->print_cr(" - [low_b, high_b]: [" INTPTR_FORMAT ", " INTPTR_FORMAT "]", low_boundary(), high_boundary());
765 }
766
708 void VirtualSpace::print() { 767 void VirtualSpace::print() {
709 tty->print ("Virtual space:"); 768 print_on(tty);
710 if (special()) tty->print(" (pinned in memory)"); 769 }
711 tty->cr(); 770
712 tty->print_cr(" - committed: " SIZE_FORMAT, committed_size()); 771 /////////////// Unit tests ///////////////
713 tty->print_cr(" - reserved: " SIZE_FORMAT, reserved_size()); 772
714 tty->print_cr(" - [low, high]: [" INTPTR_FORMAT ", " INTPTR_FORMAT "]", low(), high()); 773 #ifndef PRODUCT
715 tty->print_cr(" - [low_b, high_b]: [" INTPTR_FORMAT ", " INTPTR_FORMAT "]", low_boundary(), high_boundary()); 774
716 } 775 #define test_log(...) \
776 do {\
777 if (VerboseInternalVMTests) { \
778 tty->print_cr(__VA_ARGS__); \
779 tty->flush(); \
780 }\
781 } while (false)
782
783 class TestReservedSpace : AllStatic {
784 public:
785 static void small_page_write(void* addr, size_t size) {
786 size_t page_size = os::vm_page_size();
787
788 char* end = (char*)addr + size;
789 for (char* p = (char*)addr; p < end; p += page_size) {
790 *p = 1;
791 }
792 }
793
794 static void release_memory_for_test(ReservedSpace rs) {
795 if (rs.special()) {
796 guarantee(os::release_memory_special(rs.base(), rs.size()), "Shouldn't fail");
797 } else {
798 guarantee(os::release_memory(rs.base(), rs.size()), "Shouldn't fail");
799 }
800 }
801
802 static void test_reserved_space1(size_t size, size_t alignment) {
803 test_log("test_reserved_space1(%p)", (void*) (uintptr_t) size);
804
805 assert(is_size_aligned(size, alignment), "Incorrect input parameters");
806
807 ReservedSpace rs(size, // size
808 alignment, // alignment
809 UseLargePages, // large
810 NULL, // requested_address
811 0); // noacces_prefix
812
813 test_log(" rs.special() == %d", rs.special());
814
815 assert(rs.base() != NULL, "Must be");
816 assert(rs.size() == size, "Must be");
817
818 assert(is_ptr_aligned(rs.base(), alignment), "aligned sizes should always give aligned addresses");
819 assert(is_size_aligned(rs.size(), alignment), "aligned sizes should always give aligned addresses");
820
821 if (rs.special()) {
822 small_page_write(rs.base(), size);
823 }
824
825 release_memory_for_test(rs);
826 }
827
828 static void test_reserved_space2(size_t size) {
829 test_log("test_reserved_space2(%p)", (void*)(uintptr_t)size);
830
831 assert(is_size_aligned(size, os::vm_allocation_granularity()), "Must be at least AG aligned");
832
833 ReservedSpace rs(size);
834
835 test_log(" rs.special() == %d", rs.special());
836
837 assert(rs.base() != NULL, "Must be");
838 assert(rs.size() == size, "Must be");
839
840 if (rs.special()) {
841 small_page_write(rs.base(), size);
842 }
843
844 release_memory_for_test(rs);
845 }
846
847 static void test_reserved_space3(size_t size, size_t alignment, bool maybe_large) {
848 test_log("test_reserved_space3(%p, %p, %d)",
849 (void*)(uintptr_t)size, (void*)(uintptr_t)alignment, maybe_large);
850
851 assert(is_size_aligned(size, os::vm_allocation_granularity()), "Must be at least AG aligned");
852 assert(is_size_aligned(size, alignment), "Must be at least aligned against alignment");
853
854 bool large = maybe_large && UseLargePages && size >= os::large_page_size();
855
856 ReservedSpace rs(size, alignment, large, false);
857
858 test_log(" rs.special() == %d", rs.special());
859
860 assert(rs.base() != NULL, "Must be");
861 assert(rs.size() == size, "Must be");
862
863 if (rs.special()) {
864 small_page_write(rs.base(), size);
865 }
866
867 release_memory_for_test(rs);
868 }
869
870
871 static void test_reserved_space1() {
872 size_t size = 2 * 1024 * 1024;
873 size_t ag = os::vm_allocation_granularity();
874
875 test_reserved_space1(size, ag);
876 test_reserved_space1(size * 2, ag);
877 test_reserved_space1(size * 10, ag);
878 }
879
880 static void test_reserved_space2() {
881 size_t size = 2 * 1024 * 1024;
882 size_t ag = os::vm_allocation_granularity();
883
884 test_reserved_space2(size * 1);
885 test_reserved_space2(size * 2);
886 test_reserved_space2(size * 10);
887 test_reserved_space2(ag);
888 test_reserved_space2(size - ag);
889 test_reserved_space2(size);
890 test_reserved_space2(size + ag);
891 test_reserved_space2(size * 2);
892 test_reserved_space2(size * 2 - ag);
893 test_reserved_space2(size * 2 + ag);
894 test_reserved_space2(size * 3);
895 test_reserved_space2(size * 3 - ag);
896 test_reserved_space2(size * 3 + ag);
897 test_reserved_space2(size * 10);
898 test_reserved_space2(size * 10 + size / 2);
899 }
900
901 static void test_reserved_space3() {
902 size_t ag = os::vm_allocation_granularity();
903
904 test_reserved_space3(ag, ag , false);
905 test_reserved_space3(ag * 2, ag , false);
906 test_reserved_space3(ag * 3, ag , false);
907 test_reserved_space3(ag * 2, ag * 2, false);
908 test_reserved_space3(ag * 4, ag * 2, false);
909 test_reserved_space3(ag * 8, ag * 2, false);
910 test_reserved_space3(ag * 4, ag * 4, false);
911 test_reserved_space3(ag * 8, ag * 4, false);
912 test_reserved_space3(ag * 16, ag * 4, false);
913
914 if (UseLargePages) {
915 size_t lp = os::large_page_size();
916
917 // Without large pages
918 test_reserved_space3(lp, ag * 4, false);
919 test_reserved_space3(lp * 2, ag * 4, false);
920 test_reserved_space3(lp * 4, ag * 4, false);
921 test_reserved_space3(lp, lp , false);
922 test_reserved_space3(lp * 2, lp , false);
923 test_reserved_space3(lp * 3, lp , false);
924 test_reserved_space3(lp * 2, lp * 2, false);
925 test_reserved_space3(lp * 4, lp * 2, false);
926 test_reserved_space3(lp * 8, lp * 2, false);
927
928 // With large pages
929 test_reserved_space3(lp, ag * 4 , true);
930 test_reserved_space3(lp * 2, ag * 4, true);
931 test_reserved_space3(lp * 4, ag * 4, true);
932 test_reserved_space3(lp, lp , true);
933 test_reserved_space3(lp * 2, lp , true);
934 test_reserved_space3(lp * 3, lp , true);
935 test_reserved_space3(lp * 2, lp * 2, true);
936 test_reserved_space3(lp * 4, lp * 2, true);
937 test_reserved_space3(lp * 8, lp * 2, true);
938 }
939 }
940
941 static void test_reserved_space() {
942 test_reserved_space1();
943 test_reserved_space2();
944 test_reserved_space3();
945 }
946 };
947
948 void TestReservedSpace_test() {
949 TestReservedSpace::test_reserved_space();
950 }
951
952 #define assert_equals(actual, expected) \
953 assert(actual == expected, \
954 err_msg("Got " SIZE_FORMAT " expected " \
955 SIZE_FORMAT, actual, expected));
956
957 #define assert_ge(value1, value2) \
958 assert(value1 >= value2, \
959 err_msg("'" #value1 "': " SIZE_FORMAT " '" \
960 #value2 "': " SIZE_FORMAT, value1, value2));
961
962 #define assert_lt(value1, value2) \
963 assert(value1 < value2, \
964 err_msg("'" #value1 "': " SIZE_FORMAT " '" \
965 #value2 "': " SIZE_FORMAT, value1, value2));
966
967
968 class TestVirtualSpace : AllStatic {
969 public:
970 static void test_virtual_space_actual_committed_space(size_t reserve_size, size_t commit_size) {
971 size_t granularity = os::vm_allocation_granularity();
972 size_t reserve_size_aligned = align_size_up(reserve_size, granularity);
973
974 ReservedSpace reserved(reserve_size_aligned);
975
976 assert(reserved.is_reserved(), "Must be");
977
978 VirtualSpace vs;
979 bool initialized = vs.initialize(reserved, 0);
980 assert(initialized, "Failed to initialize VirtualSpace");
981
982 vs.expand_by(commit_size, false);
983
984 if (vs.special()) {
985 assert_equals(vs.actual_committed_size(), reserve_size_aligned);
986 } else {
987 assert_ge(vs.actual_committed_size(), commit_size);
988 // Approximate the commit granularity.
989 size_t commit_granularity = UseLargePages ? os::large_page_size() : os::vm_page_size();
990 assert_lt(vs.actual_committed_size(), commit_size + commit_granularity);
991 }
992
993 reserved.release();
994 }
995
996 static void test_virtual_space_actual_committed_space_one_large_page() {
997 if (!UseLargePages) {
998 return;
999 }
1000
1001 size_t large_page_size = os::large_page_size();
1002
1003 ReservedSpace reserved(large_page_size, large_page_size, true, false);
1004
1005 assert(reserved.is_reserved(), "Must be");
1006
1007 VirtualSpace vs;
1008 bool initialized = vs.initialize(reserved, 0);
1009 assert(initialized, "Failed to initialize VirtualSpace");
1010
1011 vs.expand_by(large_page_size, false);
1012
1013 assert_equals(vs.actual_committed_size(), large_page_size);
1014
1015 reserved.release();
1016 }
1017
1018 static void test_virtual_space_actual_committed_space() {
1019 test_virtual_space_actual_committed_space(4 * K, 0);
1020 test_virtual_space_actual_committed_space(4 * K, 4 * K);
1021 test_virtual_space_actual_committed_space(8 * K, 0);
1022 test_virtual_space_actual_committed_space(8 * K, 4 * K);
1023 test_virtual_space_actual_committed_space(8 * K, 8 * K);
1024 test_virtual_space_actual_committed_space(12 * K, 0);
1025 test_virtual_space_actual_committed_space(12 * K, 4 * K);
1026 test_virtual_space_actual_committed_space(12 * K, 8 * K);
1027 test_virtual_space_actual_committed_space(12 * K, 12 * K);
1028 test_virtual_space_actual_committed_space(64 * K, 0);
1029 test_virtual_space_actual_committed_space(64 * K, 32 * K);
1030 test_virtual_space_actual_committed_space(64 * K, 64 * K);
1031 test_virtual_space_actual_committed_space(2 * M, 0);
1032 test_virtual_space_actual_committed_space(2 * M, 4 * K);
1033 test_virtual_space_actual_committed_space(2 * M, 64 * K);
1034 test_virtual_space_actual_committed_space(2 * M, 1 * M);
1035 test_virtual_space_actual_committed_space(2 * M, 2 * M);
1036 test_virtual_space_actual_committed_space(10 * M, 0);
1037 test_virtual_space_actual_committed_space(10 * M, 4 * K);
1038 test_virtual_space_actual_committed_space(10 * M, 8 * K);
1039 test_virtual_space_actual_committed_space(10 * M, 1 * M);
1040 test_virtual_space_actual_committed_space(10 * M, 2 * M);
1041 test_virtual_space_actual_committed_space(10 * M, 5 * M);
1042 test_virtual_space_actual_committed_space(10 * M, 10 * M);
1043 }
1044
1045 static void test_virtual_space() {
1046 test_virtual_space_actual_committed_space();
1047 test_virtual_space_actual_committed_space_one_large_page();
1048 }
1049 };
1050
1051 void TestVirtualSpace_test() {
1052 TestVirtualSpace::test_virtual_space();
1053 }
1054
1055 #endif // PRODUCT
717 1056
718 #endif 1057 #endif