Bug 559408: Arena macros to methods. (r=galish)

This commit is contained in:
Chris Leary 2010-07-10 23:19:14 -07:00
Родитель 21a98fb81f
Коммит a850080a2f
17 изменённых файлов: 631 добавлений и 567 удалений

Просмотреть файл

@ -2442,8 +2442,8 @@ JS_GC(JSContext *cx)
LeaveTrace(cx);
/* Don't nuke active arenas if executing or compiling. */
if (cx->tempPool.current == &cx->tempPool.first)
JS_FinishArenaPool(&cx->tempPool);
if (cx->tempPool.currentIsFirst())
cx->tempPool.finish();
js_GC(cx, GC_NORMAL);
}
@ -4131,7 +4131,7 @@ JS_CloneFunctionObject(JSContext *cx, JSObject *funobj, JSObject *parent)
JSUpvarArray *uva = fun->u.i.script->upvars();
JS_ASSERT(uva->length <= size_t(clone->dslots[-1]));
void *mark = JS_ARENA_MARK(&cx->tempPool);
void *mark = cx->tempPool.getMark();
jsuword *names = js_GetLocalNameArray(cx, fun, &cx->tempPool);
if (!names)
return NULL;
@ -4155,7 +4155,7 @@ JS_CloneFunctionObject(JSContext *cx, JSObject *funobj, JSObject *parent)
}
break2:
JS_ARENA_RELEASE(&cx->tempPool, mark);
cx->tempPool.release(mark);
if (i < n)
return NULL;
}

Просмотреть файл

@ -47,37 +47,32 @@
#include "jstypes.h"
#include "jsstdint.h"
#include "jsbit.h"
#include "jsarena.h" /* Added by JSIFY */
#include "jsutil.h" /* Added by JSIFY */
#include "jsarenainlines.h"
#include "jsutil.h"
#ifdef JS_ARENAMETER
#ifdef DEBUG
static JSArenaStats *arena_stats_list;
#define COUNT(pool,what) (pool)->stats.what++
#else
#define COUNT(pool,what) /* nothing */
#endif
#endif /* DEBUG */
#define JS_ARENA_DEFAULT_ALIGN sizeof(double)
JS_PUBLIC_API(void)
JS_InitArenaPool(JSArenaPool *pool, const char *name, size_t size,
size_t align, size_t *quotap)
void
JSArenaPool::init(const char *name, size_t size, size_t align, size_t *quotap)
{
if (align == 0)
align = JS_ARENA_DEFAULT_ALIGN;
pool->mask = JS_BITMASK(JS_CeilingLog2(align));
pool->first.next = NULL;
pool->first.base = pool->first.avail = pool->first.limit =
JS_ARENA_ALIGN(pool, &pool->first + 1);
pool->current = &pool->first;
pool->arenasize = size;
pool->quotap = quotap;
#ifdef JS_ARENAMETER
memset(&pool->stats, 0, sizeof pool->stats);
pool->stats.name = strdup(name);
pool->stats.next = arena_stats_list;
arena_stats_list = &pool->stats;
mask = JS_BITMASK(JS_CeilingLog2(align));
first.next = NULL;
first.base = first.avail = first.limit = this->align(jsuword(&first + 1));
current = &first;
arenasize = size;
this->quotap = quotap;
#ifdef DEBUG
stats.init(name, arena_stats_list);
arena_stats_list = &stats;
#endif
}
@ -104,37 +99,30 @@ JS_InitArenaPool(JSArenaPool *pool, const char *name, size_t size,
* boundary. Given powers of two M and P as above, the extra space needed
* when M < P is P-M or POINTER_MASK - pool->mask.
*
* The size of a header including padding is given by the HEADER_SIZE macro,
* below, for any pool (for any value of M).
*
* The mask to align a->base for any pool is (pool->mask | POINTER_MASK), or
* HEADER_BASE_MASK(pool).
*
* PTR_TO_HEADER computes the address of the back-pointer, given an oversized
* allocation at p. By definition, p must be a->base for the arena a that
* contains p. GET_HEADER and SET_HEADER operate on an oversized arena a, in
* the case of SET_HEADER with back-pointer ap.
* The size of a header including padding is given by the headerSize method
* for any pool (for any value of M).
*/
#define POINTER_MASK ((jsuword)(JS_ALIGN_OF_POINTER - 1))
#define HEADER_SIZE(pool) (sizeof(JSArena **) \
+ (((pool)->mask < POINTER_MASK) \
? POINTER_MASK - (pool)->mask \
: 0))
#define HEADER_BASE_MASK(pool) ((pool)->mask | POINTER_MASK)
#define PTR_TO_HEADER(pool,p) (JS_ASSERT(((jsuword)(p) \
& HEADER_BASE_MASK(pool)) \
== 0), \
(JSArena ***)(p) - 1)
#define GET_HEADER(pool,a) (*PTR_TO_HEADER(pool, (a)->base))
#define SET_HEADER(pool,a,ap) (*PTR_TO_HEADER(pool, (a)->base) = (ap))
JS_PUBLIC_API(void *)
JS_ArenaAllocate(JSArenaPool *pool, size_t nb)
void *
JSArenaPool::allocate(size_t nb, bool limitCheck)
{
JSArena **ap, *a, *b;
jsuword extra, hdrsz, gross;
void *p;
countAllocation(nb);
size_t alignedNB = align(nb);
jsuword p = current->avail;
/*
* NB: always subtract nb from limit rather than adding nb to p to avoid overflowing a
* 32-bit address space. See bug 279273.
*/
if ((limitCheck && alignedNB > current->limit) || p > current->limit - alignedNB)
p = jsuword(allocateInternal(alignedNB));
else
current->avail = p + alignedNB;
return (void *) p;
}
void *
JSArenaPool::allocateInternal(size_t nb)
{
/*
* Search pool from current forward till we find or make enough space.
*
@ -146,24 +134,25 @@ JS_ArenaAllocate(JSArenaPool *pool, size_t nb)
* Thanks to Juergen Kreileder <jk@blackdown.de>, who brought this up in
* https://bugzilla.mozilla.org/show_bug.cgi?id=279273.
*/
JS_ASSERT((nb & pool->mask) == 0);
for (a = pool->current; nb > a->limit || a->avail > a->limit - nb;
pool->current = a) {
ap = &a->next;
JS_ASSERT((nb & mask) == 0);
JSArena *a;
for (a = current; nb > a->limit || a->avail > a->limit - nb; current = a) {
JSArena **ap = &a->next;
if (!*ap) {
/* Not enough space in pool, so we must malloc. */
extra = (nb > pool->arenasize) ? HEADER_SIZE(pool) : 0;
hdrsz = sizeof *a + extra + pool->mask;
gross = hdrsz + JS_MAX(nb, pool->arenasize);
jsuword extra = (nb > arenasize) ? headerSize() : 0;
jsuword hdrsz = sizeof *a + extra + mask;
jsuword gross = hdrsz + JS_MAX(nb, arenasize);
if (gross < nb)
return NULL;
if (pool->quotap) {
if (gross > *pool->quotap)
JSArena *b;
if (quotap) {
if (gross > *quotap)
return NULL;
b = (JSArena *) js_malloc(gross);
if (!b)
return NULL;
*pool->quotap -= gross;
*quotap -= gross;
} else {
b = (JSArena *) js_malloc(gross);
if (!b)
@ -172,32 +161,32 @@ JS_ArenaAllocate(JSArenaPool *pool, size_t nb)
b->next = NULL;
b->limit = (jsuword)b + gross;
JS_COUNT_ARENA(pool,++);
COUNT(pool, nmallocs);
incArenaCount();
COUNT(this, nmallocs);
/* If oversized, store ap in the header, just before a->base. */
*ap = a = b;
JS_ASSERT(gross <= JS_UPTRDIFF(a->limit, a));
if (extra) {
a->base = a->avail =
((jsuword)a + hdrsz) & ~HEADER_BASE_MASK(pool);
SET_HEADER(pool, a, ap);
((jsuword)a + hdrsz) & ~headerBaseMask();
setHeader(a, ap);
} else {
a->base = a->avail = JS_ARENA_ALIGN(pool, a + 1);
a->base = a->avail = align(jsuword(a + 1));
}
continue;
}
a = *ap; /* move to next arena */
}
p = (void *)a->avail;
void *p = (void *) a->avail;
a->avail += nb;
JS_ASSERT(a->base <= a->avail && a->avail <= a->limit);
return p;
}
JS_PUBLIC_API(void *)
JS_ArenaRealloc(JSArenaPool *pool, void *p, size_t size, size_t incr)
void *
JSArenaPool::reallocInternal(void *p, size_t size, size_t incr)
{
JSArena **ap, *a, *b;
jsuword boff, aoff, extra, hdrsz, gross, growth;
@ -206,55 +195,53 @@ JS_ArenaRealloc(JSArenaPool *pool, void *p, size_t size, size_t incr)
* Use the oversized-single-allocation header to avoid searching for ap.
* See JS_ArenaAllocate, the SET_HEADER call.
*/
if (size > pool->arenasize) {
ap = *PTR_TO_HEADER(pool, p);
if (size > arenasize) {
ap = *ptrToHeader(p);
a = *ap;
} else {
ap = &pool->first.next;
while ((a = *ap) != pool->current)
ap = &first.next;
while ((a = *ap) != current)
ap = &a->next;
}
JS_ASSERT(a->base == (jsuword)p);
boff = JS_UPTRDIFF(a->base, a);
aoff = JS_ARENA_ALIGN(pool, size + incr);
JS_ASSERT(aoff > pool->arenasize);
extra = HEADER_SIZE(pool); /* oversized header holds ap */
hdrsz = sizeof *a + extra + pool->mask; /* header and alignment slop */
aoff = align(size + incr);
JS_ASSERT(aoff > arenasize);
extra = headerSize(); /* oversized header holds ap */
hdrsz = sizeof *a + extra + mask; /* header and alignment slop */
gross = hdrsz + aoff;
JS_ASSERT(gross > aoff);
if (pool->quotap) {
if (quotap) {
growth = gross - (a->limit - (jsuword) a);
if (growth > *pool->quotap)
if (growth > *quotap)
return NULL;
a = (JSArena *) js_realloc(a, gross);
if (!a)
return NULL;
*pool->quotap -= growth;
*quotap -= growth;
} else {
a = (JSArena *) js_realloc(a, gross);
if (!a)
return NULL;
}
#ifdef JS_ARENAMETER
pool->stats.nreallocs++;
#endif
incReallocCount();
if (a != *ap) {
/* Oops, realloc moved the allocation: update other pointers to a. */
if (pool->current == *ap)
pool->current = a;
if (current == *ap)
current = a;
b = a->next;
if (b && b->avail - b->base > pool->arenasize) {
JS_ASSERT(GET_HEADER(pool, b) == &(*ap)->next);
SET_HEADER(pool, b, &a->next);
if (b && b->avail - b->base > arenasize) {
JS_ASSERT(getHeader(b) == &(*ap)->next);
setHeader(b, &a->next);
}
/* Now update *ap, the next link of the arena before a. */
*ap = a;
}
a->base = ((jsuword)a + hdrsz) & ~HEADER_BASE_MASK(pool);
a->base = ((jsuword)a + hdrsz) & ~headerBaseMask();
a->limit = (jsuword)a + gross;
a->avail = a->base + aoff;
JS_ASSERT(a->base <= a->avail && a->avail <= a->limit);
@ -264,102 +251,22 @@ JS_ArenaRealloc(JSArenaPool *pool, void *p, size_t size, size_t incr)
memmove((void *) a->base, (char *) a + boff, size);
/* Store ap in the oversized-load arena header. */
SET_HEADER(pool, a, ap);
setHeader(a, ap);
return (void *) a->base;
}
JS_PUBLIC_API(void *)
JS_ArenaGrow(JSArenaPool *pool, void *p, size_t size, size_t incr)
void
JSArenaPool::finish()
{
void *newp;
/*
* If p points to an oversized allocation, it owns an entire arena, so we
* can simply realloc the arena.
*/
if (size > pool->arenasize)
return JS_ArenaRealloc(pool, p, size, incr);
JS_ARENA_ALLOCATE(newp, pool, size + incr);
if (newp)
memcpy(newp, p, size);
return newp;
}
/*
* Free tail arenas linked after head, which may not be the true list head.
* Reset pool->current to point to head in case it pointed at a tail arena.
*/
static void
FreeArenaList(JSArenaPool *pool, JSArena *head)
{
JSArena **ap, *a;
ap = &head->next;
a = *ap;
if (!a)
return;
freeArenaList(&first);
#ifdef DEBUG
do {
JS_ASSERT(a->base <= a->avail && a->avail <= a->limit);
a->avail = a->base;
JS_CLEAR_UNUSED(a);
} while ((a = a->next) != NULL);
a = *ap;
#endif
do {
*ap = a->next;
if (pool->quotap)
*pool->quotap += a->limit - (jsuword) a;
JS_CLEAR_ARENA(a);
JS_COUNT_ARENA(pool,--);
js_free(a);
} while ((a = *ap) != NULL);
pool->current = head;
}
JS_PUBLIC_API(void)
JS_ArenaRelease(JSArenaPool *pool, char *mark)
{
JSArena *a;
for (a = &pool->first; a; a = a->next) {
JS_ASSERT(a->base <= a->avail && a->avail <= a->limit);
if (JS_ARENA_MARK_MATCH(a, mark)) {
a->avail = JS_ARENA_ALIGN(pool, mark);
JS_ASSERT(a->avail <= a->limit);
FreeArenaList(pool, a);
return;
}
}
}
JS_PUBLIC_API(void)
JS_FreeArenaPool(JSArenaPool *pool)
{
FreeArenaList(pool, &pool->first);
COUNT(pool, ndeallocs);
}
JS_PUBLIC_API(void)
JS_FinishArenaPool(JSArenaPool *pool)
{
FreeArenaList(pool, &pool->first);
#ifdef JS_ARENAMETER
{
JSArenaStats *stats, **statsp;
if (pool->stats.name) {
js_free(pool->stats.name);
pool->stats.name = NULL;
}
this->stats.finish();
for (statsp = &arena_stats_list; (stats = *statsp) != 0;
statsp = &stats->next) {
if (stats == &pool->stats) {
if (stats == &this->stats) {
*statsp = stats->next;
return;
}
@ -368,83 +275,82 @@ JS_FinishArenaPool(JSArenaPool *pool)
#endif
}
JS_PUBLIC_API(void)
JS_ArenaFinish()
#ifdef DEBUG
void
JSArenaPool::countAllocation(size_t nb)
{
stats.nallocs++;
stats.nbytes += nb;
if (nb > stats.maxalloc)
stats.maxalloc = nb;
stats.variance += nb * nb;
}
JS_PUBLIC_API(void)
JS_ArenaShutDown(void)
void
JSArenaPool::countGrowth(size_t size, size_t incr)
{
}
#ifdef JS_ARENAMETER
JS_PUBLIC_API(void)
JS_ArenaCountAllocation(JSArenaPool *pool, size_t nb)
{
pool->stats.nallocs++;
pool->stats.nbytes += nb;
if (nb > pool->stats.maxalloc)
pool->stats.maxalloc = nb;
pool->stats.variance += nb * nb;
}
JS_PUBLIC_API(void)
JS_ArenaCountInplaceGrowth(JSArenaPool *pool, size_t size, size_t incr)
{
pool->stats.ninplace++;
}
JS_PUBLIC_API(void)
JS_ArenaCountGrowth(JSArenaPool *pool, size_t size, size_t incr)
{
pool->stats.ngrows++;
pool->stats.nbytes += incr;
pool->stats.variance -= size * size;
stats.ngrows++;
stats.nbytes += incr;
stats.variance -= size * size;
size += incr;
if (size > pool->stats.maxalloc)
pool->stats.maxalloc = size;
pool->stats.variance += size * size;
if (size > stats.maxalloc)
stats.maxalloc = size;
stats.variance += size * size;
}
JS_PUBLIC_API(void)
JS_ArenaCountRelease(JSArenaPool *pool, char *mark)
JS_FRIEND_API(void)
JS_DumpArenaStats()
{
pool->stats.nreleases++;
const char *filename = getenv("JS_ARENA_STATFILE");
if (!filename)
return;
FILE *arenaStatFile = strcmp(filename, "stdout")
? stdout : strcmp(filename, "stderr")
? stderr : fopen(filename, "w");
for (const JSArenaStats *stats = arena_stats_list; stats; stats = stats->getNext())
stats->dump(arenaStatFile);
fclose(arenaStatFile);
}
JS_PUBLIC_API(void)
JS_ArenaCountRetract(JSArenaPool *pool, char *mark)
void
JSArenaStats::dump(FILE *fp) const
{
pool->stats.nfastrels++;
}
double sigma;
double mean = JS_MeanAndStdDev(nallocs, nbytes, variance, &sigma);
#include <stdio.h>
JS_PUBLIC_API(void)
JS_DumpArenaStats(FILE *fp)
{
JSArenaStats *stats;
double mean, sigma;
for (stats = arena_stats_list; stats; stats = stats->next) {
mean = JS_MeanAndStdDev(stats->nallocs, stats->nbytes, stats->variance,
&sigma);
fprintf(fp, "\n%s allocation statistics:\n", stats->name);
fprintf(fp, " number of arenas: %u\n", stats->narenas);
fprintf(fp, " number of allocations: %u\n", stats->nallocs);
fprintf(fp, " number of malloc calls: %u\n", stats->nmallocs);
fprintf(fp, " number of deallocations: %u\n", stats->ndeallocs);
fprintf(fp, " number of allocation growths: %u\n", stats->ngrows);
fprintf(fp, " number of in-place growths: %u\n", stats->ninplace);
fprintf(fp, " number of realloc'ing growths: %u\n", stats->nreallocs);
fprintf(fp, "number of released allocations: %u\n", stats->nreleases);
fprintf(fp, " number of fast releases: %u\n", stats->nfastrels);
fprintf(fp, " total bytes allocated: %u\n", stats->nbytes);
fprintf(fp, "\n%s allocation statistics:\n", name);
fprintf(fp, " number of arenas: %u\n", narenas);
fprintf(fp, " number of allocations: %u\n", nallocs);
fprintf(fp, " number of malloc calls: %u\n", nmallocs);
fprintf(fp, " number of deallocations: %u\n", ndeallocs);
fprintf(fp, " number of allocation growths: %u\n", ngrows);
fprintf(fp, " number of in-place growths: %u\n", ninplace);
fprintf(fp, " number of realloc'ing growths: %u\n", nreallocs);
fprintf(fp, "number of released allocations: %u\n", nreleases);
fprintf(fp, " number of fast releases: %u\n", nfastrels);
fprintf(fp, " total bytes allocated: %u\n", unsigned(nbytes));
fprintf(fp, " mean allocation size: %g\n", mean);
fprintf(fp, " standard deviation: %g\n", sigma);
fprintf(fp, " maximum allocation size: %u\n", stats->maxalloc);
fprintf(fp, " maximum allocation size: %u\n", unsigned(maxalloc));
}
#endif /* DEBUG */
/* Backwards compatibility. */
JS_FRIEND_API(void *)
JS_ARENA_MARK(const JSArenaPool *pool)
{
return pool->getMark();
}
JS_FRIEND_API(void)
JS_ARENA_RELEASE(JSArenaPool *pool, void *mark)
{
pool->release(mark);
}
JS_FRIEND_API(void *)
JS_ARENA_ALLOCATE_COMMON_SANE(jsuword p, JSArenaPool *pool, size_t nb, bool limitCheck)
{
return pool->allocate(nb, limitCheck);
}
#endif /* JS_ARENAMETER */

Просмотреть файл

@ -47,25 +47,67 @@
* Also supports LIFO allocation (JS_ARENA_MARK/JS_ARENA_RELEASE).
*/
#include <stdlib.h>
#include <memory.h>
#ifdef DEBUG
#include <stdio.h>
#endif
#include "jstypes.h"
#include "jscompat.h"
#include "jsutil.h"
JS_BEGIN_EXTERN_C
#ifdef DEBUG
const uint8_t JS_FREE_PATTERN = 0xDA;
#endif
typedef struct JSArena JSArena;
typedef struct JSArenaPool JSArenaPool;
#define JS_UPTRDIFF(p,q) (jsuword(p) - jsuword(q))
struct JSArena {
struct JSArena
{
JSArena *next; /* next arena for this lifetime */
jsuword base; /* aligned base address, follows this header */
jsuword limit; /* one beyond last byte in arena */
jsuword avail; /* points to next available byte */
public:
jsuword getBase() const { return base; }
jsuword getLimit() const { return limit; }
jsuword getAvail() const { return avail; }
void setAvail(jsuword newAvail) { avail = newAvail; }
const JSArena *getNext() const { return next; }
JSArena *getNext() { return next; }
void munge(JSArena *next) { this-> next = next; }
void munge(JSArena *next, jsuword base, jsuword avail, jsuword limit) {
this->next = next;
this->base = base;
this->avail = avail;
this->limit = limit;
}
/*
* Check if the mark is inside arena's allocated area.
*/
bool markMatch(void *mark) const {
return JS_UPTRDIFF(mark, base) <= JS_UPTRDIFF(avail, base);
}
#ifdef DEBUG
void clear() { memset(this, JS_FREE_PATTERN, limit - jsuword(this)); }
void clearUnused() {
JS_ASSERT(avail <= limit);
memset((void *) avail, JS_FREE_PATTERN, limit - avail);
}
#else
void clear() {}
void clearUnused() {}
#endif
friend class JSArenaPool;
};
#ifdef JS_ARENAMETER
typedef struct JSArenaStats JSArenaStats;
struct JSArenaStats {
#ifdef DEBUG
class JSArenaStats
{
JSArenaStats *next; /* next in arenaStats list */
char *name; /* name for debugging */
uint32 narenas; /* number of arenas in pool */
@ -80,209 +122,263 @@ struct JSArenaStats {
size_t nbytes; /* total bytes allocated */
size_t maxalloc; /* maximum allocation size in bytes */
double variance; /* size variance accumulator */
};
#endif
struct JSArenaPool {
public:
void init(const char *name, JSArenaStats *next) {
memset(this, 0, sizeof *this);
this->name = strdup(name);
this->next = next;
}
void finish() { free(name); name = 0; }
void dump(FILE *fp) const;
const JSArenaStats *getNext() const { return next; }
friend class JSArenaPool;
};
JS_FRIEND_API(void)
JS_DumpArenaStats();
#endif /* DEBUG */
class 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 */
jsuword mask; /* alignment mask (power-of-2 - 1) */
size_t *quotap; /* pointer to the quota on pool allocation
size or null if pool is unlimited */
#ifdef JS_ARENAMETER
#ifdef DEBUG
JSArenaStats stats;
#endif
};
#define JS_ARENA_ALIGN(pool, n) (((jsuword)(n) + (pool)->mask) & ~(pool)->mask)
#define JS_ARENA_ALLOCATE(p, pool, nb) \
JS_ARENA_ALLOCATE_CAST(p, void *, pool, nb)
#define JS_ARENA_ALLOCATE_TYPE(p, type, pool) \
JS_ARENA_ALLOCATE_COMMON(p, type *, pool, sizeof(type), 0)
#define JS_ARENA_ALLOCATE_CAST(p, type, pool, nb) \
JS_ARENA_ALLOCATE_COMMON(p, type, pool, nb, _nb > _a->limit)
/*
* NB: In JS_ARENA_ALLOCATE_CAST and JS_ARENA_GROW_CAST, always subtract _nb
* from a->limit rather than adding _nb to _p, to avoid overflowing a 32-bit
* address space (possible when running a 32-bit program on a 64-bit system
* where the kernel maps the heap up against the top of the 32-bit address
* space).
*
* Thanks to Juergen Kreileder <jk@blackdown.de>, who brought this up in
* https://bugzilla.mozilla.org/show_bug.cgi?id=279273.
*/
#define JS_ARENA_ALLOCATE_COMMON(p, type, pool, nb, guard) \
JS_BEGIN_MACRO \
JSArena *_a = (pool)->current; \
size_t _nb = JS_ARENA_ALIGN(pool, nb); \
jsuword _p = _a->avail; \
if ((guard) || _p > _a->limit - _nb) \
_p = (jsuword)JS_ArenaAllocate(pool, _nb); \
else \
_a->avail = _p + _nb; \
p = (type) _p; \
JS_ArenaCountAllocation(pool, nb); \
JS_END_MACRO
#define JS_ARENA_GROW(p, pool, size, incr) \
JS_ARENA_GROW_CAST(p, void *, pool, size, incr)
#define JS_ARENA_GROW_CAST(p, type, pool, size, incr) \
JS_BEGIN_MACRO \
JSArena *_a = (pool)->current; \
if (_a->avail == (jsuword)(p) + JS_ARENA_ALIGN(pool, size)) { \
size_t _nb = (size) + (incr); \
_nb = JS_ARENA_ALIGN(pool, _nb); \
if (_a->limit >= _nb && (jsuword)(p) <= _a->limit - _nb) { \
_a->avail = (jsuword)(p) + _nb; \
JS_ArenaCountInplaceGrowth(pool, size, incr); \
} else if ((jsuword)(p) == _a->base) { \
p = (type) JS_ArenaRealloc(pool, p, size, incr); \
} else { \
p = (type) JS_ArenaGrow(pool, p, size, incr); \
} \
} else { \
p = (type) JS_ArenaGrow(pool, p, size, incr); \
} \
JS_ArenaCountGrowth(pool, size, incr); \
JS_END_MACRO
#define JS_ARENA_MARK(pool) ((void *) (pool)->current->avail)
#define JS_UPTRDIFF(p,q) ((jsuword)(p) - (jsuword)(q))
/*
* Check if the mark is inside arena's allocated area.
*/
#define JS_ARENA_MARK_MATCH(a, mark) \
(JS_UPTRDIFF(mark, (a)->base) <= JS_UPTRDIFF((a)->avail, (a)->base))
#ifdef DEBUG
#define JS_FREE_PATTERN 0xDA
#define JS_CLEAR_UNUSED(a) (JS_ASSERT((a)->avail <= (a)->limit), \
memset((void*)(a)->avail, JS_FREE_PATTERN, \
(a)->limit - (a)->avail))
#define JS_CLEAR_ARENA(a) memset((void*)(a), JS_FREE_PATTERN, \
(a)->limit - (jsuword)(a))
#else
#define JS_CLEAR_UNUSED(a) /* nothing */
#define JS_CLEAR_ARENA(a) /* nothing */
#endif
#define JS_ARENA_RELEASE(pool, mark) \
JS_BEGIN_MACRO \
char *_m = (char *)(mark); \
JSArena *_a = (pool)->current; \
if (_a != &(pool)->first && JS_ARENA_MARK_MATCH(_a, _m)) { \
_a->avail = (jsuword)JS_ARENA_ALIGN(pool, _m); \
JS_ASSERT(_a->avail <= _a->limit); \
JS_CLEAR_UNUSED(_a); \
JS_ArenaCountRetract(pool, _m); \
} else { \
JS_ArenaRelease(pool, _m); \
} \
JS_ArenaCountRelease(pool, _m); \
JS_END_MACRO
#ifdef JS_ARENAMETER
#define JS_COUNT_ARENA(pool,op) ((pool)->stats.narenas op)
#else
#define JS_COUNT_ARENA(pool,op)
#endif
#define JS_ARENA_DESTROY(pool, a, pnext) \
JS_BEGIN_MACRO \
JS_COUNT_ARENA(pool,--); \
if ((pool)->current == (a)) (pool)->current = &(pool)->first; \
*(pnext) = (a)->next; \
JS_CLEAR_ARENA(a); \
js_free(a); \
(a) = NULL; \
JS_END_MACRO
public:
/*
* Initialize an arena pool with a minimum size per arena of size bytes.
*/
extern JS_PUBLIC_API(void)
JS_InitArenaPool(JSArenaPool *pool, const char *name, size_t size,
size_t align, size_t *quotap);
/*
* Free the arenas in pool. The user may continue to allocate from pool
* after calling this function. There is no need to call JS_InitArenaPool()
* again unless JS_FinishArenaPool(pool) has been called.
*/
extern JS_PUBLIC_API(void)
JS_FreeArenaPool(JSArenaPool *pool);
void init(const char *name, size_t size, size_t align, size_t *quotap);
/*
* Free the arenas in pool and finish using it altogether.
*/
extern JS_PUBLIC_API(void)
JS_FinishArenaPool(JSArenaPool *pool);
void finish();
/*
* Deprecated do-nothing function.
* Free the arenas in pool. The user may continue to allocate from pool
* after calling this function. There is no need to call |init|
* again unless JS_FinishArenaPool(pool) has been called.
*/
extern JS_PUBLIC_API(void)
JS_ArenaFinish(void);
void free() {
freeArenaList(&first);
incDeallocCount();
}
void *getMark() const { return (void *) current->avail; }
jsuword align(jsuword n) const { return (n + mask) & ~mask; }
jsuword align(void *n) const { return align(jsuword(n)); }
bool currentIsFirst() const { return current == &first; }
const JSArena *getFirst() const { return &first; }
const JSArena *getSecond() const { return first.next; }
const JSArena *getCurrent() const { return current; }
JSArena *getFirst() { return &first; }
JSArena *getSecond() { return first.next; }
JSArena *getCurrent() { return current; }
void *allocate(size_t nb, bool limitCheck);
template <typename T>
void allocateCast(T &p, size_t nb) {
p = (T) allocate(nb, true);
}
template <typename T>
void allocateType(T *&p) {
p = (T *) allocate(sizeof(T), false);
}
void allocate(void *&p, size_t nb) { allocateCast<void *>(p, nb); }
void *grow(jsuword p, size_t size, size_t incr);
template <typename T>
void growCast(T &p, size_t size, size_t incr) {
p = (T) grow(jsuword(p), size, incr);
}
void release(void *mark) {
if (current != &first && current->markMatch(mark)) {
current->avail = jsuword(align(mark));
JS_ASSERT(current->avail <= current->limit);
current->clearUnused();
countRetract(mark);
} else {
releaseInternal(mark);
}
countRelease(mark);
}
JSArena *destroy(JSArena *&a) {
decArenaCount();
if (current == a)
current = &first;
JSArena *next = a->next;
a->clear();
::free(a);
a = NULL;
return next;
}
class ScopedExtension {
JSArenaPool * const parent;
JSArena * const prevTop;
JSArena * const pushed;
public:
ScopedExtension(JSArenaPool *parent, JSArena *toPush)
: parent(parent), prevTop(parent->getCurrent()), pushed(toPush) {
JS_ASSERT(!prevTop->getNext());
JS_ASSERT(!toPush->getNext());
JS_ASSERT(prevTop != toPush);
parent->current = prevTop->next = toPush;
}
~ScopedExtension() {
JS_ASSERT(!pushed->next);
JS_ASSERT(prevTop->next == pushed);
JS_ASSERT(parent->getCurrent() == pushed);
parent->current = prevTop;
prevTop->next = NULL;
}
};
private:
static const jsuword POINTER_MASK;
/*
* Deprecated do-nothing function.
* The mask to align |base|.
*/
extern JS_PUBLIC_API(void)
JS_ArenaShutDown(void);
jsuword headerBaseMask() const;
jsuword headerSize() const;
/*
* Friend functions used by the JS_ARENA_*() macros.
* Compute the address of the back-pointer, given an oversized allocation at |p|.
* |p| must be |a->base| for the arena |a| that contains |p|.
*/
extern JS_PUBLIC_API(void *)
JS_ArenaAllocate(JSArenaPool *pool, size_t nb);
JSArena ***ptrToHeader(void *p) const {
JS_ASSERT((jsuword(p) & headerBaseMask()) == 0);
return (JSArena ***)(p) - 1;
}
JSArena ***ptrToHeader(jsuword p) const { return ptrToHeader((void *) p); }
extern JS_PUBLIC_API(void *)
JS_ArenaRealloc(JSArenaPool *pool, void *p, size_t size, size_t incr);
/*
* |getHeader| and |setHeader| operate on an oversized arena.
*/
JSArena **getHeader(const JSArena *a) const { return *ptrToHeader(a->base); }
JSArena **setHeader(JSArena *a, JSArena **ap) const { return *ptrToHeader(a->base) = ap; }
extern JS_PUBLIC_API(void *)
JS_ArenaGrow(JSArenaPool *pool, void *p, size_t size, size_t incr);
void *allocateInternal(size_t nb);
void *reallocInternal(void *p, size_t size, size_t incr);
extern JS_PUBLIC_API(void)
JS_ArenaRelease(JSArenaPool *pool, char *mark);
void releaseInternal(void *mark) {
for (JSArena *a = &first; a; a = a->next) {
JS_ASSERT(a->base <= a->avail && a->avail <= a->limit);
#ifdef JS_ARENAMETER
if (a->markMatch(mark)) {
a->avail = align(mark);
JS_ASSERT(a->avail <= a->limit);
freeArenaList(a);
return;
}
}
}
#include <stdio.h>
void *growInternal(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 > arenasize)
return reallocInternal(p, size, incr);
extern JS_PUBLIC_API(void)
JS_ArenaCountAllocation(JSArenaPool *pool, size_t nb);
void *newp = allocate(size + incr, true);
if (newp)
memcpy(newp, p, size);
return newp;
}
extern JS_PUBLIC_API(void)
JS_ArenaCountInplaceGrowth(JSArenaPool *pool, size_t size, size_t incr);
/*
* Free tail arenas linked after head, which may not be the true list head.
* Reset current to point to head in case it pointed at a tail arena.
*/
void freeArenaList(JSArena *head) {
JSArena **ap = &head->next;
JSArena *a = *ap;
if (!a)
return;
extern JS_PUBLIC_API(void)
JS_ArenaCountGrowth(JSArenaPool *pool, size_t size, size_t incr);
#ifdef DEBUG
do {
JS_ASSERT(a->base <= a->avail);
JS_ASSERT(a->avail <= a->limit);
a->avail = a->base;
a->clearUnused();
} while ((a = a->next) != NULL);
a = *ap;
#endif
extern JS_PUBLIC_API(void)
JS_ArenaCountRelease(JSArenaPool *pool, char *mark);
do {
*ap = a->next;
if (quotap)
*quotap += a->limit - (jsuword) a;
a->clear();
decArenaCount();
js_free(a);
} while ((a = *ap) != NULL);
extern JS_PUBLIC_API(void)
JS_ArenaCountRetract(JSArenaPool *pool, char *mark);
current = head;
}
extern JS_PUBLIC_API(void)
JS_DumpArenaStats(FILE *fp);
/* Counters. */
#ifdef DEBUG
void countAllocation(size_t nb);
void countInplaceGrowth(size_t size, size_t incr) { stats.ninplace++; }
void countGrowth(size_t size, size_t incr);
void countRelease(void *mark) { stats.nreleases++; }
void countRetract(void *mark) { stats.nfastrels++; }
void incArenaCount() { stats.narenas++; }
void decArenaCount() { stats.narenas--; }
void incDeallocCount() { stats.ndeallocs++; }
void incReallocCount() { stats.nreallocs++; }
#else
void countAllocation(size_t nb) {}
void countInplaceGrowth(size_t size, size_t incr) {}
void countGrowth(size_t size, size_t incr) {}
void countRelease(void *mark) {}
void countRetract(void *mark) {}
void incArenaCount() {}
void decArenaCount() {}
void incDeallocCount() {}
void incReallocCount() {}
#endif
};
#else /* !JS_ARENAMETER */
/* Backwards compatibility. */
#define JS_ArenaCountAllocation(ap, nb) /* nothing */
#define JS_ArenaCountInplaceGrowth(ap, size, incr) /* nothing */
#define JS_ArenaCountGrowth(ap, size, incr) /* nothing */
#define JS_ArenaCountRelease(ap, mark) /* nothing */
#define JS_ArenaCountRetract(ap, mark) /* nothing */
JS_BEGIN_EXTERN_C
JS_FRIEND_API(void *)
JS_ARENA_MARK(const JSArenaPool *pool);
JS_FRIEND_API(void)
JS_ARENA_RELEASE(JSArenaPool *pool, void *mark);
JS_FRIEND_API(void *)
JS_ARENA_ALLOCATE_COMMON_SANE(jsuword p, JSArenaPool *pool, size_t nb, bool limitCheck);
#define JS_ARENA_ALLOCATE_CAST(p, type, pool, nb) \
JS_BEGIN_MACRO \
(p) = (type) JS_ARENA_ALLOCATE_COMMON_SANE(jsuword(p), (pool), (nb), true); \
JS_END_MACRO
#endif /* !JS_ARENAMETER */
JS_END_EXTERN_C

79
js/src/jsarenainlines.h Normal file
Просмотреть файл

@ -0,0 +1,79 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
* vim: set ts=8 sw=4 et tw=99 ft=cpp:
*
* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Mozilla SpiderMonkey JavaScript 1.9 code, released
* June 12, 2009.
*
* The Initial Developer of the Original Code is
* the Mozilla Corporation.
*
* Contributor(s):
* Chris Leary <cdleary@mozilla.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either of the GNU General Public License Version 2 or later (the "GPL"),
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#ifndef jsarenainlines_h___
#define jsarenainlines_h___
#include "jsarena.h"
const jsuword JSArenaPool::POINTER_MASK = jsuword(JS_ALIGN_OF_POINTER - 1);
jsuword
JSArenaPool::headerBaseMask() const
{
return mask | POINTER_MASK;
}
jsuword
JSArenaPool::headerSize() const
{
return sizeof(JSArena **) + ((mask < POINTER_MASK) ? POINTER_MASK - mask : 0);
}
void *
JSArenaPool::grow(jsuword p, size_t size, size_t incr)
{
countGrowth(size, incr);
if (current->avail == p + align(size)) {
size_t nb = align(size + incr);
if (current->limit >= nb && p <= current->limit - nb) {
current->avail = p + nb;
countInplaceGrowth(size, incr);
} else if (p == current->base) {
p = jsuword(reallocInternal((void *) p, size, incr));
} else {
p = jsuword(growInternal((void *) p, size, incr));
}
} else {
p = jsuword(growInternal((void *) p, size, incr));
}
return (void *) p;
}
#endif

Просмотреть файл

@ -1004,7 +1004,7 @@ js_alloc_temp_space(void *priv, size_t size)
}
}
JS_ARENA_ALLOCATE(space, &parser->context->tempPool, size);
parser->context->tempPool.allocate(space, size);
if (!space)
js_ReportOutOfScriptQuota(parser->context);
return space;
@ -1036,7 +1036,7 @@ js_alloc_temp_entry(void *priv, const void *key)
return &ale->entry;
}
JS_ARENA_ALLOCATE_TYPE(ale, JSAtomListElement, &parser->context->tempPool);
parser->context->tempPool.allocateType<JSAtomListElement>(ale);
if (!ale) {
js_ReportOutOfScriptQuota(parser->context);
return NULL;

Просмотреть файл

@ -823,8 +823,7 @@ js_NewContext(JSRuntime *rt, size_t stackChunkSize)
JS_ASSERT(cx->version == JSVERSION_DEFAULT);
VOUCH_DOES_NOT_REQUIRE_STACK();
JS_InitArenaPool(&cx->tempPool, "temp", TEMP_POOL_CHUNK_SIZE, sizeof(jsdouble),
&cx->scriptStackQuota);
cx->tempPool.init("temp", TEMP_POOL_CHUNK_SIZE, sizeof(jsdouble), &cx->scriptStackQuota);
js_InitRegExpStatics(cx);
JS_ASSERT(cx->resolveFlags == 0);
@ -1178,7 +1177,7 @@ FreeContext(JSContext *cx)
/* Free the stuff hanging off of cx. */
js_FreeRegExpStatics(cx);
VOUCH_DOES_NOT_REQUIRE_STACK();
JS_FinishArenaPool(&cx->tempPool);
cx->tempPool.finish();
if (cx->lastMessage)
js_free(cx->lastMessage);
@ -2218,11 +2217,11 @@ JSContext::isConstructing()
inline void
FreeOldArenas(JSRuntime *rt, JSArenaPool *pool)
{
JSArena *a = pool->current;
if (a == pool->first.next && a->avail == a->base + sizeof(int64)) {
int64 age = JS_Now() - *(int64 *) a->base;
const JSArena *a = pool->getCurrent();
if (a == pool->getSecond() && a->getAvail() == a->getBase() + sizeof(int64)) {
int64 age = JS_Now() - *(int64 *) a->getBase();
if (age > int64(rt->gcEmptyArenaPoolLifespan) * 1000)
JS_FreeArenaPool(pool);
pool->free();
}
}

Просмотреть файл

@ -93,7 +93,7 @@ JSCodeGenerator::JSCodeGenerator(Parser *parser,
uintN lineno)
: JSTreeContext(parser),
codePool(cpool), notePool(npool),
codeMark(JS_ARENA_MARK(cpool)), noteMark(JS_ARENA_MARK(npool)),
codeMark(cpool->getMark()), noteMark(npool->getMark()),
stackDepth(0), maxStackDepth(0),
ntrynotes(0), lastTryNode(NULL),
spanDeps(NULL), jumpTargets(NULL), jtFreeList(NULL),
@ -118,8 +118,8 @@ bool JSCodeGenerator::init()
JSCodeGenerator::~JSCodeGenerator()
{
JS_ARENA_RELEASE(codePool, codeMark);
JS_ARENA_RELEASE(notePool, noteMark);
codePool->release(codeMark);
notePool->release(noteMark);
/* NB: non-null only after OOM. */
if (spanDeps)
@ -147,11 +147,11 @@ EmitCheck(JSContext *cx, JSCodeGenerator *cg, JSOp op, ptrdiff_t delta)
: JS_BIT(JS_CeilingLog2(length));
incr = BYTECODE_SIZE(length);
if (!base) {
JS_ARENA_ALLOCATE_CAST(base, jsbytecode *, cg->codePool, incr);
cg->codePool->allocateCast<jsbytecode *>(base, incr);
} else {
size = BYTECODE_SIZE(limit - base);
incr -= size;
JS_ARENA_GROW_CAST(base, jsbytecode *, cg->codePool, size, incr);
cg->codePool->growCast<jsbytecode *>(base, size, incr);
}
if (!base) {
js_ReportOutOfScriptQuota(cx);
@ -464,8 +464,7 @@ AddJumpTarget(AddJumpTargetArgs *args, JSJumpTarget **jtp)
if (jt) {
cg->jtFreeList = jt->kids[JT_LEFT];
} else {
JS_ARENA_ALLOCATE_CAST(jt, JSJumpTarget *, &args->cx->tempPool,
sizeof *jt);
args->cx->tempPool.allocateCast<JSJumpTarget *>(jt, sizeof *jt);
if (!jt) {
js_ReportOutOfScriptQuota(args->cx);
return 0;
@ -923,7 +922,7 @@ OptimizeSpanDeps(JSContext *cx, JSCodeGenerator *cg)
JS_ASSERT(length > BYTECODE_CHUNK);
size = BYTECODE_SIZE(limit - base);
incr = BYTECODE_SIZE(length) - size;
JS_ARENA_GROW_CAST(base, jsbytecode *, cg->codePool, size, incr);
cg->codePool->growCast<jsbytecode *>(base, size, incr);
if (!base) {
js_ReportOutOfScriptQuota(cx);
return JS_FALSE;
@ -4370,9 +4369,9 @@ js_EmitTree(JSContext *cx, JSCodeGenerator *cg, JSParseNode *pn)
FUN_KIND(fun) == JSFUN_INTERPRETED);
/* Generate code for the function's body. */
void *cg2mark = JS_ARENA_MARK(cg->codePool);
void *cg2space;
JS_ARENA_ALLOCATE_TYPE(cg2space, JSCodeGenerator, cg->codePool);
void *cg2mark = cg->codePool->getMark();
JSCodeGenerator *cg2space;
cg->codePool->allocateType<JSCodeGenerator>(cg2space);
if (!cg2space) {
js_ReportOutOfScriptQuota(cx);
return JS_FALSE;
@ -4411,7 +4410,7 @@ js_EmitTree(JSContext *cx, JSCodeGenerator *cg, JSParseNode *pn)
pn = NULL;
cg2->~JSCodeGenerator();
JS_ARENA_RELEASE(cg->codePool, cg2mark);
cg->codePool->release(cg2mark);
cg2 = NULL;
if (!pn)
return JS_FALSE;
@ -6962,10 +6961,10 @@ AllocSrcNote(JSContext *cx, JSCodeGenerator *cg)
size = SRCNOTE_SIZE(CG_NOTE_MASK(cg) + 1);
if (!CG_NOTES(cg)) {
/* Allocate the first note array lazily; leave noteMask alone. */
JS_ARENA_ALLOCATE_CAST(CG_NOTES(cg), jssrcnote *, pool, size);
pool->allocateCast<jssrcnote *>(CG_NOTES(cg), size);
} else {
/* Grow by doubling note array size; update noteMask on success. */
JS_ARENA_GROW_CAST(CG_NOTES(cg), jssrcnote *, pool, size, size);
pool->growCast<jssrcnote *>(CG_NOTES(cg), size, size);
if (CG_NOTES(cg))
CG_NOTE_MASK(cg) = (CG_NOTE_MASK(cg) << 1) | 1;
}
@ -7066,7 +7065,7 @@ GrowSrcNotes(JSContext *cx, JSCodeGenerator *cg)
/* Grow by doubling note array size; update noteMask on success. */
pool = cg->notePool;
size = SRCNOTE_SIZE(CG_NOTE_MASK(cg) + 1);
JS_ARENA_GROW_CAST(CG_NOTES(cg), jssrcnote *, pool, size, size);
pool->growCast<jssrcnote *>(CG_NOTES(cg), size, size);
if (!CG_NOTES(cg)) {
js_ReportOutOfScriptQuota(cx);
return JS_FALSE;
@ -7304,7 +7303,7 @@ NewTryNote(JSContext *cx, JSCodeGenerator *cg, JSTryNoteKind kind,
JS_ASSERT((size_t)(uint32)start == start);
JS_ASSERT((size_t)(uint32)end == end);
JS_ARENA_ALLOCATE_TYPE(tryNode, JSTryNode, &cx->tempPool);
cx->tempPool.allocateType<JSTryNode>(tryNode);
if (!tryNode) {
js_ReportOutOfScriptQuota(cx);
return JS_FALSE;

Просмотреть файл

@ -339,7 +339,7 @@ WrapEscapingClosure(JSContext *cx, JSStackFrame *fp, JSObject *funobj, JSFunctio
wfun->atom = fun->atom;
if (fun->hasLocalNames()) {
void *mark = JS_ARENA_MARK(&cx->tempPool);
void *mark = cx->tempPool.getMark();
jsuword *names = js_GetLocalNameArray(cx, fun, &cx->tempPool);
if (!names)
return NULL;
@ -361,7 +361,7 @@ WrapEscapingClosure(JSContext *cx, JSStackFrame *fp, JSObject *funobj, JSFunctio
break;
}
JS_ARENA_RELEASE(&cx->tempPool, mark);
cx->tempPool.release(mark);
if (!ok)
return NULL;
JS_ASSERT(wfun->nargs == fun->nargs);
@ -956,7 +956,7 @@ call_enumerate(JSContext *cx, JSObject *obj)
if (n == 0)
return JS_TRUE;
mark = JS_ARENA_MARK(&cx->tempPool);
mark = cx->tempPool.getMark();
MUST_FLOW_THROUGH("out");
names = js_GetLocalNameArray(cx, fun, &cx->tempPool);
@ -990,7 +990,7 @@ call_enumerate(JSContext *cx, JSObject *obj)
ok = JS_TRUE;
out:
JS_ARENA_RELEASE(&cx->tempPool, mark);
cx->tempPool.release(mark);
return ok;
}
@ -1602,16 +1602,13 @@ js_XDRFunctionObject(JSXDRState *xdr, JSObject **objp)
/* do arguments and local vars */
n = nargs + nvars + nupvars;
if (n != 0) {
void *mark;
JSArenaPool &tempPool = xdr->cx->tempPool;
void *mark = tempPool.getMark();
uintN i;
uintN bitmapLength;
uint32 *bitmap;
jsuword *names;
JSAtom *name;
JSLocalKind localKind;
bool ok = true;
mark = JS_ARENA_MARK(&xdr->cx->tempPool);
/*
* From this point the control must flow via the label release_mark.
@ -1624,16 +1621,16 @@ js_XDRFunctionObject(JSXDRState *xdr, JSObject **objp)
* name is declared as const, not as ordinary var.
* */
MUST_FLOW_THROUGH("release_mark");
bitmapLength = JS_HOWMANY(n, JS_BITS_PER_UINT32);
JS_ARENA_ALLOCATE_CAST(bitmap, uint32 *, &xdr->cx->tempPool,
bitmapLength * sizeof *bitmap);
uintN bitmapLength = JS_HOWMANY(n, JS_BITS_PER_UINT32);
uint32 *bitmap;
tempPool.allocateCast<uint32 *>(bitmap, bitmapLength * sizeof *bitmap);
if (!bitmap) {
js_ReportOutOfScriptQuota(xdr->cx);
ok = false;
goto release_mark;
}
if (xdr->mode == JSXDR_ENCODE) {
names = js_GetLocalNameArray(xdr->cx, fun, &xdr->cx->tempPool);
names = js_GetLocalNameArray(xdr->cx, fun, &tempPool);
if (!names) {
ok = false;
goto release_mark;
@ -1692,7 +1689,7 @@ js_XDRFunctionObject(JSXDRState *xdr, JSObject **objp)
}
release_mark:
JS_ARENA_RELEASE(&xdr->cx->tempPool, mark);
tempPool.release(mark);
if (!ok)
return false;
@ -2263,9 +2260,8 @@ Function(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
* for a terminating 0. Mark cx->tempPool for later release, to free
* collected_args and its tokenstream in one swoop.
*/
mark = JS_ARENA_MARK(&cx->tempPool);
JS_ARENA_ALLOCATE_CAST(cp, jschar *, &cx->tempPool,
(args_length+1) * sizeof(jschar));
mark = cx->tempPool.getMark();
cx->tempPool.allocateCast<jschar *>(cp, (args_length + 1) * sizeof(jschar));
if (!cp) {
js_ReportOutOfScriptQuota(cx);
return JS_FALSE;
@ -2287,7 +2283,7 @@ Function(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
/* Initialize a tokenstream that reads from the given string. */
if (!ts.init(collected_args, args_length, NULL, filename, lineno)) {
JS_ARENA_RELEASE(&cx->tempPool, mark);
cx->tempPool.release(mark);
return JS_FALSE;
}
@ -2347,7 +2343,7 @@ Function(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
JSMSG_BAD_FORMAL);
}
ts.close();
JS_ARENA_RELEASE(&cx->tempPool, mark);
cx->tempPool.release(mark);
if (state != OK)
return JS_FALSE;
}
@ -2956,7 +2952,7 @@ js_GetLocalNameArray(JSContext *cx, JSFunction *fun, JSArenaPool *pool)
* No need to check for overflow of the allocation size as we are making a
* copy of already allocated data. As such it must fit size_t.
*/
JS_ARENA_ALLOCATE_CAST(names, jsuword *, pool, (size_t) n * sizeof *names);
pool->allocateCast<jsuword *>(names, (size_t) n * sizeof *names);
if (!names) {
js_ReportOutOfScriptQuota(cx);
return NULL;

Просмотреть файл

@ -1511,8 +1511,8 @@ CheckLeakedRoots(JSRuntime *rt);
void
js_FinishGC(JSRuntime *rt)
{
#ifdef JS_ARENAMETER
JS_DumpArenaStats(stdout);
#ifdef DEBUG
JS_DumpArenaStats();
#endif
#ifdef JS_GCMETER
if (JS_WANT_GC_METER_PRINT)

Просмотреть файл

@ -558,9 +558,9 @@ SprintEnsureBuffer(Sprinter *sp, size_t len)
return JS_TRUE;
base = sp->base;
if (!base) {
JS_ARENA_ALLOCATE_CAST(base, char *, sp->pool, nb);
sp->pool->allocateCast<char *>(base, nb);
} else {
JS_ARENA_GROW_CAST(base, char *, sp->pool, sp->size, nb);
sp->pool->growCast<char *>(base, sp->size, nb);
}
if (!base) {
js_ReportOutOfScriptQuota(sp->context);
@ -736,11 +736,11 @@ js_QuoteString(JSContext *cx, JSString *str, jschar quote)
char *bytes;
JSString *escstr;
mark = JS_ARENA_MARK(&cx->tempPool);
mark = cx->tempPool.getMark();
INIT_SPRINTER(cx, &sprinter, &cx->tempPool, 0);
bytes = QuoteString(&sprinter, str, quote);
escstr = bytes ? JS_NewStringCopyZ(cx, bytes) : NULL;
JS_ARENA_RELEASE(&cx->tempPool, mark);
cx->tempPool.release(mark);
return escstr;
}
@ -770,7 +770,7 @@ js_NewPrinter(JSContext *cx, const char *name, JSFunction *fun,
if (!jp)
return NULL;
INIT_SPRINTER(cx, &jp->sprinter, &jp->pool, 0);
JS_InitArenaPool(&jp->pool, name, 256, 1, &cx->scriptStackQuota);
jp->pool.init(name, 256, 1, &cx->scriptStackQuota);
jp->indent = indent;
jp->pretty = !!pretty;
jp->grouped = !!grouped;
@ -793,7 +793,7 @@ js_NewPrinter(JSContext *cx, const char *name, JSFunction *fun,
void
js_DestroyPrinter(JSPrinter *jp)
{
JS_FinishArenaPool(&jp->pool);
jp->pool.finish();
jp->sprinter.context->free(jp);
}
@ -809,7 +809,7 @@ js_GetPrinterOutput(JSPrinter *jp)
str = JS_NewStringCopyZ(cx, jp->sprinter.base);
if (!str)
return NULL;
JS_FreeArenaPool(&jp->pool);
jp->pool.free();
INIT_SPRINTER(cx, &jp->sprinter, &jp->pool, 0);
return str;
}
@ -1779,7 +1779,7 @@ InitSprintStack(JSContext *cx, SprintStack *ss, JSPrinter *jp, uintN depth)
/* Allocate the parallel (to avoid padding) offset and opcode stacks. */
offsetsz = depth * sizeof(ptrdiff_t);
opcodesz = depth * sizeof(jsbytecode);
JS_ARENA_ALLOCATE(space, &cx->tempPool, offsetsz + opcodesz);
cx->tempPool.allocate(space, offsetsz + opcodesz);
if (!space) {
js_ReportOutOfScriptQuota(cx);
return JS_FALSE;
@ -4069,7 +4069,7 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb, JSOp nextop)
* Therefore after InitSprintStack succeeds, we must
* release to mark before returning.
*/
mark = JS_ARENA_MARK(&cx->tempPool);
mark = cx->tempPool.getMark();
if (!fun->hasLocalNames()) {
innerLocalNames = NULL;
} else {
@ -4079,7 +4079,7 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb, JSOp nextop)
}
inner = fun->u.i.script;
if (!InitSprintStack(cx, &ss2, jp, StackDepth(inner))) {
JS_ARENA_RELEASE(&cx->tempPool, mark);
cx->tempPool.release(mark);
return NULL;
}
ss2.inGenExp = JS_TRUE;
@ -4103,7 +4103,7 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb, JSOp nextop)
jp->fun = outerfun;
jp->localNames = outerLocalNames;
if (!ok) {
JS_ARENA_RELEASE(&cx->tempPool, mark);
cx->tempPool.release(mark);
return NULL;
}
@ -4169,7 +4169,7 @@ Decompile(SprintStack *ss, jsbytecode *pc, intN nb, JSOp nextop)
* from cx's tempPool.
*/
rval = JS_strdup(cx, PopStr(&ss2, op));
JS_ARENA_RELEASE(&cx->tempPool, mark);
cx->tempPool.release(mark);
if (!rval)
return NULL;
todo = SprintCString(&ss->sprinter, rval);
@ -4846,7 +4846,7 @@ DecompileCode(JSPrinter *jp, JSScript *script, jsbytecode *pc, uintN len,
/* Initialize a sprinter for use with the offset stack. */
cx = jp->sprinter.context;
mark = JS_ARENA_MARK(&cx->tempPool);
mark = cx->tempPool.getMark();
ok = InitSprintStack(cx, &ss, jp, depth);
if (!ok)
goto out;
@ -4900,7 +4900,7 @@ DecompileCode(JSPrinter *jp, JSScript *script, jsbytecode *pc, uintN len,
out:
/* Free all temporary stuff allocated under this call. */
JS_ARENA_RELEASE(&cx->tempPool, mark);
cx->tempPool.release(mark);
return ok;
}
@ -5017,7 +5017,7 @@ js_DecompileFunction(JSPrinter *jp)
#if JS_HAS_DESTRUCTURING
ss.printer = NULL;
jp->script = script;
mark = JS_ARENA_MARK(&jp->sprinter.context->tempPool);
mark = jp->sprinter.context->tempPool.getMark();
#endif
for (i = 0; i < fun->nargs; i++) {
@ -5068,7 +5068,7 @@ js_DecompileFunction(JSPrinter *jp)
#if JS_HAS_DESTRUCTURING
jp->script = NULL;
JS_ARENA_RELEASE(&jp->sprinter.context->tempPool, mark);
jp->sprinter.context->tempPool.release(mark);
#endif
if (!ok)
return JS_FALSE;

Просмотреть файл

@ -2574,7 +2574,7 @@ BEGIN_CASE(JSOP_CALLUPVAR_DBG)
/* Scope for tempPool mark and local names allocation in it. */
{
void *mark = JS_ARENA_MARK(&cx->tempPool);
void *mark = cx->tempPool.getMark();
jsuword *names = js_GetLocalNameArray(cx, fun, &cx->tempPool);
if (!names)
goto error;
@ -2584,7 +2584,7 @@ BEGIN_CASE(JSOP_CALLUPVAR_DBG)
id = ATOM_TO_JSID(atom);
ok = js_FindProperty(cx, id, &obj, &obj2, &prop);
JS_ARENA_RELEASE(&cx->tempPool, mark);
cx->tempPool.release(mark);
if (!ok)
goto error;
}

Просмотреть файл

@ -165,9 +165,9 @@ Parser::init(const jschar *base, size_t length,
{
JSContext *cx = context;
tempPoolMark = JS_ARENA_MARK(&cx->tempPool);
tempPoolMark = cx->tempPool.getMark();
if (!tokenStream.init(base, length, fp, filename, lineno)) {
JS_ARENA_RELEASE(&cx->tempPool, tempPoolMark);
cx->tempPool.release(tempPoolMark);
return false;
}
return true;
@ -180,7 +180,7 @@ Parser::~Parser()
if (principals)
JSPRINCIPALS_DROP(cx, principals);
tokenStream.close();
JS_ARENA_RELEASE(&cx->tempPool, tempPoolMark);
cx->tempPool.release(tempPoolMark);
}
void
@ -204,7 +204,7 @@ Parser::newObjectBox(JSObject *obj)
* parsing and code generation for the whole script or top-level function.
*/
JSObjectBox *objbox;
JS_ARENA_ALLOCATE_TYPE(objbox, JSObjectBox, &context->tempPool);
context->tempPool.allocateType<JSObjectBox>(objbox);
if (!objbox) {
js_ReportOutOfScriptQuota(context);
return NULL;
@ -229,7 +229,7 @@ Parser::newFunctionBox(JSObject *obj, JSParseNode *fn, JSTreeContext *tc)
* parsing and code generation for the whole script or top-level function.
*/
JSFunctionBox *funbox;
JS_ARENA_ALLOCATE_TYPE(funbox, JSFunctionBox, &context->tempPool);
context->tempPool.allocateType<JSFunctionBox>(funbox);
if (!funbox) {
js_ReportOutOfScriptQuota(context);
return NULL;
@ -453,7 +453,7 @@ NewOrRecycledNode(JSTreeContext *tc)
if (!pn) {
JSContext *cx = tc->parser->context;
JS_ARENA_ALLOCATE_TYPE(pn, JSParseNode, &cx->tempPool);
cx->tempPool.allocateType<JSParseNode>(pn);
if (!pn)
js_ReportOutOfScriptQuota(cx);
} else {
@ -739,10 +739,8 @@ Compiler::compileScript(JSContext *cx, JSObject *scopeChain, JSStackFrame *calle
if (!compiler.init(chars, length, file, filename, lineno))
return NULL;
JS_InitArenaPool(&codePool, "code", 1024, sizeof(jsbytecode),
&cx->scriptStackQuota);
JS_InitArenaPool(&notePool, "note", 1024, sizeof(jssrcnote),
&cx->scriptStackQuota);
codePool.init("code", 1024, sizeof(jsbytecode), &cx->scriptStackQuota);
notePool.init("note", 1024, sizeof(jssrcnote), &cx->scriptStackQuota);
Parser &parser = compiler.parser;
TokenStream &tokenStream = parser.tokenStream;
@ -936,8 +934,8 @@ Compiler::compileScript(JSContext *cx, JSObject *scopeChain, JSStackFrame *calle
printf("Code-gen growth: %d (%u bytecodes, %u srcnotes)\n",
(char *)sbrk(0) - (char *)before, CG_OFFSET(&cg), cg.noteCount);
#endif
#ifdef JS_ARENAMETER
JS_DumpArenaStats(stdout);
#ifdef DEBUG
JS_DumpArenaStats();
#endif
script = js_NewScriptFromCG(cx, &cg);
if (script && funbox && script != script->emptyScript())
@ -954,8 +952,8 @@ Compiler::compileScript(JSContext *cx, JSObject *scopeChain, JSStackFrame *calle
#endif
out:
JS_FinishArenaPool(&codePool);
JS_FinishArenaPool(&notePool);
codePool.finish();
notePool.finish();
return script;
too_many_slots:
@ -1513,10 +1511,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),
&cx->scriptStackQuota);
JS_InitArenaPool(&notePool, "note", 1024, sizeof(jssrcnote),
&cx->scriptStackQuota);
codePool.init("code", 1024, sizeof(jsbytecode), &cx->scriptStackQuota);
notePool.init("note", 1024, sizeof(jssrcnote), &cx->scriptStackQuota);
Parser &parser = compiler.parser;
TokenStream &tokenStream = parser.tokenStream;
@ -1588,8 +1584,8 @@ Compiler::compileFunctionBody(JSContext *cx, JSFunction *fun, JSPrincipals *prin
}
/* Restore saved state and release code generation arenas. */
JS_FinishArenaPool(&codePool);
JS_FinishArenaPool(&notePool);
codePool.finish();
notePool.finish();
return pn != NULL;
}

Просмотреть файл

@ -132,8 +132,7 @@ PropertyTree::init()
hash.ops = NULL;
return false;
}
JS_InitArenaPool(&arenaPool, "properties",
256 * sizeof(JSScopeProperty), sizeof(void *), NULL);
arenaPool.init("properties", 256 * sizeof(JSScopeProperty), sizeof(void *), NULL);
emptyShapeChanges = 0;
return true;
}
@ -145,7 +144,7 @@ PropertyTree::finish()
JS_DHashTableFinish(&hash);
hash.ops = NULL;
}
JS_FinishArenaPool(&arenaPool);
arenaPool.finish();
}
/*
@ -163,8 +162,7 @@ PropertyTree::newScopeProperty(JSContext *cx, bool gcLocked)
if (sprop) {
sprop->removeFree();
} else {
JS_ARENA_ALLOCATE_CAST(sprop, JSScopeProperty *, &arenaPool,
sizeof(JSScopeProperty));
arenaPool.allocateCast<JSScopeProperty *>(sprop, sizeof *sprop);
if (!sprop) {
JS_UNLOCK_GC(cx->runtime);
JS_ReportOutOfMemory(cx);
@ -852,12 +850,13 @@ js::SweepScopeProperties(JSContext *cx)
* nodes already GC'ed from the root ply, but we will avoid re-orphaning
* their kids, because the kids member will already be null.
*/
JSArena **ap = &JS_PROPERTY_TREE(cx).arenaPool.first.next;
while (JSArena *a = *ap) {
JSScopeProperty *limit = (JSScopeProperty *) a->avail;
JSArenaPool &arenaPool = JS_PROPERTY_TREE(cx).arenaPool;
JSArena * const first = arenaPool.getFirst();
for (JSArena *a = arenaPool.getSecond(); a;) {
JSScopeProperty *limit = (JSScopeProperty *) a->getAvail();
uintN liveCount = 0;
for (JSScopeProperty *sprop = (JSScopeProperty *) a->base; sprop < limit; sprop++) {
for (JSScopeProperty *sprop = (JSScopeProperty *) a->getBase(); sprop < limit; sprop++) {
/* If the id is null, sprop is already on the freelist. */
if (JSVAL_IS_NULL(sprop->id))
continue;
@ -912,15 +911,17 @@ js::SweepScopeProperties(JSContext *cx)
/* If a contains no live properties, return it to the malloc heap. */
if (liveCount == 0) {
for (JSScopeProperty *sprop = (JSScopeProperty *) a->base; sprop < limit; sprop++)
for (JSScopeProperty *sprop = (JSScopeProperty *) a->getBase(); sprop < limit; sprop++)
sprop->removeFree();
JS_ARENA_DESTROY(&JS_PROPERTY_TREE(cx).arenaPool, a, ap);
a = arenaPool.destroy(a);
first->munge(a);
} else {
#ifdef DEBUG
livePropCapacity += limit - (JSScopeProperty *) a->base;
livePropCapacity += limit - (JSScopeProperty *) a->getBase();
totalLiveCount += liveCount;
#endif
ap = &a->next;
first->munge(a->getNext());
a = a->getNext();
}
}

Просмотреть файл

@ -430,7 +430,7 @@ NewRENode(CompilerState *state, REOp op)
RENode *ren;
cx = state->context;
JS_ARENA_ALLOCATE_CAST(ren, RENode *, &cx->tempPool, sizeof *ren);
cx->tempPool.allocateCast<RENode *>(ren, sizeof *ren);
if (!ren) {
js_ReportOutOfScriptQuota(cx);
return NULL;
@ -3330,13 +3330,13 @@ CompileRegExpToNative(JSContext* cx, JSRegExp* re, Fragment* fragment)
RegExpNativeCompiler rc(cx, re, &state, fragment);
JS_ASSERT(!fragment->code());
mark = JS_ARENA_MARK(&cx->tempPool);
mark = cx->tempPool.getMark();
if (!CompileRegExpToAST(cx, NULL, re->source, re->flags, state)) {
goto out;
}
rv = rc.compile();
out:
JS_ARENA_RELEASE(&cx->tempPool, mark);
cx->tempPool.release(mark);
return rv;
}
@ -3378,7 +3378,7 @@ js_NewRegExp(JSContext *cx, TokenStream *ts,
uintN i;
re = NULL;
mark = JS_ARENA_MARK(&cx->tempPool);
mark = cx->tempPool.getMark();
/*
* Parsing the string as flat is now expressed internally using
@ -3438,7 +3438,7 @@ js_NewRegExp(JSContext *cx, TokenStream *ts,
re->source = str;
out:
JS_ARENA_RELEASE(&cx->tempPool, mark);
cx->tempPool.release(mark);
return re;
}
@ -3518,8 +3518,7 @@ PushBackTrackState(REGlobalData *gData, REOp op,
ptrdiff_t offset = (char *)result - (char *)gData->backTrackStack;
btincr = JS_ROUNDUP(btincr, btsize);
JS_ARENA_GROW_CAST(gData->backTrackStack, REBackTrackData *,
&gData->cx->regexpPool, btsize, btincr);
gData->cx->regexpPool.growCast<REBackTrackData *>(gData->backTrackStack, btsize, btincr);
if (!gData->backTrackStack) {
js_ReportOutOfScriptQuota(gData->cx);
gData->ok = JS_FALSE;
@ -3977,8 +3976,7 @@ ReallocStateStack(REGlobalData *gData)
size_t limit = gData->stateStackLimit;
size_t sz = sizeof(REProgState) * limit;
JS_ARENA_GROW_CAST(gData->stateStack, REProgState *,
&gData->cx->regexpPool, sz, sz);
gData->cx->regexpPool.growCast<REProgState *>(gData->stateStack, sz, sz);
if (!gData->stateStack) {
js_ReportOutOfScriptQuota(gData->cx);
gData->ok = JS_FALSE;
@ -4838,9 +4836,8 @@ InitMatch(JSContext *cx, REGlobalData *gData, JSRegExp *re, size_t length)
uintN i;
gData->backTrackStackSize = INITIAL_BACKTRACK;
JS_ARENA_ALLOCATE_CAST(gData->backTrackStack, REBackTrackData *,
&cx->regexpPool,
INITIAL_BACKTRACK);
JSArenaPool &regexpPool = cx->regexpPool;
regexpPool.allocateCast<REBackTrackData *>(gData->backTrackStack, INITIAL_BACKTRACK);
if (!gData->backTrackStack)
goto bad;
@ -4855,8 +4852,7 @@ InitMatch(JSContext *cx, REGlobalData *gData, JSRegExp *re, size_t length)
}
gData->stateStackLimit = INITIAL_STATESTACK;
JS_ARENA_ALLOCATE_CAST(gData->stateStack, REProgState *,
&cx->regexpPool,
regexpPool.allocateCast<REProgState *>(gData->stateStack,
sizeof(REProgState) * INITIAL_STATESTACK);
if (!gData->stateStack)
goto bad;
@ -4866,9 +4862,7 @@ InitMatch(JSContext *cx, REGlobalData *gData, JSRegExp *re, size_t length)
gData->regexp = re;
gData->ok = JS_TRUE;
JS_ARENA_ALLOCATE_CAST(result, REMatchState *,
&cx->regexpPool,
offsetof(REMatchState, parens)
regexpPool.allocateCast<REMatchState *>(result, offsetof(REMatchState, parens)
+ re->parenCount * sizeof(RECapture));
if (!result)
goto bad;
@ -4922,17 +4916,16 @@ js_ExecuteRegExp(JSContext *cx, JSRegExp *re, JSString *str, size_t *indexp,
gData.start = start;
gData.skipped = 0;
if (!cx->regexpPool.first.next) {
if (!cx->regexpPool.getSecond()) {
/*
* The first arena in the regexpPool must have a timestamp at its base.
*/
JS_ARENA_ALLOCATE_CAST(timestamp, int64 *,
&cx->regexpPool, sizeof *timestamp);
cx->regexpPool.allocateCast<int64 *>(timestamp, sizeof *timestamp);
if (!timestamp)
return JS_FALSE;
*timestamp = JS_Now();
}
mark = JS_ARENA_MARK(&cx->regexpPool);
mark = cx->regexpPool.getMark();
x = InitMatch(cx, &gData, re, length);
@ -5076,7 +5069,7 @@ js_ExecuteRegExp(JSContext *cx, JSRegExp *re, JSString *str, size_t *indexp,
res->rightContext.length = gData.cpend - ep;
out:
JS_ARENA_RELEASE(&cx->regexpPool, mark);
cx->regexpPool.release(mark);
return ok;
}
@ -5216,8 +5209,7 @@ js_InitRegExpStatics(JSContext *cx)
* + (sizeof(REProgState) * INITIAL_STATESTACK)
* + (offsetof(REMatchState, parens) + avgParanSize * sizeof(RECapture))
*/
JS_InitArenaPool(&cx->regexpPool, "regexp",
12 * 1024 - 40, /* FIXME: bug 421435 */
cx->regexpPool.init("regexp", 12 * 1024 - 40, /* FIXME: bug 421435 */
sizeof(void *), &cx->scriptStackQuota);
JS_ClearRegExpStatics(cx);
@ -5254,7 +5246,7 @@ void
js_FreeRegExpStatics(JSContext *cx)
{
JS_ClearRegExpStatics(cx);
JS_FinishArenaPool(&cx->regexpPool);
cx->regexpPool.finish();
}
#define DEFINE_STATIC_GETTER(name, code) \

Просмотреть файл

@ -194,7 +194,7 @@ TokenStream::init(const jschar *base, size_t length, FILE *fp, const char *fn, u
size_t nb = fp
? 2 * LINE_LIMIT * sizeof(jschar)
: LINE_LIMIT * sizeof(jschar);
JS_ARENA_ALLOCATE_CAST(buf, jschar *, &cx->tempPool, nb);
cx->tempPool.allocateCast<jschar *>(buf, nb);
if (!buf) {
js_ReportOutOfScriptQuota(cx);
return false;

Просмотреть файл

@ -3384,7 +3384,7 @@ TraceRecorder::import(LIns* base, ptrdiff_t offset, jsval* p, TraceType t,
jsuword* localNames = NULL;
const char* funName = NULL;
if (*prefix == 'a' || *prefix == 'v') {
mark = JS_ARENA_MARK(&cx->tempPool);
mark = cx->tempPool.getMark();
if (fp->fun->hasLocalNames())
localNames = js_GetLocalNameArray(cx, fp->fun, &cx->tempPool);
funName = fp->fun->atom ? js_AtomToPrintableString(cx, fp->fun->atom) : "<anonymous>";
@ -3404,7 +3404,7 @@ TraceRecorder::import(LIns* base, ptrdiff_t offset, jsval* p, TraceType t,
}
if (mark)
JS_ARENA_RELEASE(&cx->tempPool, mark);
cx->tempPool.release(mark);
addName(ins, name);
static const char* typestr[] = {

Просмотреть файл

@ -1762,7 +1762,7 @@ DisassembleValue(JSContext *cx, jsval v, bool lines, bool recursive)
if (fun->u.i.nupvars) {
fputs("\nupvars: {\n", stdout);
void *mark = JS_ARENA_MARK(&cx->tempPool);
void *mark = cx->tempPool.getMark();
jsuword *localNames = js_GetLocalNameArray(cx, fun, &cx->tempPool);
if (!localNames)
return false;
@ -1778,7 +1778,7 @@ DisassembleValue(JSContext *cx, jsval v, bool lines, bool recursive)
js_AtomToPrintableString(cx, atom), cookie.level(), cookie.slot());
}
JS_ARENA_RELEASE(&cx->tempPool, mark);
cx->tempPool.release(mark);
putchar('}');
}
}