From: Dmitry Antipov <dmantipov@yandex.ru>
To: emacs-devel@gnu.org
Subject: Finding objects on C stack - alternate GCPRO
Date: Wed, 16 Nov 2011 14:07:46 +0400 [thread overview]
Message-ID: <4EC38B72.1000101@yandex.ru> (raw)
[-- Attachment #1: Type: text/plain, Size: 926 bytes --]
Everyone agrees that GGPROs are ugly and painful. On the other side,
current C stack marking code introduces substantial overhead by
maintaining red-black tree. And, since C stack marking is
conservative, it becomes very tricky to implement GC that may
relocate live objects (copying or compacting approach).
But there is another method to implement GCPROs. It looks not very
portable beyond GNU C since it uses __attribute__ ((cleanup (function)))
and compound statement expressions C extensions. But it doesn't
require UNGCPRO and dumbs like 'struct gcpro gcpro1, struct gcpro2, ...'.
And I believe it should work across longjmps.
This idea is briefly illustrated by an attached example. As for the
Emacs, it would be enough to declare every local Lisp_Object which
should survive the GC with the stuff like FOOPTR from this example,
and we're ready for exact C stack marking with (hopefully) very small
overhead.
Dmitry
[-- Attachment #2: cleanup.c --]
[-- Type: text/plain, Size: 1906 bytes --]
#include <stdio.h>
#include <stdlib.h>
typedef struct {
int x;
int y;
} foo_t;
typedef struct gcpro {
void *addr;
struct gcpro *next;
} gcpro_t;
gcpro_t *foo_root;
static foo_t * foo_add (gcpro_t *fl, void *fooaddr)
{
/* printf ("New local var at %p\n", fooaddr); */
fl->addr = fooaddr;
fl->next = foo_root;
foo_root = fl;
return NULL;
}
static void foo_remove (void *fooaddr)
{
/* printf ("Drop local var at %p\n", fooaddr); */
if (fooaddr != foo_root->addr)
abort ();
foo_root = foo_root->next;
}
#define FOOPTR(name) \
foo_t __attribute__ ((cleanup (foo_remove))) *name = \
({ gcpro_t *fl = alloca (sizeof (gcpro_t)); foo_add (fl, &name); })
void gc (int locals)
{
gcpro_t *fl;
/* We should print addresses of all live
locals defined with FOOPTR. */
printf ("In GC, expect %d locals at:\n", locals);
for (fl = foo_root; fl; fl = fl->next)
printf (" %p\n", fl->addr);
printf ("GC end\n");
}
int foofun (foo_t *f1, foo_t *f2)
{
FOOPTR (fooptr3);
int ret;
printf ("In foofun, local var at %p\n", &fooptr3);
fooptr3 = malloc (sizeof *fooptr3);
fooptr3->x = f1->x + f2->x;
fooptr3->y = f1->y - f2->y;
if (fooptr3->x > 0)
{
FOOPTR (fooptr4);
printf ("In foofun, inner local var at %p\n", &fooptr4);
gc (4); /* Here we expect 4 fooptrs on C stack. */
}
ret = fooptr3->x + fooptr3->y;
free (fooptr3);
return ret;
}
int main (int argc, char *argv[])
{
FOOPTR (fooptr1);
FOOPTR (fooptr2);
int val;
printf ("In main, local vars at %p and %p\n", &fooptr1, &fooptr2);
fooptr1 = malloc (sizeof *fooptr1);
fooptr1->x = argc;
fooptr1->y = argc + 1;
fooptr2 = malloc (sizeof *fooptr2);
fooptr2->x = argc * 2;
fooptr2->y = argc * 2 + 1;
val = foofun (fooptr1, fooptr2);
free (fooptr1);
free (fooptr2);
gc (2); /* Here we expect 2 fooptrs on C stack. */
return val;
}
next reply other threads:[~2011-11-16 10:07 UTC|newest]
Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top
2011-11-16 10:07 Dmitry Antipov [this message]
2011-11-16 10:18 ` Finding objects on C stack - alternate GCPRO Helmut Eller
2011-11-16 10:33 ` Dmitry Antipov
2011-11-16 23:27 ` Richard Stallman
2011-11-17 4:17 ` Stephen J. Turnbull
2011-11-17 19:12 ` Richard Stallman
2011-11-16 11:06 ` Eli Zaretskii
2011-11-17 12:50 ` Stephen Berman
2011-11-17 16:50 ` Eli Zaretskii
2011-11-16 14:41 ` Stefan Monnier
2011-11-16 18:19 ` Tom Tromey
2011-11-16 21:07 ` Ken Raeburn
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=4EC38B72.1000101@yandex.ru \
--to=dmantipov@yandex.ru \
--cc=emacs-devel@gnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this external index
https://git.savannah.gnu.org/cgit/emacs.git
https://git.savannah.gnu.org/cgit/emacs/org-mode.git
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.