зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1132564 part 2 - Move ExecutableAllocator into JitRuntime. r=luke
This commit is contained in:
Родитель
e42bc80af0
Коммит
cbb9dbe418
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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_;
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче