Bug 1132564 part 2 - Move ExecutableAllocator into JitRuntime. r=luke

This commit is contained in:
Jan de Mooij 2015-02-14 10:37:44 +01:00
parent 7c46f47261
commit ee80386b9c
8 changed files with 45 additions and 77 deletions

View File

@ -78,7 +78,8 @@ namespace jit {
class ExecutablePool {
friend class ExecutableAllocator;
private:
private:
struct Allocation {
char* pages;
size_t size;
@ -98,7 +99,7 @@ private:
size_t m_regexpCodeBytes;
size_t m_otherCodeBytes;
public:
public:
void release(bool willDestroy = false)
{
MOZ_ASSERT(m_refCount != 0);
@ -140,7 +141,10 @@ public:
~ExecutablePool();
private:
private:
ExecutablePool(const ExecutablePool &) = delete;
void operator=(const ExecutablePool &) = delete;
// It should be impossible for us to roll over, because only small
// pools have multiple holders, and they have one holder per chunk
// of generated code, and they only hold 16KB or so of code.
@ -177,9 +181,9 @@ class ExecutableAllocator {
enum ProtectionSetting { Writable, Executable };
DestroyCallback destroyCallback;
public:
public:
ExecutableAllocator()
: destroyCallback(NULL)
: destroyCallback(nullptr)
{
if (!pageSize) {
pageSize = determinePageSize();
@ -229,13 +233,13 @@ public:
MOZ_ASSERT(roundUpAllocationSize(n, sizeof(void*)) == n);
if (n == OVERSIZE_ALLOCATION) {
*poolp = NULL;
return NULL;
*poolp = nullptr;
return nullptr;
}
*poolp = poolForSize(n);
if (!*poolp)
return NULL;
return nullptr;
// This alloc is infallible because poolForSize() just obtained
// (found, or created if necessary) a pool that had enough space.
@ -259,7 +263,7 @@ public:
this->destroyCallback = destroyCallback;
}
private:
private:
static size_t pageSize;
static size_t largeAllocSize;
#ifdef XP_WIN
@ -286,7 +290,7 @@ private:
return size;
}
// On OOM, this will return an Allocation where pages is NULL.
// On OOM, this will return an Allocation where pages is nullptr.
ExecutablePool::Allocation systemAlloc(size_t n);
static void systemRelease(const ExecutablePool::Allocation& alloc);
void *computeRandomAllocationAddress();
@ -295,25 +299,25 @@ private:
{
size_t allocSize = roundUpAllocationSize(n, pageSize);
if (allocSize == OVERSIZE_ALLOCATION)
return NULL;
return nullptr;
if (!m_pools.initialized() && !m_pools.init())
return NULL;
return nullptr;
ExecutablePool::Allocation a = systemAlloc(allocSize);
if (!a.pages)
return NULL;
return nullptr;
ExecutablePool *pool = js_new<ExecutablePool>(this, a);
if (!pool) {
systemRelease(a);
return NULL;
return nullptr;
}
m_pools.put(pool);
return pool;
}
public:
public:
ExecutablePool* poolForSize(size_t n)
{
// Try to fit in an existing small allocator. Use the pool with the
@ -321,7 +325,7 @@ public:
// best strategy because (a) it maximizes the chance of the next
// allocation fitting in a small pool, and (b) it minimizes the
// potential waste when a small pool is next abandoned.
ExecutablePool *minPool = NULL;
ExecutablePool *minPool = nullptr;
for (size_t i = 0; i < m_smallPools.length(); i++) {
ExecutablePool *pool = m_smallPools[i];
if (n <= pool->available() && (!minPool || pool->available() < minPool->available()))
@ -339,7 +343,7 @@ public:
// Create a new allocator
ExecutablePool* pool = createPool(largeAllocSize);
if (!pool)
return NULL;
return nullptr;
// At this point, local |pool| is the owner.
if (m_smallPools.length() < maxSmallPools) {
@ -349,12 +353,13 @@ public:
} else {
// Find the pool with the least space.
int iMin = 0;
for (size_t i = 1; i < m_smallPools.length(); i++)
for (size_t i = 1; i < m_smallPools.length(); i++) {
if (m_smallPools[i]->available() <
m_smallPools[iMin]->available())
{
iMin = i;
}
}
// If the new allocator will result in more free space than the small
// pool with the least space, then we will use it instead
@ -433,7 +438,9 @@ public:
}
#endif
private:
private:
ExecutableAllocator(const ExecutableAllocator &) = delete;
void operator=(const ExecutableAllocator &) = delete;
#if ENABLE_ASSEMBLER_WX_EXCLUSIVE
static void reprotectRegion(void*, size_t, ProtectionSetting);

View File

@ -228,7 +228,7 @@ js::jit::DeallocateExecutableMemory(void *addr, size_t bytes, size_t pageSize)
ExecutablePool::Allocation ExecutableAllocator::systemAlloc(size_t n)
{
void *allocation = NULL;
void *allocation = nullptr;
// Randomization disabled to avoid a performance fault on x64 builds.
// See bug 728623.
#ifndef JS_CPU_X64

View File

@ -146,7 +146,7 @@ jit::InitializeIon()
}
JitRuntime::JitRuntime()
: execAlloc_(nullptr),
: execAlloc_(),
exceptionTail_(nullptr),
bailoutTail_(nullptr),
profilerExitFrameTail_(nullptr),
@ -185,10 +185,6 @@ JitRuntime::initialize(JSContext *cx)
JitContext jctx(cx, nullptr);
execAlloc_ = cx->runtime()->getExecAlloc(cx);
if (!execAlloc_)
return false;
if (!cx->compartment()->ensureJitCompartmentExists(cx))
return false;

View File

@ -141,9 +141,8 @@ class JitRuntime
{
friend class JitCompartment;
// Executable allocator for all code except asm.js code. Shared with the
// runtime.
ExecutableAllocator *execAlloc_;
// Executable allocator for all code except asm.js code.
ExecutableAllocator execAlloc_;
// Shared exception-handler tail.
JitCode *exceptionTail_;
@ -257,7 +256,7 @@ class JitRuntime
static void Mark(JSTracer *trc);
ExecutableAllocator *execAlloc() const {
ExecutableAllocator &execAlloc() {
return execAlloc_;
}

View File

@ -28,8 +28,15 @@ class Linker
return nullptr;
}
public:
explicit Linker(MacroAssembler &masm)
: masm(masm)
{
masm.finish();
}
template <AllowGC allowGC>
JitCode *newCode(JSContext *cx, ExecutableAllocator *execAlloc, CodeKind kind) {
JitCode *newCode(JSContext *cx, CodeKind kind) {
MOZ_ASSERT(masm.numAsmJSAbsoluteLinks() == 0);
gc::AutoSuppressGC suppressGC(cx);
@ -44,7 +51,8 @@ class Linker
// ExecutableAllocator requires bytesNeeded to be word-size aligned.
bytesNeeded = AlignBytes(bytesNeeded, sizeof(void *));
uint8_t *result = (uint8_t *)execAlloc->alloc(bytesNeeded, &pool, kind);
ExecutableAllocator &execAlloc = cx->runtime()->jitRuntime()->execAlloc();
uint8_t *result = (uint8_t *)execAlloc.alloc(bytesNeeded, &pool, kind);
if (!result)
return fail(cx);
@ -66,18 +74,6 @@ class Linker
cx->runtime()->gc.storeBuffer.putWholeCellFromMainThread(code);
return code;
}
public:
explicit Linker(MacroAssembler &masm)
: masm(masm)
{
masm.finish();
}
template <AllowGC allowGC>
JitCode *newCode(JSContext *cx, CodeKind kind) {
return newCode<allowGC>(cx, cx->runtime()->jitRuntime()->execAlloc(), kind);
}
};
} // namespace jit

View File

@ -5354,8 +5354,8 @@ GCRuntime::endSweepPhase(bool lastGC)
SweepScriptData(rt);
/* Clear out any small pools that we're hanging on to. */
if (jit::ExecutableAllocator *execAlloc = rt->maybeExecAlloc())
execAlloc->purge();
if (jit::JitRuntime *jitRuntime = rt->jitRuntime())
jitRuntime->execAlloc().purge();
/*
* This removes compartments from rt->compartment, so we do it last to make

View File

@ -138,7 +138,6 @@ JSRuntime::JSRuntime(JSRuntime *parentRuntime)
ownerThread_(nullptr),
ownerThreadNative_(0),
tempLifoAlloc(TEMP_LIFO_ALLOC_PRIMARY_CHUNK_SIZE),
execAlloc_(nullptr),
jitRuntime_(nullptr),
selfHostingGlobal_(nullptr),
nativeStackBase(GetNativeStackBase()),
@ -422,7 +421,6 @@ JSRuntime::~JSRuntime()
js_free(defaultLocale);
js_delete(mathCache_);
js_delete(jitRuntime_);
js_delete(execAlloc_); /* Delete after jitRuntime_. */
js_delete(ionPcScriptCache);
@ -507,8 +505,8 @@ JSRuntime::addSizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf, JS::Runtim
for (ScriptDataTable::Range r = scriptDataTable().all(); !r.empty(); r.popFront())
rtSizes->scriptData += mallocSizeOf(r.front());
if (execAlloc_)
execAlloc_->addSizeOfCode(&rtSizes->code);
if (jitRuntime_)
jitRuntime_->execAlloc().addSizeOfCode(&rtSizes->code);
rtSizes->gc.marker += gc.marker.sizeOfExcludingThis(mallocSizeOf);
rtSizes->gc.nurseryCommitted += gc.nursery.sizeOfHeapCommitted();
@ -620,18 +618,6 @@ JSRuntime::handleInterrupt(JSContext *cx)
return true;
}
jit::ExecutableAllocator *
JSRuntime::createExecutableAllocator(JSContext *cx)
{
MOZ_ASSERT(!execAlloc_);
MOZ_ASSERT(cx->runtime() == this);
execAlloc_ = js_new<jit::ExecutableAllocator>();
if (!execAlloc_)
js_ReportOutOfMemory(cx);
return execAlloc_;
}
MathCache *
JSRuntime::createMathCache(JSContext *cx)
{

View File

@ -807,11 +807,6 @@ struct JSRuntime : public JS::shadow::Runtime,
js::LifoAlloc tempLifoAlloc;
private:
/*
* Both of these allocators are used for regular expression code which is shared at the
* thread-data level.
*/
js::jit::ExecutableAllocator *execAlloc_;
js::jit::JitRuntime *jitRuntime_;
/*
@ -826,20 +821,9 @@ struct JSRuntime : public JS::shadow::Runtime,
/* Space for interpreter frames. */
js::InterpreterStack interpreterStack_;
js::jit::ExecutableAllocator *createExecutableAllocator(JSContext *cx);
js::jit::JitRuntime *createJitRuntime(JSContext *cx);
public:
js::jit::ExecutableAllocator *getExecAlloc(JSContext *cx) {
return execAlloc_ ? execAlloc_ : createExecutableAllocator(cx);
}
js::jit::ExecutableAllocator &execAlloc() {
MOZ_ASSERT(execAlloc_);
return *execAlloc_;
}
js::jit::ExecutableAllocator *maybeExecAlloc() {
return execAlloc_;
}
js::jit::JitRuntime *getJitRuntime(JSContext *cx) {
return jitRuntime_ ? jitRuntime_ : createJitRuntime(cx);
}