Okay, after some major changes, here's the second revision of my patch.
This one is fully functional.
On my system, it creates over a 10x speedup for lazy DOD runs!
(I'll post the benchmark program if someone wants; it's pretty long)
Luke
Index: core.ops
===================================================================
RCS file: /cvs/public/parrot/core.ops,v
retrieving revision 1.324
diff -u -r1.324 core.ops
--- core.ops 29 Aug 2003 11:30:17 -0000 1.324
+++ core.ops 10 Sep 2003 04:37:06 -0000
@@ -837,8 +837,11 @@
=cut
op sweep(inconst INT) {
- if ($1 || interpreter->has_early_DOD_PMCs)
+ if ($1)
Parrot_do_dod_run(interpreter, 0);
+ else
+ if (interpreter->num_early_DOD_PMCs)
+ Parrot_do_dod_run(interpreter, DOD_lazy_FLAG);
goto NEXT();
}
@@ -906,8 +909,8 @@
op needs_destroy(in PMC) {
PObj_needs_early_DOD_SET($1);
- interpreter->has_early_DOD_PMCs = 1;
- goto NEXT();
+ interpreter->num_early_DOD_PMCs++;
+ goto NEXT();
}
=back
Index: dod.c
===================================================================
RCS file: /cvs/public/parrot/dod.c,v
retrieving revision 1.70
diff -u -r1.70 dod.c
--- dod.c 28 Aug 2003 16:56:15 -0000 1.70
+++ dod.c 10 Sep 2003 04:37:06 -0000
@@ -31,7 +31,7 @@
#endif
static size_t find_common_mask(size_t val1, size_t val2);
-static void trace_children(struct Parrot_Interp *interpreter, PMC *current);
+static int trace_children(struct Parrot_Interp *interpreter, PMC *current);
#if ARENA_DOD_FLAGS
@@ -43,23 +43,49 @@
size_t ns = n >> ARENA_FLAG_SHIFT;
UINTVAL nm = (n & ARENA_FLAG_MASK) << 2;
UINTVAL *dod_flags = arena->dod_flags + ns;
- if (*dod_flags & ((PObj_on_free_list_FLAG | PObj_live_FLAG) << nm))
+
+ if (*dod_flags & PObj_on_free_list_FLAG << nm)
+ return;
+ if (PObj_high_priority_DOD_TEST(obj) && interpreter->dod_trace_ptr)
+ /* set obj's parent to high priority */
+ PObj_high_priority_DOD_SET(interpreter->dod_trace_ptr);
+ if (*dod_flags & PObj_live_FLAG << nm)
return;
++arena->live_objects;
*dod_flags |= PObj_live_FLAG << nm;
+ if (PObj_needs_early_DOD_TEST(obj))
+ ++interpreter->DOD_early_PMCs_seen;
+
if (*dod_flags & (PObj_is_special_PMC_FLAG << nm)) {
if (((PMC*)obj)->pmc_ext) {
- /* put it on the end of the list */
- interpreter->mark_ptr->next_for_GC = (PMC *)obj;
+ if (PObj_high_priority_DOD_TEST(obj)
+ && interpreter->dod_trace_ptr) {
+ PMC* tptr = interpreter->dod_trace_ptr;
+ /* Ugh, we have to check for self reference, otherwise
+ * we get a nasty circular loop. But, since whenever
+ * this block is executed, we're getting a nice
+ * optimization, I figure it's okay */
+ if (tptr->next_for_GC == tptr) {
+ ((PMC*)obj)->next_for_GC = (PMC*)obj;
+ }
+ else {
+ /* put it at the head of the list */
+ ((PMC*)obj)->next_for_GC = tptr->next_for_GC;
+ }
+ interpreter->dod_trace_ptr->next_for_GC = (PMC*)obj;
+ }
+ else {
+ /* put it on the end of the list */
+ interpreter->dod_mark_ptr->next_for_GC = (PMC *)obj;
- /* Explicitly make the tail of the linked list be
- * self-referential */
- interpreter->mark_ptr = ((PMC*)obj)->next_for_GC = (PMC *)obj;
+ /* Explicitly make the tail of the linked list be
+ * self-referential */
+ interpreter->dod_mark_ptr = ((PMC*)obj)->next_for_GC = (PMC *)obj;
+ }
}
else if (PObj_custom_mark_TEST(obj))
VTABLE_mark(interpreter, (PMC *) obj);
- return;
}
}
@@ -84,23 +110,42 @@
}
# endif
#endif
+ if (PObj_high_priority_DOD_TEST(obj) && interpreter->dod_trace_ptr)
+ PObj_high_priority_DOD_SET(interpreter->dod_trace_ptr);
/* mark it live */
PObj_live_SET(obj);
/* if object is a PMC and contains buffers or PMCs, then attach
* the PMC to the chained mark list
*/
- if (PObj_is_special_PMC_TEST(obj)) {
+ if (*dod_flags & (PObj_is_special_PMC_FLAG << nm)) {
if (((PMC*)obj)->pmc_ext) {
- /* put it on the end of the list */
- interpreter->mark_ptr->next_for_GC = (PMC *)obj;
+ if (PObj_high_priority_DOD_TEST(obj)
+ && interpreter->dod_trace_ptr) {
+ PMC* tptr = interpreter->dod_trace_ptr;
+ /* Ugh, we have to check for self reference, otherwise
+ * we get a nasty circular loop. But, since whenever
+ * this block is executed, we're getting a nice
+ * optimization, I figure it's okay */
+ if (tptr->next_for_GC == tptr) {
+ ((PMC*)obj)->next_for_GC = (PMC*)obj;
+ }
+ else {
+ /* put it at the head of the list */
+ ((PMC*)obj)->next_for_GC = tptr->next_for_GC;
+ }
+ interpreter->dod_trace_ptr->next_for_GC = (PMC*)obj;
+ }
+ else {
+ /* put it on the end of the list */
+ interpreter->dod_mark_ptr->next_for_GC = (PMC *)obj;
- /* Explicitly make the tail of the linked list be
- * self-referential */
- interpreter->mark_ptr = ((PMC*)obj)->next_for_GC = (PMC *)obj;
+ /* Explicitly make the tail of the linked list be
+ * self-referential */
+ interpreter->dod_mark_ptr = ((PMC*)obj)->next_for_GC = (PMC *)obj;
+ }
}
else if (PObj_custom_mark_TEST(obj))
VTABLE_mark(interpreter, (PMC *) obj);
- return;
}
#if GC_VERBOSE
/* buffer GC_DEBUG stuff */
@@ -117,8 +162,10 @@
#endif
-/* Do a full trace run and mark all the PMCs as active if they are */
-static void
+/* Do a full trace run and mark all the PMCs as active if they are.
+ * Returns whether the run wasn't aborted (whether it is safe to
+ * proceed with GC) */
+static int
trace_active_PMCs(struct Parrot_Interp *interpreter, int trace_stack)
{
PMC *current;
@@ -134,7 +181,7 @@
struct Stash *stash = 0;
/* We have to start somewhere, the interpreter globals is a good place */
- interpreter->mark_ptr = current = interpreter->iglobals;
+ interpreter->dod_mark_ptr = current = interpreter->iglobals;
/* mark it as used */
pobject_lives(interpreter, (PObj *)interpreter->iglobals);
@@ -194,20 +241,30 @@
#endif
/* Okay, we've marked the whole root set, and should have a good-sized
* list 'o things to look at. Run through it */
- trace_children(interpreter, current);
+ return trace_children(interpreter, current);
}
-static void
+/* Returns whether the process wasn't aborted. */
+static int
trace_children(struct Parrot_Interp *interpreter, PMC *current)
{
PMC *prev = NULL;
unsigned i = 0;
UINTVAL mask = PObj_is_PMC_ptr_FLAG | PObj_is_buffer_ptr_FLAG
| PObj_custom_mark_FLAG;
-
+ int lazy_dod = interpreter->lazy_dod;
+
for (; current != prev; current = current->next_for_GC) {
UINTVAL bits = PObj_get_FLAGS(current) & mask;
+ if (lazy_dod &&
+ interpreter->DOD_early_PMCs_seen >= interpreter->num_early_DOD_PMCs) {
+ return 0;
+ }
+ interpreter->dod_trace_ptr = current;
+ if (!PObj_needs_early_DOD_TEST(current))
+ PObj_high_priority_DOD_CLEAR(current);
+
/* mark properties */
if (current->metadata) {
pobject_lives(interpreter, (PObj *)current->metadata);
@@ -250,6 +307,7 @@
prev = current;
}
+ return 1;
}
/* Scan any buffers in S registers and other non-PMC places and mark
@@ -453,9 +511,6 @@
UINTVAL free_arenas = 0, old_total_used = 0;
#endif
- /* We have no impatient things. Yet. */
- interpreter->has_early_DOD_PMCs = 0;
-
/* Run through all the buffer header pools and mark */
for (cur_arena = pool->last_Arena;
NULL != cur_arena; cur_arena = cur_arena->prev) {
@@ -497,13 +552,8 @@
{
/* its live */
total_used++;
-#if ARENA_DOD_FLAGS
- if ((*dod_flags & (PObj_needs_early_DOD_FLAG << nm)))
- interpreter->has_early_DOD_PMCs = 1;
-#else
+#if !ARENA_DOD_FLAGS
PObj_live_CLEAR(b);
- if (PObj_needs_early_DOD_TEST(b))
- interpreter->has_early_DOD_PMCs = 1;
#endif
}
else {
@@ -517,6 +567,8 @@
if (PObj_is_PMC_TEST(b)) {
/* then destroy it here
*/
+ if (PObj_high_priority_DOD_TEST(b))
+ --interpreter->num_early_DOD_PMCs;
if (PObj_active_destroy_TEST(b))
VTABLE_destroy(interpreter, (PMC *)b);
@@ -699,7 +751,7 @@
/* See if we can find some unused headers */
void
-Parrot_do_dod_run(struct Parrot_Interp *interpreter, int trace_stack)
+Parrot_do_dod_run(struct Parrot_Interp *interpreter, UINTVAL flags)
{
struct Small_Object_Pool *header_pool;
int j;
@@ -711,6 +763,8 @@
}
Parrot_block_DOD(interpreter);
+ interpreter->lazy_dod = flags & DOD_lazy_FLAG;
+ interpreter->dod_trace_ptr = NULL;
#if ARENA_DOD_FLAGS
clear_live_counter(interpreter, interpreter->arena_base->pmc_pool);
for (j = 0; j < (INTVAL)interpreter->arena_base->num_sized; j++) {
@@ -720,49 +774,51 @@
}
#endif
/* Now go trace the PMCs */
- trace_active_PMCs(interpreter, trace_stack);
+ if (trace_active_PMCs(interpreter, flags & DOD_trace_stack_FLAG)) {
- /* And the buffers */
- trace_active_buffers(interpreter);
+ /* And the buffers */
+ trace_active_buffers(interpreter);
#if !TRACE_SYSTEM_AREAS
# if GC_VERBOSE
- /* whe, we don't trace stack and registers, we check after
- * marking everything, if something was missed
- * not - these could also be stale objects
- */
- if (trace_stack) {
+ /* whe, we don't trace stack and registers, we check after
+ * marking everything, if something was missed
+ * not - these could also be stale objects
+ */
+ if (flags & DOD_trace_stack_FLAG) {
# if ! DISABLE_GC_DEBUG
- CONSERVATIVE_POINTER_CHASING = 1;
+ CONSERVATIVE_POINTER_CHASING = 1;
# endif
- trace_system_areas(interpreter);
+ trace_system_areas(interpreter);
# if ! DISABLE_GC_DEBUG
- CONSERVATIVE_POINTER_CHASING = 0;
+ CONSERVATIVE_POINTER_CHASING = 0;
# endif
- }
+ }
# endif
#endif
- /* Now put unused PMCs on the free list */
- header_pool = interpreter->arena_base->pmc_pool;
- free_unused_pobjects(interpreter, header_pool);
- total_free += header_pool->num_free_objects;
-
- /* And unused buffers on the free list */
- for (j = 0; j < (INTVAL)interpreter->arena_base->num_sized; j++) {
- header_pool = interpreter->arena_base->sized_header_pools[j];
- if (header_pool) {
+ /* Now put unused PMCs on the free list */
+ header_pool = interpreter->arena_base->pmc_pool;
+ free_unused_pobjects(interpreter, header_pool);
+ total_free += header_pool->num_free_objects;
+
+ /* And unused buffers on the free list */
+ for (j = 0; j < (INTVAL)interpreter->arena_base->num_sized; j++) {
+ header_pool = interpreter->arena_base->sized_header_pools[j];
+ if (header_pool) {
#ifdef GC_IS_MALLOC
- used_cow(interpreter, header_pool, 0);
+ used_cow(interpreter, header_pool, 0);
#endif
- free_unused_pobjects(interpreter, header_pool);
- total_free += header_pool->num_free_objects;
+ free_unused_pobjects(interpreter, header_pool);
+ total_free += header_pool->num_free_objects;
#ifdef GC_IS_MALLOC
- clear_cow(interpreter, header_pool, 0);
+ clear_cow(interpreter, header_pool, 0);
#endif
+ }
}
}
/* Note it */
interpreter->dod_runs++;
+ interpreter->dod_trace_ptr = NULL;
Parrot_unblock_DOD(interpreter);
return;
}
Index: interpreter.c
===================================================================
RCS file: /cvs/public/parrot/interpreter.c,v
retrieving revision 1.199
diff -u -r1.199 interpreter.c
--- interpreter.c 28 Aug 2003 15:26:21 -0000 1.199
+++ interpreter.c 10 Sep 2003 04:37:06 -0000
@@ -865,7 +865,7 @@
*/
Parrot_IOData_mark(interpreter, interpreter->piodata);
- if (interpreter->has_early_DOD_PMCs)
+ if (interpreter->num_early_DOD_PMCs)
free_unused_pobjects(interpreter, interpreter->arena_base->pmc_pool);
/* we destroy all child interpreters and the last one too,
@@ -1006,6 +1006,9 @@
break;
case TOTAL_COPIED:
ret = interpreter->memory_collected;
+ break;
+ case IMPATIENT_PMCS:
+ ret = interpreter->num_early_DOD_PMCs;
break;
}
return ret;
Index: resources.c
===================================================================
RCS file: /cvs/public/parrot/resources.c,v
retrieving revision 1.108
diff -u -r1.108 resources.c
--- resources.c 28 Jul 2003 13:37:55 -0000 1.108
+++ resources.c 10 Sep 2003 04:37:07 -0000
@@ -106,13 +106,13 @@
interpreter->mem_allocs_since_last_collect++;
}
if (0 && GC_DEBUG(interpreter)) {
- Parrot_do_dod_run(interpreter, 1);
+ Parrot_do_dod_run(interpreter, DOD_trace_stack_FLAG);
if (pool->compact) {
(*pool->compact) (interpreter, pool);
}
}
if (pool->top_block->free < size) {
- Parrot_do_dod_run(interpreter, 1);
+ Parrot_do_dod_run(interpreter, DOD_trace_stack_FLAG);
/* Compact the pool if allowed and worthwhile */
if (pool->compact) {
/* don't bother reclaiming if it's just chicken feed */
Index: smallobject.c
===================================================================
RCS file: /cvs/public/parrot/smallobject.c,v
retrieving revision 1.26
diff -u -r1.26 smallobject.c
--- smallobject.c 26 Aug 2003 10:05:44 -0000 1.26
+++ smallobject.c 10 Sep 2003 04:37:07 -0000
@@ -68,7 +68,7 @@
if (pool->skip)
pool->skip = 0;
else {
- Parrot_do_dod_run(interpreter, 1);
+ Parrot_do_dod_run(interpreter, DOD_trace_stack_FLAG);
if (pool->num_free_objects <= pool->replenish_level)
pool->skip = 1;
}
Index: string.c
===================================================================
RCS file: /cvs/public/parrot/string.c,v
retrieving revision 1.143
diff -u -r1.143 string.c
--- string.c 27 Aug 2003 16:27:28 -0000 1.143
+++ string.c 10 Sep 2003 04:37:07 -0000
@@ -943,7 +943,7 @@
/* It's easy to forget that string comparison can trigger GC */
if (interpreter && GC_DEBUG(interpreter))
- Parrot_do_dod_run(interpreter, 1);
+ Parrot_do_dod_run(interpreter, DOD_trace_stack_FLAG);
if (s1->type != s2->type || s1->encoding != s2->encoding) {
s1 = string_transcode(interpreter, s1, NULL, string_unicode_type,
@@ -1018,7 +1018,7 @@
/* trigger GC for debug */
if (interpreter && GC_DEBUG(interpreter))
- Parrot_do_dod_run(interpreter, 1);
+ Parrot_do_dod_run(interpreter, DOD_trace_stack_FLAG);
if (s1->type != s2->type || s1->encoding != s2->encoding) {
s1 = string_transcode(interpreter, s1, NULL, string_unicode_type,
@@ -1080,7 +1080,7 @@
/* trigger GC for debug */
if (interpreter && GC_DEBUG(interpreter))
- Parrot_do_dod_run(interpreter, 1);
+ Parrot_do_dod_run(interpreter, DOD_trace_stack_FLAG);
if (s1 && s2) {
if (s1->type != s2->type || s1->encoding != s2->encoding) {
@@ -1162,7 +1162,7 @@
/* trigger GC for debug */
if (interpreter && GC_DEBUG(interpreter))
- Parrot_do_dod_run(interpreter, 1);
+ Parrot_do_dod_run(interpreter, DOD_trace_stack_FLAG);
if (s1 && s2) {
if (s1->type != s2->type || s1->encoding != s2->encoding) {
Index: classes/timer.pmc
===================================================================
RCS file: /cvs/public/parrot/classes/timer.pmc,v
retrieving revision 1.7
diff -u -r1.7 timer.pmc
--- classes/timer.pmc 25 Aug 2003 09:46:23 -0000 1.7
+++ classes/timer.pmc 10 Sep 2003 04:37:07 -0000
@@ -253,7 +253,7 @@
t->self = SELF;
SELF->cache.struct_val = t;
PObj_active_destroy_SET(SELF);
- interpreter->has_early_DOD_PMCs = 1;
+ interpreter->num_early_DOD_PMCs++;
}
void init_pmc(PMC *init) {
Index: include/parrot/dod.h
===================================================================
RCS file: /cvs/public/parrot/include/parrot/dod.h,v
retrieving revision 1.11
diff -u -r1.11 dod.h
--- include/parrot/dod.h 28 Jul 2003 13:38:00 -0000 1.11
+++ include/parrot/dod.h 10 Sep 2003 04:37:07 -0000
@@ -40,7 +40,12 @@
#define Parrot_is_blocked_GC(interpreter) \
((interpreter)->GC_block_level)
-void Parrot_do_dod_run(struct Parrot_Interp *, int trace_stack);
+enum {
+ DOD_trace_stack_FLAG = 1 << 0,
+ DOD_lazy_FLAG = 1 << 1
+};
+
+void Parrot_do_dod_run(struct Parrot_Interp *, UINTVAL flags);
void trace_system_areas(struct Parrot_Interp *);
void trace_mem_block(struct Parrot_Interp *, size_t, size_t);
Index: include/parrot/interpreter.h
===================================================================
RCS file: /cvs/public/parrot/include/parrot/interpreter.h,v
retrieving revision 1.85
diff -u -r1.85 interpreter.h
--- include/parrot/interpreter.h 28 Aug 2003 15:26:24 -0000 1.85
+++ include/parrot/interpreter.h 10 Sep 2003 04:37:07 -0000
@@ -188,14 +188,19 @@
/* per interpreter global vars */
INTVAL world_inited; /* Parrot_init is done */
- PMC *mark_ptr; /* last PMC marked used in DOD runs */
PMC *iglobals; /* SArray of PMCs, containing: */
/* 0: PMC *Parrot_base_classname_hash; hash containing name->base_type */
/* 1: PMC *Parrot_compreg_hash; hash containing assembler/compilers */
/* 2: PMC *Argv; list of argv */
/* 3: PMC *Env; hash_like Env PMC */
/* 4: PMC *ParrotInterpreter that's me */
- int has_early_DOD_PMCs; /* Flag that some want immediate destruction */
+ UINTVAL num_early_DOD_PMCs; /* how many want immediate destruction */
+ UINTVAL DOD_early_PMCs_seen; /* how many that want immediate destruction
+ * has DOD seen */
+ PMC *dod_mark_ptr; /* last PMC marked used in DOD runs */
+ PMC *dod_trace_ptr; /* last PMC trace_children was called on */
+ int lazy_dod; /* flag indicating whether we should stop
+ when we find all impatient pmcs */
} Interp;
/* &gen_from_enum(iglobals.pasm) */
Index: include/parrot/pobj.h
===================================================================
RCS file: /cvs/public/parrot/include/parrot/pobj.h,v
retrieving revision 1.28
diff -u -r1.28 pobj.h
--- include/parrot/pobj.h 28 Aug 2003 13:44:25 -0000 1.28
+++ include/parrot/pobj.h 10 Sep 2003 04:37:07 -0000
@@ -198,7 +198,7 @@
PObj_active_destroy_FLAG = 1 << 22,
/* For debugging, report when this buffer gets moved around */
PObj_report_FLAG = 1 << 23,
-
+
/* PMC specific FLAGs */
/* Set to true if the PMC data pointer points to something that
@@ -218,12 +218,14 @@
*/
b_PObj_is_special_PMC_FLAG = 1 << 26,
- b_PObj_needs_early_DOD_FLAG = 1 << 27,
+ /* This PObj is connected by some route to a "needs_early_DOD" object */
+ PObj_high_priority_DOD_FLAG = 1 << 27,
+ PObj_needs_early_DOD_FLAG = (1 << 27 | 1 << 28),
/* True if the PMC is a class */
- PObj_is_class_FLAG = 1 << 28,
+ PObj_is_class_FLAG = 1 << 29,
/* True if the PMC is a parrot object */
- PObj_is_object_FLAG = 1 << 29
+ PObj_is_object_FLAG = 1 << 30
} PObj_flags;
@@ -240,7 +242,6 @@
# define d_PObj_live_FLAG 0x01
# define d_PObj_on_free_list_FLAG 0x02
# define d_PObj_is_special_PMC_FLAG 0x04
-# define d_PObj_needs_early_DOD_FLAG 0x08
/*
* arenas are constant sized ~32 byte object size, ~128K objects
@@ -297,14 +298,12 @@
# define PObj_live_FLAG d_PObj_live_FLAG
# define PObj_on_free_list_FLAG d_PObj_on_free_list_FLAG
# define PObj_is_special_PMC_FLAG d_PObj_is_special_PMC_FLAG
-# define PObj_needs_early_DOD_FLAG d_PObj_needs_early_DOD_FLAG
#else
# define PObj_live_FLAG b_PObj_live_FLAG
# define PObj_on_free_list_FLAG b_PObj_on_free_list_FLAG
# define PObj_is_special_PMC_FLAG b_PObj_is_special_PMC_FLAG
-# define PObj_needs_early_DOD_FLAG b_PObj_needs_early_DOD_FLAG
# define DOD_flag_TEST(flag, o) PObj_flag_TEST(flag, o)
# define DOD_flag_SET(flag, o) PObj_flag_SET(flag, o)
@@ -341,6 +340,10 @@
#define PObj_report_SET(o) PObj_flag_SET(report, o)
#define PObj_report_CLEAR(o) PObj_flag_CLEAR(report, o)
+#define PObj_high_priority_DOD_TEST(o) PObj_flag_TEST(high_priority_DOD, o)
+#define PObj_high_priority_DOD_SET(o) PObj_flag_SET(high_priority_DOD, o)
+#define PObj_high_priority_DOD_CLEAR(o) PObj_flag_CLEAR(high_priority_DOD, o)
+
#define PObj_on_free_list_TEST(o) DOD_flag_TEST(on_free_list, o)
#define PObj_on_free_list_SET(o) DOD_flag_SET(on_free_list, o)
#define PObj_on_free_list_CLEAR(o) DOD_flag_CLEAR(on_free_list, o)
@@ -361,9 +364,9 @@
#define PObj_sysmem_SET(o) PObj_flag_SET(sysmem, o)
#define PObj_sysmem_CLEAR(o) PObj_flag_CLEAR(sysmem, o)
-#define PObj_needs_early_DOD_TEST(o) DOD_flag_TEST(needs_early_DOD, o)
-#define PObj_needs_early_DOD_SET(o) DOD_flag_SET(needs_early_DOD, o)
-#define PObj_needs_early_DOD_CLEAR(o) DOD_flag_CLEAR(needs_early_DOD, o)
+#define PObj_needs_early_DOD_TEST(o) PObj_flag_TEST(needs_early_DOD, o)
+#define PObj_needs_early_DOD_SET(o) PObj_flag_SET(needs_early_DOD, o)
+#define PObj_needs_early_DOD_CLEAR(o) PObj_flag_CLEAR(needs_early_DOD, o)
#define PObj_special_SET(flag, o) do { \
PObj_flag_SET(flag, o); \
Index: include/parrot/resources.h
===================================================================
RCS file: /cvs/public/parrot/include/parrot/resources.h,v
retrieving revision 1.44
diff -u -r1.44 resources.h
--- include/parrot/resources.h 21 Jul 2003 18:00:42 -0000 1.44
+++ include/parrot/resources.h 10 Sep 2003 04:37:07 -0000
@@ -82,6 +82,7 @@
#define HEADER_ALLOCS_SINCE_COLLECT 8
#define MEM_ALLOCS_SINCE_COLLECT 9
#define TOTAL_COPIED 10
+#define IMPATIENT_PMCS 11
/* &end_gen */
Index: io/io.c
===================================================================
RCS file: /cvs/public/parrot/io/io.c,v
retrieving revision 1.53
diff -u -r1.53 io.c
--- io/io.c 2 Sep 2003 16:41:14 -0000 1.53
+++ io/io.c 10 Sep 2003 04:37:07 -0000
@@ -748,12 +748,12 @@
INTVAL i;
ParrotIOTable table = piodata->table;
- /* XXX boe: Parrot_really_destroy might call us with mark_ptr not
+ /* XXX boe: Parrot_really_destroy might call us with pmc_mark_ptr not
* set. This is neccessary until destruction ordering prevents
* the premature destruction of the standardhandles
*/
- if (!interpreter->mark_ptr)
- interpreter->mark_ptr = table[0];
+ if (!interpreter->dod_mark_ptr)
+ interpreter->dod_mark_ptr = table[0];
for (i = 0; i < PIO_NR_OPEN; i++) {
if (table[i]) {
Index: t/op/gc.t
===================================================================
RCS file: /cvs/public/parrot/t/op/gc.t,v
retrieving revision 1.5
diff -u -r1.5 gc.t
--- t/op/gc.t 1 Jul 2003 23:08:14 -0000 1.5
+++ t/op/gc.t 10 Sep 2003 04:37:07 -0000
@@ -35,10 +35,10 @@
interpinfo I1, 2 # How many DOD runs have we done already?
new P0, .PerlUndef
needs_destroy P0
+ new P0, .PerlUndef # kill object
sweep 0
interpinfo I2, 2 # Should be one more now
sub I3, I2, I1
- new P0, .PerlUndef # kill 1st object
sweep 0
interpinfo I4, 2 # Should be same as last
sub I5, I4, I2