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

This commit is contained in:
Nicholas Nethercote 2011-09-07 16:49:28 -07:00
parent 186855328d
commit 106a4349fb
4 changed files with 17 additions and 17 deletions

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

@ -66,7 +66,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) */
};
@ -174,7 +175,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,
@ -225,6 +226,8 @@ JS_END_EXTERN_C
#ifdef __cplusplus
#include "jstl.h"
namespace js {
template <typename T>
@ -307,7 +310,7 @@ inline void
MoveArenaPool(JSArenaPool *oldPool, JSArenaPool *newPool)
{
*newPool = *oldPool;
JS_InitArenaPool(oldPool, NULL, newPool->arenasize, newPool->mask + 1);
JS_InitArenaPool(oldPool, NULL, RoundUpPow2(newPool->netsize), newPool->mask + 1);
}
} /* namespace js */

View File

@ -316,9 +316,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)
{
@ -345,8 +342,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", 4096, sizeof(jsdouble));
JS_InitArenaPool(&cx->regExpPool, "regExp", 4096, sizeof(int));
JS_ASSERT(cx->resolveFlags == 0);

View File

@ -132,10 +132,7 @@ JSCompartment::init(JSContext *cx)
activeAnalysis = activeInference = false;
types.init(cx);
/* Duplicated from jscntxt.cpp. :XXX: bug 675150 fix hack. */
static const size_t ARENA_HEADER_SIZE_HACK = 40;
JS_InitArenaPool(&pool, "analysis", 4096 - ARENA_HEADER_SIZE_HACK, 8);
JS_InitArenaPool(&pool, "analysis", 4096, 8);
if (!crossCompartmentWrappers.init())
return false;