Diff
Modified: trunk/Source/_javascript_Core/ChangeLog (86905 => 86906)
--- trunk/Source/_javascript_Core/ChangeLog 2011-05-19 23:43:51 UTC (rev 86905)
+++ trunk/Source/_javascript_Core/ChangeLog 2011-05-19 23:46:16 UTC (rev 86906)
@@ -1,5 +1,36 @@
2011-05-19 Oliver Hunt <[email protected]>
+ Reviewed by Gavin Barraclough.
+
+ Add guard pages to each end of the memory region used by the fixedvm allocator
+ https://bugs.webkit.org/show_bug.cgi?id=61150
+
+ Add mechanism to notify the OSAllocator that pages at either end of an
+ allocation should be considered guard pages. Update PageReservation,
+ PageAllocation, etc to handle this.
+
+ * _javascript_Core.exp:
+ * jit/ExecutableAllocatorFixedVMPool.cpp:
+ (JSC::FixedVMPoolAllocator::FixedVMPoolAllocator):
+ * wtf/OSAllocator.h:
+ * wtf/OSAllocatorPosix.cpp:
+ (WTF::OSAllocator::reserveUncommitted):
+ (WTF::OSAllocator::reserveAndCommit):
+ * wtf/PageAllocation.h:
+ (WTF::PageAllocation::PageAllocation):
+ * wtf/PageAllocationAligned.h:
+ (WTF::PageAllocationAligned::PageAllocationAligned):
+ * wtf/PageBlock.h:
+ (WTF::PageBlock::PageBlock):
+ * wtf/PageReservation.h:
+ (WTF::PageReservation::reserve):
+ (WTF::PageReservation::reserveWithGuardPages):
+ Add a new function to make a reservation that will add guard
+ pages to the ends of an allocation.
+ (WTF::PageReservation::PageReservation):
+
+2011-05-19 Oliver Hunt <[email protected]>
+
Reviewed by Geoffrey Garen.
Make Executables release their JIT code as soon as they become dead
Modified: trunk/Source/_javascript_Core/_javascript_Core.exp (86905 => 86906)
--- trunk/Source/_javascript_Core/_javascript_Core.exp 2011-05-19 23:43:51 UTC (rev 86905)
+++ trunk/Source/_javascript_Core/_javascript_Core.exp 2011-05-19 23:46:16 UTC (rev 86906)
@@ -375,7 +375,7 @@
__ZN3WTF10fastCallocEmm
__ZN3WTF10fastMallocEm
__ZN3WTF10fastStrDupEPKc
-__ZN3WTF11OSAllocator16reserveAndCommitEmNS0_5UsageEbb
+__ZN3WTF11OSAllocator16reserveAndCommitEmNS0_5UsageEbbb
__ZN3WTF11OSAllocator18releaseDecommittedEPvm
__ZN3WTF11commentAtomE
__ZN3WTF11currentTimeEv
Modified: trunk/Source/_javascript_Core/_javascript_Core.vcproj/_javascript_Core/_javascript_Core.def (86905 => 86906)
--- trunk/Source/_javascript_Core/_javascript_Core.vcproj/_javascript_Core/_javascript_Core.def 2011-05-19 23:43:51 UTC (rev 86905)
+++ trunk/Source/_javascript_Core/_javascript_Core.vcproj/_javascript_Core/_javascript_Core.def 2011-05-19 23:46:16 UTC (rev 86906)
@@ -285,7 +285,7 @@
?releaseDecommitted@OSAllocator@WTF@@SAXPAXI@Z
?releaseStack@MarkStack@JSC@@CAXPAXI@Z
?reportExtraMemoryCostSlowCase@Heap@JSC@@AAEXI@Z
- ?reserveAndCommit@OSAllocator@WTF@@SAPAXIW4Usage@12@_N1@Z
+ ?reserveAndCommit@OSAllocator@WTF@@SAPAXIW4Usage@12@_N11@Z
?reserveCapacity@StringBuilder@WTF@@QAEXI@Z
?reset@ParserArena@JSC@@QAEXXZ
?reset@TimeoutChecker@JSC@@QAEXXZ
Modified: trunk/Source/_javascript_Core/jit/ExecutableAllocatorFixedVMPool.cpp (86905 => 86906)
--- trunk/Source/_javascript_Core/jit/ExecutableAllocatorFixedVMPool.cpp 2011-05-19 23:43:51 UTC (rev 86905)
+++ trunk/Source/_javascript_Core/jit/ExecutableAllocatorFixedVMPool.cpp 2011-05-19 23:46:16 UTC (rev 86906)
@@ -409,7 +409,7 @@
ASSERT(PageTables32MB::size() == 32 * 1024 * 1024);
ASSERT(PageTables1GB::size() == 1024 * 1024 * 1024);
- m_reservation = PageReservation::reserve(FixedVMPoolPageTables::size(), OSAllocator::JSJITCodePages, EXECUTABLE_POOL_WRITABLE, true);
+ m_reservation = PageReservation::reserveWithGuardPages(FixedVMPoolPageTables::size(), OSAllocator::JSJITCodePages, EXECUTABLE_POOL_WRITABLE, true);
#if !ENABLE(INTERPRETER)
if (!isValid())
CRASH();
Modified: trunk/Source/_javascript_Core/wtf/OSAllocator.h (86905 => 86906)
--- trunk/Source/_javascript_Core/wtf/OSAllocator.h 2011-05-19 23:43:51 UTC (rev 86905)
+++ trunk/Source/_javascript_Core/wtf/OSAllocator.h 2011-05-19 23:46:16 UTC (rev 86906)
@@ -45,7 +45,7 @@
// These methods are symmetric; reserveUncommitted allocates VM in an uncommitted state,
// releaseDecommitted should be called on a region of VM allocated by a single reservation,
// the memory must all currently be in a decommitted state.
- static void* reserveUncommitted(size_t, Usage = UnknownUsage, bool writable = true, bool executable = false);
+ static void* reserveUncommitted(size_t, Usage = UnknownUsage, bool writable = true, bool executable = false, bool includesGuardPages = false);
static void releaseDecommitted(void*, size_t);
// These methods are symmetric; they commit or decommit a region of VM (uncommitted VM should
@@ -57,7 +57,7 @@
// These methods are symmetric; reserveAndCommit allocates VM in an committed state,
// decommitAndRelease should be called on a region of VM allocated by a single reservation,
// the memory must all currently be in a committed state.
- static void* reserveAndCommit(size_t, Usage = UnknownUsage, bool writable = true, bool executable = false);
+ static void* reserveAndCommit(size_t, Usage = UnknownUsage, bool writable = true, bool executable = false, bool includesGuardPages = false);
static void decommitAndRelease(void* base, size_t size);
// These methods are akin to reserveAndCommit/decommitAndRelease, above - however rather than
Modified: trunk/Source/_javascript_Core/wtf/OSAllocatorPosix.cpp (86905 => 86906)
--- trunk/Source/_javascript_Core/wtf/OSAllocatorPosix.cpp 2011-05-19 23:43:51 UTC (rev 86905)
+++ trunk/Source/_javascript_Core/wtf/OSAllocatorPosix.cpp 2011-05-19 23:46:16 UTC (rev 86906)
@@ -26,6 +26,7 @@
#include "config.h"
#include "OSAllocator.h"
+#include "PageAllocation.h"
#include <errno.h>
#include <sys/mman.h>
#include <wtf/Assertions.h>
@@ -33,9 +34,9 @@
namespace WTF {
-void* OSAllocator::reserveUncommitted(size_t bytes, Usage usage, bool writable, bool executable)
+void* OSAllocator::reserveUncommitted(size_t bytes, Usage usage, bool writable, bool executable, bool includesGuardPages)
{
- void* result = reserveAndCommit(bytes, usage, writable, executable);
+ void* result = reserveAndCommit(bytes, usage, writable, executable, includesGuardPages);
#if HAVE(MADV_FREE_REUSE)
// To support the "reserve then commit" model, we have to initially decommit.
while (madvise(result, bytes, MADV_FREE_REUSABLE) == -1 && errno == EAGAIN) { }
@@ -43,7 +44,7 @@
return result;
}
-void* OSAllocator::reserveAndCommit(size_t bytes, Usage usage, bool writable, bool executable)
+void* OSAllocator::reserveAndCommit(size_t bytes, Usage usage, bool writable, bool executable, bool includesGuardPages)
{
// All POSIX reservations start out logically committed.
int protection = PROT_READ;
@@ -63,6 +64,7 @@
void* result = 0;
#if (OS(DARWIN) && CPU(X86_64))
if (executable) {
+ ASSERT(includesGuardPages);
// Cook up an address to allocate at, using the following recipe:
// 17 bits of zero, stay in userspace kids.
// 26 bits of randomness for ASLR.
@@ -83,6 +85,10 @@
result = mmap(result, bytes, protection, flags, fd, 0);
if (result == MAP_FAILED)
CRASH();
+ if (includesGuardPages) {
+ mprotect(result, pageSize(), PROT_NONE);
+ mprotect(static_cast<char*>(result) + bytes - pageSize(), pageSize(), PROT_NONE);
+ }
return result;
}
Modified: trunk/Source/_javascript_Core/wtf/OSAllocatorSymbian.cpp (86905 => 86906)
--- trunk/Source/_javascript_Core/wtf/OSAllocatorSymbian.cpp 2011-05-19 23:43:51 UTC (rev 86905)
+++ trunk/Source/_javascript_Core/wtf/OSAllocatorSymbian.cpp 2011-05-19 23:46:16 UTC (rev 86906)
@@ -74,7 +74,7 @@
}
// Reserve memory and return the base address of the region
-void* OSAllocator::reserveUncommitted(size_t reservationSize, Usage usage, bool , bool executable)
+void* OSAllocator::reserveUncommitted(size_t reservationSize, Usage usage, bool , bool executable, bool)
{
void* base = 0;
if (executable)
@@ -110,7 +110,7 @@
deallocateCodeChunk(address); // for code chunk, decommit AND release
}
-void* OSAllocator::reserveAndCommit(size_t bytes, Usage usage, bool writable, bool executable)
+void* OSAllocator::reserveAndCommit(size_t bytes, Usage usage, bool writable, bool executable, bool)
{
void* base = reserveUncommitted(bytes, usage, writable, executable);
commit(base, bytes, writable, executable);
Modified: trunk/Source/_javascript_Core/wtf/PageAllocation.h (86905 => 86906)
--- trunk/Source/_javascript_Core/wtf/PageAllocation.h 2011-05-19 23:43:51 UTC (rev 86905)
+++ trunk/Source/_javascript_Core/wtf/PageAllocation.h 2011-05-19 23:46:16 UTC (rev 86906)
@@ -117,7 +117,7 @@
private:
PageAllocation(void* base, size_t size)
- : PageBlock(base, size)
+ : PageBlock(base, size, false)
{
}
};
Modified: trunk/Source/_javascript_Core/wtf/PageAllocationAligned.h (86905 => 86906)
--- trunk/Source/_javascript_Core/wtf/PageAllocationAligned.h 2011-05-19 23:43:51 UTC (rev 86905)
+++ trunk/Source/_javascript_Core/wtf/PageAllocationAligned.h 2011-05-19 23:46:16 UTC (rev 86906)
@@ -48,13 +48,13 @@
private:
#if OS(DARWIN)
PageAllocationAligned(void* base, size_t size)
- : PageBlock(base, size)
+ : PageBlock(base, size, false)
{
}
#else
PageAllocationAligned(void* base, size_t size, void* reservationBase, size_t reservationSize)
- : PageBlock(base, size)
- , m_reservation(reservationBase, reservationSize)
+ : PageBlock(base, size, false)
+ , m_reservation(reservationBase, reservationSize, false)
{
}
Modified: trunk/Source/_javascript_Core/wtf/PageBlock.h (86905 => 86906)
--- trunk/Source/_javascript_Core/wtf/PageBlock.h 2011-05-19 23:43:51 UTC (rev 86905)
+++ trunk/Source/_javascript_Core/wtf/PageBlock.h 2011-05-19 23:46:16 UTC (rev 86906)
@@ -37,7 +37,7 @@
public:
PageBlock();
PageBlock(const PageBlock&);
- PageBlock(void*, size_t);
+ PageBlock(void*, size_t, bool hasGuardPages);
void* base() const { return m_base; }
size_t size() const { return m_size; }
@@ -51,24 +51,28 @@
}
private:
+ void* m_realBase;
void* m_base;
size_t m_size;
};
inline PageBlock::PageBlock()
- : m_base(0)
+ : m_realBase(0)
+ , m_base(0)
, m_size(0)
{
}
inline PageBlock::PageBlock(const PageBlock& other)
- : m_base(other.m_base)
+ : m_realBase(other.m_realBase)
+ , m_base(other.m_base)
, m_size(other.m_size)
{
}
-inline PageBlock::PageBlock(void* base, size_t size)
- : m_base(base)
+inline PageBlock::PageBlock(void* base, size_t size, bool hasGuardPages)
+ : m_realBase(base)
+ , m_base(static_cast<char*>(base) + (hasGuardPages ? pageSize() : 0))
, m_size(size)
{
}
Modified: trunk/Source/_javascript_Core/wtf/PageReservation.h (86905 => 86906)
--- trunk/Source/_javascript_Core/wtf/PageReservation.h 2011-05-19 23:43:51 UTC (rev 86905)
+++ trunk/Source/_javascript_Core/wtf/PageReservation.h 2011-05-19 23:46:16 UTC (rev 86906)
@@ -104,8 +104,14 @@
static PageReservation reserve(size_t size, OSAllocator::Usage usage = OSAllocator::UnknownUsage, bool writable = true, bool executable = false)
{
ASSERT(isPageAligned(size));
- return PageReservation(OSAllocator::reserveUncommitted(size, usage, writable, executable), size, writable, executable);
+ return PageReservation(OSAllocator::reserveUncommitted(size, usage, writable, executable), size, writable, executable, false);
}
+
+ static PageReservation reserveWithGuardPages(size_t size, OSAllocator::Usage usage = OSAllocator::UnknownUsage, bool writable = true, bool executable = false)
+ {
+ ASSERT(isPageAligned(size));
+ return PageReservation(OSAllocator::reserveUncommitted(size + pageSize() * 2, usage, writable, executable, true), size, writable, executable, true);
+ }
void deallocate()
{
@@ -123,8 +129,8 @@
}
private:
- PageReservation(void* base, size_t size, bool writable, bool executable)
- : PageBlock(base, size)
+ PageReservation(void* base, size_t size, bool writable, bool executable, bool hasGuardPages)
+ : PageBlock(base, size, hasGuardPages)
, m_committed(0)
, m_writable(writable)
, m_executable(executable)