Mercurial > hg > graal-compiler
comparison src/share/vm/runtime/virtualspace.cpp @ 12110:4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
Summary: Replace the broken large pages implementation on Linux. New flag: -XX:+UseTransparentHugePages - Linux specific flag to turn on transparent huge page hinting with madvise(..., MAP_HUGETLB). Changed behavior: -XX:+UseLargePages - tries to use -XX:+UseTransparentHugePages before trying other large pages implementations (on Linux). Changed behavior: -XX:+UseHugeTLBFS - Use upfront allocation of Large Pages instead of using the broken implementation to dynamically committing large pages. Changed behavior: -XX:LargePageSizeInBytes - Turned off the ability to use this flag on Linux and provides warning to user if set to a value different than the OS chosen large page size. Changed behavior: Setting no large page size - Now defaults to use -XX:UseTransparentHugePages if the OS supports it. Previously, -XX:+UseHugeTLBFS was chosen if the OS was configured to use large pages.
Reviewed-by: tschatzl, dcubed, brutisso
author | stefank |
---|---|
date | Fri, 16 Aug 2013 13:22:32 +0200 |
parents | a837fa3d3f86 |
children | c4c768305a8f e2722a66aba7 |
comparison
equal
deleted
inserted
replaced
12108:badf4244ceae | 12110:4c84d351cca9 |
---|---|
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))) { |
713 tty->print_cr(" - reserved: " SIZE_FORMAT, reserved_size()); | 726 tty->print_cr(" - reserved: " SIZE_FORMAT, reserved_size()); |
714 tty->print_cr(" - [low, high]: [" INTPTR_FORMAT ", " INTPTR_FORMAT "]", low(), high()); | 727 tty->print_cr(" - [low, high]: [" INTPTR_FORMAT ", " INTPTR_FORMAT "]", low(), high()); |
715 tty->print_cr(" - [low_b, high_b]: [" INTPTR_FORMAT ", " INTPTR_FORMAT "]", low_boundary(), high_boundary()); | 728 tty->print_cr(" - [low_b, high_b]: [" INTPTR_FORMAT ", " INTPTR_FORMAT "]", low_boundary(), high_boundary()); |
716 } | 729 } |
717 | 730 |
731 | |
732 /////////////// Unit tests /////////////// | |
733 | |
734 #ifndef PRODUCT | |
735 | |
736 #define test_log(...) \ | |
737 do {\ | |
738 if (VerboseInternalVMTests) { \ | |
739 tty->print_cr(__VA_ARGS__); \ | |
740 tty->flush(); \ | |
741 }\ | |
742 } while (false) | |
743 | |
744 class TestReservedSpace : AllStatic { | |
745 public: | |
746 static void small_page_write(void* addr, size_t size) { | |
747 size_t page_size = os::vm_page_size(); | |
748 | |
749 char* end = (char*)addr + size; | |
750 for (char* p = (char*)addr; p < end; p += page_size) { | |
751 *p = 1; | |
752 } | |
753 } | |
754 | |
755 static void release_memory_for_test(ReservedSpace rs) { | |
756 if (rs.special()) { | |
757 guarantee(os::release_memory_special(rs.base(), rs.size()), "Shouldn't fail"); | |
758 } else { | |
759 guarantee(os::release_memory(rs.base(), rs.size()), "Shouldn't fail"); | |
760 } | |
761 } | |
762 | |
763 static void test_reserved_space1(size_t size, size_t alignment) { | |
764 test_log("test_reserved_space1(%p)", (void*) (uintptr_t) size); | |
765 | |
766 assert(is_size_aligned(size, alignment), "Incorrect input parameters"); | |
767 | |
768 ReservedSpace rs(size, // size | |
769 alignment, // alignment | |
770 UseLargePages, // large | |
771 NULL, // requested_address | |
772 0); // noacces_prefix | |
773 | |
774 test_log(" rs.special() == %d", rs.special()); | |
775 | |
776 assert(rs.base() != NULL, "Must be"); | |
777 assert(rs.size() == size, "Must be"); | |
778 | |
779 assert(is_ptr_aligned(rs.base(), alignment), "aligned sizes should always give aligned addresses"); | |
780 assert(is_size_aligned(rs.size(), alignment), "aligned sizes should always give aligned addresses"); | |
781 | |
782 if (rs.special()) { | |
783 small_page_write(rs.base(), size); | |
784 } | |
785 | |
786 release_memory_for_test(rs); | |
787 } | |
788 | |
789 static void test_reserved_space2(size_t size) { | |
790 test_log("test_reserved_space2(%p)", (void*)(uintptr_t)size); | |
791 | |
792 assert(is_size_aligned(size, os::vm_allocation_granularity()), "Must be at least AG aligned"); | |
793 | |
794 ReservedSpace rs(size); | |
795 | |
796 test_log(" rs.special() == %d", rs.special()); | |
797 | |
798 assert(rs.base() != NULL, "Must be"); | |
799 assert(rs.size() == size, "Must be"); | |
800 | |
801 if (rs.special()) { | |
802 small_page_write(rs.base(), size); | |
803 } | |
804 | |
805 release_memory_for_test(rs); | |
806 } | |
807 | |
808 static void test_reserved_space3(size_t size, size_t alignment, bool maybe_large) { | |
809 test_log("test_reserved_space3(%p, %p, %d)", | |
810 (void*)(uintptr_t)size, (void*)(uintptr_t)alignment, maybe_large); | |
811 | |
812 assert(is_size_aligned(size, os::vm_allocation_granularity()), "Must be at least AG aligned"); | |
813 assert(is_size_aligned(size, alignment), "Must be at least aligned against alignment"); | |
814 | |
815 bool large = maybe_large && UseLargePages && size >= os::large_page_size(); | |
816 | |
817 ReservedSpace rs(size, alignment, large, false); | |
818 | |
819 test_log(" rs.special() == %d", rs.special()); | |
820 | |
821 assert(rs.base() != NULL, "Must be"); | |
822 assert(rs.size() == size, "Must be"); | |
823 | |
824 if (rs.special()) { | |
825 small_page_write(rs.base(), size); | |
826 } | |
827 | |
828 release_memory_for_test(rs); | |
829 } | |
830 | |
831 | |
832 static void test_reserved_space1() { | |
833 size_t size = 2 * 1024 * 1024; | |
834 size_t ag = os::vm_allocation_granularity(); | |
835 | |
836 test_reserved_space1(size, ag); | |
837 test_reserved_space1(size * 2, ag); | |
838 test_reserved_space1(size * 10, ag); | |
839 } | |
840 | |
841 static void test_reserved_space2() { | |
842 size_t size = 2 * 1024 * 1024; | |
843 size_t ag = os::vm_allocation_granularity(); | |
844 | |
845 test_reserved_space2(size * 1); | |
846 test_reserved_space2(size * 2); | |
847 test_reserved_space2(size * 10); | |
848 test_reserved_space2(ag); | |
849 test_reserved_space2(size - ag); | |
850 test_reserved_space2(size); | |
851 test_reserved_space2(size + ag); | |
852 test_reserved_space2(size * 2); | |
853 test_reserved_space2(size * 2 - ag); | |
854 test_reserved_space2(size * 2 + ag); | |
855 test_reserved_space2(size * 3); | |
856 test_reserved_space2(size * 3 - ag); | |
857 test_reserved_space2(size * 3 + ag); | |
858 test_reserved_space2(size * 10); | |
859 test_reserved_space2(size * 10 + size / 2); | |
860 } | |
861 | |
862 static void test_reserved_space3() { | |
863 size_t ag = os::vm_allocation_granularity(); | |
864 | |
865 test_reserved_space3(ag, ag , false); | |
866 test_reserved_space3(ag * 2, ag , false); | |
867 test_reserved_space3(ag * 3, ag , false); | |
868 test_reserved_space3(ag * 2, ag * 2, false); | |
869 test_reserved_space3(ag * 4, ag * 2, false); | |
870 test_reserved_space3(ag * 8, ag * 2, false); | |
871 test_reserved_space3(ag * 4, ag * 4, false); | |
872 test_reserved_space3(ag * 8, ag * 4, false); | |
873 test_reserved_space3(ag * 16, ag * 4, false); | |
874 | |
875 if (UseLargePages) { | |
876 size_t lp = os::large_page_size(); | |
877 | |
878 // Without large pages | |
879 test_reserved_space3(lp, ag * 4, false); | |
880 test_reserved_space3(lp * 2, ag * 4, false); | |
881 test_reserved_space3(lp * 4, ag * 4, false); | |
882 test_reserved_space3(lp, lp , false); | |
883 test_reserved_space3(lp * 2, lp , false); | |
884 test_reserved_space3(lp * 3, lp , false); | |
885 test_reserved_space3(lp * 2, lp * 2, false); | |
886 test_reserved_space3(lp * 4, lp * 2, false); | |
887 test_reserved_space3(lp * 8, lp * 2, false); | |
888 | |
889 // With large pages | |
890 test_reserved_space3(lp, ag * 4 , true); | |
891 test_reserved_space3(lp * 2, ag * 4, true); | |
892 test_reserved_space3(lp * 4, ag * 4, true); | |
893 test_reserved_space3(lp, lp , true); | |
894 test_reserved_space3(lp * 2, lp , true); | |
895 test_reserved_space3(lp * 3, lp , true); | |
896 test_reserved_space3(lp * 2, lp * 2, true); | |
897 test_reserved_space3(lp * 4, lp * 2, true); | |
898 test_reserved_space3(lp * 8, lp * 2, true); | |
899 } | |
900 } | |
901 | |
902 static void test_reserved_space() { | |
903 test_reserved_space1(); | |
904 test_reserved_space2(); | |
905 test_reserved_space3(); | |
906 } | |
907 }; | |
908 | |
909 void TestReservedSpace_test() { | |
910 TestReservedSpace::test_reserved_space(); | |
911 } | |
912 | |
913 #endif // PRODUCT | |
914 | |
718 #endif | 915 #endif |