Skip to content

Allocate memory from the parser in "pspace", not GC space #205

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
May 3, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion es.h
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ extern List *sortlist(List *list);

/* tree.c */

extern Tree *mk(NodeKind VARARGS);
extern Tree *gcmk(NodeKind VARARGS); /* gcalloc a tree node */


/* closure.c */
Expand Down Expand Up @@ -404,6 +404,12 @@ extern void gcenable(void); /* enable collections */
extern void gcdisable(void); /* disable collections */
extern Boolean gcisblocked(void); /* is collection disabled? */

/* operations with pspace, the explicitly-collected gc space for parse tree building */
extern void *palloc(size_t n, Tag *t); /* allocate n with collection tag t, but in pspace */
extern void *pseal(void *p); /* collect pspace into gcspace with root p */
extern char *pdup(const char *s); /* copy a 0-terminated string into pspace */
extern char *pndup(const char *s, size_t n); /* copy a counted string into pspace */


/*
* garbage collector tags
Expand Down
169 changes: 156 additions & 13 deletions gc.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,11 @@ struct Space {
#define INSPACE(p, sp) ((sp)->bot <= (char *) (p) && (char *) (p) < (sp)->top)

#define MIN_minspace 10000
#define MIN_minpspace 1000

#if GCPROTECT
#define NSPACES 10
#define NSPACES 12
#define FIRSTSPACE 1
#endif

#if HAVE_SYSCONF
Expand All @@ -38,12 +40,13 @@ int gcblocked = 0;
Tag StringTag;

/* own variables */
static Space *new, *old;
static Space *new, *old, *pspace;
#if GCPROTECT
static Space *spaces;
#endif
static Root *globalrootlist, *exceptionrootlist;
static size_t minspace = MIN_minspace; /* minimum number of bytes in a new space */
static size_t minpspace = MIN_minpspace;


/*
Expand Down Expand Up @@ -136,14 +139,15 @@ static void initmmu(void) {
#if GCPROTECT

/* mkspace -- create a new ``half'' space in debugging mode */
static Space *mkspace(Space *space, Space *next) {
static Space *mkspace(Space *space, Space *next, size_t size) {
assert(space == NULL || (&spaces[0] <= space && space < &spaces[NSPACES]));

/* find and clear out any existing/next spaces */
if (space != NULL) {
Space *sp;
if (space->bot == NULL)
sp = NULL;
else if ((size_t) SPACESIZE(space) < minspace)
else if ((size_t) SPACESIZE(space) < size)
sp = space;
else {
sp = space->next;
Expand All @@ -160,12 +164,13 @@ static Space *mkspace(Space *space, Space *next) {
}
}

/* build new space (or set up existing &space[n]) */
if (space == NULL) {
space = ealloc(sizeof (Space));
memzero(space, sizeof (Space));
}
if (space->bot == NULL) {
size_t n = PAGEROUND(minspace);
size_t n = PAGEROUND(size);
space->bot = take(n);
space->top = space->bot + n / (sizeof (*space->bot));
}
Expand All @@ -175,20 +180,23 @@ static Space *mkspace(Space *space, Space *next) {

return space;
}
#define newspace(next) mkspace(NULL, next)
#define newspace(next) mkspace(NULL, next, minspace)
#define newpspace(next) mkspace(NULL, next, minpspace)

#else /* !GCPROTECT */

/* newspace -- create a new ``half'' space */
static Space *newspace(Space *next) {
size_t n = ALIGN(minspace);
static Space *newspacesz(Space *next, size_t size) {
size_t n = ALIGN(size);
Space *space = ealloc(sizeof (Space) + n);
space->bot = (void *) &space[1];
space->top = (void *) (((char *) space->bot) + n);
space->current = space->bot;
space->next = next;
return space;
}
#define newspace(next) newspacesz(next, minspace)
#define newpspace(next) newspacesz(next, minpspace)

#endif /* !GCPROTECT */

Expand Down Expand Up @@ -273,12 +281,20 @@ extern void exceptionunroot(void) {
#define FOLLOWTO(p) ((Tag *) (((char *) p) + 1))
#define FOLLOW(tagp) ((void *) (((char *) tagp) - 1))

/* TODO: remove pmode: it's the Wrong Thing */
static Boolean pmode = FALSE;

/* forward -- forward an individual pointer from old space */
extern void *forward(void *p) {
Tag *tag;
void *np;

if (!isinspace(old, p)) {
if (pmode && !isinspace(pspace, p)) {
VERBOSE(("GC %8ux : <<not in pspace>>\n", p));
return p;
}

if (!pmode && !isinspace(old, p)) {
VERBOSE(("GC %8ux : <<not in old space>>\n", p));
return p;
}
Expand All @@ -297,6 +313,12 @@ extern void *forward(void *p) {
VERBOSE(("%s -> %8ux (forwarded)\n", tag->typename, np));
TAG(p) = FOLLOWTO(np);
}

if (pmode) {
tag = TAG(np);
(*tag->scan)(np);
}

return np;
}

Expand Down Expand Up @@ -395,8 +417,8 @@ extern void gc(void) {
for (; new->next != NULL; new = new->next)
;
if (++new >= &spaces[NSPACES])
new = &spaces[0];
new = mkspace(new, NULL);
new = &spaces[FIRSTSPACE];
new = mkspace(new, NULL, minspace);
#else
new = newspace(NULL);
#endif
Expand Down Expand Up @@ -425,7 +447,7 @@ extern void gc(void) {
#if GCINFO
if (gcinfo)
eprint(
"[GC: old %8d live %8d min %8d (pid %5d)]\n",
"[ GC: old %8d live %8d min %8d (pid %5d)]\n",
olddata, livedata, minspace, getpid()
);
#endif
Expand All @@ -439,15 +461,91 @@ extern void gc(void) {
} while (new->next != NULL);
}

/* pseal -- collect pspace to new with p as its only root, and return the collected p */
extern void *pseal(void *p) {
size_t psize = 0;
Space *sp;
#if GCINFO
size_t newdata = 0, livedata = 0;
#endif
#if GCPROTECT
Space *base;
#endif

for (sp = pspace; sp != NULL; sp = sp->next)
psize += SPACEUSED(sp);

if (psize == 0)
return p;

/* TODO: this is an overestimate since it counts garbage */
gcreserve(psize);
VERBOSE(("Reserved %d for pspace copy\n", psize));

#if GCINFO
if (gcinfo)
for (sp = new; sp != NULL; sp = sp->next)
newdata += SPACEUSED(sp);
#endif

assert (gcblocked >= 0);
++gcblocked;

#if GCVERBOSE
for (sp = pspace; sp != NULL; sp = sp->next)
VERBOSE(("GC pspace = %ux ... %ux\n", sp->bot, sp->current));
#endif
if (p != NULL) {
VERBOSE(("GC new space = %ux ... %ux\n", new->bot, new->top));

pmode = TRUE;
p = forward(p);
(*(TAG(p))->scan)(p);
pmode = FALSE;
}

#if GCINFO
if (gcinfo) {
for (sp = new; sp != NULL; sp = sp->next)
livedata += SPACEUSED(sp);
eprint(
"[pseal: old %8d live %8d min %8d diff %5d (pid %5d)]\n",
psize, livedata, minpspace, (livedata - newdata), getpid()
);
}
#endif

if (psize > minpspace)
minpspace = psize * 2;
else if (psize < minpspace / 2 && MIN_minpspace <= minpspace / 2)
minpspace /= 2;

#if GCPROTECT
for (base = pspace; base->next != NULL; base = base->next)
;
#endif
deprecate(pspace);
#if GCPROTECT
pspace = mkspace(base, NULL, minpspace);
#else
pspace = newpspace(NULL);
#endif

--gcblocked;
return p;
}

/* initgc -- initialize the garbage collector */
extern void initgc(void) {
#if GCPROTECT
initmmu();
spaces = ealloc(NSPACES * sizeof (Space));
memzero(spaces, NSPACES * sizeof (Space));
new = mkspace(&spaces[0], NULL);
new = mkspace(&spaces[FIRSTSPACE], NULL, minspace);
pspace = mkspace(&spaces[0], NULL, minpspace);
#else
new = newspace(NULL);
pspace = newpspace(NULL);
#endif
old = NULL;
}
Expand Down Expand Up @@ -481,6 +579,24 @@ extern void *gcalloc(size_t nbytes, Tag *tag) {
}
}

/* palloc -- allocate an object in pspace */
extern void *palloc(size_t nbytes, Tag *tag) {
size_t n = ALIGN(nbytes + sizeof (Tag *));
assert(tag == NULL || tag->magic == TAGMAGIC);
for (;;) {
Tag **p = (void *) pspace->current;
char *q = ((char *) p) + n;
if (q <= pspace->top) {
pspace->current = q;
*p++ = tag;
return p;
}
if (minpspace < nbytes)
minpspace = nbytes + sizeof (Tag *);
pspace = newpspace(pspace);
}
}


/*
* strings
Expand All @@ -503,10 +619,25 @@ extern char *gcndup(const char *s, size_t n) {
RefReturn(result);
}

extern char *pndup(const char *s, size_t n) {
char *ns;

ns = palloc((n + 1) * sizeof (char), &StringTag);
memcpy(ns, s, n);
ns[n] = '\0';
assert(strlen(ns) == n);

return ns;
}

extern char *gcdup(const char *s) {
return gcndup(s, strlen(s));
}

extern char *pdup(const char *s) {
return pndup(s, strlen(s));
}

static void *StringCopy(void *op) {
size_t n = strlen(op) + 1;
char *np = gcalloc(n, &StringTag);
Expand Down Expand Up @@ -547,12 +678,24 @@ extern char *sealbuffer(Buffer *buf) {
return s;
}

extern char *psealbuffer(Buffer *buf) {
char *s = pdup(buf->str);
efree(buf);
return s;
}

extern char *sealcountedbuffer(Buffer *buf) {
char *s = gcndup(buf->str, buf->current);
efree(buf);
return s;
}

extern char *psealcountedbuffer(Buffer *buf) {
char *s = pndup(buf->str, buf->current);
efree(buf);
return s;
}

extern Buffer *bufncat(Buffer *buf, const char *s, size_t len) {
while (buf->current + len >= buf->len)
buf = expandbuffer(buf, buf->current + len - buf->len);
Expand Down
2 changes: 2 additions & 0 deletions gc.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@ extern Buffer *bufcat(Buffer *buf, const char *s);
extern Buffer *bufputc(Buffer *buf, char c);
extern char *sealbuffer(Buffer *buf);
extern char *sealcountedbuffer(Buffer *buf);
extern char *psealbuffer(Buffer *buf); /* pspace variant of sealbuffer */
extern char *psealcountedbuffer(Buffer *buf); /* pspace variant of sealcountedbuffer */
extern void freebuffer(Buffer *buf);

extern void *forward(void *p);
8 changes: 4 additions & 4 deletions heredoc.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ extern Tree *getherevar(void) {
while ((c = GETC()) != EOF && !dnw[c])
buf = bufputc(buf, c);
len = buf->len;
s = sealcountedbuffer(buf);
s = psealcountedbuffer(buf);
if (len == 0) {
yyerror("null variable name in here document");
return NULL;
Expand Down Expand Up @@ -54,7 +54,7 @@ extern Tree *snarfheredoc(const char *eof, Boolean quoted) {
if (buf->current == 0 && tree != NULL)
freebuffer(buf);
else
*tailp = treecons(mk(nQword, sealcountedbuffer(buf)), NULL);
*tailp = treecons(mk(nQword, psealcountedbuffer(buf)), NULL);
break;
}
if (s != (unsigned char *) eof)
Expand All @@ -72,7 +72,7 @@ extern Tree *snarfheredoc(const char *eof, Boolean quoted) {
if (buf->current == 0)
freebuffer(buf);
else {
*tailp = treecons(mk(nQword, sealcountedbuffer(buf)), NULL);
*tailp = treecons(mk(nQword, psealcountedbuffer(buf)), NULL);
tailp = &(*tailp)->CDR;
}
var = getherevar();
Expand Down Expand Up @@ -133,7 +133,7 @@ extern Boolean queueheredoc(Tree *t) {
return FALSE;
}

here = gcalloc(sizeof (Here), NULL);
here = palloc(sizeof (Here), NULL);
here->next = hereq;
here->marker = eof;
hereq = here;
Expand Down
Loading