1.1 --- a/src/share/vm/runtime/virtualspace.cpp Thu Aug 22 09:39:54 2013 -0700 1.2 +++ b/src/share/vm/runtime/virtualspace.cpp Thu Sep 05 11:04:39 2013 -0700 1.3 @@ -45,8 +45,19 @@ 1.4 1.5 1.6 // ReservedSpace 1.7 + 1.8 +// Dummy constructor 1.9 +ReservedSpace::ReservedSpace() : _base(NULL), _size(0), _noaccess_prefix(0), 1.10 + _alignment(0), _special(false), _executable(false) { 1.11 +} 1.12 + 1.13 ReservedSpace::ReservedSpace(size_t size) { 1.14 - initialize(size, 0, false, NULL, 0, false); 1.15 + size_t page_size = os::page_size_for_region(size, size, 1); 1.16 + bool large_pages = page_size != (size_t)os::vm_page_size(); 1.17 + // Don't force the alignment to be large page aligned, 1.18 + // since that will waste memory. 1.19 + size_t alignment = os::vm_allocation_granularity(); 1.20 + initialize(size, alignment, large_pages, NULL, 0, false); 1.21 } 1.22 1.23 ReservedSpace::ReservedSpace(size_t size, size_t alignment, 1.24 @@ -132,16 +143,18 @@ 1.25 1.26 if (special) { 1.27 1.28 - base = os::reserve_memory_special(size, requested_address, executable); 1.29 + base = os::reserve_memory_special(size, alignment, requested_address, executable); 1.30 1.31 if (base != NULL) { 1.32 if (failed_to_reserve_as_requested(base, requested_address, size, true)) { 1.33 // OS ignored requested address. Try different address. 1.34 return; 1.35 } 1.36 - // Check alignment constraints 1.37 + // Check alignment constraints. 1.38 assert((uintptr_t) base % alignment == 0, 1.39 - "Large pages returned a non-aligned address"); 1.40 + err_msg("Large pages returned a non-aligned address, base: " 1.41 + PTR_FORMAT " alignment: " PTR_FORMAT, 1.42 + base, (void*)(uintptr_t)alignment)); 1.43 _special = true; 1.44 } else { 1.45 // failed; try to reserve regular memory below 1.46 @@ -718,4 +731,188 @@ 1.47 tty->print_cr(" - [low_b, high_b]: [" INTPTR_FORMAT ", " INTPTR_FORMAT "]", low_boundary(), high_boundary()); 1.48 } 1.49 1.50 + 1.51 +/////////////// Unit tests /////////////// 1.52 + 1.53 +#ifndef PRODUCT 1.54 + 1.55 +#define test_log(...) \ 1.56 + do {\ 1.57 + if (VerboseInternalVMTests) { \ 1.58 + tty->print_cr(__VA_ARGS__); \ 1.59 + tty->flush(); \ 1.60 + }\ 1.61 + } while (false) 1.62 + 1.63 +class TestReservedSpace : AllStatic { 1.64 + public: 1.65 + static void small_page_write(void* addr, size_t size) { 1.66 + size_t page_size = os::vm_page_size(); 1.67 + 1.68 + char* end = (char*)addr + size; 1.69 + for (char* p = (char*)addr; p < end; p += page_size) { 1.70 + *p = 1; 1.71 + } 1.72 + } 1.73 + 1.74 + static void release_memory_for_test(ReservedSpace rs) { 1.75 + if (rs.special()) { 1.76 + guarantee(os::release_memory_special(rs.base(), rs.size()), "Shouldn't fail"); 1.77 + } else { 1.78 + guarantee(os::release_memory(rs.base(), rs.size()), "Shouldn't fail"); 1.79 + } 1.80 + } 1.81 + 1.82 + static void test_reserved_space1(size_t size, size_t alignment) { 1.83 + test_log("test_reserved_space1(%p)", (void*) (uintptr_t) size); 1.84 + 1.85 + assert(is_size_aligned(size, alignment), "Incorrect input parameters"); 1.86 + 1.87 + ReservedSpace rs(size, // size 1.88 + alignment, // alignment 1.89 + UseLargePages, // large 1.90 + NULL, // requested_address 1.91 + 0); // noacces_prefix 1.92 + 1.93 + test_log(" rs.special() == %d", rs.special()); 1.94 + 1.95 + assert(rs.base() != NULL, "Must be"); 1.96 + assert(rs.size() == size, "Must be"); 1.97 + 1.98 + assert(is_ptr_aligned(rs.base(), alignment), "aligned sizes should always give aligned addresses"); 1.99 + assert(is_size_aligned(rs.size(), alignment), "aligned sizes should always give aligned addresses"); 1.100 + 1.101 + if (rs.special()) { 1.102 + small_page_write(rs.base(), size); 1.103 + } 1.104 + 1.105 + release_memory_for_test(rs); 1.106 + } 1.107 + 1.108 + static void test_reserved_space2(size_t size) { 1.109 + test_log("test_reserved_space2(%p)", (void*)(uintptr_t)size); 1.110 + 1.111 + assert(is_size_aligned(size, os::vm_allocation_granularity()), "Must be at least AG aligned"); 1.112 + 1.113 + ReservedSpace rs(size); 1.114 + 1.115 + test_log(" rs.special() == %d", rs.special()); 1.116 + 1.117 + assert(rs.base() != NULL, "Must be"); 1.118 + assert(rs.size() == size, "Must be"); 1.119 + 1.120 + if (rs.special()) { 1.121 + small_page_write(rs.base(), size); 1.122 + } 1.123 + 1.124 + release_memory_for_test(rs); 1.125 + } 1.126 + 1.127 + static void test_reserved_space3(size_t size, size_t alignment, bool maybe_large) { 1.128 + test_log("test_reserved_space3(%p, %p, %d)", 1.129 + (void*)(uintptr_t)size, (void*)(uintptr_t)alignment, maybe_large); 1.130 + 1.131 + assert(is_size_aligned(size, os::vm_allocation_granularity()), "Must be at least AG aligned"); 1.132 + assert(is_size_aligned(size, alignment), "Must be at least aligned against alignment"); 1.133 + 1.134 + bool large = maybe_large && UseLargePages && size >= os::large_page_size(); 1.135 + 1.136 + ReservedSpace rs(size, alignment, large, false); 1.137 + 1.138 + test_log(" rs.special() == %d", rs.special()); 1.139 + 1.140 + assert(rs.base() != NULL, "Must be"); 1.141 + assert(rs.size() == size, "Must be"); 1.142 + 1.143 + if (rs.special()) { 1.144 + small_page_write(rs.base(), size); 1.145 + } 1.146 + 1.147 + release_memory_for_test(rs); 1.148 + } 1.149 + 1.150 + 1.151 + static void test_reserved_space1() { 1.152 + size_t size = 2 * 1024 * 1024; 1.153 + size_t ag = os::vm_allocation_granularity(); 1.154 + 1.155 + test_reserved_space1(size, ag); 1.156 + test_reserved_space1(size * 2, ag); 1.157 + test_reserved_space1(size * 10, ag); 1.158 + } 1.159 + 1.160 + static void test_reserved_space2() { 1.161 + size_t size = 2 * 1024 * 1024; 1.162 + size_t ag = os::vm_allocation_granularity(); 1.163 + 1.164 + test_reserved_space2(size * 1); 1.165 + test_reserved_space2(size * 2); 1.166 + test_reserved_space2(size * 10); 1.167 + test_reserved_space2(ag); 1.168 + test_reserved_space2(size - ag); 1.169 + test_reserved_space2(size); 1.170 + test_reserved_space2(size + ag); 1.171 + test_reserved_space2(size * 2); 1.172 + test_reserved_space2(size * 2 - ag); 1.173 + test_reserved_space2(size * 2 + ag); 1.174 + test_reserved_space2(size * 3); 1.175 + test_reserved_space2(size * 3 - ag); 1.176 + test_reserved_space2(size * 3 + ag); 1.177 + test_reserved_space2(size * 10); 1.178 + test_reserved_space2(size * 10 + size / 2); 1.179 + } 1.180 + 1.181 + static void test_reserved_space3() { 1.182 + size_t ag = os::vm_allocation_granularity(); 1.183 + 1.184 + test_reserved_space3(ag, ag , false); 1.185 + test_reserved_space3(ag * 2, ag , false); 1.186 + test_reserved_space3(ag * 3, ag , false); 1.187 + test_reserved_space3(ag * 2, ag * 2, false); 1.188 + test_reserved_space3(ag * 4, ag * 2, false); 1.189 + test_reserved_space3(ag * 8, ag * 2, false); 1.190 + test_reserved_space3(ag * 4, ag * 4, false); 1.191 + test_reserved_space3(ag * 8, ag * 4, false); 1.192 + test_reserved_space3(ag * 16, ag * 4, false); 1.193 + 1.194 + if (UseLargePages) { 1.195 + size_t lp = os::large_page_size(); 1.196 + 1.197 + // Without large pages 1.198 + test_reserved_space3(lp, ag * 4, false); 1.199 + test_reserved_space3(lp * 2, ag * 4, false); 1.200 + test_reserved_space3(lp * 4, ag * 4, false); 1.201 + test_reserved_space3(lp, lp , false); 1.202 + test_reserved_space3(lp * 2, lp , false); 1.203 + test_reserved_space3(lp * 3, lp , false); 1.204 + test_reserved_space3(lp * 2, lp * 2, false); 1.205 + test_reserved_space3(lp * 4, lp * 2, false); 1.206 + test_reserved_space3(lp * 8, lp * 2, false); 1.207 + 1.208 + // With large pages 1.209 + test_reserved_space3(lp, ag * 4 , true); 1.210 + test_reserved_space3(lp * 2, ag * 4, true); 1.211 + test_reserved_space3(lp * 4, ag * 4, true); 1.212 + test_reserved_space3(lp, lp , true); 1.213 + test_reserved_space3(lp * 2, lp , true); 1.214 + test_reserved_space3(lp * 3, lp , true); 1.215 + test_reserved_space3(lp * 2, lp * 2, true); 1.216 + test_reserved_space3(lp * 4, lp * 2, true); 1.217 + test_reserved_space3(lp * 8, lp * 2, true); 1.218 + } 1.219 + } 1.220 + 1.221 + static void test_reserved_space() { 1.222 + test_reserved_space1(); 1.223 + test_reserved_space2(); 1.224 + test_reserved_space3(); 1.225 + } 1.226 +}; 1.227 + 1.228 +void TestReservedSpace_test() { 1.229 + TestReservedSpace::test_reserved_space(); 1.230 +} 1.231 + 1.232 +#endif // PRODUCT 1.233 + 1.234 #endif