Changeset 3461 for trunk/src


Ignore:
Timestamp:
Sep 15, 2020, 2:55:26 PM (5 years ago)
Author:
bird
Message:

kash: Cache one pstack_block since parsecmd seems to be called for each statement line in a script. Also, mark pstack blocks as 'done' before returning from parsecmd and prevent them from becoming current (curpstack) again upon popping.

Location:
trunk/src/kash
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/kash/memalloc.c

    r3458 r3461  
    371371                TRACE2((NULL, "pstackrelease: %p - %u refs (%s)\n", pst, refs, caller)); K_NOREF(caller);
    372372                if (refs == 0) {
    373                         shinstance * const psh = shthread_get_shell();
    374373                        struct stack_block *top;
    375374                        while ((top = pst->top) != &pst->first)
     
    382381                        pst->nextbyte = NULL;
    383382                        pst->top = NULL;
    384                         /** @todo push into an alloc cache rather than freeing it */
    385                         sh_free(psh, pst);
     383
     384                        if (!psh->freepstack)
     385                                psh->freepstack = pst;
     386                        else
     387                                sh_free(psh, pst);
    386388                }
    387389        } else
     
    395397        while (target < psh->pstacksize) {
    396398                unsigned idx = --psh->pstacksize;
    397                 pstack_block *psk = psh->pstack[idx];
     399                pstack_block *pst = psh->pstack[idx];
    398400                psh->pstack[idx] = NULL;
    399                 if (psh->curpstack == psk)
    400                     psh->curpstack = idx > 0 ? psh->pstack[idx - 1] : NULL;
    401                 pstackrelease(psh, psk, "popstackmark");
     401                if (psh->curpstack == pst) {
     402                        pstack_block *pstnext;
     403                        if (idx <= 0 || (pstnext = psh->pstack[idx - 1])->done)
     404                                psh->curpstack = NULL;
     405                        else
     406                                psh->curpstack = pstnext;
     407                }
     408                pstackrelease(psh, pst, "popstackmark");
    402409        }
    403410
     
    454461         * Allocate and initialize it.
    455462         */
    456         pst = (pstack_block *)ckmalloc(psh, blocksize);
     463        pst = psh->freepstack;
     464        if (pst)
     465                psh->freepstack = NULL;
     466        else
     467                pst = (pstack_block *)ckmalloc(psh, blocksize);
    457468        pst->nextbyte          = &pst->first.space[0];
    458469        pst->avail             = blocksize - offsetof(pstack_block, first.space);
    459470        pst->topsize           = blocksize - offsetof(pstack_block, first.space);
     471        pst->top               = &pst->first;
    460472        pst->strleft           = 0;
    461         pst->top               = &pst->first;
    462473        pst->allocations       = 0;
    463474        pst->bytesalloced      = 0;
     
    468479        pst->fragmentation     = 0;
    469480        pst->refs              = 1;
    470         pst->padding           = 42;
     481        pst->done              = K_FALSE;
    471482        pst->first.prev        = NULL;
    472483
     
    480491        TRACE2((psh, "pstackallocpush: %p - entry %u\n", pst, psh->pstacksize - 1));
    481492        return pst;
     493}
     494
     495/**
     496 * Marks the block as done, preventing it from being marked current again.
     497 */
     498void pstackmarkdone(pstack_block *pst)
     499{
     500        pst->done = K_TRUE;
    482501}
    483502
  • trunk/src/kash/memalloc.h

    r3458 r3461  
    9494unsigned pstackretainpush(struct shinstance *, struct pstack_block *);
    9595struct pstack_block *pstackallocpush(struct shinstance *);
     96void pstackmarkdone(struct pstack_block *);
    9697#endif
    9798void *pstalloc(struct shinstance *, size_t);
  • trunk/src/kash/parser.c

    r3458 r3461  
    133133        union node *ret;
    134134        int t;
    135 
     135#ifdef KASH_SEPARATE_PARSER_ALLOCATOR
     136        pstack_block *pst = pstackallocpush(psh);
     137#endif
    136138        TRACE2((psh, "parsecmd(%d)\n", interact));
    137 #ifdef KASH_SEPARATE_PARSER_ALLOCATOR
    138         pstackallocpush(psh);
    139 #endif
     139
    140140        psh->tokpushback = 0;
    141141        psh->doprompt = interact;
     
    155155        TRACE2((psh, "parsecmd(%d) returns:\n", interact));
    156156        showtree(psh, ret);
     157#endif
     158#ifdef KASH_SEPARATE_PARSER_ALLOCATOR
     159        pstackmarkdone(pst);
    157160#endif
    158161        return ret;
  • trunk/src/kash/shinstance.c

    r3460 r3461  
    541541        psh->pstack = NULL;
    542542    }
     543    sh_free(psh, psh->freepstack);
     544    psh->freepstack = NULL;
    543545#endif
    544546    psh->markp = NULL;
    545 
    546547
    547548    /*
  • trunk/src/kash/shinstance.h

    r3460 r3461  
    131131    /** Reference counter. */
    132132    unsigned volatile   refs;
    133     unsigned            padding;
     133    /** Whether to make it current when is restored to the top of the stack. */
     134    KBOOL               done;
    134135    /** The first stack block. */
    135136    struct stack_block  first;
     
    339340    unsigned            pstacksize;     /**< Number of entries in pstack. */
    340341    unsigned            pstackalloced;  /**< The allocated size of pstack. */
     342    pstack_block       *freepstack;     /**< One cached pstack entry (lots of parsecmd calls). */
    341343#endif
    342344
Note: See TracChangeset for help on using the changeset viewer.