@@ -352,6 +352,23 @@ TEST_VM(os, jio_snprintf) {
352352 test_snprintf (jio_snprintf, false );
353353}
354354
355+ #ifdef __APPLE__
356+ // Not all macOS versions can use os::reserve_memory (i.e. anon_mmap) API
357+ // to reserve executable memory, so before attempting to use it,
358+ // we need to verify that we can do so by asking for a tiny executable
359+ // memory chunk.
360+ static inline bool can_reserve_executable_memory (void ) {
361+ bool executable = true ;
362+ size_t len = 128 ;
363+ char * p = os::reserve_memory (len, executable);
364+ bool exec_supported = (p != NULL );
365+ if (exec_supported) {
366+ os::release_memory (p, len);
367+ }
368+ return exec_supported;
369+ }
370+ #endif
371+
355372// Test that os::release_memory() can deal with areas containing multiple mappings.
356373#define PRINT_MAPPINGS (s ) { tty->print_cr (" %s" , s); os::print_memory_mappings ((char *)p, total_range_len, tty); }
357374// #define PRINT_MAPPINGS
@@ -361,6 +378,13 @@ TEST_VM(os, jio_snprintf) {
361378// (from multiple calls to os::reserve_memory)
362379static address reserve_multiple (int num_stripes, size_t stripe_len) {
363380 assert (is_aligned (stripe_len, os::vm_allocation_granularity ()), " Sanity" );
381+
382+ #ifdef __APPLE__
383+ // Workaround: try reserving executable memory to figure out
384+ // if such operation is supported on this macOS version
385+ const bool exec_supported = can_reserve_executable_memory ();
386+ #endif
387+
364388 size_t total_range_len = num_stripes * stripe_len;
365389 // Reserve a large contiguous area to get the address space...
366390 address p = (address)os::reserve_memory (total_range_len);
@@ -372,7 +396,11 @@ static address reserve_multiple(int num_stripes, size_t stripe_len) {
372396 address q = p + (stripe * stripe_len);
373397 // Commit, alternatingly with or without exec permission,
374398 // to prevent kernel from folding these mappings.
399+ #ifdef __APPLE__
400+ const bool executable = exec_supported ? (stripe % 2 == 0 ) : false ;
401+ #else
375402 const bool executable = stripe % 2 == 0 ;
403+ #endif
376404 q = (address)os::attempt_reserve_memory_at ((char *)q, stripe_len, executable);
377405 EXPECT_NE (q, (address)NULL );
378406 EXPECT_TRUE (os::commit_memory ((char *)q, stripe_len, executable));
@@ -414,11 +442,7 @@ struct NUMASwitcher {
414442#endif
415443
416444#ifndef _AIX // JDK-8257041
417- #if defined(__APPLE__) && !defined(AARCH64) // JDK-8267339
418- TEST_VM (os, DISABLED_release_multi_mappings) {
419- #else
420445 TEST_VM (os, release_multi_mappings) {
421- #endif
422446
423447 // With NMT enabled, this will trigger JDK-8263464. For now disable the test if NMT=on.
424448 if (MemTracker::tracking_level () > NMT_off) {
0 commit comments