Index: nspr/lib/ds/plarena.c |
=================================================================== |
--- nspr/lib/ds/plarena.c (revision 233722) |
+++ nspr/lib/ds/plarena.c (working copy) |
@@ -153,7 +153,7 @@ |
{ |
a = pool->current; |
do { |
- if ( a->avail +nb <= a->limit ) { |
+ if ( nb <= a->limit - a->avail ) { |
pool->current = a; |
rp = (char *)a->avail; |
a->avail += nb; |
@@ -171,7 +171,7 @@ |
return(0); |
for ( a = arena_freelist, p = NULL; a != NULL ; p = a, a = a->next ) { |
- if ( a->base +nb <= a->limit ) { |
+ if ( nb <= a->limit - a->base ) { |
if ( p == NULL ) |
arena_freelist = a->next; |
else |
@@ -196,11 +196,16 @@ |
/* attempt to allocate from the heap */ |
{ |
PRUint32 sz = PR_MAX(pool->arenasize, nb); |
- sz += sizeof *a + pool->mask; /* header and alignment slop */ |
- a = (PLArena*)PR_MALLOC(sz); |
+ if (PR_UINT32_MAX - sz < sizeof *a + pool->mask) { |
+ a = NULL; |
+ } else { |
+ sz += sizeof *a + pool->mask; /* header and alignment slop */ |
+ a = (PLArena*)PR_MALLOC(sz); |
+ } |
if ( NULL != a ) { |
a->limit = (PRUword)a + sz; |
a->base = a->avail = (PRUword)PL_ARENA_ALIGN(pool, a + 1); |
+ PL_MAKE_MEM_NOACCESS((void*)a->avail, a->limit - a->avail); |
rp = (char *)a->avail; |
a->avail += nb; |
/* the newly allocated arena is linked after pool->current |
@@ -237,7 +242,8 @@ |
for (; a; a = a->next) { |
PR_ASSERT(a->base <= a->avail && a->avail <= a->limit); |
a->avail = a->base; |
- PL_CLEAR_UNUSED_PATTERN(a, pattern); |
+ PL_CLEAR_UNUSED_PATTERN(a, pattern); |
+ PL_MAKE_MEM_NOACCESS((void*)a->avail, a->limit - a->avail); |
} |
} |
@@ -273,6 +279,8 @@ |
} else { |
/* Insert the whole arena chain at the front of the freelist. */ |
do { |
+ PL_MAKE_MEM_NOACCESS((void*)(*ap)->base, |
+ (*ap)->limit - (*ap)->base); |
ap = &(*ap)->next; |
} while (*ap); |
LockArena(); |
@@ -345,6 +353,22 @@ |
once = pristineCallOnce; |
} |
+PR_IMPLEMENT(size_t) PL_SizeOfArenaPoolExcludingPool( |
+ const PLArenaPool *pool, PLMallocSizeFn mallocSizeOf) |
+{ |
+ /* |
+ * The first PLArena is within |pool|, so don't measure it. Subsequent |
+ * PLArenas are separate and must be measured. |
+ */ |
+ size_t size = 0; |
+ const PLArena *arena = pool->first.next; |
+ while (arena) { |
+ size += mallocSizeOf(arena); |
+ arena = arena->next; |
+ } |
+ return size; |
+} |
+ |
#ifdef PL_ARENAMETER |
PR_IMPLEMENT(void) PL_ArenaCountAllocation(PLArenaPool *pool, PRUint32 nb) |
{ |