@@ -416,11 +416,49 @@ stderr_last_error(char *msg)
416
416
/* OS Allocation */
417
417
/*****************/
418
418
419
+ static void zend_mm_munmap (void * addr , size_t size )
420
+ {
421
+ #ifdef _WIN32
422
+ MEMORY_BASIC_INFORMATION mbi ;
423
+ if (VirtualQuery (addr , & mbi , sizeof (mbi )) == 0 ) {
424
+ #if ZEND_MM_ERROR
425
+ stderr_last_error ("VirtualQuery() failed" );
426
+ #endif
427
+ }
428
+ addr = mbi .AllocationBase ;
429
+
430
+ if (VirtualFree (addr , 0 , MEM_RELEASE ) == 0 ) {
431
+ #if ZEND_MM_ERROR
432
+ stderr_last_error ("VirtualFree() failed" );
433
+ #endif
434
+ }
435
+ #else
436
+ if (munmap (addr , size ) != 0 ) {
437
+ #if ZEND_MM_ERROR
438
+ fprintf (stderr , "\nmunmap() failed: [%d] %s\n" , errno , strerror (errno ));
439
+ #endif
440
+ }
441
+ #endif
442
+ }
443
+
419
444
#ifndef HAVE_MREMAP
420
445
static void * zend_mm_mmap_fixed (void * addr , size_t size )
421
446
{
422
447
#ifdef _WIN32
423
- return VirtualAlloc (addr , size , MEM_COMMIT | MEM_RESERVE , PAGE_READWRITE );
448
+ void * ptr = VirtualAlloc (addr , size , MEM_COMMIT | MEM_RESERVE , PAGE_READWRITE );
449
+
450
+ if (ptr == NULL ) {
451
+ /** ERROR_INVALID_ADDRESS is expected when fixed addr range is not free */
452
+ if (GetLastError () != ERROR_INVALID_ADDRESS ) {
453
+ #if ZEND_MM_ERROR
454
+ stderr_last_error ("VirtualAlloc() fixed failed" );
455
+ #endif
456
+ }
457
+ SetLastError (0 );
458
+ return NULL ;
459
+ }
460
+ ZEND_ASSERT (ptr == addr );
461
+ return ptr ;
424
462
#else
425
463
int flags = MAP_PRIVATE | MAP_ANON ;
426
464
#if defined(MAP_EXCL )
@@ -431,15 +469,11 @@ static void *zend_mm_mmap_fixed(void *addr, size_t size)
431
469
432
470
if (ptr == MAP_FAILED ) {
433
471
#if ZEND_MM_ERROR && !defined(MAP_EXCL )
434
- fprintf (stderr , "\nmmap() failed: [%d] %s\n" , errno , strerror (errno ));
472
+ fprintf (stderr , "\nmmap() fixed failed: [%d] %s\n" , errno , strerror (errno ));
435
473
#endif
436
474
return NULL ;
437
475
} else if (ptr != addr ) {
438
- if (munmap (ptr , size ) != 0 ) {
439
- #if ZEND_MM_ERROR
440
- fprintf (stderr , "\nmunmap() failed: [%d] %s\n" , errno , strerror (errno ));
441
- #endif
442
- }
476
+ zend_mm_munmap (ptr , size );
443
477
return NULL ;
444
478
}
445
479
return ptr ;
@@ -483,23 +517,6 @@ static void *zend_mm_mmap(size_t size)
483
517
#endif
484
518
}
485
519
486
- static void zend_mm_munmap (void * addr , size_t size )
487
- {
488
- #ifdef _WIN32
489
- if (VirtualFree (addr , 0 , MEM_RELEASE ) == 0 ) {
490
- #if ZEND_MM_ERROR
491
- stderr_last_error ("VirtualFree() failed" );
492
- #endif
493
- }
494
- #else
495
- if (munmap (addr , size ) != 0 ) {
496
- #if ZEND_MM_ERROR
497
- fprintf (stderr , "\nmunmap() failed: [%d] %s\n" , errno , strerror (errno ));
498
- #endif
499
- }
500
- #endif
501
- }
502
-
503
520
/***********/
504
521
/* Bitmask */
505
522
/***********/
@@ -682,14 +699,28 @@ static void *zend_mm_chunk_alloc_int(size_t size, size_t alignment)
682
699
zend_mm_munmap (ptr , size );
683
700
ptr = zend_mm_mmap (size + alignment - REAL_PAGE_SIZE );
684
701
#ifdef _WIN32
685
- offset = ZEND_MM_ALIGNED_OFFSET (ptr , alignment );
686
- zend_mm_munmap (ptr , size + alignment - REAL_PAGE_SIZE );
687
- ptr = zend_mm_mmap_fixed ((void * )((char * )ptr + (alignment - offset )), size );
688
702
offset = ZEND_MM_ALIGNED_OFFSET (ptr , alignment );
689
703
if (offset != 0 ) {
690
- zend_mm_munmap (ptr , size );
691
- return NULL ;
704
+ offset = alignment - offset ;
692
705
}
706
+ zend_mm_munmap (ptr , size + alignment - REAL_PAGE_SIZE );
707
+ ptr = zend_mm_mmap_fixed ((void * )((char * )ptr + offset ), size );
708
+ if (ptr == NULL ) { // fix GH-9650, fixed addr range is not free
709
+ ptr = zend_mm_mmap (size + alignment - REAL_PAGE_SIZE );
710
+ if (ptr == NULL ) {
711
+ return NULL ;
712
+ }
713
+ offset = ZEND_MM_ALIGNED_OFFSET (ptr , alignment );
714
+ if (offset != 0 ) {
715
+ ptr = (void * )((char * )ptr + alignment - offset );
716
+ }
717
+ } else {
718
+ offset = ZEND_MM_ALIGNED_OFFSET (ptr , alignment );
719
+ if (offset != 0 ) {
720
+ zend_mm_munmap (ptr , size );
721
+ return NULL ;
722
+ }
723
+ }
693
724
return ptr ;
694
725
#else
695
726
offset = ZEND_MM_ALIGNED_OFFSET (ptr , alignment );
@@ -1847,11 +1878,7 @@ static zend_mm_heap *zend_mm_init(void)
1847
1878
1848
1879
if (UNEXPECTED (chunk == NULL )) {
1849
1880
#if ZEND_MM_ERROR
1850
- #ifdef _WIN32
1851
- stderr_last_error ("Can't initialize heap" );
1852
- #else
1853
- fprintf (stderr , "\nCan't initialize heap: [%d] %s\n" , errno , strerror (errno ));
1854
- #endif
1881
+ fprintf (stderr , "Can't initialize heap\n" );
1855
1882
#endif
1856
1883
return NULL ;
1857
1884
}
@@ -2978,11 +3005,7 @@ ZEND_API zend_mm_heap *zend_mm_startup_ex(const zend_mm_handlers *handlers, void
2978
3005
chunk = (zend_mm_chunk * )handlers -> chunk_alloc (& tmp_storage , ZEND_MM_CHUNK_SIZE , ZEND_MM_CHUNK_SIZE );
2979
3006
if (UNEXPECTED (chunk == NULL )) {
2980
3007
#if ZEND_MM_ERROR
2981
- #ifdef _WIN32
2982
- stderr_last_error ("Can't initialize heap" );
2983
- #else
2984
- fprintf (stderr , "\nCan't initialize heap: [%d] %s\n" , errno , strerror (errno ));
2985
- #endif
3008
+ fprintf (stderr , "Can't initialize heap\n" );
2986
3009
#endif
2987
3010
return NULL ;
2988
3011
}
@@ -3025,11 +3048,7 @@ ZEND_API zend_mm_heap *zend_mm_startup_ex(const zend_mm_handlers *handlers, void
3025
3048
if (!storage ) {
3026
3049
handlers -> chunk_free (& tmp_storage , chunk , ZEND_MM_CHUNK_SIZE );
3027
3050
#if ZEND_MM_ERROR
3028
- #ifdef _WIN32
3029
- stderr_last_error ("Can't initialize heap" );
3030
- #else
3031
- fprintf (stderr , "\nCan't initialize heap: [%d] %s\n" , errno , strerror (errno ));
3032
- #endif
3051
+ fprintf (stderr , "Can't initialize heap\n" );
3033
3052
#endif
3034
3053
return NULL ;
3035
3054
}
0 commit comments