Changeset 3457 for trunk/src


Ignore:
Timestamp:
Sep 14, 2020, 7:34:28 PM (5 years ago)
Author:
bird
Message:

kash: New parser allocator for non-forked-mode.

Location:
trunk/src/kash
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/kash/Makefile.kmk

    r3451 r3457  
    3636kash_NAME = kmk_ash
    3737kash_ASTOOL = YASM
    38 kash_DEFS = lint SHELL SMALL
     38kash_DEFS = lint SHELL SMALL #KASH_SEPARATE_PARSER_ALLOCATOR
    3939if "$(KBUILD_TARGET)" != "win" || defined(KASH_WIN_FORKED_MODE)
    4040kash_DEFS += SH_FORKED_MODE
  • trunk/src/kash/memalloc.c

    r3456 r3457  
    4242
    4343#include <stdlib.h>
     44#include <stddef.h>
    4445#include <assert.h>
    4546
     
    183184        mark->stacknleft = psh->stacknleft;
    184185        mark->marknext = psh->markp;
     186#ifdef KASH_SEPARATE_PARSER_ALLOCATOR
     187        mark->pstacksize = psh->pstacksize;
     188#endif
    185189        psh->markp = mark;
    186190}
     
    201205        psh->stacknxt = mark->stacknxt;
    202206        psh->stacknleft = mark->stacknleft;
     207
     208#ifdef KASH_SEPARATE_PARSER_ALLOCATOR
     209        assert(mark->pstacksize <= psh->pstacksize);
     210        while (mark->pstacksize < psh->pstacksize) {
     211                unsigned idx = --psh->pstacksize;
     212                pstack_block *psk = psh->pstack[idx];
     213                psh->pstack[idx] = NULL;
     214                if (psh->curpstack == psk)
     215                    psh->curpstack = idx > 0 ? psh->pstack[idx - 1] : NULL;
     216                pstackrelease(psh, psk);
     217        }
     218
     219# ifndef NDEBUG
     220        if (psh->curpstack) {
     221                unsigned i;
     222                for (i = 0; i < psh->pstacksize; i++)
     223                        if (psh->curpstack == psh->pstack[i])
     224                                break;
     225                assert(i < psh->pstacksize);
     226        }
     227# endif
     228#endif
    203229        INTON;
    204230}
     
    354380 * Parser stack allocator.
    355381 */
     382#ifdef KASH_SEPARATE_PARSER_ALLOCATOR
     383
     384unsigned pstackretain(pstack_block *pst)
     385{
     386        unsigned refs = sh_atomic_inc(&pst->refs);
     387        assert(refs > 1);
     388        assert(refs < 256 /* bogus, but useful */);
     389        return refs;
     390}
     391
     392unsigned pstackrelease(shinstance *psh, pstack_block *pst)
     393{
     394        unsigned refs;
     395        if (pst) {
     396                refs = sh_atomic_dec(&pst->refs);
     397                if (refs == 0) {
     398                        shinstance * const psh = shthread_get_shell();
     399                        struct stack_block *top;
     400                        while ((top = pst->top) != &pst->first)
     401                        {
     402                            pst->top = top->prev;
     403                            assert(pst->top);
     404                            top->prev = NULL;
     405                            sh_free(psh, top);
     406                        }
     407                        pst->nextbyte = NULL;
     408                        pst->top = NULL;
     409                        sh_free(psh, pst);
     410                }
     411        } else
     412                refs = 0;
     413        return refs;
     414}
     415
     416pstack_block *pstackpush(shinstance *psh)
     417{
     418        size_t const blocksize = offsetof(pstack_block, first.space) + MINSIZE;
     419        pstack_block *pst;
     420        unsigned i;
     421
     422        INTOFF;
     423
     424        /*
     425         * Allocate and initialize it.
     426         */
     427        pst = (pstack_block *)ckmalloc(psh, blocksize);
     428        pst->nextbyte          = &pst->first.space[0];
     429        pst->avail             = blocksize - offsetof(pstack_block, first.space);
     430        pst->topsize           = blocksize - offsetof(pstack_block, first.space);
     431        pst->strleft           = 0;
     432        pst->top               = &pst->first;
     433        pst->allocations       = 0;
     434        pst->bytesalloced      = 0;
     435        pst->nodesalloced      = 0;
     436        pst->entriesalloced    = 0;
     437        pst->strbytesalloced   = 0;
     438        pst->blocks            = 0;
     439        pst->fragmentation     = 0;
     440        pst->refs              = 1;
     441        pst->padding           = 42;
     442        pst->first.prev        = NULL;
     443
     444        /*
     445         * Push it onto the stack.
     446         */
     447        i = psh->pstacksize;
     448        if (i + 1 < psh->pstackalloced) {
     449                /* likely, except for the first time */
     450        } else {
     451                psh->pstack = (pstack_block **)ckrealloc(psh, psh->pstack, sizeof(psh->pstack[0]) * (i + 32));
     452                memset(&psh->pstack[i], 0, sizeof(psh->pstack[0]) * 32);
     453        }
     454        psh->pstack[i] = pst;
     455        psh->pstacksize = i + 1;
     456        psh->curpstack = pst;
     457
     458        INTON;
     459        return pst;
     460}
     461
     462/**
     463 * Allocates and pushes a new block onto the stack, min payload size @a nbytes.
     464 */
     465static void pstallocnewblock(shinstance *psh, pstack_block *pst, size_t nbytes)
     466{
     467        /* Allocate a new stack node. */
     468        struct stack_block *sp;
     469        size_t const blocksize = nbytes <= MINSIZE
     470                               ? offsetof(struct stack_block, space) + MINSIZE
     471                               : K_ALIGN_Z(nbytes + offsetof(struct stack_block, space), 1024);
     472
     473        INTOFF;
     474        sp = ckmalloc(psh, blocksize);
     475        sp->prev = pst->top;
     476        pst->fragmentation += pst->avail;
     477        pst->topsize        = blocksize - offsetof(struct stack_block, space);
     478        pst->avail          = blocksize - offsetof(struct stack_block, space);
     479        pst->nextbyte       = sp->space;
     480        pst->top            = sp;
     481        pst->blocks        += 1;
     482        INTON;
     483}
     484
     485/**
     486 * Tries to grow the current stack block to hold a minimum of @a nbytes,
     487 * will allocate a new block and copy over pending string bytes if that's not
     488 * possible.
     489 */
     490static void pstgrowblock(shinstance *psh, pstack_block *pst, size_t nbytes, size_t tocopy)
     491{
     492        struct stack_block *top = pst->top;
     493        size_t blocksize;
     494
     495        assert(pst->avail < nbytes); /* only called when we need more space */
     496        assert(tocopy <= pst->avail);
     497
     498        /* Double the size used thus far and add some fudge and alignment.  Make
     499           sure to at least allocate MINSIZE. */
     500        blocksize = K_MAX(K_ALIGN_Z(pst->avail * 2 + 100 + offsetof(struct stack_block, space), 64), MINSIZE);
     501
     502        /* If that isn't sufficient, do request size w/ some fudge and alignment. */
     503        if (blocksize < nbytes + offsetof(struct stack_block, space))
     504            blocksize = K_ALIGN_Z(nbytes + offsetof(struct stack_block, space) + 100, 1024);
     505
     506        /*
     507         * Reallocate the current stack node if we can.
     508         */
     509        if (   pst->nextbyte == &top->space[0] /* can't have anything else in the block */
     510            && top->prev != NULL /* first block is embedded in pst and cannot be reallocated */ ) {
     511                top = (struct stack_block *)ckrealloc(psh, top, blocksize);
     512                pst->top      = top;
     513                pst->topsize  = blocksize - offsetof(struct stack_block, space);
     514                pst->avail    = blocksize - offsetof(struct stack_block, space);
     515                pst->nextbyte = top->space;
     516        }
     517        /*
     518         * Otherwise allocate a new node and copy over the avail bytes
     519         * from the old one.
     520         */
     521        else {
     522                char const * const copysrc = pst->nextbyte;
     523                pstallocnewblock(psh, pst, nbytes);
     524                assert(pst->avail >= nbytes);
     525                assert(pst->avail >= tocopy);
     526                memcpy(pst->nextbyte, copysrc, tocopy);
     527        }
     528}
     529
     530K_INLINE void *pstallocint(shinstance *psh, pstack_block *pst, size_t nbytes)
     531{
     532        void *ret;
     533
     534        /*
     535         * Align the size and make sure we've got sufficient bytes available:
     536         */
     537        nbytes = SHELL_ALIGN(nbytes);
     538        if (pst->avail >= nbytes && (ssize_t)pst->avail >= 0) { /* likely*/ }
     539        else pstallocnewblock(psh, pst, nbytes);
     540
     541        /*
     542         * Carve out the return block.
     543         */
     544        ret = pst->nextbyte;
     545        pst->nextbyte     += nbytes;
     546        pst->avail        -= nbytes;
     547        pst->bytesalloced += nbytes;
     548        pst->allocations  += 1;
     549        return ret;
     550}
     551
     552#endif KASH_SEPARATE_PARSER_ALLOCATOR
     553
     554
    356555void *pstalloc(struct shinstance *psh, size_t nbytes)
    357556{
     557#ifdef KASH_SEPARATE_PARSER_ALLOCATOR
     558        return pstallocint(psh, psh->curpstack, nbytes);
     559#else
    358560        return stalloc(psh, nbytes);
     561#endif
    359562}
    360563
    361564union node *pstallocnode(struct shinstance *psh, size_t nbytes)
    362565{
     566#ifdef KASH_SEPARATE_PARSER_ALLOCATOR
     567        pstack_block *pst = psh->curpstack;
     568        pst->nodesalloced++;
     569        return (union node *)pstallocint(psh, pst, nbytes);
     570#else
    363571        return (union node *)pstalloc(psh, nbytes);
     572#endif
    364573}
    365574
    366575struct nodelist *pstalloclist(struct shinstance *psh)
    367576{
     577#ifdef KASH_SEPARATE_PARSER_ALLOCATOR
     578        pstack_block *pst = psh->curpstack;
     579        pst->entriesalloced++;
     580        return (struct nodelist *)pstallocint(psh, pst, sizeof(struct nodelist));
     581#endif
    368582        return (struct nodelist *)pstalloc(psh, sizeof(struct nodelist));
    369583}
     
    372586{
    373587        if (str) {
    374                 size_t nbytes = strlen(str) + 1;
     588                size_t const nbytes = strlen(str) + 1;
     589#ifdef KASH_SEPARATE_PARSER_ALLOCATOR
     590                pstack_block *pst = psh->curpstack;
     591                pst->strbytesalloced += SHELL_ALIGN(nbytes);
     592                return (char *)memcpy(pstallocint(psh, pst, nbytes), str, nbytes);
     593#else
    375594                return (char *)memcpy(pstalloc(psh, nbytes), str, nbytes);
     595#endif
    376596        }
    377597        return NULL;
     
    380600char *pstmakestrspace(struct shinstance *psh, size_t minbytes, char *end)
    381601{
     602#ifdef KASH_SEPARATE_PARSER_ALLOCATOR
     603        pstack_block *pst = psh->curpstack;
     604        size_t const len = end - pst->nextbyte;
     605
     606        assert(pst->avail - pst->strleft == len);
     607        TRACE2((psh, "pstmakestrspace: len=%u minbytes=%u (=> %u)\n", len, minbytes, len + minbytes));
     608
     609        pstgrowblock(psh, pst, minbytes + len, len);
     610
     611        pst->strleft = pst->avail - len;
     612        return pst->nextbyte + len;
     613
     614#else
    382615        size_t const len = end - stackblock(psh);
     616
    383617        assert(stackblocksize(psh) - psh->sstrnleft == len);
    384 TRACE2((psh, "pstmakestrspace: len=%u minbytes=%u (=> %u)\n", len, minbytes, len + minbytes));
     618        TRACE2((psh, "pstmakestrspace: len=%u minbytes=%u (=> %u)\n", len, minbytes, len + minbytes));
     619
    385620        minbytes += len;
    386621        while (stackblocksize(psh) < minbytes)
    387622                growstackblock(psh);
     623
    388624        psh->sstrnleft = (int)(stackblocksize(psh) - len);
    389625        return (char *)stackblock(psh) + len;
     626#endif
    390627}
    391628
     
    393630char *pstputcgrow(shinstance *psh, char *end, char c)
    394631{
    395         psh->sstrnleft++; /* PSTPUTC() already incremented it. */
     632#ifdef KASH_SEPARATE_PARSER_ALLOCATOR
     633        pstack_block *pst = psh->curpstack;
     634        pst->strleft++;         /* PSTPUTC() already incremented it. */
     635        end = pstmakestrspace(psh, 1, end);
     636        assert(pst->strleft > 0);
     637        pst->strleft--;
     638#else
     639        psh->sstrnleft++;       /* PSTPUTC() already incremented it. */
    396640        end = pstmakestrspace(psh, 1, end);
    397641        assert(psh->sstrnleft > 0);
    398642        psh->sstrnleft--;
     643#endif
    399644        *end++ = c;
    400645        return end;
     
    404649char *pstgrabstr(struct shinstance *psh, char *end)
    405650{
     651#ifdef KASH_SEPARATE_PARSER_ALLOCATOR
     652        pstack_block *pst = psh->curpstack;
     653        char * const pstart = pst->nextbyte;
     654        size_t nbytes = (size_t)(end - pstart);
     655
     656        assert((uintptr_t)end > (uintptr_t)pstart);
     657        assert(end[-1] == '\0');
     658        assert(SHELL_ALIGN((uintptr_t)pstart) == (uintptr_t)pstart);
     659        assert(pst->avail - pst->strleft >= nbytes);
     660
     661        nbytes = SHELL_ALIGN(nbytes); /** @todo don't align strings, align the other allocations. */
     662        pst->nextbyte += nbytes;
     663        pst->avail    -= nbytes;
     664        pst->strbytesalloced += nbytes;
     665
     666        return pstart;
     667
     668#else
    406669        char * const pstart = stackblock(psh);
    407670        size_t nbytes = (size_t)(end - pstart);
     
    417680
    418681        return pstart;
    419 }
    420 
     682#endif
     683}
     684
  • trunk/src/kash/memalloc.h

    r3456 r3457  
    3939        char *stacknxt;
    4040        int stacknleft;
     41#ifdef KASH_SEPARATE_PARSER_ALLOCATOR
     42        unsigned pstacksize;
     43#endif
    4144        struct stackmark *marknext;
    4245};
     
    8487 * subshells by simple reference counting.
    8588 * @{ */
     89#ifdef KASH_SEPARATE_PARSER_ALLOCATOR
     90struct pstack_block;
     91unsigned pstackretain(struct pstack_block *);
     92unsigned pstackrelease(struct shinstance *, struct pstack_block *);
     93struct pstack_block *pstackpush(struct shinstance *);
     94#endif
    8695void *pstalloc(struct shinstance *, size_t);
    8796union node;
     
    9099struct nodelist *pstalloclist(struct shinstance *);
    91100char *pstsavestr(struct shinstance *, const char *); /* was: stsavestr */
    92 #define PSTARTSTACKSTR(psh, p)      do { (p) = (psh)->stacknxt; (psh)->sstrnleft = (psh)->stacknleft; } while (0)
    93101char *pstmakestrspace(struct shinstance *, size_t, char *); /* was: makestrspace / growstackstr */
    94 #define PSTCHECKSTRSPACE(psh, n, p) do { if ((psh)->sstrnleft >= (n)) {/*likely*/} \
     102char *pstputcgrow(struct shinstance *, char *, char);
     103char *pstgrabstr(struct shinstance *, char *); /* was: grabstackstr / grabstackblock*/
     104#ifdef KASH_SEPARATE_PARSER_ALLOCATOR
     105# define PSTBLOCK(psh)               ((psh)->curpstack->nextbyte)
     106# define PSTARTSTACKSTR(psh, p) do { \
     107        pstack_block *pstmacro = (psh)->curpstack; \
     108        pstmacro->strleft = pstmacro->avail; \
     109        (p) = pstmacro->nextbyte; \
     110    } while (0)
     111# define PSTCHECKSTRSPACE(psh, n, p) do { \
     112        if ((psh)->curpstack->strleft >= (n)) {/*likely*/} \
     113        else { (p) = pstmakestrspace(psh, (n), (p)); assert((psh)->curpstack->strleft >= (n)); } \
     114    } while (0)
     115# define PSTUPUTC(psh, c, p) do { \
     116        assert((psh)->curpstack->strleft > 0); \
     117        (psh)->curpstack->strleft -= 1; \
     118        *(p)++ = (c); \
     119    } while (0)
     120# define PSTPUTC(psh, c, p) do { \
     121        if ((ssize_t)--(psh)->curpstack->strleft >= 0) *(p)++ = (c); \
     122        else (p) = pstputcgrow(psh, (p), (c)); \
     123    } while (0)
     124# define PSTPUTSTRN(psh, str, n, p) do { \
     125        pstack_block *pstmacro = (psh)->curpstack; \
     126        if (pstmacro->strleft >= (n)) {/*likely?*/} \
     127        else (p) = pstmakestrspace(psh, (n), (p)); \
     128        pstmacro->strleft -= (n); \
     129        memcpy((p), (str), (n)); \
     130        (p) += (n); \
     131    } while (0)
     132#else
     133# define PSTBLOCK(psh)               ((psh)->stacknxt)
     134# define PSTARTSTACKSTR(psh, p)      do { (p) = (psh)->stacknxt; (psh)->sstrnleft = (psh)->stacknleft; } while (0)
     135# define PSTCHECKSTRSPACE(psh, n, p) do { if ((psh)->sstrnleft >= (n)) {/*likely*/} \
    95136                                         else { (p) = pstmakestrspace(psh, (n), (p)); assert((psh)->sstrnleft >= (n)); } } while (0)
    96 #define PSTUPUTC(psh, c, p)         do { assert((psh)->sstrnleft > 0); --(psh)->sstrnleft; *(p)++ = (c); } while (0)
    97 char *pstputcgrow(struct shinstance *, char *, char);
    98 #define PSTPUTC(psh, c, p)          do { if (--(psh)->sstrnleft >= 0) *(p)++ = (c); else (p) = pstputcgrow(psh, (p), (c)); } while (0)
    99 #define PSTPUTSTRN(psh, str, n, p)  do { if ((psh)->sstrnleft >= (n)) {/*likely?*/} else (p) = pstmakestrspace(psh, (n), (p)); \
     137# define PSTUPUTC(psh, c, p)         do { assert((psh)->sstrnleft > 0); --(psh)->sstrnleft; *(p)++ = (c); } while (0)
     138# define PSTPUTC(psh, c, p)          do { if (--(psh)->sstrnleft >= 0) *(p)++ = (c); else (p) = pstputcgrow(psh, (p), (c)); } while (0)
     139# define PSTPUTSTRN(psh, str, n, p)  do { if ((psh)->sstrnleft >= (n)) {/*likely?*/} else (p) = pstmakestrspace(psh, (n), (p)); \
    100140                                         memcpy((p), (str), (n)); (psh)->sstrnleft -= (n); (p) += (n); } while (0)
    101 #define PSTBLOCK(psh)               ((psh)->stacknxt)
    102 char *pstgrabstr(struct shinstance *, char *); /* was: grabstackstr / grabstackblock*/
     141#endif
    103142/** @} */
    104143
  • trunk/src/kash/parser.c

    r3456 r3457  
    133133        union node *ret;
    134134        int t;
     135
    135136        TRACE2((psh, "parsecmd(%d)\n", interact));
    136 
     137#ifdef KASH_SEPARATE_PARSER_ALLOCATOR
     138        pstackpush(psh);
     139#endif
    137140        psh->tokpushback = 0;
    138141        psh->doprompt = interact;
     
    17851788}
    17861789
     1790static union node *copyparsetreeint(shinstance *psh, union node *src);
     1791
    17871792/*
    1788  * Helper to copyparsetree.
     1793 * Helper to copyparsetreeint.
    17891794 */
    17901795static struct nodelist *
     
    17991804                        *ppnext = dst;
    18001805                        ppnext = &dst->next;
    1801                         dst->n = copyparsetree(psh, src->n);
     1806                        dst->n = copyparsetreeint(psh, src->n);
    18021807                        src = src->next;
    18031808                }
     
    18111816 * Note! This could probably be generated from nodelist.
    18121817 */
    1813 union node *
    1814 copyparsetree(shinstance *psh, union node *src)
     1818static union node *
     1819copyparsetreeint(shinstance *psh, union node *src)
    18151820{
    18161821        /** @todo Try avoid recursion for one of the sub-nodes, esp. when there
     
    18271832                                ret = pstallocnode(psh, sizeof(src->nbinary));
    18281833                                ret->nbinary.type = type;
    1829                                 ret->nbinary.ch1  = copyparsetree(psh, src->nbinary.ch1);
    1830                                 ret->nbinary.ch2  = copyparsetree(psh, src->nbinary.ch2);
     1834                                ret->nbinary.ch1  = copyparsetreeint(psh, src->nbinary.ch1);
     1835                                ret->nbinary.ch2  = copyparsetreeint(psh, src->nbinary.ch2);
    18311836                                break;
    18321837
     
    18351840                                ret->ncmd.type     = NCMD;
    18361841                                ret->ncmd.backgnd  = src->ncmd.backgnd;
    1837                                 ret->ncmd.args     = copyparsetree(psh, src->ncmd.args);
    1838                                 ret->ncmd.redirect = copyparsetree(psh, src->ncmd.redirect);
     1842                                ret->ncmd.args     = copyparsetreeint(psh, src->ncmd.args);
     1843                                ret->ncmd.redirect = copyparsetreeint(psh, src->ncmd.redirect);
    18391844                                break;
    18401845
     
    18511856                                ret = pstallocnode(psh, sizeof(src->nredir));
    18521857                                ret->nredir.type     = type;
    1853                                 ret->nredir.n        = copyparsetree(psh, src->nredir.n);
    1854                                 ret->nredir.redirect = copyparsetree(psh, src->nredir.redirect);
     1858                                ret->nredir.n        = copyparsetreeint(psh, src->nredir.n);
     1859                                ret->nredir.redirect = copyparsetreeint(psh, src->nredir.redirect);
    18551860                                break;
    18561861
     
    18581863                                ret = pstallocnode(psh, sizeof(src->nif));
    18591864                                ret->nif.type        = NIF;
    1860                                 ret->nif.test        = copyparsetree(psh, src->nif.test);
    1861                                 ret->nif.ifpart      = copyparsetree(psh, src->nif.ifpart);
    1862                                 ret->nif.elsepart    = copyparsetree(psh, src->nif.elsepart);
     1865                                ret->nif.test        = copyparsetreeint(psh, src->nif.test);
     1866                                ret->nif.ifpart      = copyparsetreeint(psh, src->nif.ifpart);
     1867                                ret->nif.elsepart    = copyparsetreeint(psh, src->nif.elsepart);
    18631868                                break;
    18641869
     
    18661871                                ret = pstallocnode(psh, sizeof(src->nfor));
    18671872                                ret->nfor.type       = NFOR;
    1868                                 ret->nfor.args       = copyparsetree(psh, src->nfor.args);
    1869                                 ret->nfor.body       = copyparsetree(psh, src->nfor.body);
     1873                                ret->nfor.args       = copyparsetreeint(psh, src->nfor.args);
     1874                                ret->nfor.body       = copyparsetreeint(psh, src->nfor.body);
    18701875                                ret->nfor.var        = pstsavestr(psh, src->nfor.var);
    18711876                                break;
     
    18741879                                ret = pstallocnode(psh, sizeof(src->ncase));
    18751880                                ret->ncase.type      = NCASE;
    1876                                 ret->ncase.expr      = copyparsetree(psh, src->ncase.expr);
    1877                                 ret->ncase.cases     = copyparsetree(psh, src->ncase.cases);
     1881                                ret->ncase.expr      = copyparsetreeint(psh, src->ncase.expr);
     1882                                ret->ncase.cases     = copyparsetreeint(psh, src->ncase.cases);
    18781883                                break;
    18791884
     
    18811886                                ret = pstallocnode(psh, sizeof(src->nclist));
    18821887                                ret->nclist.type     = NCLIST;
    1883                                 ret->nclist.next     = copyparsetree(psh, src->nclist.next);
    1884                                 ret->nclist.pattern  = copyparsetree(psh, src->nclist.pattern);
    1885                                 ret->nclist.body     = copyparsetree(psh, src->nclist.body);
     1888                                ret->nclist.next     = copyparsetreeint(psh, src->nclist.next);
     1889                                ret->nclist.pattern  = copyparsetreeint(psh, src->nclist.pattern);
     1890                                ret->nclist.body     = copyparsetreeint(psh, src->nclist.body);
    18861891                                break;
    18871892
     
    18901895                                ret = pstallocnode(psh, sizeof(src->narg));
    18911896                                ret->narg.type       = type;
    1892                                 ret->narg.next       = copyparsetree(psh, src->narg.next);
     1897                                ret->narg.next       = copyparsetreeint(psh, src->narg.next);
    18931898                                ret->narg.text       = pstsavestr(psh, src->narg.text);
    18941899                                ret->narg.backquote  = copynodelist(psh, src->narg.backquote);
     
    19031908                                ret->nfile.type      = type;
    19041909                                ret->nfile.fd        = src->nfile.fd;
    1905                                 ret->nfile.next      = copyparsetree(psh, src->nfile.next);
    1906                                 ret->nfile.fname     = copyparsetree(psh, src->nfile.fname);
     1910                                ret->nfile.next      = copyparsetreeint(psh, src->nfile.next);
     1911                                ret->nfile.fname     = copyparsetreeint(psh, src->nfile.fname);
    19071912                                break;
    19081913
     
    19121917                                ret->ndup.type       = type;
    19131918                                ret->ndup.fd         = src->ndup.fd;
    1914                                 ret->ndup.next       = copyparsetree(psh, src->ndup.next);
     1919                                ret->ndup.next       = copyparsetreeint(psh, src->ndup.next);
    19151920                                ret->ndup.dupfd      = src->ndup.dupfd;
    1916                                 ret->ndup.vname      = copyparsetree(psh, src->ndup.vname);
     1921                                ret->ndup.vname      = copyparsetreeint(psh, src->ndup.vname);
    19171922                                break;
    19181923
     
    19221927                                ret->nhere.type      = type;
    19231928                                ret->nhere.fd        = src->nhere.fd;
    1924                                 ret->nhere.next      = copyparsetree(psh, src->nhere.next);
    1925                                 ret->nhere.doc       = copyparsetree(psh, src->nhere.doc);
     1929                                ret->nhere.next      = copyparsetreeint(psh, src->nhere.next);
     1930                                ret->nhere.doc       = copyparsetreeint(psh, src->nhere.doc);
    19261931                                break;
    19271932
     
    19291934                                ret = pstallocnode(psh, sizeof(src->nnot));
    19301935                                ret->nnot.type      = NNOT;
    1931                                 ret->nnot.com       = copyparsetree(psh, src->nnot.com);
     1936                                ret->nnot.com       = copyparsetreeint(psh, src->nnot.com);
    19321937                                break;
    19331938
     
    19421947}
    19431948
     1949union node *copyparsetree(shinstance *psh, union node *src)
     1950{
     1951#ifdef KASH_SEPARATE_PARSER_ALLOCATOR
     1952        pstackpush(psh);
     1953#endif
     1954        return copyparsetreeint(psh, src);
     1955}
     1956
  • trunk/src/kash/shinstance.h

    r3451 r3457  
    8484        char space[MINSIZE];
    8585};
     86
     87#ifdef KASH_SEPARATE_PARSER_ALLOCATOR
     88/** Parser stack allocator block.
     89 * These are reference counted so they can be shared between the parent and
     90 * child shells.  They are also using as an alternative to copying function
     91 * definitions, here the final goal is to automatically emit separate
     92 * pstack_blocks for function while parsing to make it more flexible. */
     93typedef struct pstack_block {
     94    /** Pointer to the next unallocated byte (= stacknxt). */
     95    char               *nextbyte;
     96    /** Number of bytes available in the current stack block (= stacknleft). */
     97    size_t              avail;
     98    /* Number of chars left for string data (PSTPUTC, PSTUPUTC, et al) (= sstrnleft). */
     99    size_t              strleft;
     100    /** Top of the allocation stack (nextbyte points within this). */
     101    struct stack_block *top;
     102    /** Size of the top stack element (user space only). */
     103    size_t              topsize;
     104    /** @name statistics
     105     * @{ */
     106    size_t              allocations;
     107    size_t              bytesalloced;
     108    size_t              nodesalloced;
     109    size_t              entriesalloced;
     110    size_t              strbytesalloced;
     111    size_t              blocks;
     112    size_t              fragmentation;
     113    /** @} */
     114    /** Reference counter. */
     115    unsigned volatile   refs;
     116    unsigned            padding;
     117    /** The first stack block. */
     118    struct stack_block  first;
     119} pstack_block;
     120#endif
    86121
    87122/* input.c */
     
    275310    struct stack_block *stackp/* = &stackbase*/;
    276311    struct stackmark   *markp;
     312
     313#ifdef KASH_SEPARATE_PARSER_ALLOCATOR
     314    pstack_block       *curpstack;      /**< The pstack entry we're currently allocating from (NULL when not in parse.c). */
     315    pstack_block      **pstack;         /**< Stack of parsed stuff. */
     316    unsigned            pstacksize;     /**< Number of entries in pstack. */
     317    unsigned            pstackalloced;  /**< The allocated size of pstack. */
     318#endif
    277319
    278320    /* myhistedit.h */
  • trunk/src/kash/shthread.h

    r3448 r3457  
    6464    return _InterlockedIncrement((long *)valuep);
    6565#else
    66     return __sync_fetch_and_add(valuep, 1);
     66    return __sync_add_and_fetch(valuep, 1);
    6767#endif
    6868}
     
    7373    return _InterlockedDecrement((long *)valuep);
    7474#else
    75     return __sync_fetch_and_sub(valuep, 1);
     75    return __sync_sub_and_fetch(valuep, 1);
    7676#endif
    7777}
Note: See TracChangeset for help on using the changeset viewer.