- Timestamp:
- Sep 14, 2020, 7:34:28 PM (5 years ago)
- Location:
- trunk/src/kash
- Files:
-
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/kash/Makefile.kmk
r3451 r3457 36 36 kash_NAME = kmk_ash 37 37 kash_ASTOOL = YASM 38 kash_DEFS = lint SHELL SMALL 38 kash_DEFS = lint SHELL SMALL #KASH_SEPARATE_PARSER_ALLOCATOR 39 39 if "$(KBUILD_TARGET)" != "win" || defined(KASH_WIN_FORKED_MODE) 40 40 kash_DEFS += SH_FORKED_MODE -
trunk/src/kash/memalloc.c
r3456 r3457 42 42 43 43 #include <stdlib.h> 44 #include <stddef.h> 44 45 #include <assert.h> 45 46 … … 183 184 mark->stacknleft = psh->stacknleft; 184 185 mark->marknext = psh->markp; 186 #ifdef KASH_SEPARATE_PARSER_ALLOCATOR 187 mark->pstacksize = psh->pstacksize; 188 #endif 185 189 psh->markp = mark; 186 190 } … … 201 205 psh->stacknxt = mark->stacknxt; 202 206 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 203 229 INTON; 204 230 } … … 354 380 * Parser stack allocator. 355 381 */ 382 #ifdef KASH_SEPARATE_PARSER_ALLOCATOR 383 384 unsigned 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 392 unsigned 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 416 pstack_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 */ 465 static 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 */ 490 static 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 530 K_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 356 555 void *pstalloc(struct shinstance *psh, size_t nbytes) 357 556 { 557 #ifdef KASH_SEPARATE_PARSER_ALLOCATOR 558 return pstallocint(psh, psh->curpstack, nbytes); 559 #else 358 560 return stalloc(psh, nbytes); 561 #endif 359 562 } 360 563 361 564 union node *pstallocnode(struct shinstance *psh, size_t nbytes) 362 565 { 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 363 571 return (union node *)pstalloc(psh, nbytes); 572 #endif 364 573 } 365 574 366 575 struct nodelist *pstalloclist(struct shinstance *psh) 367 576 { 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 368 582 return (struct nodelist *)pstalloc(psh, sizeof(struct nodelist)); 369 583 } … … 372 586 { 373 587 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 375 594 return (char *)memcpy(pstalloc(psh, nbytes), str, nbytes); 595 #endif 376 596 } 377 597 return NULL; … … 380 600 char *pstmakestrspace(struct shinstance *psh, size_t minbytes, char *end) 381 601 { 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 382 615 size_t const len = end - stackblock(psh); 616 383 617 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 385 620 minbytes += len; 386 621 while (stackblocksize(psh) < minbytes) 387 622 growstackblock(psh); 623 388 624 psh->sstrnleft = (int)(stackblocksize(psh) - len); 389 625 return (char *)stackblock(psh) + len; 626 #endif 390 627 } 391 628 … … 393 630 char *pstputcgrow(shinstance *psh, char *end, char c) 394 631 { 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. */ 396 640 end = pstmakestrspace(psh, 1, end); 397 641 assert(psh->sstrnleft > 0); 398 642 psh->sstrnleft--; 643 #endif 399 644 *end++ = c; 400 645 return end; … … 404 649 char *pstgrabstr(struct shinstance *psh, char *end) 405 650 { 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 406 669 char * const pstart = stackblock(psh); 407 670 size_t nbytes = (size_t)(end - pstart); … … 417 680 418 681 return pstart; 419 } 420 682 #endif 683 } 684 -
trunk/src/kash/memalloc.h
r3456 r3457 39 39 char *stacknxt; 40 40 int stacknleft; 41 #ifdef KASH_SEPARATE_PARSER_ALLOCATOR 42 unsigned pstacksize; 43 #endif 41 44 struct stackmark *marknext; 42 45 }; … … 84 87 * subshells by simple reference counting. 85 88 * @{ */ 89 #ifdef KASH_SEPARATE_PARSER_ALLOCATOR 90 struct pstack_block; 91 unsigned pstackretain(struct pstack_block *); 92 unsigned pstackrelease(struct shinstance *, struct pstack_block *); 93 struct pstack_block *pstackpush(struct shinstance *); 94 #endif 86 95 void *pstalloc(struct shinstance *, size_t); 87 96 union node; … … 90 99 struct nodelist *pstalloclist(struct shinstance *); 91 100 char *pstsavestr(struct shinstance *, const char *); /* was: stsavestr */ 92 #define PSTARTSTACKSTR(psh, p) do { (p) = (psh)->stacknxt; (psh)->sstrnleft = (psh)->stacknleft; } while (0)93 101 char *pstmakestrspace(struct shinstance *, size_t, char *); /* was: makestrspace / growstackstr */ 94 #define PSTCHECKSTRSPACE(psh, n, p) do { if ((psh)->sstrnleft >= (n)) {/*likely*/} \ 102 char *pstputcgrow(struct shinstance *, char *, char); 103 char *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*/} \ 95 136 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)); \ 100 140 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 103 142 /** @} */ 104 143 -
trunk/src/kash/parser.c
r3456 r3457 133 133 union node *ret; 134 134 int t; 135 135 136 TRACE2((psh, "parsecmd(%d)\n", interact)); 136 137 #ifdef KASH_SEPARATE_PARSER_ALLOCATOR 138 pstackpush(psh); 139 #endif 137 140 psh->tokpushback = 0; 138 141 psh->doprompt = interact; … … 1785 1788 } 1786 1789 1790 static union node *copyparsetreeint(shinstance *psh, union node *src); 1791 1787 1792 /* 1788 * Helper to copyparsetree .1793 * Helper to copyparsetreeint. 1789 1794 */ 1790 1795 static struct nodelist * … … 1799 1804 *ppnext = dst; 1800 1805 ppnext = &dst->next; 1801 dst->n = copyparsetree (psh, src->n);1806 dst->n = copyparsetreeint(psh, src->n); 1802 1807 src = src->next; 1803 1808 } … … 1811 1816 * Note! This could probably be generated from nodelist. 1812 1817 */ 1813 union node *1814 copyparsetree (shinstance *psh, union node *src)1818 static union node * 1819 copyparsetreeint(shinstance *psh, union node *src) 1815 1820 { 1816 1821 /** @todo Try avoid recursion for one of the sub-nodes, esp. when there … … 1827 1832 ret = pstallocnode(psh, sizeof(src->nbinary)); 1828 1833 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); 1831 1836 break; 1832 1837 … … 1835 1840 ret->ncmd.type = NCMD; 1836 1841 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); 1839 1844 break; 1840 1845 … … 1851 1856 ret = pstallocnode(psh, sizeof(src->nredir)); 1852 1857 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); 1855 1860 break; 1856 1861 … … 1858 1863 ret = pstallocnode(psh, sizeof(src->nif)); 1859 1864 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); 1863 1868 break; 1864 1869 … … 1866 1871 ret = pstallocnode(psh, sizeof(src->nfor)); 1867 1872 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); 1870 1875 ret->nfor.var = pstsavestr(psh, src->nfor.var); 1871 1876 break; … … 1874 1879 ret = pstallocnode(psh, sizeof(src->ncase)); 1875 1880 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); 1878 1883 break; 1879 1884 … … 1881 1886 ret = pstallocnode(psh, sizeof(src->nclist)); 1882 1887 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); 1886 1891 break; 1887 1892 … … 1890 1895 ret = pstallocnode(psh, sizeof(src->narg)); 1891 1896 ret->narg.type = type; 1892 ret->narg.next = copyparsetree (psh, src->narg.next);1897 ret->narg.next = copyparsetreeint(psh, src->narg.next); 1893 1898 ret->narg.text = pstsavestr(psh, src->narg.text); 1894 1899 ret->narg.backquote = copynodelist(psh, src->narg.backquote); … … 1903 1908 ret->nfile.type = type; 1904 1909 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); 1907 1912 break; 1908 1913 … … 1912 1917 ret->ndup.type = type; 1913 1918 ret->ndup.fd = src->ndup.fd; 1914 ret->ndup.next = copyparsetree (psh, src->ndup.next);1919 ret->ndup.next = copyparsetreeint(psh, src->ndup.next); 1915 1920 ret->ndup.dupfd = src->ndup.dupfd; 1916 ret->ndup.vname = copyparsetree (psh, src->ndup.vname);1921 ret->ndup.vname = copyparsetreeint(psh, src->ndup.vname); 1917 1922 break; 1918 1923 … … 1922 1927 ret->nhere.type = type; 1923 1928 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); 1926 1931 break; 1927 1932 … … 1929 1934 ret = pstallocnode(psh, sizeof(src->nnot)); 1930 1935 ret->nnot.type = NNOT; 1931 ret->nnot.com = copyparsetree (psh, src->nnot.com);1936 ret->nnot.com = copyparsetreeint(psh, src->nnot.com); 1932 1937 break; 1933 1938 … … 1942 1947 } 1943 1948 1949 union 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 84 84 char space[MINSIZE]; 85 85 }; 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. */ 93 typedef 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 86 121 87 122 /* input.c */ … … 275 310 struct stack_block *stackp/* = &stackbase*/; 276 311 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 277 319 278 320 /* myhistedit.h */ -
trunk/src/kash/shthread.h
r3448 r3457 64 64 return _InterlockedIncrement((long *)valuep); 65 65 #else 66 return __sync_ fetch_and_add(valuep, 1);66 return __sync_add_and_fetch(valuep, 1); 67 67 #endif 68 68 } … … 73 73 return _InterlockedDecrement((long *)valuep); 74 74 #else 75 return __sync_ fetch_and_sub(valuep, 1);75 return __sync_sub_and_fetch(valuep, 1); 76 76 #endif 77 77 }
Note:
See TracChangeset
for help on using the changeset viewer.