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