@@ -417,11 +417,61 @@ stderr_last_error(char *msg)
417
417
/* OS Allocation */
418
418
/*****************/
419
419
420
+ static void zend_mm_munmap (void * addr , size_t size )
421
+ {
422
+ #ifdef _WIN32
423
+ if (VirtualFree (addr , 0 , MEM_RELEASE ) == 0 ) {
424
+ /** ERROR_INVALID_ADDRESS is expected when addr is not range start address */
425
+ if (GetLastError () != ERROR_INVALID_ADDRESS ) {
426
+ #if ZEND_MM_ERROR
427
+ stderr_last_error ("VirtualFree() failed" );
428
+ #endif
429
+ return ;
430
+ }
431
+ SetLastError (0 );
432
+
433
+ MEMORY_BASIC_INFORMATION mbi ;
434
+ if (VirtualQuery (addr , & mbi , sizeof (mbi )) == 0 ) {
435
+ #if ZEND_MM_ERROR
436
+ stderr_last_error ("VirtualQuery() failed" );
437
+ #endif
438
+ return ;
439
+ }
440
+ addr = mbi .AllocationBase ;
441
+
442
+ if (VirtualFree (addr , 0 , MEM_RELEASE ) == 0 ) {
443
+ #if ZEND_MM_ERROR
444
+ stderr_last_error ("VirtualFree() failed" );
445
+ #endif
446
+ }
447
+ }
448
+ #else
449
+ if (munmap (addr , size ) != 0 ) {
450
+ #if ZEND_MM_ERROR
451
+ fprintf (stderr , "\nmunmap() failed: [%d] %s\n" , errno , strerror (errno ));
452
+ #endif
453
+ }
454
+ #endif
455
+ }
456
+
420
457
#ifndef HAVE_MREMAP
421
458
static void * zend_mm_mmap_fixed (void * addr , size_t size )
422
459
{
423
460
#ifdef _WIN32
424
- return VirtualAlloc (addr , size , MEM_COMMIT | MEM_RESERVE , PAGE_READWRITE );
461
+ void * ptr = VirtualAlloc (addr , size , MEM_COMMIT | MEM_RESERVE , PAGE_READWRITE );
462
+
463
+ if (ptr == NULL ) {
464
+ /** ERROR_INVALID_ADDRESS is expected when fixed addr range is not free */
465
+ if (GetLastError () != ERROR_INVALID_ADDRESS ) {
466
+ #if ZEND_MM_ERROR
467
+ stderr_last_error ("VirtualAlloc() fixed failed" );
468
+ #endif
469
+ }
470
+ SetLastError (0 );
471
+ return NULL ;
472
+ }
473
+ ZEND_ASSERT (ptr == addr );
474
+ return ptr ;
425
475
#else
426
476
int flags = MAP_PRIVATE | MAP_ANON ;
427
477
#if defined(MAP_EXCL )
@@ -434,15 +484,11 @@ static void *zend_mm_mmap_fixed(void *addr, size_t size)
434
484
435
485
if (ptr == MAP_FAILED ) {
436
486
#if ZEND_MM_ERROR && !defined(MAP_EXCL ) && !defined(MAP_TRYFIXED )
437
- fprintf (stderr , "\nmmap() failed: [%d] %s\n" , errno , strerror (errno ));
487
+ fprintf (stderr , "\nmmap() fixed failed: [%d] %s\n" , errno , strerror (errno ));
438
488
#endif
439
489
return NULL ;
440
490
} else if (ptr != addr ) {
441
- if (munmap (ptr , size ) != 0 ) {
442
- #if ZEND_MM_ERROR
443
- fprintf (stderr , "\nmunmap() failed: [%d] %s\n" , errno , strerror (errno ));
444
- #endif
445
- }
491
+ zend_mm_munmap (ptr , size );
446
492
return NULL ;
447
493
}
448
494
return ptr ;
@@ -495,23 +541,6 @@ static void *zend_mm_mmap(size_t size)
495
541
#endif
496
542
}
497
543
498
- static void zend_mm_munmap (void * addr , size_t size )
499
- {
500
- #ifdef _WIN32
501
- if (VirtualFree (addr , 0 , MEM_RELEASE ) == 0 ) {
502
- #if ZEND_MM_ERROR
503
- stderr_last_error ("VirtualFree() failed" );
504
- #endif
505
- }
506
- #else
507
- if (munmap (addr , size ) != 0 ) {
508
- #if ZEND_MM_ERROR
509
- fprintf (stderr , "\nmunmap() failed: [%d] %s\n" , errno , strerror (errno ));
510
- #endif
511
- }
512
- #endif
513
- }
514
-
515
544
/***********/
516
545
/* Bitmask */
517
546
/***********/
@@ -704,13 +733,21 @@ static void *zend_mm_chunk_alloc_int(size_t size, size_t alignment)
704
733
zend_mm_munmap (ptr , size );
705
734
ptr = zend_mm_mmap (size + alignment - REAL_PAGE_SIZE );
706
735
#ifdef _WIN32
707
- offset = ZEND_MM_ALIGNED_OFFSET (ptr , alignment );
708
- zend_mm_munmap (ptr , size + alignment - REAL_PAGE_SIZE );
709
- ptr = zend_mm_mmap_fixed ((void * )((char * )ptr + (alignment - offset )), size );
710
736
offset = ZEND_MM_ALIGNED_OFFSET (ptr , alignment );
711
737
if (offset != 0 ) {
712
- zend_mm_munmap (ptr , size );
713
- return NULL ;
738
+ offset = alignment - offset ;
739
+ }
740
+ zend_mm_munmap (ptr , size + alignment - REAL_PAGE_SIZE );
741
+ ptr = zend_mm_mmap_fixed ((void * )((char * )ptr + offset ), size );
742
+ if (ptr == NULL ) { // fix GH-9650, fixed addr range is not free
743
+ ptr = zend_mm_mmap (size + alignment - REAL_PAGE_SIZE );
744
+ if (ptr == NULL ) {
745
+ return NULL ;
746
+ }
747
+ offset = ZEND_MM_ALIGNED_OFFSET (ptr , alignment );
748
+ if (offset != 0 ) {
749
+ ptr = (void * )((char * )ptr + alignment - offset );
750
+ }
714
751
}
715
752
return ptr ;
716
753
#else
@@ -1867,11 +1904,7 @@ static zend_mm_heap *zend_mm_init(void)
1867
1904
1868
1905
if (UNEXPECTED (chunk == NULL )) {
1869
1906
#if ZEND_MM_ERROR
1870
- #ifdef _WIN32
1871
- stderr_last_error ("Can't initialize heap" );
1872
- #else
1873
- fprintf (stderr , "\nCan't initialize heap: [%d] %s\n" , errno , strerror (errno ));
1874
- #endif
1907
+ fprintf (stderr , "Can't initialize heap\n" );
1875
1908
#endif
1876
1909
return NULL ;
1877
1910
}
@@ -3017,11 +3050,7 @@ ZEND_API zend_mm_heap *zend_mm_startup_ex(const zend_mm_handlers *handlers, void
3017
3050
chunk = (zend_mm_chunk * )handlers -> chunk_alloc (& tmp_storage , ZEND_MM_CHUNK_SIZE , ZEND_MM_CHUNK_SIZE );
3018
3051
if (UNEXPECTED (chunk == NULL )) {
3019
3052
#if ZEND_MM_ERROR
3020
- #ifdef _WIN32
3021
- stderr_last_error ("Can't initialize heap" );
3022
- #else
3023
- fprintf (stderr , "\nCan't initialize heap: [%d] %s\n" , errno , strerror (errno ));
3024
- #endif
3053
+ fprintf (stderr , "Can't initialize heap\n" );
3025
3054
#endif
3026
3055
return NULL ;
3027
3056
}
@@ -3064,11 +3093,7 @@ ZEND_API zend_mm_heap *zend_mm_startup_ex(const zend_mm_handlers *handlers, void
3064
3093
if (!storage ) {
3065
3094
handlers -> chunk_free (& tmp_storage , chunk , ZEND_MM_CHUNK_SIZE );
3066
3095
#if ZEND_MM_ERROR
3067
- #ifdef _WIN32
3068
- stderr_last_error ("Can't initialize heap" );
3069
- #else
3070
- fprintf (stderr , "\nCan't initialize heap: [%d] %s\n" , errno , strerror (errno ));
3071
- #endif
3096
+ fprintf (stderr , "Can't initialize heap\n" );
3072
3097
#endif
3073
3098
return NULL ;
3074
3099
}
0 commit comments