1 /* 2 * Copyright (c) 2016, 2024, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 24 #include "precompiled.hpp" 25 #include "memory/allocation.hpp" 26 #include "memory/resourceArea.hpp" 27 #include "nmt/memTracker.hpp" 28 #include "runtime/frame.inline.hpp" 29 #include "runtime/globals.hpp" 30 #include "runtime/os.inline.hpp" 31 #include "runtime/thread.hpp" 32 #include "runtime/threads.hpp" 33 #include "utilities/align.hpp" 34 #include "utilities/globalDefinitions.hpp" 35 #include "utilities/macros.hpp" 36 #include "utilities/ostream.hpp" 37 #include "unittest.hpp" 38 #ifdef _WIN32 39 #include "os_windows.hpp" 40 #endif 41 42 using testing::HasSubstr; 43 44 static size_t small_page_size() { 45 return os::vm_page_size(); 46 } 47 48 static size_t large_page_size() { 49 const size_t large_page_size_example = 4 * M; 50 return os::page_size_for_region_aligned(large_page_size_example, 1); 51 } 52 53 TEST_VM(os, page_size_for_region) { 54 size_t large_page_example = 4 * M; 55 size_t large_page = os::page_size_for_region_aligned(large_page_example, 1); 56 57 size_t small_page = os::vm_page_size(); 58 if (large_page > small_page) { 59 size_t num_small_in_large = large_page / small_page; 60 size_t page = os::page_size_for_region_aligned(large_page, num_small_in_large); 61 ASSERT_EQ(page, small_page) << "Did not get a small page"; 62 } 63 } 64 65 TEST_VM(os, page_size_for_region_aligned) { 66 if (UseLargePages) { 67 const size_t small_page = small_page_size(); 68 const size_t large_page = large_page_size(); 69 70 if (large_page > small_page) { 71 size_t num_small_pages_in_large = large_page / small_page; 72 size_t page = os::page_size_for_region_aligned(large_page, num_small_pages_in_large); 73 74 ASSERT_EQ(page, small_page); 75 } 76 } 77 } 78 79 TEST_VM(os, page_size_for_region_alignment) { 80 if (UseLargePages) { 81 const size_t small_page = small_page_size(); 82 const size_t large_page = large_page_size(); 83 if (large_page > small_page) { 84 const size_t unaligned_region = large_page + 17; 85 size_t page = os::page_size_for_region_aligned(unaligned_region, 1); 86 ASSERT_EQ(page, small_page); 87 88 const size_t num_pages = 5; 89 const size_t aligned_region = large_page * num_pages; 90 page = os::page_size_for_region_aligned(aligned_region, num_pages); 91 ASSERT_EQ(page, large_page); 92 } 93 } 94 } 95 96 TEST_VM(os, page_size_for_region_unaligned) { 97 if (UseLargePages) { 98 // Given exact page size, should return that page size. 99 for (size_t s = os::page_sizes().largest(); s != 0; s = os::page_sizes().next_smaller(s)) { 100 size_t actual = os::page_size_for_region_unaligned(s, 1); 101 ASSERT_EQ(s, actual); 102 } 103 104 // Given slightly larger size than a page size, return the page size. 105 for (size_t s = os::page_sizes().largest(); s != 0; s = os::page_sizes().next_smaller(s)) { 106 size_t actual = os::page_size_for_region_unaligned(s + 17, 1); 107 ASSERT_EQ(s, actual); 108 } 109 110 // Given a slightly smaller size than a page size, 111 // return the next smaller page size. 112 for (size_t s = os::page_sizes().largest(); s != 0; s = os::page_sizes().next_smaller(s)) { 113 const size_t expected = os::page_sizes().next_smaller(s); 114 if (expected != 0) { 115 size_t actual = os::page_size_for_region_unaligned(s - 17, 1); 116 ASSERT_EQ(actual, expected); 117 } 118 } 119 120 // Return small page size for values less than a small page. 121 size_t small_page = os::page_sizes().smallest(); 122 size_t actual = os::page_size_for_region_unaligned(small_page - 17, 1); 123 ASSERT_EQ(small_page, actual); 124 } 125 } 126 127 TEST(os, test_random) { 128 const double m = 2147483647; 129 double mean = 0.0, variance = 0.0, t; 130 const int reps = 10000; 131 unsigned int seed = 1; 132 133 // tty->print_cr("seed %ld for %ld repeats...", seed, reps); 134 int num; 135 for (int k = 0; k < reps; k++) { 136 // Use next_random so the calculation is stateless. 137 num = seed = os::next_random(seed); 138 double u = (double)num / m; 139 ASSERT_TRUE(u >= 0.0 && u <= 1.0) << "bad random number!"; 140 141 // calculate mean and variance of the random sequence 142 mean += u; 143 variance += (u*u); 144 } 145 mean /= reps; 146 variance /= (reps - 1); 147 148 ASSERT_EQ(num, 1043618065) << "bad seed"; 149 // tty->print_cr("mean of the 1st 10000 numbers: %f", mean); 150 int intmean = (int)(mean*100); 151 ASSERT_EQ(intmean, 50); 152 // tty->print_cr("variance of the 1st 10000 numbers: %f", variance); 153 int intvariance = (int)(variance*100); 154 ASSERT_EQ(intvariance, 33); 155 const double eps = 0.0001; 156 t = fabsd(mean - 0.5018); 157 ASSERT_LT(t, eps) << "bad mean"; 158 t = (variance - 0.3355) < 0.0 ? -(variance - 0.3355) : variance - 0.3355; 159 ASSERT_LT(t, eps) << "bad variance"; 160 } 161 162 #ifdef ASSERT 163 TEST_VM_ASSERT_MSG(os, page_size_for_region_with_zero_min_pages, 164 "assert.min_pages > 0. failed: sanity") { 165 size_t region_size = 16 * os::vm_page_size(); 166 os::page_size_for_region_aligned(region_size, 0); // should assert 167 } 168 #endif 169 170 static void do_test_print_hex_dump(address addr, size_t len, int unitsize, const char* expected) { 171 char buf[256]; 172 buf[0] = '\0'; 173 stringStream ss(buf, sizeof(buf)); 174 os::print_hex_dump(&ss, addr, addr + len, unitsize); 175 // tty->print_cr("expected: %s", expected); 176 // tty->print_cr("result: %s", buf); 177 EXPECT_THAT(buf, HasSubstr(expected)); 178 } 179 180 TEST_VM(os, test_print_hex_dump) { 181 const char* pattern [4] = { 182 #ifdef VM_LITTLE_ENDIAN 183 "00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f", 184 "0100 0302 0504 0706 0908 0b0a 0d0c 0f0e", 185 "03020100 07060504 0b0a0908 0f0e0d0c", 186 "0706050403020100 0f0e0d0c0b0a0908" 187 #else 188 "00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f", 189 "0001 0203 0405 0607 0809 0a0b 0c0d 0e0f", 190 "00010203 04050607 08090a0b 0c0d0e0f", 191 "0001020304050607 08090a0b0c0d0e0f" 192 #endif 193 }; 194 195 const char* pattern_not_readable [4] = { 196 "?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ??", 197 "???? ???? ???? ???? ???? ???? ???? ????", 198 "???????? ???????? ???????? ????????", 199 "???????????????? ????????????????" 200 }; 201 202 // On AIX, zero page is readable. 203 address unreadable = 204 #ifdef AIX 205 (address) 0xFFFFFFFFFFFF0000ULL; 206 #else 207 (address) 0 208 #endif 209 ; 210 211 ResourceMark rm; 212 char buf[64]; 213 stringStream ss(buf, sizeof(buf)); 214 outputStream* out = &ss; 215 // outputStream* out = tty; // enable for printout 216 217 // Test dumping unreadable memory 218 // Exclude test for Windows for now, since it needs SEH handling to work which cannot be 219 // guaranteed when we call directly into VM code. (see JDK-8220220) 220 #ifndef _WIN32 221 do_test_print_hex_dump(unreadable, 100, 1, pattern_not_readable[0]); 222 do_test_print_hex_dump(unreadable, 100, 2, pattern_not_readable[1]); 223 do_test_print_hex_dump(unreadable, 100, 4, pattern_not_readable[2]); 224 do_test_print_hex_dump(unreadable, 100, 8, pattern_not_readable[3]); 225 #endif 226 227 // Test dumping readable memory 228 address arr = (address)os::malloc(100, mtInternal); 229 for (u1 c = 0; c < 100; c++) { 230 arr[c] = c; 231 } 232 233 // properly aligned 234 do_test_print_hex_dump(arr, 100, 1, pattern[0]); 235 do_test_print_hex_dump(arr, 100, 2, pattern[1]); 236 do_test_print_hex_dump(arr, 100, 4, pattern[2]); 237 do_test_print_hex_dump(arr, 100, 8, pattern[3]); 238 239 // Not properly aligned. Should automatically down-align by unitsize 240 do_test_print_hex_dump(arr + 1, 100, 2, pattern[1]); 241 do_test_print_hex_dump(arr + 1, 100, 4, pattern[2]); 242 do_test_print_hex_dump(arr + 1, 100, 8, pattern[3]); 243 244 os::free(arr); 245 } 246 247 ////////////////////////////////////////////////////////////////////////////// 248 // Test os::vsnprintf and friends. 249 250 static void check_snprintf_result(int expected, size_t limit, int actual, bool expect_count) { 251 if (expect_count || ((size_t)expected < limit)) { 252 ASSERT_EQ(expected, actual); 253 } else { 254 ASSERT_GT(0, actual); 255 } 256 } 257 258 // PrintFn is expected to be int (*)(char*, size_t, const char*, ...). 259 // But jio_snprintf is a C-linkage function with that signature, which 260 // has a different type on some platforms (like Solaris). 261 template<typename PrintFn> 262 static void test_snprintf(PrintFn pf, bool expect_count) { 263 const char expected[] = "abcdefghijklmnopqrstuvwxyz"; 264 const int expected_len = sizeof(expected) - 1; 265 const size_t padding_size = 10; 266 char buffer[2 * (sizeof(expected) + padding_size)]; 267 char check_buffer[sizeof(buffer)]; 268 const char check_char = '1'; // Something not in expected. 269 memset(check_buffer, check_char, sizeof(check_buffer)); 270 const size_t sizes_to_test[] = { 271 sizeof(buffer) - padding_size, // Fits, with plenty of space to spare. 272 sizeof(buffer)/2, // Fits, with space to spare. 273 sizeof(buffer)/4, // Doesn't fit. 274 sizeof(expected) + padding_size + 1, // Fits, with a little room to spare 275 sizeof(expected) + padding_size, // Fits exactly. 276 sizeof(expected) + padding_size - 1, // Doesn't quite fit. 277 2, // One char + terminating NUL. 278 1, // Only space for terminating NUL. 279 0 }; // No space at all. 280 for (unsigned i = 0; i < ARRAY_SIZE(sizes_to_test); ++i) { 281 memset(buffer, check_char, sizeof(buffer)); // To catch stray writes. 282 size_t test_size = sizes_to_test[i]; 283 ResourceMark rm; 284 stringStream s; 285 s.print("test_size: " SIZE_FORMAT, test_size); 286 SCOPED_TRACE(s.as_string()); 287 size_t prefix_size = padding_size; 288 guarantee(test_size <= (sizeof(buffer) - prefix_size), "invariant"); 289 size_t write_size = MIN2(sizeof(expected), test_size); 290 size_t suffix_size = sizeof(buffer) - prefix_size - write_size; 291 char* write_start = buffer + prefix_size; 292 char* write_end = write_start + write_size; 293 294 int result = pf(write_start, test_size, "%s", expected); 295 296 check_snprintf_result(expected_len, test_size, result, expect_count); 297 298 // Verify expected output. 299 if (test_size > 0) { 300 ASSERT_EQ(0, strncmp(write_start, expected, write_size - 1)); 301 // Verify terminating NUL of output. 302 ASSERT_EQ('\0', write_start[write_size - 1]); 303 } else { 304 guarantee(test_size == 0, "invariant"); 305 guarantee(write_size == 0, "invariant"); 306 guarantee(prefix_size + suffix_size == sizeof(buffer), "invariant"); 307 guarantee(write_start == write_end, "invariant"); 308 } 309 310 // Verify no scribbling on prefix or suffix. 311 ASSERT_EQ(0, strncmp(buffer, check_buffer, prefix_size)); 312 ASSERT_EQ(0, strncmp(write_end, check_buffer, suffix_size)); 313 } 314 315 // Special case of 0-length buffer with empty (except for terminator) output. 316 check_snprintf_result(0, 0, pf(nullptr, 0, "%s", ""), expect_count); 317 check_snprintf_result(0, 0, pf(nullptr, 0, ""), expect_count); 318 } 319 320 // This is probably equivalent to os::snprintf, but we're being 321 // explicit about what we're testing here. 322 static int vsnprintf_wrapper(char* buf, size_t len, const char* fmt, ...) { 323 va_list args; 324 va_start(args, fmt); 325 int result = os::vsnprintf(buf, len, fmt, args); 326 va_end(args); 327 return result; 328 } 329 330 TEST_VM(os, vsnprintf) { 331 test_snprintf(vsnprintf_wrapper, true); 332 } 333 334 TEST_VM(os, snprintf) { 335 test_snprintf(os::snprintf, true); 336 } 337 338 // These are declared in jvm.h; test here, with related functions. 339 extern "C" { 340 int jio_vsnprintf(char*, size_t, const char*, va_list); 341 int jio_snprintf(char*, size_t, const char*, ...); 342 } 343 344 // This is probably equivalent to jio_snprintf, but we're being 345 // explicit about what we're testing here. 346 static int jio_vsnprintf_wrapper(char* buf, size_t len, const char* fmt, ...) { 347 va_list args; 348 va_start(args, fmt); 349 int result = jio_vsnprintf(buf, len, fmt, args); 350 va_end(args); 351 return result; 352 } 353 354 TEST_VM(os, jio_vsnprintf) { 355 test_snprintf(jio_vsnprintf_wrapper, false); 356 } 357 358 TEST_VM(os, jio_snprintf) { 359 test_snprintf(jio_snprintf, false); 360 } 361 362 #ifdef __APPLE__ 363 // Not all macOS versions can use os::reserve_memory (i.e. anon_mmap) API 364 // to reserve executable memory, so before attempting to use it, 365 // we need to verify that we can do so by asking for a tiny executable 366 // memory chunk. 367 static inline bool can_reserve_executable_memory(void) { 368 bool executable = true; 369 size_t len = 128; 370 char* p = os::reserve_memory(len, executable); 371 bool exec_supported = (p != nullptr); 372 if (exec_supported) { 373 os::release_memory(p, len); 374 } 375 return exec_supported; 376 } 377 #endif 378 379 // Test that os::release_memory() can deal with areas containing multiple mappings. 380 #define PRINT_MAPPINGS(s) { tty->print_cr("%s", s); os::print_memory_mappings((char*)p, total_range_len, tty); tty->cr(); } 381 //#define PRINT_MAPPINGS 382 383 // Release a range allocated with reserve_multiple carefully, to not trip mapping 384 // asserts on Windows in os::release_memory() 385 static void carefully_release_multiple(address start, int num_stripes, size_t stripe_len) { 386 for (int stripe = 0; stripe < num_stripes; stripe++) { 387 address q = start + (stripe * stripe_len); 388 EXPECT_TRUE(os::release_memory((char*)q, stripe_len)); 389 } 390 } 391 392 #ifndef _AIX // JDK-8257041 393 // Reserve an area consisting of multiple mappings 394 // (from multiple calls to os::reserve_memory) 395 static address reserve_multiple(int num_stripes, size_t stripe_len) { 396 assert(is_aligned(stripe_len, os::vm_allocation_granularity()), "Sanity"); 397 398 #ifdef __APPLE__ 399 // Workaround: try reserving executable memory to figure out 400 // if such operation is supported on this macOS version 401 const bool exec_supported = can_reserve_executable_memory(); 402 #endif 403 404 address p = nullptr; 405 for (int tries = 0; tries < 256 && p == nullptr; tries ++) { 406 size_t total_range_len = num_stripes * stripe_len; 407 // Reserve a large contiguous area to get the address space... 408 p = (address)os::reserve_memory(total_range_len); 409 EXPECT_NE(p, (address)nullptr); 410 // .. release it... 411 EXPECT_TRUE(os::release_memory((char*)p, total_range_len)); 412 // ... re-reserve in the same spot multiple areas... 413 for (int stripe = 0; stripe < num_stripes; stripe++) { 414 address q = p + (stripe * stripe_len); 415 // Commit, alternatingly with or without exec permission, 416 // to prevent kernel from folding these mappings. 417 #ifdef __APPLE__ 418 const bool executable = exec_supported ? (stripe % 2 == 0) : false; 419 #else 420 const bool executable = stripe % 2 == 0; 421 #endif 422 q = (address)os::attempt_reserve_memory_at((char*)q, stripe_len, executable); 423 if (q == nullptr) { 424 // Someone grabbed that area concurrently. Cleanup, then retry. 425 tty->print_cr("reserve_multiple: retry (%d)...", stripe); 426 carefully_release_multiple(p, stripe, stripe_len); 427 p = nullptr; 428 } else { 429 EXPECT_TRUE(os::commit_memory((char*)q, stripe_len, executable)); 430 } 431 } 432 } 433 return p; 434 } 435 #endif // !AIX 436 437 // Reserve an area with a single call to os::reserve_memory, 438 // with multiple committed and uncommitted regions 439 static address reserve_one_commit_multiple(int num_stripes, size_t stripe_len) { 440 assert(is_aligned(stripe_len, os::vm_allocation_granularity()), "Sanity"); 441 size_t total_range_len = num_stripes * stripe_len; 442 address p = (address)os::reserve_memory(total_range_len); 443 EXPECT_NE(p, (address)nullptr); 444 for (int stripe = 0; stripe < num_stripes; stripe++) { 445 address q = p + (stripe * stripe_len); 446 if (stripe % 2 == 0) { 447 EXPECT_TRUE(os::commit_memory((char*)q, stripe_len, false)); 448 } 449 } 450 return p; 451 } 452 453 #ifdef _WIN32 454 struct NUMASwitcher { 455 const bool _b; 456 NUMASwitcher(bool v): _b(UseNUMAInterleaving) { UseNUMAInterleaving = v; } 457 ~NUMASwitcher() { UseNUMAInterleaving = _b; } 458 }; 459 #endif 460 461 #ifndef _AIX // JDK-8257041 462 TEST_VM(os, release_multi_mappings) { 463 464 // With NMT enabled, this will trigger JDK-8263464. For now disable the test if NMT=on. 465 if (MemTracker::tracking_level() > NMT_off) { 466 return; 467 } 468 469 // Test that we can release an area created with multiple reservation calls 470 // What we do: 471 // A) we reserve 6 small segments (stripes) adjacent to each other. We commit 472 // them with alternating permissions to prevent the kernel from folding them into 473 // a single segment. 474 // -stripe-stripe-stripe-stripe-stripe-stripe- 475 // B) we release the middle four stripes with a single os::release_memory call. This 476 // tests that os::release_memory indeed works across multiple segments created with 477 // multiple os::reserve calls. 478 // -stripe-___________________________-stripe- 479 // C) Into the now vacated address range between the first and the last stripe, we 480 // re-reserve a new memory range. We expect this to work as a proof that the address 481 // range was really released by the single release call (B). 482 // 483 // Note that this is inherently racy. Between (B) and (C), some other thread may have 484 // reserved something into the hole in the meantime. Therefore we keep that range small and 485 // entrenched between the first and last stripe, which reduces the chance of some concurrent 486 // thread grabbing that memory. 487 488 const size_t stripe_len = os::vm_allocation_granularity(); 489 const int num_stripes = 6; 490 const size_t total_range_len = stripe_len * num_stripes; 491 492 // reserve address space... 493 address p = reserve_multiple(num_stripes, stripe_len); 494 ASSERT_NE(p, (address)nullptr); 495 PRINT_MAPPINGS("A"); 496 497 // .. release the middle stripes... 498 address p_middle_stripes = p + stripe_len; 499 const size_t middle_stripe_len = (num_stripes - 2) * stripe_len; 500 { 501 // On Windows, temporarily switch on UseNUMAInterleaving to allow release_memory to release 502 // multiple mappings in one go (otherwise we assert, which we test too, see death test below). 503 WINDOWS_ONLY(NUMASwitcher b(true);) 504 ASSERT_TRUE(os::release_memory((char*)p_middle_stripes, middle_stripe_len)); 505 } 506 PRINT_MAPPINGS("B"); 507 508 // ...re-reserve the middle stripes. This should work unless release silently failed. 509 address p2 = (address)os::attempt_reserve_memory_at((char*)p_middle_stripes, middle_stripe_len); 510 511 ASSERT_EQ(p2, p_middle_stripes); 512 513 PRINT_MAPPINGS("C"); 514 515 // Clean up. Release all mappings. 516 { 517 WINDOWS_ONLY(NUMASwitcher b(true);) // allow release_memory to release multiple regions 518 ASSERT_TRUE(os::release_memory((char*)p, total_range_len)); 519 } 520 } 521 #endif // !AIX 522 523 #ifdef _WIN32 524 // On Windows, test that we recognize bad ranges. 525 // On debug this would assert. Test that too. 526 // On other platforms, we are unable to recognize bad ranges. 527 #ifdef ASSERT 528 TEST_VM_ASSERT_MSG(os, release_bad_ranges, ".*bad release") { 529 #else 530 TEST_VM(os, release_bad_ranges) { 531 #endif 532 char* p = os::reserve_memory(4 * M); 533 ASSERT_NE(p, (char*)nullptr); 534 // Release part of range 535 ASSERT_FALSE(os::release_memory(p, M)); 536 // Release part of range 537 ASSERT_FALSE(os::release_memory(p + M, M)); 538 // Release more than the range (explicitly switch off NUMA here 539 // to make os::release_memory() test more strictly and to not 540 // accidentally release neighbors) 541 { 542 NUMASwitcher b(false); 543 ASSERT_FALSE(os::release_memory(p, M * 5)); 544 ASSERT_FALSE(os::release_memory(p - M, M * 5)); 545 ASSERT_FALSE(os::release_memory(p - M, M * 6)); 546 } 547 548 ASSERT_TRUE(os::release_memory(p, 4 * M)); // Release for real 549 ASSERT_FALSE(os::release_memory(p, 4 * M)); // Again, should fail 550 } 551 #endif // _WIN32 552 553 TEST_VM(os, release_one_mapping_multi_commits) { 554 // Test that we can release an area consisting of interleaved 555 // committed and uncommitted regions: 556 const size_t stripe_len = os::vm_allocation_granularity(); 557 const int num_stripes = 6; 558 const size_t total_range_len = stripe_len * num_stripes; 559 560 // reserve address space... 561 address p = reserve_one_commit_multiple(num_stripes, stripe_len); 562 PRINT_MAPPINGS("A"); 563 ASSERT_NE(p, (address)nullptr); 564 565 // // make things even more difficult by trying to reserve at the border of the region 566 address border = p + num_stripes * stripe_len; 567 address p2 = (address)os::attempt_reserve_memory_at((char*)border, stripe_len); 568 PRINT_MAPPINGS("B"); 569 570 ASSERT_TRUE(p2 == nullptr || p2 == border); 571 572 ASSERT_TRUE(os::release_memory((char*)p, total_range_len)); 573 PRINT_MAPPINGS("C"); 574 575 if (p2 != nullptr) { 576 ASSERT_TRUE(os::release_memory((char*)p2, stripe_len)); 577 PRINT_MAPPINGS("D"); 578 } 579 } 580 581 static void test_show_mappings(address start, size_t size) { 582 // Note: should this overflow, thats okay. stream will silently truncate. Does not matter for the test. 583 const size_t buflen = 4 * M; 584 char* buf = NEW_C_HEAP_ARRAY(char, buflen, mtInternal); 585 buf[0] = '\0'; 586 stringStream ss(buf, buflen); 587 if (start != nullptr) { 588 os::print_memory_mappings((char*)start, size, &ss); 589 } else { 590 os::print_memory_mappings(&ss); // prints full address space 591 } 592 // Still an empty implementation on MacOS and AIX 593 #if defined(LINUX) || defined(_WIN32) 594 EXPECT_NE(buf[0], '\0'); 595 #endif 596 // buf[buflen - 1] = '\0'; 597 // tty->print_raw(buf); 598 FREE_C_HEAP_ARRAY(char, buf); 599 } 600 601 TEST_VM(os, show_mappings_small_range) { 602 test_show_mappings((address)0x100000, 2 * G); 603 } 604 605 TEST_VM(os, show_mappings_full_range) { 606 // Reserve a small range and fill it with a marker string, should show up 607 // on implementations displaying range snippets 608 char* p = os::reserve_memory(1 * M, false, mtInternal); 609 if (p != nullptr) { 610 if (os::commit_memory(p, 1 * M, false)) { 611 strcpy(p, "ABCDEFGHIJKLMNOPQRSTUVWXYZ"); 612 } 613 } 614 test_show_mappings(nullptr, 0); 615 if (p != nullptr) { 616 os::release_memory(p, 1 * M); 617 } 618 } 619 620 #ifdef _WIN32 621 // Test os::win32::find_mapping 622 TEST_VM(os, find_mapping_simple) { 623 const size_t total_range_len = 4 * M; 624 os::win32::mapping_info_t mapping_info; 625 626 // Some obvious negatives 627 ASSERT_FALSE(os::win32::find_mapping((address)nullptr, &mapping_info)); 628 ASSERT_FALSE(os::win32::find_mapping((address)4711, &mapping_info)); 629 630 // A simple allocation 631 { 632 address p = (address)os::reserve_memory(total_range_len); 633 ASSERT_NE(p, (address)nullptr); 634 PRINT_MAPPINGS("A"); 635 for (size_t offset = 0; offset < total_range_len; offset += 4711) { 636 ASSERT_TRUE(os::win32::find_mapping(p + offset, &mapping_info)); 637 ASSERT_EQ(mapping_info.base, p); 638 ASSERT_EQ(mapping_info.regions, 1); 639 ASSERT_EQ(mapping_info.size, total_range_len); 640 ASSERT_EQ(mapping_info.committed_size, 0); 641 } 642 // Test just outside the allocation 643 if (os::win32::find_mapping(p - 1, &mapping_info)) { 644 ASSERT_NE(mapping_info.base, p); 645 } 646 if (os::win32::find_mapping(p + total_range_len, &mapping_info)) { 647 ASSERT_NE(mapping_info.base, p); 648 } 649 ASSERT_TRUE(os::release_memory((char*)p, total_range_len)); 650 PRINT_MAPPINGS("B"); 651 ASSERT_FALSE(os::win32::find_mapping(p, &mapping_info)); 652 } 653 } 654 655 TEST_VM(os, find_mapping_2) { 656 // A more complex allocation, consisting of multiple regions. 657 const size_t total_range_len = 4 * M; 658 os::win32::mapping_info_t mapping_info; 659 660 const size_t stripe_len = total_range_len / 4; 661 address p = reserve_one_commit_multiple(4, stripe_len); 662 ASSERT_NE(p, (address)nullptr); 663 PRINT_MAPPINGS("A"); 664 for (size_t offset = 0; offset < total_range_len; offset += 4711) { 665 ASSERT_TRUE(os::win32::find_mapping(p + offset, &mapping_info)); 666 ASSERT_EQ(mapping_info.base, p); 667 ASSERT_EQ(mapping_info.regions, 4); 668 ASSERT_EQ(mapping_info.size, total_range_len); 669 ASSERT_EQ(mapping_info.committed_size, total_range_len / 2); 670 } 671 // Test just outside the allocation 672 if (os::win32::find_mapping(p - 1, &mapping_info)) { 673 ASSERT_NE(mapping_info.base, p); 674 } 675 if (os::win32::find_mapping(p + total_range_len, &mapping_info)) { 676 ASSERT_NE(mapping_info.base, p); 677 } 678 ASSERT_TRUE(os::release_memory((char*)p, total_range_len)); 679 PRINT_MAPPINGS("B"); 680 ASSERT_FALSE(os::win32::find_mapping(p, &mapping_info)); 681 } 682 683 TEST_VM(os, find_mapping_3) { 684 const size_t total_range_len = 4 * M; 685 os::win32::mapping_info_t mapping_info; 686 687 // A more complex case, consisting of multiple allocations. 688 { 689 const size_t stripe_len = total_range_len / 4; 690 address p = reserve_multiple(4, stripe_len); 691 ASSERT_NE(p, (address)nullptr); 692 PRINT_MAPPINGS("E"); 693 for (int stripe = 0; stripe < 4; stripe++) { 694 ASSERT_TRUE(os::win32::find_mapping(p + (stripe * stripe_len), &mapping_info)); 695 ASSERT_EQ(mapping_info.base, p + (stripe * stripe_len)); 696 ASSERT_EQ(mapping_info.regions, 1); 697 ASSERT_EQ(mapping_info.size, stripe_len); 698 ASSERT_EQ(mapping_info.committed_size, stripe_len); 699 } 700 carefully_release_multiple(p, 4, stripe_len); 701 PRINT_MAPPINGS("F"); 702 ASSERT_FALSE(os::win32::find_mapping(p, &mapping_info)); 703 } 704 } 705 #endif // _WIN32 706 707 TEST_VM(os, os_pagesizes) { 708 ASSERT_EQ(os::min_page_size(), 4 * K); 709 ASSERT_LE(os::min_page_size(), os::vm_page_size()); 710 // The vm_page_size should be the smallest in the set of allowed page sizes 711 // (contract says "default" page size but a lot of code actually assumes 712 // this to be the smallest page size; notable, deliberate exception is 713 // AIX which can have smaller page sizes but those are not part of the 714 // page_sizes() set). 715 ASSERT_EQ(os::page_sizes().smallest(), os::vm_page_size()); 716 // The large page size, if it exists, shall be part of the set 717 if (UseLargePages) { 718 ASSERT_GT(os::large_page_size(), os::vm_page_size()); 719 ASSERT_TRUE(os::page_sizes().contains(os::large_page_size())); 720 } 721 os::page_sizes().print_on(tty); 722 tty->cr(); 723 } 724 725 static const int min_page_size_log2 = exact_log2(os::min_page_size()); 726 static const int max_page_size_log2 = (int)BitsPerWord; 727 728 TEST_VM(os, pagesizes_test_range) { 729 for (int bit = min_page_size_log2; bit < max_page_size_log2; bit++) { 730 for (int bit2 = min_page_size_log2; bit2 < max_page_size_log2; bit2++) { 731 const size_t s = (size_t)1 << bit; 732 const size_t s2 = (size_t)1 << bit2; 733 os::PageSizes pss; 734 ASSERT_EQ((size_t)0, pss.smallest()); 735 ASSERT_EQ((size_t)0, pss.largest()); 736 // one size set 737 pss.add(s); 738 ASSERT_TRUE(pss.contains(s)); 739 ASSERT_EQ(s, pss.smallest()); 740 ASSERT_EQ(s, pss.largest()); 741 ASSERT_EQ(pss.next_larger(s), (size_t)0); 742 ASSERT_EQ(pss.next_smaller(s), (size_t)0); 743 // two set 744 pss.add(s2); 745 ASSERT_TRUE(pss.contains(s2)); 746 if (s2 < s) { 747 ASSERT_EQ(s2, pss.smallest()); 748 ASSERT_EQ(s, pss.largest()); 749 ASSERT_EQ(pss.next_larger(s2), (size_t)s); 750 ASSERT_EQ(pss.next_smaller(s2), (size_t)0); 751 ASSERT_EQ(pss.next_larger(s), (size_t)0); 752 ASSERT_EQ(pss.next_smaller(s), (size_t)s2); 753 } else if (s2 > s) { 754 ASSERT_EQ(s, pss.smallest()); 755 ASSERT_EQ(s2, pss.largest()); 756 ASSERT_EQ(pss.next_larger(s), (size_t)s2); 757 ASSERT_EQ(pss.next_smaller(s), (size_t)0); 758 ASSERT_EQ(pss.next_larger(s2), (size_t)0); 759 ASSERT_EQ(pss.next_smaller(s2), (size_t)s); 760 } 761 for (int bit3 = min_page_size_log2; bit3 < max_page_size_log2; bit3++) { 762 const size_t s3 = (size_t)1 << bit3; 763 ASSERT_EQ(s3 == s || s3 == s2, pss.contains(s3)); 764 } 765 } 766 } 767 } 768 769 TEST_VM(os, pagesizes_test_print) { 770 os::PageSizes pss; 771 const size_t sizes[] = { 16 * K, 64 * K, 128 * K, 1 * M, 4 * M, 1 * G, 2 * G, 0 }; 772 static const char* const expected = "16k, 64k, 128k, 1M, 4M, 1G, 2G"; 773 for (int i = 0; sizes[i] != 0; i++) { 774 pss.add(sizes[i]); 775 } 776 char buffer[256]; 777 stringStream ss(buffer, sizeof(buffer)); 778 pss.print_on(&ss); 779 EXPECT_STREQ(expected, buffer); 780 } 781 782 TEST_VM(os, dll_address_to_function_and_library_name) { 783 char tmp[1024]; 784 char output[1024]; 785 stringStream st(output, sizeof(output)); 786 787 #define EXPECT_CONTAINS(haystack, needle) \ 788 EXPECT_THAT(haystack, HasSubstr(needle)); 789 #define EXPECT_DOES_NOT_CONTAIN(haystack, needle) \ 790 EXPECT_THAT(haystack, Not(HasSubstr(needle))); 791 // #define LOG(...) tty->print_cr(__VA_ARGS__); // enable if needed 792 #define LOG(...) 793 794 // Invalid addresses 795 LOG("os::print_function_and_library_name(st, -1) expects FALSE."); 796 address addr = (address)(intptr_t)-1; 797 EXPECT_FALSE(os::print_function_and_library_name(&st, addr)); 798 LOG("os::print_function_and_library_name(st, nullptr) expects FALSE."); 799 addr = nullptr; 800 EXPECT_FALSE(os::print_function_and_library_name(&st, addr)); 801 802 // Valid addresses 803 // Test with or without shorten-paths, demangle, and scratch buffer 804 for (int i = 0; i < 16; i++) { 805 const bool shorten_paths = (i & 1) != 0; 806 const bool demangle = (i & 2) != 0; 807 const bool strip_arguments = (i & 4) != 0; 808 const bool provide_scratch_buffer = (i & 8) != 0; 809 LOG("shorten_paths=%d, demangle=%d, strip_arguments=%d, provide_scratch_buffer=%d", 810 shorten_paths, demangle, strip_arguments, provide_scratch_buffer); 811 812 // Should show os::min_page_size in libjvm 813 addr = CAST_FROM_FN_PTR(address, Threads::create_vm); 814 st.reset(); 815 EXPECT_TRUE(os::print_function_and_library_name(&st, addr, 816 provide_scratch_buffer ? tmp : nullptr, 817 sizeof(tmp), 818 shorten_paths, demangle, 819 strip_arguments)); 820 EXPECT_CONTAINS(output, "Threads"); 821 EXPECT_CONTAINS(output, "create_vm"); 822 EXPECT_CONTAINS(output, "jvm"); // "jvm.dll" or "libjvm.so" or similar 823 LOG("%s", output); 824 825 // Test truncation on scratch buffer 826 if (provide_scratch_buffer) { 827 st.reset(); 828 tmp[10] = 'X'; 829 EXPECT_TRUE(os::print_function_and_library_name(&st, addr, tmp, 10, 830 shorten_paths, demangle)); 831 EXPECT_EQ(tmp[10], 'X'); 832 LOG("%s", output); 833 } 834 } 835 } 836 837 // Not a regex! Very primitive, just match: 838 // "d" - digit 839 // "a" - ascii 840 // "." - everything 841 // rest must match 842 static bool very_simple_string_matcher(const char* pattern, const char* s) { 843 const size_t lp = strlen(pattern); 844 const size_t ls = strlen(s); 845 if (ls < lp) { 846 return false; 847 } 848 for (size_t i = 0; i < lp; i ++) { 849 switch (pattern[i]) { 850 case '.': continue; 851 case 'd': if (!isdigit(s[i])) return false; break; 852 case 'a': if (!isascii(s[i])) return false; break; 853 default: if (s[i] != pattern[i]) return false; break; 854 } 855 } 856 return true; 857 } 858 859 TEST_VM(os, iso8601_time) { 860 char buffer[os::iso8601_timestamp_size + 1]; // + space for canary 861 buffer[os::iso8601_timestamp_size] = 'X'; // canary 862 const char* result = nullptr; 863 // YYYY-MM-DDThh:mm:ss.mmm+zzzz 864 const char* const pattern_utc = "dddd-dd-dd.dd:dd:dd.ddd.0000"; 865 const char* const pattern_local = "dddd-dd-dd.dd:dd:dd.ddd.dddd"; 866 867 result = os::iso8601_time(buffer, sizeof(buffer), true); 868 tty->print_cr("%s", result); 869 EXPECT_EQ(result, buffer); 870 EXPECT_TRUE(very_simple_string_matcher(pattern_utc, result)); 871 872 result = os::iso8601_time(buffer, sizeof(buffer), false); 873 tty->print_cr("%s", result); 874 EXPECT_EQ(result, buffer); 875 EXPECT_TRUE(very_simple_string_matcher(pattern_local, result)); 876 877 // Test with explicit timestamps 878 result = os::iso8601_time(0, buffer, sizeof(buffer), true); 879 tty->print_cr("%s", result); 880 EXPECT_EQ(result, buffer); 881 EXPECT_TRUE(very_simple_string_matcher("1970-01-01.00:00:00.000+0000", result)); 882 883 result = os::iso8601_time(17, buffer, sizeof(buffer), true); 884 tty->print_cr("%s", result); 885 EXPECT_EQ(result, buffer); 886 EXPECT_TRUE(very_simple_string_matcher("1970-01-01.00:00:00.017+0000", result)); 887 888 // Canary should still be intact 889 EXPECT_EQ(buffer[os::iso8601_timestamp_size], 'X'); 890 } 891 892 TEST_VM(os, is_first_C_frame) { 893 #if !defined(_WIN32) && !defined(ZERO) && !defined(__thumb__) 894 frame invalid_frame; 895 EXPECT_TRUE(os::is_first_C_frame(&invalid_frame)); // the frame has zeroes for all values 896 897 frame cur_frame = os::current_frame(); // this frame has to have a sender 898 EXPECT_FALSE(os::is_first_C_frame(&cur_frame)); 899 #endif // _WIN32 900 } 901 902 #ifdef __GLIBC__ 903 TEST_VM(os, trim_native_heap) { 904 EXPECT_TRUE(os::can_trim_native_heap()); 905 os::size_change_t sc; 906 sc.before = sc.after = (size_t)-1; 907 EXPECT_TRUE(os::trim_native_heap(&sc)); 908 tty->print_cr(SIZE_FORMAT "->" SIZE_FORMAT, sc.before, sc.after); 909 // Regardless of whether we freed memory, both before and after 910 // should be somewhat believable numbers (RSS). 911 const size_t min = 5 * M; 912 const size_t max = LP64_ONLY(20 * G) NOT_LP64(3 * G); 913 ASSERT_LE(min, sc.before); 914 ASSERT_GT(max, sc.before); 915 ASSERT_LE(min, sc.after); 916 ASSERT_GT(max, sc.after); 917 // Should also work 918 EXPECT_TRUE(os::trim_native_heap()); 919 } 920 #else 921 TEST_VM(os, trim_native_heap) { 922 EXPECT_FALSE(os::can_trim_native_heap()); 923 } 924 #endif // __GLIBC__ 925 926 TEST_VM(os, open_O_CLOEXEC) { 927 #if !defined(_WIN32) 928 int fd = os::open("test_file.txt", O_RDWR | O_CREAT | O_TRUNC, 0666); // open will use O_CLOEXEC 929 EXPECT_TRUE(fd > 0); 930 int flags = ::fcntl(fd, F_GETFD); 931 EXPECT_TRUE((flags & FD_CLOEXEC) != 0); // if O_CLOEXEC worked, then FD_CLOEXEC should be ON 932 ::close(fd); 933 #endif 934 } 935 936 TEST_VM(os, reserve_at_wish_address_shall_not_replace_mappings_smallpages) { 937 char* p1 = os::reserve_memory(M, false, mtTest); 938 ASSERT_NE(p1, nullptr); 939 char* p2 = os::attempt_reserve_memory_at(p1, M); 940 ASSERT_EQ(p2, nullptr); // should have failed 941 os::release_memory(p1, M); 942 } 943 944 TEST_VM(os, reserve_at_wish_address_shall_not_replace_mappings_largepages) { 945 if (UseLargePages && !os::can_commit_large_page_memory()) { // aka special 946 const size_t lpsz = os::large_page_size(); 947 char* p1 = os::reserve_memory_aligned(lpsz, lpsz, false); 948 ASSERT_NE(p1, nullptr); 949 char* p2 = os::reserve_memory_special(lpsz, lpsz, lpsz, p1, false); 950 ASSERT_EQ(p2, nullptr); // should have failed 951 os::release_memory(p1, M); 952 } else { 953 tty->print_cr("Skipped."); 954 } 955 } 956 957 #ifdef AIX 958 // On Aix, we should fail attach attempts not aligned to segment boundaries (256m) 959 TEST_VM(os, aix_reserve_at_non_shmlba_aligned_address) { 960 if (Use64KPages) { 961 char* p = os::attempt_reserve_memory_at((char*)0x1f00000, M); 962 ASSERT_EQ(p, nullptr); // should have failed 963 p = os::attempt_reserve_memory_at((char*)((64 * G) + M), M); 964 ASSERT_EQ(p, nullptr); // should have failed 965 } 966 } 967 #endif // AIX 968 969 TEST_VM(os, vm_min_address) { 970 size_t s = os::vm_min_address(); 971 ASSERT_GE(s, M); 972 // Test upper limit. On Linux, its adjustable, so we just test for absurd values to prevent errors 973 // with high vm.mmap_min_addr settings. 974 #if defined(_LP64) 975 ASSERT_LE(s, NOT_LINUX(G * 4) LINUX_ONLY(G * 1024)); 976 #endif 977 }