summaryrefslogtreecommitdiffstats
path: root/JavaScriptCore/wtf/PageReservation.h
diff options
context:
space:
mode:
Diffstat (limited to 'JavaScriptCore/wtf/PageReservation.h')
-rw-r--r--JavaScriptCore/wtf/PageReservation.h193
1 files changed, 38 insertions, 155 deletions
diff --git a/JavaScriptCore/wtf/PageReservation.h b/JavaScriptCore/wtf/PageReservation.h
index cfc7cd9..8c097a4 100644
--- a/JavaScriptCore/wtf/PageReservation.h
+++ b/JavaScriptCore/wtf/PageReservation.h
@@ -49,208 +49,91 @@ namespace WTF {
is deallocated. Values in memory may not be retained accross a pair of calls if
the region of memory is decommitted and then committed again.
- Where HAVE(PAGE_ALLOCATE_AT) is available a PageReservation::reserveAt method
- also exists, with behaviour mirroring PageAllocation::allocateAt.
-
Memory protection should not be changed on decommitted memory, and if protection
is changed on memory while it is committed it should be returned to the orignal
protection before decommit is called.
-
- Note: Inherits from PageAllocation privately to prevent clients accidentally
- calling PageAllocation::deallocate on a PageReservation.
*/
-class PageReservation : private PageAllocation {
+
+class PageReservation : private PageBlock {
public:
PageReservation()
+ : m_writable(false)
+ , m_executable(false)
+#ifndef NDEBUG
+ , m_committed(0)
+#endif
{
}
+
+ using PageBlock::operator bool;
+ using PageBlock::base;
+ using PageBlock::size;
- using PageAllocation::operator!;
- using PageAllocation::base;
- using PageAllocation::size;
-
- bool commit(void* start, size_t size)
+ void commit(void* start, size_t size)
{
- ASSERT(m_base);
+ ASSERT(*this);
ASSERT(isPageAligned(start));
ASSERT(isPageAligned(size));
+ ASSERT(contains(start, size));
- bool commited = systemCommit(start, size);
#ifndef NDEBUG
- if (commited)
- m_committed += size;
+ m_committed += size;
#endif
- return commited;
+ OSAllocator::commit(start, size, m_writable, m_executable);
}
+
void decommit(void* start, size_t size)
{
- ASSERT(m_base);
+ ASSERT(*this);
ASSERT(isPageAligned(start));
ASSERT(isPageAligned(size));
+ ASSERT(contains(start, size));
#ifndef NDEBUG
m_committed -= size;
#endif
- systemDecommit(start, size);
+ OSAllocator::decommit(start, size);
}
- static PageReservation reserve(size_t size, Usage usage = UnknownUsage, bool writable = true, bool executable = false)
+ static PageReservation reserve(size_t size, OSAllocator::Usage usage = OSAllocator::UnknownUsage, bool writable = true, bool executable = false)
{
ASSERT(isPageAligned(size));
- return systemReserve(size, usage, writable, executable);
+ return PageReservation(OSAllocator::reserveUncommitted(size, usage, writable, executable), size, writable, executable);
}
-#if HAVE(PAGE_ALLOCATE_AT)
- static PageReservation reserveAt(void* address, bool fixed, size_t size, Usage usage = UnknownUsage, bool writable = true, bool executable = false)
- {
- ASSERT(isPageAligned(address));
- ASSERT(isPageAligned(size));
- return systemReserveAt(address, fixed, size, usage, writable, executable);
- }
-#endif
-
void deallocate()
{
- ASSERT(m_base);
ASSERT(!m_committed);
- systemDeallocate(false);
- }
-#ifndef NDEBUG
- using PageAllocation::lastError;
-#endif
+ // Clear base & size before calling release; if this is *inside* allocation
+ // then we won't be able to clear then after deallocating the memory.
+ PageReservation tmp;
+ std::swap(tmp, *this);
+
+ ASSERT(tmp);
+ ASSERT(!*this);
+
+ OSAllocator::releaseDecommitted(tmp.base(), tmp.size());
+ }
private:
-#if OS(SYMBIAN)
- PageReservation(void* base, size_t size, RChunk* chunk)
- : PageAllocation(base, size, chunk)
-#else
- PageReservation(void* base, size_t size)
- : PageAllocation(base, size)
-#endif
+ PageReservation(void* base, size_t size, bool writable, bool executable)
+ : PageBlock(base, size)
+ , m_writable(writable)
+ , m_executable(executable)
#ifndef NDEBUG
, m_committed(0)
#endif
{
}
- bool systemCommit(void*, size_t);
- void systemDecommit(void*, size_t);
- static PageReservation systemReserve(size_t, Usage, bool, bool);
-#if HAVE(PAGE_ALLOCATE_AT)
- static PageReservation systemReserveAt(void*, bool, size_t, Usage, bool, bool);
-#endif
-
-#if HAVE(VIRTUALALLOC)
- DWORD m_protection;
-#endif
+ bool m_writable;
+ bool m_executable;
#ifndef NDEBUG
size_t m_committed;
#endif
};
-
-#if HAVE(MMAP)
-
-
-inline bool PageReservation::systemCommit(void* start, size_t size)
-{
-#if HAVE(MADV_FREE_REUSE)
- while (madvise(start, size, MADV_FREE_REUSE) == -1 && errno == EAGAIN) { }
-#else
- UNUSED_PARAM(start);
- UNUSED_PARAM(size);
-#endif
- return true;
-}
-
-inline void PageReservation::systemDecommit(void* start, size_t size)
-{
-#if HAVE(MADV_FREE_REUSE)
- while (madvise(start, size, MADV_FREE_REUSABLE) == -1 && errno == EAGAIN) { }
-#elif HAVE(MADV_FREE)
- while (madvise(start, size, MADV_FREE) == -1 && errno == EAGAIN) { }
-#elif HAVE(MADV_DONTNEED)
- while (madvise(start, size, MADV_DONTNEED) == -1 && errno == EAGAIN) { }
-#else
- UNUSED_PARAM(start);
- UNUSED_PARAM(size);
-#endif
-}
-
-inline PageReservation PageReservation::systemReserve(size_t size, Usage usage, bool writable, bool executable)
-{
- return systemReserveAt(0, false, size, usage, writable, executable);
-}
-
-inline PageReservation PageReservation::systemReserveAt(void* address, bool fixed, size_t size, Usage usage, bool writable, bool executable)
-{
- void* base = systemAllocateAt(address, fixed, size, usage, writable, executable).base();
-#if HAVE(MADV_FREE_REUSE)
- // When using MADV_FREE_REUSE we keep all decommitted memory marked as REUSABLE.
- // We call REUSE on commit, and REUSABLE on decommit.
- if (base)
- while (madvise(base, size, MADV_FREE_REUSABLE) == -1 && errno == EAGAIN) { }
-#endif
- return PageReservation(base, size);
-}
-
-
-#elif HAVE(VIRTUALALLOC)
-
-
-inline bool PageReservation::systemCommit(void* start, size_t size)
-{
- return VirtualAlloc(start, size, MEM_COMMIT, m_protection) == start;
-}
-
-inline void PageReservation::systemDecommit(void* start, size_t size)
-{
- VirtualFree(start, size, MEM_DECOMMIT);
-}
-
-inline PageReservation PageReservation::systemReserve(size_t size, Usage usage, bool writable, bool executable)
-{
- // Record the protection for use during commit.
- DWORD protection = executable ?
- (writable ? PAGE_EXECUTE_READWRITE : PAGE_EXECUTE_READ) :
- (writable ? PAGE_READWRITE : PAGE_READONLY);
- PageReservation reservation(VirtualAlloc(0, size, MEM_RESERVE, protection), size);
- reservation.m_protection = protection;
- return reservation;
-}
-
-
-#elif OS(SYMBIAN)
-
-
-inline bool PageReservation::systemCommit(void* start, size_t size)
-{
- intptr_t offset = reinterpret_cast<intptr_t>(start) - reinterpret_cast<intptr_t>(m_base);
- m_chunk->Commit(offset, size);
- return true;
-}
-
-inline void PageReservation::systemDecommit(void* start, size_t size)
-{
- intptr_t offset = reinterpret_cast<intptr_t>(start) - reinterpret_cast<intptr_t>(m_base);
- m_chunk->Decommit(offset, size);
-}
-
-inline PageReservation PageReservation::systemReserve(size_t size, Usage usage, bool writable, bool executable)
-{
- RChunk* rchunk = new RChunk();
- if (executable)
- rchunk->CreateLocalCode(0, size);
- else
- rchunk->CreateDisconnectedLocal(0, 0, size);
- return PageReservation(rchunk->Base(), size, rchunk);
-}
-
-
-#endif
-
-
}
using WTF::PageReservation;