diff --git a/mozilla/js/ref/jsgc.c b/mozilla/js/ref/jsgc.c index 25d4f6dc1b1..d695a42c69a 100644 --- a/mozilla/js/ref/jsgc.c +++ b/mozilla/js/ref/jsgc.c @@ -80,7 +80,7 @@ js_InitGC(JSRuntime *rt, uint32 maxbytes) gc_finalizers[GCX_STRING] = (GCFinalizeOp)js_FinalizeString; gc_finalizers[GCX_DOUBLE] = (GCFinalizeOp)js_FinalizeDouble; } - + PR_ArenaInit(); PR_InitArenaPool(&rt->gcArenaPool, "gc-arena", GC_ARENA_SIZE, sizeof(JSGCThing)); PR_InitArenaPool(&rt->gcFlagsPool, "gc-flags", GC_FLAGS_SIZE, diff --git a/mozilla/js/ref/prarena.c b/mozilla/js/ref/prarena.c index a2f8e88b8d9..2b6583a2c60 100644 --- a/mozilla/js/ref/prarena.c +++ b/mozilla/js/ref/prarena.c @@ -29,11 +29,13 @@ #include "prassert.h" #ifdef JS_THREADSAFE -extern js_CompareAndSwap(prword *, prword, prword); +#include "prlock.h" #endif -static PRArena *arena_freelist; - +static PRArena *arena_freelist=0; +#ifdef JS_THREADSAFE +static PRLock *arena_lock=0; +#endif #ifdef PR_ARENAMETER static PRArenaStats *arena_stats_list; @@ -67,9 +69,6 @@ PR_PUBLIC_API(void *) PR_ArenaAllocate(PRArenaPool *pool, PRUint32 nb) { PRArena **ap, *a, *b; -#ifdef JS_THREADSAFE - PRArena *c; -#endif PRUint32 sz; void *p; @@ -84,23 +83,25 @@ PR_ArenaAllocate(PRArenaPool *pool, PRUint32 nb) a = a->next; continue; } +#ifdef JS_THREADSAFE + PR_Lock(arena_lock); +#endif while ((b = *ap) != NULL) { /* reclaim a free arena */ 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; -#endif b->next = NULL; a = a->next = b; COUNT(pool, nreclaims); +#ifdef JS_THREADSAFE + PR_Unlock(arena_lock); +#endif goto claim; } ap = &b->next; } +#ifdef JS_THREADSAFE + PR_Unlock(arena_lock); +#endif sz = PR_MAX(pool->arenasize, nb); /* allocate a new arena */ sz += sizeof *a + pool->mask; /* header and alignment slop */ b = malloc(sz); @@ -137,9 +138,6 @@ static void FreeArenaList(PRArenaPool *pool, PRArena *head, PRBool reallyFree) { PRArena **ap, *a; -#ifdef JS_THREADSAFE - PRArena *b; -#endif ap = &head->next; a = *ap; @@ -164,16 +162,16 @@ FreeArenaList(PRArenaPool *pool, PRArena *head, PRBool reallyFree) } while ((a = *ap) != NULL); } else { /* Insert the whole arena chain at the front of the freelist. */ +#ifdef JS_THREADSAFE + PR_Lock(arena_lock); +#endif do { ap = &(*ap)->next; } while (*ap); -#ifdef JS_THREADSAFE - do { - *ap = b = arena_freelist; - } while (!js_CompareAndSwap((prword*)&arena_freelist,(prword)b,(prword)a)); -#else *ap = arena_freelist; arena_freelist = a; +#ifdef JS_THREADSAFE + PR_Unlock(arena_lock); #endif head->next = NULL; } @@ -237,24 +235,30 @@ PR_CompactArenaPool(PRArenaPool *pool) #endif } +PR_PUBLIC_API(void) +PR_ArenaInit() +{ +#ifdef JS_THREADSAFE + arena_lock = PR_NewLock(); +#endif +} + PR_PUBLIC_API(void) PR_ArenaFinish() { PRArena *a, *next; #ifdef JS_THREADSAFE - while (arena_freelist) { - a = arena_freelist; - next = a->next; - if (js_CompareAndSwap((prword*)&arena_freelist,(prword)a,(prword)next)) - free(a); - } -#else + PR_Lock(arena_lock); +#endif for (a = arena_freelist; a; a = next) { next = a->next; free(a); } arena_freelist = NULL; +#ifdef JS_THREADSAFE + PR_Unlock(arena_lock); + PR_DestroyLock(arena_lock); #endif } diff --git a/mozilla/js/ref/prarena.h b/mozilla/js/ref/prarena.h index 821e2d98000..03466fa2fa5 100644 --- a/mozilla/js/ref/prarena.h +++ b/mozilla/js/ref/prarena.h @@ -187,6 +187,12 @@ PR_FinishArenaPool(PRArenaPool *pool); extern PR_PUBLIC_API(void) 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. */