summaryrefslogtreecommitdiffstats
path: root/bin/sh/memalloc.c
diff options
context:
space:
mode:
Diffstat (limited to 'bin/sh/memalloc.c')
-rw-r--r--bin/sh/memalloc.c68
1 files changed, 25 insertions, 43 deletions
diff --git a/bin/sh/memalloc.c b/bin/sh/memalloc.c
index d00b4d9..bc567d0 100644
--- a/bin/sh/memalloc.c
+++ b/bin/sh/memalloc.c
@@ -127,8 +127,7 @@ static struct stack_block *stackp;
static struct stackmark *markp;
char *stacknxt;
int stacknleft;
-int sstrnleft;
-int herefd = -1;
+char *sstrend;
static void
@@ -147,6 +146,7 @@ stnewblock(int nbytes)
sp->prev = stackp;
stacknxt = SPACE(sp);
stacknleft = allocsize - (stacknxt - (char*)sp);
+ sstrend = stacknxt + stacknleft;
stackp = sp;
INTON;
}
@@ -205,6 +205,7 @@ popstackmark(struct stackmark *mark)
}
stacknxt = mark->stacknxt;
stacknleft = mark->stacknleft;
+ sstrend = stacknxt + stacknleft;
INTON;
}
@@ -219,8 +220,8 @@ popstackmark(struct stackmark *mark)
* part of the block that has been used.
*/
-void
-growstackblock(void)
+static void
+growstackblock(int min)
{
char *p;
int newlen;
@@ -230,8 +231,15 @@ growstackblock(void)
struct stack_block *oldstackp;
struct stackmark *xmark;
- newlen = (stacknleft == 0) ? MINSIZE : stacknleft * 2 + 100;
- newlen = ALIGN(newlen);
+ if (min < stacknleft)
+ min = stacknleft;
+ if (min >= INT_MAX / 2 - ALIGN(sizeof(struct stack_block)))
+ error("Out of space");
+ min += stacknleft;
+ min += ALIGN(sizeof(struct stack_block));
+ newlen = 512;
+ while (newlen < min)
+ newlen <<= 1;
oldspace = stacknxt;
oldlen = stacknleft;
@@ -244,6 +252,7 @@ growstackblock(void)
stackp = sp;
stacknxt = SPACE(sp);
stacknleft = newlen - (stacknxt - (char*)sp);
+ sstrend = stacknxt + stacknleft;
/*
* Stack marks pointing to the start of the old block
@@ -258,6 +267,7 @@ growstackblock(void)
}
INTON;
} else {
+ newlen -= ALIGN(sizeof(struct stack_block));
p = stalloc(newlen);
if (oldlen != 0)
memcpy(p, oldspace, oldlen);
@@ -267,16 +277,6 @@ growstackblock(void)
-void
-grabstackblock(int len)
-{
- len = ALIGN(len);
- stacknxt += len;
- stacknleft -= len;
-}
-
-
-
/*
* The following routines are somewhat easier to use that the above.
* The user declares a variable of type STACKSTR, which may be declared
@@ -296,10 +296,9 @@ grabstackblock(int len)
*/
static char *
-growstrstackblock(int n)
+growstrstackblock(int n, int min)
{
- growstackblock();
- sstrnleft = stackblocksize() - n;
+ growstackblock(min);
return stackblock() + n;
}
@@ -309,12 +308,7 @@ growstackstr(void)
int len;
len = stackblocksize();
- if (herefd >= 0 && len >= 1024) {
- xwrite(herefd, stackblock(), len);
- sstrnleft = len;
- return stackblock();
- }
- return growstrstackblock(len);
+ return (growstrstackblock(len, 0));
}
@@ -323,33 +317,21 @@ growstackstr(void)
*/
char *
-makestrspace(void)
+makestrspace(int min, char *p)
{
int len;
- len = stackblocksize() - sstrnleft;
- return growstrstackblock(len);
-}
-
-
-
-void
-ungrabstackstr(char *s, char *p)
-{
- stacknleft += stacknxt - s;
- stacknxt = s;
- sstrnleft = stacknleft - (p - s);
+ len = p - stackblock();
+ return (growstrstackblock(len, min));
}
char *
stputbin(const char *data, int len, char *p)
{
- int i;
-
- for (i = 0; i < len; i++)
- STPUTC(data[i], p);
- return (p);
+ CHECKSTRSPACE(len, p);
+ memcpy(p, data, len);
+ return (p + len);
}
char *
OpenPOWER on IntegriCloud