@@ -418,6 +418,14 @@ stderr_last_error(char *msg)
418
418
static void zend_mm_munmap (void * addr , size_t size )
419
419
{
420
420
#ifdef _WIN32
421
+ MEMORY_BASIC_INFORMATION mbi ;
422
+ if (VirtualQuery (addr , & mbi , sizeof (mbi )) == 0 ) {
423
+ #if ZEND_MM_ERROR
424
+ stderr_last_error ("VirtualQuery() failed" );
425
+ #endif
426
+ }
427
+ addr = mbi .AllocationBase ;
428
+
421
429
if (VirtualFree (addr , 0 , MEM_RELEASE ) == 0 ) {
422
430
#if ZEND_MM_ERROR
423
431
stderr_last_error ("VirtualFree() failed" );
@@ -432,54 +440,34 @@ static void zend_mm_munmap(void *addr, size_t size)
432
440
#endif
433
441
}
434
442
435
- #ifndef HAVE_MREMAP
436
- static void * zend_mm_mmap_fixed (void * addr , size_t size )
437
- {
438
443
#ifdef _WIN32
439
- void * ptr = VirtualAlloc (addr , size , MEM_COMMIT | MEM_RESERVE , PAGE_READWRITE );
444
+ static void * zend_mm_mmap_reserve (size_t size )
445
+ {
446
+ void * ptr = VirtualAlloc (NULL , size , MEM_RESERVE , PAGE_READWRITE );
440
447
if (ptr == NULL ) {
441
448
#if ZEND_MM_ERROR
442
- stderr_last_error ("VirtualAlloc() failed" );
449
+ stderr_last_error ("VirtualAlloc() reserve failed" );
443
450
#endif
444
451
return NULL ;
445
452
}
446
- ZEND_ASSERT (ptr == addr );
447
453
return ptr ;
448
- #else
449
- int flags = MAP_PRIVATE | MAP_ANON ;
450
- #if defined(MAP_EXCL )
451
- flags |= MAP_FIXED | MAP_EXCL ;
452
- #endif
453
- /* MAP_FIXED leads to discarding of the old mapping, so it can't be used. */
454
- void * ptr = mmap (addr , size , PROT_READ | PROT_WRITE , flags /*| MAP_POPULATE | MAP_HUGETLB*/ , ZEND_MM_FD , 0 );
455
-
456
- if (ptr == MAP_FAILED ) {
457
- #if ZEND_MM_ERROR && !defined(MAP_EXCL )
458
- fprintf (stderr , "\nmmap() failed: [%d] %s\n" , errno , strerror (errno ));
459
- #endif
460
- return NULL ;
461
- } else if (ptr != addr ) {
462
- zend_mm_munmap (ptr , size );
463
- return NULL ;
464
- }
465
- return ptr ;
466
- #endif
467
454
}
468
- #endif
469
455
470
- static void * zend_mm_mmap ( size_t size )
456
+ static void * zend_mm_mmap_commit ( void * addr , size_t size )
471
457
{
472
- #ifdef _WIN32
473
- void * ptr = VirtualAlloc (NULL , size , MEM_COMMIT | MEM_RESERVE , PAGE_READWRITE );
474
-
458
+ void * ptr = VirtualAlloc (addr , size , MEM_COMMIT , PAGE_READWRITE );
475
459
if (ptr == NULL ) {
476
460
#if ZEND_MM_ERROR
477
- stderr_last_error ("VirtualAlloc() failed" );
461
+ stderr_last_error ("VirtualAlloc() commit failed" );
478
462
#endif
479
463
return NULL ;
480
464
}
465
+ ZEND_ASSERT (ptr == addr );
481
466
return ptr ;
467
+ }
482
468
#else
469
+ static void * zend_mm_mmap (size_t size )
470
+ {
483
471
void * ptr ;
484
472
485
473
#ifdef MAP_HUGETLB
@@ -492,16 +480,39 @@ static void *zend_mm_mmap(size_t size)
492
480
#endif
493
481
494
482
ptr = mmap (NULL , size , PROT_READ | PROT_WRITE , MAP_PRIVATE | MAP_ANON , ZEND_MM_FD , 0 );
495
-
496
483
if (ptr == MAP_FAILED ) {
497
484
#if ZEND_MM_ERROR
498
485
fprintf (stderr , "\nmmap() failed: [%d] %s\n" , errno , strerror (errno ));
499
486
#endif
500
487
return NULL ;
501
488
}
502
489
return ptr ;
490
+ }
491
+ #endif
492
+
493
+ #ifndef HAVE_MREMAP
494
+ #ifndef _WIN32
495
+ static void * zend_mm_mmap_fixed (void * addr , size_t size )
496
+ {
497
+ int flags = MAP_PRIVATE | MAP_ANON ;
498
+ #if defined(MAP_EXCL )
499
+ flags |= MAP_FIXED | MAP_EXCL ;
503
500
#endif
501
+ /* MAP_FIXED leads to discarding of the old mapping, so it can't be used. */
502
+ void * ptr = mmap (addr , size , PROT_READ | PROT_WRITE , flags /*| MAP_POPULATE | MAP_HUGETLB*/ , ZEND_MM_FD , 0 );
503
+ if (ptr == MAP_FAILED ) {
504
+ #if ZEND_MM_ERROR && !defined(MAP_EXCL )
505
+ fprintf (stderr , "\nmmap() failed: [%d] %s\n" , errno , strerror (errno ));
506
+ #endif
507
+ return NULL ;
508
+ } else if (ptr != addr ) {
509
+ zend_mm_munmap (ptr , size );
510
+ return NULL ;
511
+ }
512
+ return ptr ;
504
513
}
514
+ #endif
515
+ #endif
505
516
506
517
/***********/
507
518
/* Bitmask */
@@ -667,52 +678,44 @@ static zend_always_inline int zend_mm_bitset_is_free_range(zend_mm_bitset *bitse
667
678
668
679
static void * zend_mm_chunk_alloc_int (size_t size , size_t alignment )
669
680
{
670
- void * ptr = zend_mm_mmap (size );
681
+ #ifdef _WIN32
682
+ void * ptr = zend_mm_mmap_reserve (size + alignment /* - REAL_PAGE_SIZE TODO check if really 4KB */ );
683
+ if (ptr == NULL ) {
684
+ return NULL ;
685
+ }
671
686
687
+ size_t offset = ZEND_MM_ALIGNED_OFFSET (ptr , alignment );
688
+ return zend_mm_mmap_commit ((void * )((char * )ptr + (alignment - offset )), size );
689
+ #else
690
+ void * ptr = zend_mm_mmap (size );
672
691
if (ptr == NULL ) {
673
692
return NULL ;
674
- } else if (ZEND_MM_ALIGNED_OFFSET (ptr , alignment ) == 0 ) {
693
+ }
694
+
695
+ if (ZEND_MM_ALIGNED_OFFSET (ptr , alignment ) != 0 ) {
696
+ zend_mm_munmap (ptr , size );
697
+ ptr = zend_mm_mmap (size + alignment - REAL_PAGE_SIZE );
698
+
699
+ size_t offset = ZEND_MM_ALIGNED_OFFSET (ptr , alignment );
700
+ if (offset != 0 ) {
701
+ offset = alignment - offset ;
702
+ zend_mm_munmap (ptr , offset );
703
+ ptr = (char * )ptr + offset ;
704
+ alignment -= offset ;
705
+ }
706
+ if (alignment > REAL_PAGE_SIZE ) {
707
+ zend_mm_munmap ((char * )ptr + size , alignment - REAL_PAGE_SIZE );
708
+ }
709
+ }
710
+
675
711
#ifdef MADV_HUGEPAGE
676
- if (zend_mm_use_huge_pages ) {
677
- madvise (ptr , size , MADV_HUGEPAGE );
678
- }
712
+ if (zend_mm_use_huge_pages ) {
713
+ madvise (ptr , size , MADV_HUGEPAGE );
714
+ }
679
715
#endif
680
- return ptr ;
681
- } else {
682
- size_t offset ;
683
716
684
- /* chunk has to be aligned */
685
- zend_mm_munmap (ptr , size );
686
- ptr = zend_mm_mmap (size + alignment - REAL_PAGE_SIZE );
687
- #ifdef _WIN32
688
- offset = ZEND_MM_ALIGNED_OFFSET (ptr , alignment );
689
- zend_mm_munmap (ptr , size + alignment - REAL_PAGE_SIZE );
690
- ptr = zend_mm_mmap_fixed ((void * )((char * )ptr + (alignment - offset )), size );
691
- offset = ZEND_MM_ALIGNED_OFFSET (ptr , alignment );
692
- if (offset != 0 ) {
693
- zend_mm_munmap (ptr , size );
694
- return NULL ;
695
- }
696
- return ptr ;
697
- #else
698
- offset = ZEND_MM_ALIGNED_OFFSET (ptr , alignment );
699
- if (offset != 0 ) {
700
- offset = alignment - offset ;
701
- zend_mm_munmap (ptr , offset );
702
- ptr = (char * )ptr + offset ;
703
- alignment -= offset ;
704
- }
705
- if (alignment > REAL_PAGE_SIZE ) {
706
- zend_mm_munmap ((char * )ptr + size , alignment - REAL_PAGE_SIZE );
707
- }
708
- # ifdef MADV_HUGEPAGE
709
- if (zend_mm_use_huge_pages ) {
710
- madvise (ptr , size , MADV_HUGEPAGE );
711
- }
712
- # endif
717
+ return ptr ;
713
718
#endif
714
- return ptr ;
715
- }
716
719
}
717
720
718
721
static void * zend_mm_chunk_alloc (zend_mm_heap * heap , size_t size , size_t alignment )
0 commit comments