static void FreeArenaList(PLArenaPool *pool, PLArena *head, PRBool reallyFree)
{
    PLArena **ap, *a;

    ap = &head->next;
    a = *ap;
    if (!a)
        return;


    do {
        ((a->base <= a->avail && a->avail <= a->limit)?((void)0):PR_Assert("a->base <= a->avail && a->avail <= a->limit","../../../mozilla/nsprpub/lib/ds/plarena.c",274));
        a->avail = a->base;
        ((((a)->avail <= (a)->limit)?((void)0):PR_Assert("(a)->avail <= (a)->limit","../../../mozilla/nsprpub/lib/ds/plarena.c",276)), memset((void*)(a)->avail, 0xDA, (a)->limit - (a)->avail));
    } while ((a = a->next) != 0);
    a = *ap;


    if (reallyFree) {
        do {
            *ap = a->next;
            memset((void*)(a), 0xDA, (a)->limit - (PRUword)(a));
            ;
            { PR_Free(a); (a) = ((void *)0); };
        } while ((a = *ap) != 0);
    } else {

        do {
            ap = &(*ap)->next;
        } while (*ap);
        LockArena();
        *ap = arena_freelist;
        arena_freelist = a;
        head->next = 0;
        UnlockArena();
    }

    pool->current = head;
}
/* # 168 "../../../mozilla/nsprpub/lib/ds/plarena.c" */
__attribute__((visibility("default"))) void * PL_ArenaAllocate(PLArenaPool *pool, PRUint32 nb)
{
    PLArena *a;
    char *rp;

    (((nb & pool->mask) == 0)?((void)0):PR_Assert("(nb & pool->mask) == 0","../../../mozilla/nsprpub/lib/ds/plarena.c",173));

    nb = (PRUword)(((PRUword)(nb) + (pool)->mask) & ~(pool)->mask);


    {
        a = pool->current;
        do {
            if ( a->avail +nb <= a->limit ) {
                pool->current = a;
                rp = (char *)a->avail;
                a->avail += nb;
                return rp;
            }
        } while( ((void *)0) != (a = a->next) );
    }


    {
        PLArena *p;


        if ( PR_FAILURE == LockArena())
            return(0);

        for ( a = arena_freelist, p = ((void *)0); a != ((void *)0) ; p = a, a = a->next ) {
            if ( a->base +nb <= a->limit ) {
                if ( p == ((void *)0) )
                    arena_freelist = a->next;
                else
                    p->next = a->next;
                UnlockArena();
                a->avail = a->base;
                rp = (char *)a->avail;
                a->avail += nb;


                a->next = pool->current->next;
                pool->current->next = a;
                pool->current = a;
                if ( ((void *)0) == pool->first.next )
                    pool->first.next = a;
                return(rp);
            }
        }
        UnlockArena();
    }


    {
        PRUint32 sz = ((pool->arenasize)>(nb)?(pool->arenasize):(nb));
        sz += sizeof *a + pool->mask;
        a = (PLArena*)(PR_Malloc((sz)));
        if ( ((void *)0) != a ) {
            a->limit = (PRUword)a + sz;
            a->base = a->avail = (PRUword)(((PRUword)(a + 1) + (pool)->mask) /*& ~(pool)->mask*/);
            rp = (char *)a->avail;
            a->avail += nb;


            a->next = pool->current->next;
            pool->current->next = a;
            pool->current = a;
            if ( ((void *)0) == pool->first.next )
                pool->first.next = a;
            ;
            ;
            return(rp);
        }
    }


    return(((void *)0));
}
示例#3
0
PR_IMPLEMENT(void *) PL_ArenaAllocate(PLArenaPool *pool, PRUint32 nb)
{
    PLArena *a;   
    char *rp;     /* returned pointer */

    PR_ASSERT((nb & pool->mask) == 0);
    
    nb = (PRUword)PL_ARENA_ALIGN(pool, nb); /* force alignment */

    /* attempt to allocate from arenas at pool->current */
    {
        a = pool->current;
        do {
            if ( a->avail +nb <= a->limit )  {
                pool->current = a;
                rp = (char *)a->avail;
                a->avail += nb;
                return rp;
            }
        } while( NULL != (a = a->next) );
    }

    /* attempt to allocate from arena_freelist */
    {
        PLArena *p; /* previous pointer, for unlinking from freelist */

        /* lock the arena_freelist. Make access to the freelist MT-Safe */
        if ( PR_FAILURE == LockArena())
            return(0);

        for ( a = arena_freelist, p = NULL; a != NULL ; p = a, a = a->next ) {
            if ( a->base +nb <= a->limit )  {
                if ( p == NULL )
                    arena_freelist = a->next;
                else
                    p->next = a->next;
                UnlockArena();
                a->avail = a->base;
                rp = (char *)a->avail;
                a->avail += nb;
                /* the newly allocated arena is linked after pool->current 
                *  and becomes pool->current */
                a->next = pool->current->next;
                pool->current->next = a;
                pool->current = a;
                if ( NULL == pool->first.next )
                    pool->first.next = a;
                return(rp);
            }
        }
        UnlockArena();
    }

    /* 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 ( NULL != a )  {
            a->limit = (PRUword)a + sz;
            a->base = a->avail = (PRUword)PL_ARENA_ALIGN(pool, a + 1);
            rp = (char *)a->avail;
            a->avail += nb;
            /* the newly allocated arena is linked after pool->current 
            *  and becomes pool->current */
            a->next = pool->current->next;
            pool->current->next = a;
            pool->current = a;
            if ( NULL == pool->first.next )
                pool->first.next = a;
            PL_COUNT_ARENA(pool,++);
            COUNT(pool, nmallocs);
            return(rp);
        }
    }