зеркало из https://github.com/mozilla/gecko-dev.git
Now using a lock in prarena instead of compare-and-swap.
This commit is contained in:
Родитель
728050bc38
Коммит
d376dd5861
|
@ -80,7 +80,7 @@ js_InitGC(JSRuntime *rt, uint32 maxbytes)
|
||||||
gc_finalizers[GCX_STRING] = (GCFinalizeOp)js_FinalizeString;
|
gc_finalizers[GCX_STRING] = (GCFinalizeOp)js_FinalizeString;
|
||||||
gc_finalizers[GCX_DOUBLE] = (GCFinalizeOp)js_FinalizeDouble;
|
gc_finalizers[GCX_DOUBLE] = (GCFinalizeOp)js_FinalizeDouble;
|
||||||
}
|
}
|
||||||
|
PR_ArenaInit();
|
||||||
PR_InitArenaPool(&rt->gcArenaPool, "gc-arena", GC_ARENA_SIZE,
|
PR_InitArenaPool(&rt->gcArenaPool, "gc-arena", GC_ARENA_SIZE,
|
||||||
sizeof(JSGCThing));
|
sizeof(JSGCThing));
|
||||||
PR_InitArenaPool(&rt->gcFlagsPool, "gc-flags", GC_FLAGS_SIZE,
|
PR_InitArenaPool(&rt->gcFlagsPool, "gc-flags", GC_FLAGS_SIZE,
|
||||||
|
|
|
@ -29,11 +29,13 @@
|
||||||
#include "prassert.h"
|
#include "prassert.h"
|
||||||
|
|
||||||
#ifdef JS_THREADSAFE
|
#ifdef JS_THREADSAFE
|
||||||
extern js_CompareAndSwap(prword *, prword, prword);
|
#include "prlock.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static PRArena *arena_freelist;
|
static PRArena *arena_freelist=0;
|
||||||
|
#ifdef JS_THREADSAFE
|
||||||
|
static PRLock *arena_lock=0;
|
||||||
|
#endif
|
||||||
#ifdef PR_ARENAMETER
|
#ifdef PR_ARENAMETER
|
||||||
static PRArenaStats *arena_stats_list;
|
static PRArenaStats *arena_stats_list;
|
||||||
|
|
||||||
|
@ -67,9 +69,6 @@ PR_PUBLIC_API(void *)
|
||||||
PR_ArenaAllocate(PRArenaPool *pool, PRUint32 nb)
|
PR_ArenaAllocate(PRArenaPool *pool, PRUint32 nb)
|
||||||
{
|
{
|
||||||
PRArena **ap, *a, *b;
|
PRArena **ap, *a, *b;
|
||||||
#ifdef JS_THREADSAFE
|
|
||||||
PRArena *c;
|
|
||||||
#endif
|
|
||||||
PRUint32 sz;
|
PRUint32 sz;
|
||||||
void *p;
|
void *p;
|
||||||
|
|
||||||
|
@ -84,23 +83,25 @@ PR_ArenaAllocate(PRArenaPool *pool, PRUint32 nb)
|
||||||
a = a->next;
|
a = a->next;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
#ifdef JS_THREADSAFE
|
||||||
|
PR_Lock(arena_lock);
|
||||||
|
#endif
|
||||||
while ((b = *ap) != NULL) { /* reclaim a free arena */
|
while ((b = *ap) != NULL) { /* reclaim a free arena */
|
||||||
if (b->limit - b->base == pool->arenasize) {
|
if (b->limit - b->base == pool->arenasize) {
|
||||||
#ifdef JS_THREADSAFE
|
|
||||||
do {
|
|
||||||
b = *ap;
|
|
||||||
c = b->next;
|
|
||||||
} while (!js_CompareAndSwap((prword *)ap,(prword)b,(prword)c));
|
|
||||||
#else
|
|
||||||
*ap = b->next;
|
*ap = b->next;
|
||||||
#endif
|
|
||||||
b->next = NULL;
|
b->next = NULL;
|
||||||
a = a->next = b;
|
a = a->next = b;
|
||||||
COUNT(pool, nreclaims);
|
COUNT(pool, nreclaims);
|
||||||
|
#ifdef JS_THREADSAFE
|
||||||
|
PR_Unlock(arena_lock);
|
||||||
|
#endif
|
||||||
goto claim;
|
goto claim;
|
||||||
}
|
}
|
||||||
ap = &b->next;
|
ap = &b->next;
|
||||||
}
|
}
|
||||||
|
#ifdef JS_THREADSAFE
|
||||||
|
PR_Unlock(arena_lock);
|
||||||
|
#endif
|
||||||
sz = PR_MAX(pool->arenasize, nb); /* allocate a new arena */
|
sz = PR_MAX(pool->arenasize, nb); /* allocate a new arena */
|
||||||
sz += sizeof *a + pool->mask; /* header and alignment slop */
|
sz += sizeof *a + pool->mask; /* header and alignment slop */
|
||||||
b = malloc(sz);
|
b = malloc(sz);
|
||||||
|
@ -137,9 +138,6 @@ static void
|
||||||
FreeArenaList(PRArenaPool *pool, PRArena *head, PRBool reallyFree)
|
FreeArenaList(PRArenaPool *pool, PRArena *head, PRBool reallyFree)
|
||||||
{
|
{
|
||||||
PRArena **ap, *a;
|
PRArena **ap, *a;
|
||||||
#ifdef JS_THREADSAFE
|
|
||||||
PRArena *b;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
ap = &head->next;
|
ap = &head->next;
|
||||||
a = *ap;
|
a = *ap;
|
||||||
|
@ -164,16 +162,16 @@ FreeArenaList(PRArenaPool *pool, PRArena *head, PRBool reallyFree)
|
||||||
} while ((a = *ap) != NULL);
|
} while ((a = *ap) != NULL);
|
||||||
} else {
|
} else {
|
||||||
/* Insert the whole arena chain at the front of the freelist. */
|
/* Insert the whole arena chain at the front of the freelist. */
|
||||||
|
#ifdef JS_THREADSAFE
|
||||||
|
PR_Lock(arena_lock);
|
||||||
|
#endif
|
||||||
do {
|
do {
|
||||||
ap = &(*ap)->next;
|
ap = &(*ap)->next;
|
||||||
} while (*ap);
|
} while (*ap);
|
||||||
#ifdef JS_THREADSAFE
|
|
||||||
do {
|
|
||||||
*ap = b = arena_freelist;
|
|
||||||
} while (!js_CompareAndSwap((prword*)&arena_freelist,(prword)b,(prword)a));
|
|
||||||
#else
|
|
||||||
*ap = arena_freelist;
|
*ap = arena_freelist;
|
||||||
arena_freelist = a;
|
arena_freelist = a;
|
||||||
|
#ifdef JS_THREADSAFE
|
||||||
|
PR_Unlock(arena_lock);
|
||||||
#endif
|
#endif
|
||||||
head->next = NULL;
|
head->next = NULL;
|
||||||
}
|
}
|
||||||
|
@ -237,24 +235,30 @@ PR_CompactArenaPool(PRArenaPool *pool)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PR_PUBLIC_API(void)
|
||||||
|
PR_ArenaInit()
|
||||||
|
{
|
||||||
|
#ifdef JS_THREADSAFE
|
||||||
|
arena_lock = PR_NewLock();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
PR_PUBLIC_API(void)
|
PR_PUBLIC_API(void)
|
||||||
PR_ArenaFinish()
|
PR_ArenaFinish()
|
||||||
{
|
{
|
||||||
PRArena *a, *next;
|
PRArena *a, *next;
|
||||||
|
|
||||||
#ifdef JS_THREADSAFE
|
#ifdef JS_THREADSAFE
|
||||||
while (arena_freelist) {
|
PR_Lock(arena_lock);
|
||||||
a = arena_freelist;
|
#endif
|
||||||
next = a->next;
|
|
||||||
if (js_CompareAndSwap((prword*)&arena_freelist,(prword)a,(prword)next))
|
|
||||||
free(a);
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
for (a = arena_freelist; a; a = next) {
|
for (a = arena_freelist; a; a = next) {
|
||||||
next = a->next;
|
next = a->next;
|
||||||
free(a);
|
free(a);
|
||||||
}
|
}
|
||||||
arena_freelist = NULL;
|
arena_freelist = NULL;
|
||||||
|
#ifdef JS_THREADSAFE
|
||||||
|
PR_Unlock(arena_lock);
|
||||||
|
PR_DestroyLock(arena_lock);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -187,6 +187,12 @@ PR_FinishArenaPool(PRArenaPool *pool);
|
||||||
extern PR_PUBLIC_API(void)
|
extern PR_PUBLIC_API(void)
|
||||||
PR_CompactArenaPool(PRArenaPool *pool);
|
PR_CompactArenaPool(PRArenaPool *pool);
|
||||||
|
|
||||||
|
/*
|
||||||
|
do arena global initialization
|
||||||
|
*/
|
||||||
|
extern PR_PUBLIC_API(void)
|
||||||
|
PR_ArenaInit(void);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Finish using arenas, freeing all memory associated with them.
|
* Finish using arenas, freeing all memory associated with them.
|
||||||
*/
|
*/
|
||||||
|
|
Загрузка…
Ссылка в новой задаче