diff options
author | Simon Hausmann <simon.hausmann@digia.com> | 2013-03-25 17:31:38 +0100 |
---|---|---|
committer | Lars Knoll <lars.knoll@digia.com> | 2013-04-01 11:24:24 +0200 |
commit | e0a3ca32a7e9d546c364efb40eb10e2c552d2951 (patch) | |
tree | 690d222a26ca77d00cf03444d231f45e033ad00e /src/3rdparty/masm/stubs/ExecutableAllocator.h | |
parent | e2ae9ddf6d619e10b7f7040f4d37e3e44799a56e (diff) |
Fix memory allocation of executable code
Previously we allocated at least one page for each compiled function, even if
it required less bytes (common). That causes excessive memory usages for large
scripts or long running scripts with frequent eval usage.
This patch introduces a simple allocator that allocates also on page
granularity from the system but allocates the remaining space in the pages in
sub-sequent calls. It is optimized to scale with the number of requests and
also return pages to the system as soon as possible.
Change-Id: I0751a8094afe97e94b5f44c6a691a679ecdb1df0
Reviewed-by: Lars Knoll <lars.knoll@digia.com>
Diffstat (limited to 'src/3rdparty/masm/stubs/ExecutableAllocator.h')
-rw-r--r-- | src/3rdparty/masm/stubs/ExecutableAllocator.h | 37 |
1 files changed, 17 insertions, 20 deletions
diff --git a/src/3rdparty/masm/stubs/ExecutableAllocator.h b/src/3rdparty/masm/stubs/ExecutableAllocator.h index 47768c6931..f4292c791d 100644 --- a/src/3rdparty/masm/stubs/ExecutableAllocator.h +++ b/src/3rdparty/masm/stubs/ExecutableAllocator.h @@ -45,6 +45,8 @@ #include <RefCounted.h> #include <wtf/PageBlock.h> +#include <qv4executableallocator.h> + #if OS(WINDOWS) #include <windows.h> #else @@ -57,27 +59,15 @@ namespace JSC { class JSGlobalData; struct ExecutableMemoryHandle : public RefCounted<ExecutableMemoryHandle> { - ExecutableMemoryHandle(int size) - : m_size(size) + ExecutableMemoryHandle(QQmlJS::VM::ExecutableAllocator *allocator, int size) + : m_allocator(allocator) + , m_size(size) { - size_t pageSize = WTF::pageSize(); - m_size = (m_size + pageSize - 1) & ~(pageSize - 1); -#if OS(WINDOWS) - m_data = VirtualAlloc(0, m_size, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE); -#else -#if OS(DARWIN) -# define MAP_ANONYMOUS MAP_ANON -#endif - m_data = mmap(0, m_size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); -#endif + m_allocation = allocator->allocate(size); } ~ExecutableMemoryHandle() { -#if OS(WINDOWS) - VirtualFree(m_data, 0, MEM_RELEASE); -#else - munmap(m_data, m_size); -#endif + m_allocator->free(m_allocation); } inline void shrink(size_t) { @@ -86,17 +76,22 @@ struct ExecutableMemoryHandle : public RefCounted<ExecutableMemoryHandle> { inline bool isManaged() const { return true; } - void* start() { return m_data; } + void* start() { return m_allocation->start(); } int sizeInBytes() { return m_size; } - void* m_data; + QQmlJS::VM::ExecutableAllocator *m_allocator; + QQmlJS::VM::ExecutableAllocator::Allocation *m_allocation; int m_size; }; struct ExecutableAllocator { + ExecutableAllocator(QQmlJS::VM::ExecutableAllocator *alloc) + : realAllocator(alloc) + {} + PassRefPtr<ExecutableMemoryHandle> allocate(JSGlobalData&, int size, void*, int) { - return adoptRef(new ExecutableMemoryHandle(size)); + return adoptRef(new ExecutableMemoryHandle(realAllocator, size)); } static void makeWritable(void*, int) @@ -116,6 +111,8 @@ struct ExecutableAllocator { mprotect(reinterpret_cast<void*>(roundAddr), size + (iaddr - roundAddr), mode); #endif } + + QQmlJS::VM::ExecutableAllocator *realAllocator; }; } |