@@ -373,6 +373,15 @@ static inline bool can_reserve_executable_memory(void) {
373
373
#define PRINT_MAPPINGS (s ) { tty->print_cr (" %s" , s); os::print_memory_mappings ((char *)p, total_range_len, tty); }
374
374
// #define PRINT_MAPPINGS
375
375
376
+ // Release a range allocated with reserve_multiple carefully, to not trip mapping
377
+ // asserts on Windows in os::release_memory()
378
+ static void carefully_release_multiple (address start, int num_stripes, size_t stripe_len) {
379
+ for (int stripe = 0 ; stripe < num_stripes; stripe++) {
380
+ address q = start + (stripe * stripe_len);
381
+ EXPECT_TRUE (os::release_memory ((char *)q, stripe_len));
382
+ }
383
+ }
384
+
376
385
#ifndef _AIX // JDK-8257041
377
386
// Reserve an area consisting of multiple mappings
378
387
// (from multiple calls to os::reserve_memory)
@@ -385,25 +394,34 @@ static address reserve_multiple(int num_stripes, size_t stripe_len) {
385
394
const bool exec_supported = can_reserve_executable_memory ();
386
395
#endif
387
396
388
- size_t total_range_len = num_stripes * stripe_len;
389
- // Reserve a large contiguous area to get the address space...
390
- address p = (address)os::reserve_memory (total_range_len);
391
- EXPECT_NE (p, (address)NULL );
392
- // .. release it...
393
- EXPECT_TRUE (os::release_memory ((char *)p, total_range_len));
394
- // ... re-reserve in the same spot multiple areas...
395
- for (int stripe = 0 ; stripe < num_stripes; stripe++) {
396
- address q = p + (stripe * stripe_len);
397
- // Commit, alternatingly with or without exec permission,
398
- // to prevent kernel from folding these mappings.
397
+ address p = NULL ;
398
+ for (int tries = 0 ; tries < 256 && p == NULL ; tries ++) {
399
+ size_t total_range_len = num_stripes * stripe_len;
400
+ // Reserve a large contiguous area to get the address space...
401
+ p = (address)os::reserve_memory (total_range_len);
402
+ EXPECT_NE (p, (address)NULL );
403
+ // .. release it...
404
+ EXPECT_TRUE (os::release_memory ((char *)p, total_range_len));
405
+ // ... re-reserve in the same spot multiple areas...
406
+ for (int stripe = 0 ; stripe < num_stripes; stripe++) {
407
+ address q = p + (stripe * stripe_len);
408
+ // Commit, alternatingly with or without exec permission,
409
+ // to prevent kernel from folding these mappings.
399
410
#ifdef __APPLE__
400
- const bool executable = exec_supported ? (stripe % 2 == 0 ) : false ;
411
+ const bool executable = exec_supported ? (stripe % 2 == 0 ) : false ;
401
412
#else
402
- const bool executable = stripe % 2 == 0 ;
413
+ const bool executable = stripe % 2 == 0 ;
403
414
#endif
404
- q = (address)os::attempt_reserve_memory_at ((char *)q, stripe_len, executable);
405
- EXPECT_NE (q, (address)NULL );
406
- EXPECT_TRUE (os::commit_memory ((char *)q, stripe_len, executable));
415
+ q = (address)os::attempt_reserve_memory_at ((char *)q, stripe_len, executable);
416
+ if (q == NULL ) {
417
+ // Someone grabbed that area concurrently. Cleanup, then retry.
418
+ tty->print_cr (" reserve_multiple: retry (%d)..." , stripe);
419
+ carefully_release_multiple (p, stripe, stripe_len);
420
+ p = NULL ;
421
+ } else {
422
+ EXPECT_TRUE (os::commit_memory ((char *)q, stripe_len, executable));
423
+ }
424
+ }
407
425
}
408
426
return p;
409
427
}
@@ -426,14 +444,6 @@ static address reserve_one_commit_multiple(int num_stripes, size_t stripe_len) {
426
444
}
427
445
428
446
#ifdef _WIN32
429
- // Release a range allocated with reserve_multiple carefully, to not trip mapping
430
- // asserts on Windows in os::release_memory()
431
- static void carefully_release_multiple (address start, int num_stripes, size_t stripe_len) {
432
- for (int stripe = 0 ; stripe < num_stripes; stripe++) {
433
- address q = start + (stripe * stripe_len);
434
- EXPECT_TRUE (os::release_memory ((char *)q, stripe_len));
435
- }
436
- }
437
447
struct NUMASwitcher {
438
448
const bool _b;
439
449
NUMASwitcher (bool v): _b(UseNUMAInterleaving) { UseNUMAInterleaving = v; }
0 commit comments