@@ -419,6 +419,14 @@ stderr_last_error(char *msg)
419
419
static void zend_mm_munmap (void * addr , size_t size )
420
420
{
421
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
+
422
430
if (VirtualFree (addr , 0 , MEM_RELEASE ) == 0 ) {
423
431
#if ZEND_MM_ERROR
424
432
stderr_last_error ("VirtualFree() failed" );
@@ -440,9 +448,13 @@ static void *zend_mm_mmap_fixed(void *addr, size_t size)
440
448
void * ptr = VirtualAlloc (addr , size , MEM_COMMIT | MEM_RESERVE , PAGE_READWRITE );
441
449
442
450
if (ptr == NULL ) {
451
+ /** ERROR_INVALID_ADDRESS is expected when fixed addr range is not free */
452
+ if (GetLastError () != ERROR_INVALID_ADDRESS ) {
443
453
#if ZEND_MM_ERROR
444
- stderr_last_error ("VirtualAlloc() fixed failed" );
454
+ stderr_last_error ("VirtualAlloc() fixed failed" );
445
455
#endif
456
+ }
457
+ SetLastError (0 );
446
458
return NULL ;
447
459
}
448
460
return ptr ;
@@ -686,14 +698,28 @@ static void *zend_mm_chunk_alloc_int(size_t size, size_t alignment)
686
698
zend_mm_munmap (ptr , size );
687
699
ptr = zend_mm_mmap (size + alignment - REAL_PAGE_SIZE );
688
700
#ifdef _WIN32
689
- offset = ZEND_MM_ALIGNED_OFFSET (ptr , alignment );
690
- zend_mm_munmap (ptr , size + alignment - REAL_PAGE_SIZE );
691
- ptr = zend_mm_mmap_fixed ((void * )((char * )ptr + (alignment - offset )), size );
692
701
offset = ZEND_MM_ALIGNED_OFFSET (ptr , alignment );
693
702
if (offset != 0 ) {
694
- zend_mm_munmap (ptr , size );
695
- return NULL ;
703
+ offset = alignment - offset ;
696
704
}
705
+ zend_mm_munmap (ptr , size + alignment - REAL_PAGE_SIZE );
706
+ ptr = zend_mm_mmap_fixed ((void * )((char * )ptr + offset ), size );
707
+ if (ptr == NULL ) { // GH-9650, fixed addr range is not free
708
+ ptr = zend_mm_mmap (size + alignment - REAL_PAGE_SIZE );
709
+ if (ptr == NULL ) {
710
+ return NULL ;
711
+ }
712
+ offset = ZEND_MM_ALIGNED_OFFSET (ptr , alignment );
713
+ if (offset != 0 ) {
714
+ ptr += alignment - offset ;
715
+ }
716
+ } else {
717
+ offset = ZEND_MM_ALIGNED_OFFSET (ptr , alignment );
718
+ if (offset != 0 ) {
719
+ zend_mm_munmap (ptr , size );
720
+ return NULL ;
721
+ }
722
+ }
697
723
return ptr ;
698
724
#else
699
725
offset = ZEND_MM_ALIGNED_OFFSET (ptr , alignment );
0 commit comments