Bug 675150 - Avoid wasted space in JSArenaPools due to jemalloc rounding up. r=cdleary.

This commit is contained in:
Nicholas Nethercote 2011-08-29 17:36:49 -07:00
parent f2c3c84e57
commit 98ac3390a5
5 changed files with 18 additions and 17 deletions

View File

@ -292,7 +292,7 @@ Script::analyze(JSContext *cx, JSScript *script)
JS_ASSERT(!code && !locals);
this->script = script;
JS_InitArenaPool(&pool, "script_analyze", 256, 8);
JS_InitArenaPool(&pool, "script_analyze", 4096, 8);
unsigned length = script->length;
unsigned nfixed = localCount();

View File

@ -59,6 +59,7 @@ JS_STATIC_ASSERT(sizeof(JSArena) % 8 == 0);
JS_PUBLIC_API(void)
JS_InitArenaPool(JSArenaPool *pool, const char *name, size_t size, size_t align)
{
JS_ASSERT(JS_CeilingLog2(size) == JS_FloorLog2(size));
/* Restricting ourselves to some simple alignments keeps things simple. */
if (align == 1 || align == 2 || align == 4 || align == 8) {
pool->mask = align - 1;
@ -72,7 +73,9 @@ JS_InitArenaPool(JSArenaPool *pool, const char *name, size_t size, size_t align)
pool->first.base = pool->first.avail = pool->first.limit =
JS_ARENA_ALIGN(pool, &pool->first + 1);
pool->current = &pool->first;
pool->arenasize = size;
pool->netsize = size - sizeof(JSArena);
/* Check the net size has the right alignment. */
JS_ASSERT(pool->netsize == JS_ARENA_ALIGN(pool, pool->netsize));
}
JS_PUBLIC_API(void *)
@ -98,7 +101,7 @@ JS_ArenaAllocate(JSArenaPool *pool, size_t nb)
JSArena **ap = &a->next;
if (!*ap) {
/* Not enough space in pool, so we must malloc. */
size_t gross = sizeof(JSArena) + JS_MAX(nb, pool->arenasize);
size_t gross = sizeof(JSArena) + JS_MAX(nb, pool->netsize);
a = (JSArena *) OffTheBooks::malloc_(gross);
if (!a)
return NULL;
@ -128,8 +131,8 @@ JS_ArenaAllocate(JSArenaPool *pool, size_t nb)
JS_PUBLIC_API(void *)
JS_ArenaRealloc(JSArenaPool *pool, void *p, size_t size, size_t incr)
{
/* If we've called JS_ArenaRealloc, the new size must be bigger than pool->arenasize. */
JS_ASSERT(size + incr > pool->arenasize);
/* If we've called JS_ArenaRealloc, the new size must be bigger than pool->netsize. */
JS_ASSERT(size + incr > pool->netsize);
/* Find the arena containing |p|. */
JSArena *a;
@ -177,7 +180,7 @@ JS_ArenaGrow(JSArenaPool *pool, void *p, size_t size, size_t incr)
* If p points to an oversized allocation, it owns an entire arena, so we
* can simply realloc the arena.
*/
if (size > pool->arenasize)
if (size > pool->netsize)
return JS_ArenaRealloc(pool, p, size, incr);
JS_ARENA_ALLOCATE(newp, pool, size + incr);

View File

@ -65,7 +65,8 @@ struct JSArena {
struct JSArenaPool {
JSArena first; /* first arena in pool list */
JSArena *current; /* arena from which to allocate space */
size_t arenasize; /* net exact size of a new arena */
size_t netsize; /* net exact size of a new arena; equal to |size|
from JS_InitArenaPool minus sizeof(JSArena) */
jsuword mask; /* alignment mask (power-of-2 - 1) */
};
@ -173,7 +174,7 @@ struct JSArenaPool {
/*
* Initialize an arena pool with a minimum size per arena of |size| bytes.
* |align| must be 1, 2, 4 or 8.
* |size| must be a power-of-two. |align| must be 1, 2, 4 or 8.
*/
extern JS_PUBLIC_API(void)
JS_InitArenaPool(JSArenaPool *pool, const char *name, size_t size,

View File

@ -311,9 +311,6 @@ js_PurgeThreads(JSContext *cx)
#endif
}
static const size_t ARENA_HEADER_SIZE_HACK = 40;
static const size_t TEMP_POOL_CHUNK_SIZE = 4096 - ARENA_HEADER_SIZE_HACK;
JSContext *
js_NewContext(JSRuntime *rt, size_t stackChunkSize)
{
@ -340,8 +337,8 @@ js_NewContext(JSRuntime *rt, size_t stackChunkSize)
JS_ASSERT(cx->findVersion() == JSVERSION_DEFAULT);
VOUCH_DOES_NOT_REQUIRE_STACK();
JS_InitArenaPool(&cx->tempPool, "temp", TEMP_POOL_CHUNK_SIZE, sizeof(jsdouble));
JS_InitArenaPool(&cx->regExpPool, "regExp", TEMP_POOL_CHUNK_SIZE, sizeof(int));
JS_InitArenaPool(&cx->tempPool, "temp", 16384, sizeof(jsdouble));
JS_InitArenaPool(&cx->regExpPool, "regExp", 4096, sizeof(int));
JS_ASSERT(cx->resolveFlags == 0);

View File

@ -927,8 +927,8 @@ Compiler::compileScript(JSContext *cx, JSObject *scopeChain, StackFrame *callerF
if (!compiler.init(chars, length, filename, lineno, version))
return NULL;
JS_InitArenaPool(&codePool, "code", 1024, sizeof(jsbytecode));
JS_InitArenaPool(&notePool, "note", 1024, sizeof(jssrcnote));
JS_InitArenaPool(&codePool, "code", 4096, sizeof(jsbytecode));
JS_InitArenaPool(&notePool, "note", 4096, sizeof(jssrcnote));
Parser &parser = compiler.parser;
TokenStream &tokenStream = parser.tokenStream;
@ -1785,8 +1785,8 @@ Compiler::compileFunctionBody(JSContext *cx, JSFunction *fun, JSPrincipals *prin
/* No early return from after here until the js_FinishArenaPool calls. */
JSArenaPool codePool, notePool;
JS_InitArenaPool(&codePool, "code", 1024, sizeof(jsbytecode));
JS_InitArenaPool(&notePool, "note", 1024, sizeof(jssrcnote));
JS_InitArenaPool(&codePool, "code", 4096, sizeof(jsbytecode));
JS_InitArenaPool(&notePool, "note", 4096, sizeof(jssrcnote));
Parser &parser = compiler.parser;
TokenStream &tokenStream = parser.tokenStream;