diff options
Diffstat (limited to 'libpixelflinger/codeflinger/CodeCache.cpp')
-rw-r--r-- | libpixelflinger/codeflinger/CodeCache.cpp | 34 |
1 files changed, 28 insertions, 6 deletions
diff --git a/libpixelflinger/codeflinger/CodeCache.cpp b/libpixelflinger/codeflinger/CodeCache.cpp index 29410c8..5877ff4 100644 --- a/libpixelflinger/codeflinger/CodeCache.cpp +++ b/libpixelflinger/codeflinger/CodeCache.cpp @@ -19,6 +19,8 @@ #include <assert.h> #include <stdio.h> #include <stdlib.h> +#include <unistd.h> +#include <sys/mman.h> #include <cutils/log.h> #include <cutils/atomic.h> @@ -39,15 +41,14 @@ namespace android { Assembly::Assembly(size_t size) : mCount(1), mSize(0) { - mBase = (uint32_t*)malloc(size); - if (mBase) { - mSize = size; - } + mBase = (uint32_t*)mspace_malloc(getMspace(), size); + mSize = size; + ensureMbaseExecutable(); } Assembly::~Assembly() { - free(mBase); + mspace_free(getMspace(), mBase); } void Assembly::incStrong(const void*) const @@ -75,11 +76,32 @@ uint32_t* Assembly::base() const ssize_t Assembly::resize(size_t newSize) { - mBase = (uint32_t*)realloc(mBase, newSize); + mBase = (uint32_t*)mspace_realloc(getMspace(), mBase, newSize); mSize = newSize; + ensureMbaseExecutable(); return size(); } +mspace Assembly::getMspace() +{ + static mspace msp = create_contiguous_mspace(2 * 1024, 1024 * 1024, /*locked=*/ false); + return msp; +} + +void Assembly::ensureMbaseExecutable() +{ + long pagesize = sysconf(_SC_PAGESIZE); + long pagemask = ~(pagesize - 1); // assumes pagesize is a power of 2 + + uint32_t* pageStart = (uint32_t*) (((uintptr_t) mBase) & pagemask); + size_t adjustedLength = mBase - pageStart + mSize; + + if (mBase && mprotect(pageStart, adjustedLength, PROT_READ | PROT_WRITE | PROT_EXEC) != 0) { + mspace_free(getMspace(), mBase); + mBase = NULL; + } +} + // ---------------------------------------------------------------------------- CodeCache::CodeCache(size_t size) |