Branch: refs/heads/main Home: https://github.com/WebKit/WebKit Commit: 69371bd0991ed38ae47d56b9bb2dc7f940e9a3e3 https://github.com/WebKit/WebKit/commit/69371bd0991ed38ae47d56b9bb2dc7f940e9a3e3 Author: Mark Lam <mark....@apple.com> Date: 2025-08-25 (Mon, 25 Aug 2025)
Changed paths: M Source/JavaScriptCore/jit/ExecutableAllocator.cpp M Source/WTF/wtf/OSAllocator.h M Source/WTF/wtf/PageAllocation.h M Source/WTF/wtf/PageBlock.h M Source/WTF/wtf/PageReservation.h M Source/WTF/wtf/playstation/OSAllocatorPlayStation.cpp M Source/WTF/wtf/posix/OSAllocatorPOSIX.cpp M Source/WTF/wtf/win/OSAllocatorWin.cpp Log Message: ----------- Push guard page de/allocation down into OSAllocator. https://bugs.webkit.org/show_bug.cgi?id=297841 rdar://159065710 Reviewed by Yusuke Suzuki. Previously, PageReservation can increase the allocation size by 2 pages to include guard pages. It then tells OSAllocator that there are guard pages included by passing a includesGuardPages bool. Based on this includesGuardPages bool, OSAllocator also assumes that the allocation size includes exactly 2 page sized guard regions on each end. Unfortunately, this treatment is not applied consistents everywhere. For example, 1. OSAllocator::tryReserveUncommitted() calls tryReserveAndCommit() with includesGuardPages being true. tryReserveAndCommit() allocates the buffer including the guard pages, and maps the guard pages to be PROT_NONE. Then, tryReserveUncommitted() fails to account for the Guard pages and madvise() the whole range as MADV_FREE_REUSABLE (including guard pages). This madvise fails, because it's not allowed to do this to the PROT_NONE guard pages. 2. PageReservation::deallocate() calls OSAllocator::releaseDecommitted() on its base() for size() bytes. base() is not the base of the allocation, but just the start of the usable section after the guard page at the start. releaseDecommitted() munmaps that memory range. However, if there are guard regions on each end, the pages for the guard regions are never munmapped. This change makes the division of labor and responsibility clearer: 1. PageReservation just specifies how many guard pages it wants on each end, if any. 2. OSAllocator takes care of allocation / deallocation, including for guard pages. So, PageReservation will now pass in the number of pages it wants as guard on each end. OSAllocator takes care of the rest. Similarly. PageReservation::deallocate() also passes in the number of pages it requested as guard on each end, and OSAllocator::releaseDecommitted() does the right thing to munmap the actual memory range including any guard regions. This approach simplifies the logic significantly, and makes it easier to get right: 1. PageBlock::m_realBase was initialized but never used. It can not be removed. It also makes it clear that PageBlock is not responsible for dealing with guard regions. 2. PageReservation can now think of its buffer size request without needing to do any padding math to account for guard regions. 3. PageReservation can now think of its addressHint without needing to do any padding math to account for guard regions. PageReservation no longer needs to do any padding math for the guard regions. OSAllocator will take care of that as needed. This is also fine from a performance angle. OSAllocator calls are already dominated by the mmap and munmap calls. The extra arithmetic for the padding math is not going to move the needle in terms of perf impact. Two additional changes: 4. Change addressHints to be specified using a void* instead of a std::optional. There's no value add with using a std::optional for it. An addressHint of nullptr would indicated that no hint is specified. This is already consistent with the convention mmap and munmap expects. 5. Change Linux's OSAllocator::tryReserveUncommitted() to also forward to OSAllocator::tryReserveAndCommit() to do the mapping just like for OS(DARWIN), instead of rolling its own. There were only 2 differences between the 2 implementations to begin with: a. Linux's OSAllocator::tryReserveUncommitted() sets the MAP_NORESERVE flag for its call to mmap(). We now achieve this by repurposing the unused usage parameter to pass a new OSAllocator::UncommittedPages value. This value tells OSAllocator::tryReserveAndCommit() to add the MAP_NORESERVE flag for Linux. b. After the mmap call, Linux's OSAllocator::tryReserveUncommitted() does a madvise() with MADV_DONTNEED instead of MADV_FREE_REUSABLE. We retain this behavior by keeping different madvise() calls for the 2 ports. * Source/JavaScriptCore/jit/ExecutableAllocator.cpp: (JSC::initializeJITPageReservation): * Source/WTF/wtf/OSAllocator.h: (WTF::OSAllocator::decommitAndRelease): * Source/WTF/wtf/PageAllocation.h: (WTF::PageAllocation::PageAllocation): * Source/WTF/wtf/PageBlock.h: (WTF::PageBlock::operator bool const): (WTF::PageBlock::PageBlock): * Source/WTF/wtf/PageReservation.h: (WTF::PageReservation::reserve): (WTF::PageReservation::tryReserve): (WTF::PageReservation::reserveWithGuardPages): (WTF::PageReservation::tryReserveWithGuardPages): (WTF::PageReservation::deallocate): (WTF::PageReservation::PageReservation): * Source/WTF/wtf/playstation/OSAllocatorPlayStation.cpp: (WTF::OSAllocator::tryReserveAndCommit): (WTF::OSAllocator::tryReserveUncommitted): (WTF::OSAllocator::reserveUncommitted): (WTF::OSAllocator::tryReserveUncommittedAligned): (WTF::OSAllocator::reserveAndCommit): (WTF::OSAllocator::releaseDecommitted): * Source/WTF/wtf/posix/OSAllocatorPOSIX.cpp: (WTF::OSAllocator::tryReserveAndCommit): (WTF::OSAllocator::tryReserveUncommitted): (WTF::OSAllocator::reserveUncommitted): (WTF::OSAllocator::tryReserveUncommittedAligned): (WTF::OSAllocator::reserveAndCommit): (WTF::OSAllocator::releaseDecommitted): * Source/WTF/wtf/win/OSAllocatorWin.cpp: (WTF::OSAllocator::tryReserveUncommitted): (WTF::OSAllocator::reserveUncommitted): (WTF::OSAllocator::tryReserveUncommittedAligned): (WTF::OSAllocator::tryReserveAndCommit): (WTF::OSAllocator::reserveAndCommit): (WTF::OSAllocator::releaseDecommitted): Canonical link: https://commits.webkit.org/299145@main To unsubscribe from these emails, change your notification settings at https://github.com/WebKit/WebKit/settings/notifications _______________________________________________ webkit-changes mailing list webkit-changes@lists.webkit.org https://lists.webkit.org/mailman/listinfo/webkit-changes