Force gcc to build library functions out-of-line, even if they happen to be in the same file. Signed-off-by: Herbert Xu <herbert@xxxxxxxxxxxxxxxxxxx> --- src/memalloc.c | 59 ++++++++++++++++++++++++++++---------------------- 1 file changed, 33 insertions(+), 26 deletions(-) diff --git a/src/memalloc.c b/src/memalloc.c index 7aa8c58..3275e51 100644 --- a/src/memalloc.c +++ b/src/memalloc.c @@ -43,18 +43,28 @@ #include "mystring.h" #include "system.h" +static __attribute__((__always_inline__)) inline void outofspace(void) +{ + sh_error("Out of space"); +} + +static void *checknull(void *p) +{ + if (!p) + outofspace(); + return p; +} + /* * Like malloc, but returns an error when out of space. */ -void *ckmalloc(size_t nbytes) +__attribute__((__noinline__)) void *ckmalloc(size_t nbytes) { void *p; p = malloc(nbytes); - if (p == NULL) - sh_error("Out of space"); - return p; + return checknull(p); } @@ -62,12 +72,10 @@ void *ckmalloc(size_t nbytes) * Same for realloc. */ -void *ckrealloc(void *p, size_t nbytes) +__attribute__((__noinline__)) void *ckrealloc(void *p, size_t nbytes) { p = realloc(p, nbytes); - if (p == NULL) - sh_error("Out of space"); - return p; + return checknull(p); } @@ -78,10 +86,7 @@ void *ckrealloc(void *p, size_t nbytes) char * savestr(const char *s) { - char *p = strdup(s); - if (!p) - sh_error("Out of space"); - return p; + return checknull(strdup(s)); } @@ -124,7 +129,7 @@ void *stalloc(size_t nbytes) blocksize = MINSIZE; len = sizeof(struct stack_block) - MINSIZE + blocksize; if (len < blocksize) - sh_error("Out of space"); + outofspace(); INTOFF; sp = ckmalloc(len); sp->prev = stackp; @@ -155,7 +160,8 @@ void stunalloc(void *p) -void pushstackmark(struct stackmark *mark, size_t len) +__attribute__((__noinline__)) void pushstackmark(struct stackmark *mark, + size_t len) { mark->stackp = stackp; mark->stacknxt = stacknxt; @@ -197,13 +203,14 @@ popstackmark(struct stackmark *mark) * part of the block that has been used. */ -static void growstackblock(size_t min) +static char *growstackblock(size_t min) { size_t newlen; + char *p; newlen = stacknleft * 2; if (newlen < stacknleft) - sh_error("Out of space"); + outofspace(); min = SHELL_ALIGN(min | 128); if (newlen < min) newlen += min; @@ -220,19 +227,22 @@ static void growstackblock(size_t min) sp = ckrealloc(sp, grosslen); sp->prev = prevstackp; stackp = sp; - stacknxt = sp->space; + p = stacknxt = sp->space; stacknleft = newlen; sstrend = sp->space + newlen; INTON; } else { char *oldspace = stacknxt; int oldlen = stacknleft; - char *p = stalloc(newlen); + + p = stalloc(newlen); /* free the space we just allocated */ stacknxt = memcpy(p, oldspace, oldlen); stacknleft += newlen; } + + return p; } /* @@ -258,14 +268,13 @@ growstackstr(void) { size_t len = stackblocksize(); - growstackblock(0); - return stackblock() + len; + return growstackblock(0) + len; } -char *growstackto(size_t len) +__attribute__((__noinline__)) char *growstackto(size_t len) { if (stackblocksize() < len) - growstackblock(len); + return growstackblock(len); return stackblock(); } @@ -273,16 +282,14 @@ char *growstackto(size_t len) * Called from CHECKSTRSPACE. */ -char * -makestrspace(size_t newlen, char *p) +__attribute__((__noinline__)) char *makestrspace(size_t newlen, char *p) { size_t len = p - stacknxt; return growstackto(len + newlen) + len; } -char * -stnputs(const char *s, size_t n, char *p) +__attribute__((__noinline__)) char *stnputs(const char *s, size_t n, char *p) { p = makestrspace(n, p); p = mempcpy(p, s, n); -- 2.39.2 -- Email: Herbert Xu <herbert@xxxxxxxxxxxxxxxxxxx> Home Page: http://gondor.apana.org.au/~herbert/ PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt