summaryrefslogtreecommitdiffstats
path: root/JavaScriptCore/wtf/PageAllocation.h
diff options
context:
space:
mode:
Diffstat (limited to 'JavaScriptCore/wtf/PageAllocation.h')
-rw-r--r--JavaScriptCore/wtf/PageAllocation.h281
1 files changed, 21 insertions, 260 deletions
diff --git a/JavaScriptCore/wtf/PageAllocation.h b/JavaScriptCore/wtf/PageAllocation.h
index 26d53a5..232cd20 100644
--- a/JavaScriptCore/wtf/PageAllocation.h
+++ b/JavaScriptCore/wtf/PageAllocation.h
@@ -27,8 +27,11 @@
#define PageAllocation_h
#include <wtf/Assertions.h>
+#include <wtf/OSAllocator.h>
+#include <wtf/PageBlock.h>
#include <wtf/UnusedParam.h>
#include <wtf/VMTags.h>
+#include <algorithm>
#if OS(DARWIN)
#include <mach/mach_init.h>
@@ -74,287 +77,45 @@ namespace WTF {
Callers may also optinally provide a flag indicating the usage (for use by
system memory usage tracking tools, where implemented), and boolean values
specifying the required protection (defaulting to writable, non-executable).
-
- Where HAVE(PAGE_ALLOCATE_AT) and HAVE(PAGE_ALLOCATE_ALIGNED) are available
- memory may also be allocated at a specified address, or with a specified
- alignment respectively. PageAllocation::allocateAt take an address to try
- to allocate at, and a boolean indicating whether this behaviour is strictly
- required (if this address is unavailable, should memory at another address
- be allocated instead). PageAllocation::allocateAligned requires that the
- size is a power of two that is >= system page size.
*/
-class PageAllocation {
-public:
- enum Usage {
- UnknownUsage = -1,
- FastMallocPages = VM_TAG_FOR_TCMALLOC_MEMORY,
- JSGCHeapPages = VM_TAG_FOR_COLLECTOR_MEMORY,
- JSVMStackPages = VM_TAG_FOR_REGISTERFILE_MEMORY,
- JSJITCodePages = VM_TAG_FOR_EXECUTABLEALLOCATOR_MEMORY,
- };
+class PageAllocation : private PageBlock {
+public:
PageAllocation()
- : m_base(0)
- , m_size(0)
-#if OS(SYMBIAN)
- , m_chunk(0)
-#endif
- {
- }
-
- bool operator!() const { return !m_base; }
- void* base() const { return m_base; }
- size_t size() const { return m_size; }
-
- static PageAllocation allocate(size_t size, Usage usage = UnknownUsage, bool writable = true, bool executable = false)
{
- ASSERT(isPageAligned(size));
- return systemAllocate(size, usage, writable, executable);
}
-#if HAVE(PAGE_ALLOCATE_AT)
- static PageAllocation allocateAt(void* address, bool fixed, size_t size, Usage usage = UnknownUsage, bool writable = true, bool executable = false)
- {
- ASSERT(isPageAligned(address));
- ASSERT(isPageAligned(size));
- return systemAllocateAt(address, fixed, size, usage, writable, executable);
- }
-#endif
+ using PageBlock::operator bool;
+ using PageBlock::size;
+ using PageBlock::base;
-#if HAVE(PAGE_ALLOCATE_ALIGNED)
- static PageAllocation allocateAligned(size_t size, Usage usage = UnknownUsage)
+ static PageAllocation allocate(size_t size, OSAllocator::Usage usage = OSAllocator::UnknownUsage, bool writable = true, bool executable = false)
{
ASSERT(isPageAligned(size));
- ASSERT(isPowerOfTwo(size));
- return systemAllocateAligned(size, usage);
+ return PageAllocation(OSAllocator::reserveAndCommit(size, usage, writable, executable), size);
}
-#endif
void deallocate()
{
- ASSERT(m_base);
- systemDeallocate(true);
- }
-
- static size_t pageSize()
- {
- if (!s_pageSize)
- s_pageSize = systemPageSize();
- ASSERT(isPowerOfTwo(s_pageSize));
- return s_pageSize;
- }
+ // Clear base & size before calling release; if this is *inside* allocation
+ // then we won't be able to clear then after deallocating the memory.
+ PageAllocation tmp;
+ std::swap(tmp, *this);
-#ifndef NDEBUG
- static bool isPageAligned(void* address) { return !(reinterpret_cast<intptr_t>(address) & (pageSize() - 1)); }
- static bool isPageAligned(size_t size) { return !(size & (pageSize() - 1)); }
- static bool isPowerOfTwo(size_t size) { return !(size & (size - 1)); }
- static int lastError();
-#endif
+ ASSERT(tmp);
+ ASSERT(!*this);
-protected:
-#if OS(SYMBIAN)
- PageAllocation(void* base, size_t size, RChunk* chunk)
- : m_base(base)
- , m_size(size)
- , m_chunk(chunk)
- {
+ OSAllocator::decommitAndRelease(tmp.base(), tmp.size());
}
-#else
+
+private:
PageAllocation(void* base, size_t size)
- : m_base(base)
- , m_size(size)
+ : PageBlock(base, size)
{
}
-#endif
-
- static PageAllocation systemAllocate(size_t, Usage, bool, bool);
-#if HAVE(PAGE_ALLOCATE_AT)
- static PageAllocation systemAllocateAt(void*, bool, size_t, Usage, bool, bool);
-#endif
-#if HAVE(PAGE_ALLOCATE_ALIGNED)
- static PageAllocation systemAllocateAligned(size_t, Usage);
-#endif
- // systemDeallocate takes a parameter indicating whether memory is currently committed
- // (this should always be true for PageAllocation, false for PageReservation).
- void systemDeallocate(bool committed);
- static size_t systemPageSize();
-
- void* m_base;
- size_t m_size;
-#if OS(SYMBIAN)
- RChunk* m_chunk;
-#endif
-
- static JS_EXPORTDATA size_t s_pageSize;
};
-
-#if HAVE(MMAP)
-
-
-inline PageAllocation PageAllocation::systemAllocate(size_t size, Usage usage, bool writable, bool executable)
-{
- return systemAllocateAt(0, false, size, usage, writable, executable);
-}
-
-inline PageAllocation PageAllocation::systemAllocateAt(void* address, bool fixed, size_t size, Usage usage, bool writable, bool executable)
-{
- int protection = PROT_READ;
- if (writable)
- protection |= PROT_WRITE;
- if (executable)
- protection |= PROT_EXEC;
-
- int flags = MAP_PRIVATE | MAP_ANON;
- if (fixed)
- flags |= MAP_FIXED;
-
-#if OS(DARWIN) && !defined(BUILDING_ON_TIGER)
- int fd = usage;
-#else
- int fd = -1;
-#endif
-
- void* base = mmap(address, size, protection, flags, fd, 0);
- if (base == MAP_FAILED)
- base = 0;
- return PageAllocation(base, size);
-}
-
-inline PageAllocation PageAllocation::systemAllocateAligned(size_t size, Usage usage)
-{
-#if OS(DARWIN)
- vm_address_t address = 0;
- int flags = VM_FLAGS_ANYWHERE;
- if (usage != -1)
- flags |= usage;
- vm_map(current_task(), &address, size, (size - 1), flags, MEMORY_OBJECT_NULL, 0, FALSE, PROT_READ | PROT_WRITE, PROT_READ | PROT_WRITE | PROT_EXEC, VM_INHERIT_DEFAULT);
- return PageAllocation(reinterpret_cast<void*>(address), size);
-#elif HAVE(POSIX_MEMALIGN)
- void* address;
- posix_memalign(&address, size, size);
- return PageAllocation(address, size);
-#else
- size_t extra = size - pageSize();
-
- // Check for overflow.
- if ((size + extra) < size)
- return PageAllocation(0, size);
-
-#if OS(DARWIN) && !defined(BUILDING_ON_TIGER)
- int fd = usage;
-#else
- int fd = -1;
-#endif
- void* mmapResult = mmap(0, size + extra, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, fd, 0);
- if (mmapResult == MAP_FAILED)
- return PageAllocation(0, size);
- uintptr_t address = reinterpret_cast<uintptr_t>(mmapResult);
-
- size_t adjust = 0;
- if ((address & (size - 1)))
- adjust = size - (address & (size - 1));
- if (adjust > 0)
- munmap(reinterpret_cast<char*>(address), adjust);
- if (adjust < extra)
- munmap(reinterpret_cast<char*>(address + adjust + size), extra - adjust);
- address += adjust;
-
- return PageAllocation(reinterpret_cast<void*>(address), size);
-#endif
-}
-
-inline void PageAllocation::systemDeallocate(bool)
-{
- int result = munmap(m_base, m_size);
- ASSERT_UNUSED(result, !result);
- m_base = 0;
-}
-
-inline size_t PageAllocation::systemPageSize()
-{
- return getpagesize();
-}
-
-
-#elif HAVE(VIRTUALALLOC)
-
-
-inline PageAllocation PageAllocation::systemAllocate(size_t size, Usage, bool writable, bool executable)
-{
- DWORD protection = executable ?
- (writable ? PAGE_EXECUTE_READWRITE : PAGE_EXECUTE_READ) :
- (writable ? PAGE_READWRITE : PAGE_READONLY);
- return PageAllocation(VirtualAlloc(0, size, MEM_COMMIT | MEM_RESERVE, protection), size);
-}
-
-#if HAVE(ALIGNED_MALLOC)
-inline PageAllocation PageAllocation::systemAllocateAligned(size_t size, Usage usage)
-{
-#if COMPILER(MINGW) && !COMPILER(MINGW64)
- void* address = __mingw_aligned_malloc(size, size);
-#else
- void* address = _aligned_malloc(size, size);
-#endif
- memset(address, 0, size);
- return PageAllocation(address, size);
-}
-#endif
-
-inline void PageAllocation::systemDeallocate(bool committed)
-{
-#if OS(WINCE)
- if (committed)
- VirtualFree(m_base, m_size, MEM_DECOMMIT);
-#else
- UNUSED_PARAM(committed);
-#endif
- VirtualFree(m_base, 0, MEM_RELEASE);
- m_base = 0;
-}
-
-inline size_t PageAllocation::systemPageSize()
-{
- static size_t size = 0;
- SYSTEM_INFO system_info;
- GetSystemInfo(&system_info);
- size = system_info.dwPageSize;
- return size;
-}
-
-
-#elif OS(SYMBIAN)
-
-
-inline PageAllocation PageAllocation::systemAllocate(size_t size, Usage usage, bool writable, bool executable)
-{
- RChunk* rchunk = new RChunk();
- if (executable)
- rchunk->CreateLocalCode(size, size);
- else
- rchunk->CreateLocal(size, size);
- return PageAllocation(rchunk->Base(), size, rchunk);
-}
-
-inline void PageAllocation::systemDeallocate(bool)
-{
- m_chunk->Close();
- delete m_chunk;
- m_base = 0;
-}
-
-inline size_t PageAllocation::systemPageSize()
-{
- static TInt page_size = 0;
- UserHal::PageSizeInBytes(page_size);
- return page_size;
-}
-
-
-#endif
-
-
-}
+} // namespace WTF
using WTF::PageAllocation;