diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2017-07-31 17:42:07 -0700 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2017-07-31 17:42:07 -0700 |
commit | 0bf28ecd2bf99a65d6284b6bc00dc15ca01b93b2 (patch) | |
tree | bcdde754cf051acbc0c67b25fdbbf83409fa549f /gc.c | |
parent | b38e34fdec127166ac1e4a3db47c07c53959c677 (diff) | |
download | txr-0bf28ecd2bf99a65d6284b6bc00dc15ca01b93b2.tar.gz txr-0bf28ecd2bf99a65d6284b6bc00dc15ca01b93b2.tar.bz2 txr-0bf28ecd2bf99a65d6284b6bc00dc15ca01b93b2.zip |
txr-017 2009-10-17txr-017
Note: Version 016 ChangeLog message incorrect.
Diffstat (limited to 'gc.c')
-rw-r--r-- | gc.c | 26 |
1 files changed, 14 insertions, 12 deletions
@@ -180,6 +180,13 @@ static void mark_obj(obj_t *obj) { type_t t; +#if 1 +tail_call: +#define mark_obj_tail(o) do { obj = (o); goto tail_call; } while (0) +#else +#define mark_obj_tail(o) return mark_obj(o) +#endif + if (obj == nil) return; @@ -196,22 +203,19 @@ static void mark_obj(obj_t *obj) switch (t) { case CONS: mark_obj(obj->c.car); - mark_obj(obj->c.cdr); - break; + mark_obj_tail(obj->c.cdr); case STR: - mark_obj(obj->st.len); - break; + mark_obj_tail(obj->st.len); case CHR: case NUM: break; case SYM: mark_obj(obj->s.name); - mark_obj(obj->s.val); - break; + mark_obj_tail(obj->s.val); case FUN: mark_obj(obj->f.env); if (obj->f.functype == FINTERP) - mark_obj(obj->f.f.interp_fun); + mark_obj_tail(obj->f.f.interp_fun); break; case VEC: { @@ -227,15 +231,13 @@ static void mark_obj(obj_t *obj) } break; case LCONS: - mark_obj(obj->lc.car); - mark_obj(obj->lc.cdr); mark_obj(obj->lc.func); - break; + mark_obj(obj->lc.car); + mark_obj_tail(obj->lc.cdr); case COBJ: - mark_obj(obj->co.cls); if (obj->co.ops->mark) obj->co.ops->mark(obj); - break; + mark_obj_tail(obj->co.cls); default: assert (0 && "corrupt type field"); } |