@@ -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,11 +448,16 @@ 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
}
460
+ ZEND_ASSERT (ptr == addr );
448
461
return ptr ;
449
462
#else
450
463
int flags = MAP_PRIVATE | MAP_ANON ;
@@ -686,14 +699,28 @@ static void *zend_mm_chunk_alloc_int(size_t size, size_t alignment)
686
699
zend_mm_munmap (ptr , size );
687
700
ptr = zend_mm_mmap (size + alignment - REAL_PAGE_SIZE );
688
701
#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
702
offset = ZEND_MM_ALIGNED_OFFSET (ptr , alignment );
693
703
if (offset != 0 ) {
694
- zend_mm_munmap (ptr , size );
695
- return NULL ;
704
+ offset = alignment - offset ;
696
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
+ }
697
724
return ptr ;
698
725
#else
699
726
offset = ZEND_MM_ALIGNED_OFFSET (ptr , alignment );
0 commit comments