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 }

--- EOF ---