correct handing of mark-stack overflow in ephemeron processing

svn: r3934
This commit is contained in:
Matthew Flatt 2006-08-02 18:37:21 +00:00
parent 2d7c1f6947
commit 3028094e42
2 changed files with 12 additions and 15 deletions

View File

@ -604,7 +604,11 @@ void GC_mark_from_mark_stack(void)
{ {
MARK_FROM_MARK_STACK(); MARK_FROM_MARK_STACK();
} }
void GC_mark_overflow_recover(void *p)
{
GC_set_mark_bit(p);
while (!GC_mark_some((ptr_t)0));
}
/* /*
* Mark objects pointed to by the regions described by * Mark objects pointed to by the regions described by

View File

@ -1797,10 +1797,12 @@ static Scheme_Ephemeron *ephemerons, *done_ephemerons; /* not registered as a ro
extern void *GC_base(void *d); extern void *GC_base(void *d);
# define GC_is_marked(p) GC_base(p) # define GC_is_marked(p) GC_base(p)
# define GC_did_mark_stack_overflow() 0 # define GC_did_mark_stack_overflow() 0
# define GC_mark_overflow_recover(ptr) /**/
#else #else
extern MZ_DLLIMPORT void *GC_base(void *); extern MZ_DLLIMPORT void *GC_base(void *);
extern MZ_DLLIMPORT int GC_is_marked(void *); extern MZ_DLLIMPORT int GC_is_marked(void *);
extern MZ_DLLIMPORT int GC_did_mark_stack_overflow(void); extern MZ_DLLIMPORT int GC_did_mark_stack_overflow(void);
extern MZ_DLLIMPORT void GC_mark_overflow_recover(void *p);
#endif #endif
extern MZ_DLLIMPORT void GC_push_all_stack(void *, void *); extern MZ_DLLIMPORT void GC_push_all_stack(void *, void *);
extern MZ_DLLIMPORT void GC_flush_mark_stack(void); extern MZ_DLLIMPORT void GC_flush_mark_stack(void);
@ -1842,7 +1844,7 @@ Scheme_Object *scheme_ephemeron_value(Scheme_Object *o)
#ifndef MZ_PRECISE_GC #ifndef MZ_PRECISE_GC
static void set_ephemerons(Scheme_Ephemeron *ae, Scheme_Ephemeron *be, Scheme_Ephemeron *ce, Scheme_Ephemeron *de) static void set_ephemerons(Scheme_Ephemeron *ae, Scheme_Ephemeron *be)
{ {
if (be) { if (be) {
Scheme_Ephemeron *e; Scheme_Ephemeron *e;
@ -1851,12 +1853,7 @@ static void set_ephemerons(Scheme_Ephemeron *ae, Scheme_Ephemeron *be, Scheme_Ep
ae = be; ae = be;
} }
if (ce) ephemerons = ae;
set_ephemerons(ae, ce, de, NULL);
else if (de)
set_ephemerons(ae, de, NULL, NULL);
else
ephemerons = ae;
} }
static int mark_ephemerons() static int mark_ephemerons()
@ -1891,15 +1888,11 @@ static int mark_ephemerons()
ever_done = 1; ever_done = 1;
GC_push_all_stack(&e->val, &e->val + 1); GC_push_all_stack(&e->val, &e->val + 1);
if (GC_did_mark_stack_overflow()) { if (GC_did_mark_stack_overflow()) {
/* printf("mark stack overflow\n"); */ GC_mark_overflow_recover(e->val);
set_ephemerons(ae, be, done_ephemerons, e);
return 0;
} else { } else {
GC_flush_mark_stack(); GC_flush_mark_stack();
if (GC_did_mark_stack_overflow()) { if (GC_did_mark_stack_overflow()) {
/* printf("mark stack overflow (late)\n"); */ GC_mark_overflow_recover(e->val);
set_ephemerons(ae, be, done_ephemerons, e);
return 0;
} }
} }
/* Done with this one: */ /* Done with this one: */
@ -1914,7 +1907,7 @@ static int mark_ephemerons()
} }
/* Combine ae & be back into ephemerons list: */ /* Combine ae & be back into ephemerons list: */
set_ephemerons(ae, be, NULL, NULL); set_ephemerons(ae, be);
} while (did_one); } while (did_one);
return ever_done; return ever_done;