On Thursday 08 May 2008 11:09:52 chromatic wrote: > That to me seems like the real problem. Did anyone experiment with using > hash_delete? > > > The problem can be fixed by checking in parrot_mark_hash that the key > > is no null before calling pobject_lives. The attached path does it. > > That seems like treating the symptom to me. I'd like to see if really > deleting the item works, first.
No, that won't work. It changes the semantics of OrderedHash. Your null-checking patch will work, but I don't want to add more checking to parrot_mark_hash() right now, as it's already full of special cases. Here's my inclination. -- c
=== src/pmc/orderedhash.pmc ================================================================== --- src/pmc/orderedhash.pmc (revision 27400) +++ src/pmc/orderedhash.pmc (local) @@ -46,6 +46,39 @@ /* +=item C<void mark()> + +Marks the OrderedHash as live. + +=cut + +*/ + + VTABLE void mark() { + Hash *h = (Hash *)PMC_struct_val(SELF); + INTVAL i; + + if (!h) + return; + + for (i = h->mask; i >= 0; --i) { + HashBucket *b = h->bi[i]; + + while (b) { + + if (b->key) { + pobject_lives(interp, (PObj *)b->key); + if (b->value) + pobject_lives(interp, (PObj *)b->value); + } + + b = b->next; + } + } + } + +/* + =item C<PMC *get_pmc_keyed(PMC *key)> =item C<PMC *get_pmc_keyed_int(INTVAL key)> @@ -348,7 +381,7 @@ VTABLE INTVAL exists_keyed_int(INTVAL idx) { Hash * const h = (Hash *)PMC_struct_val(SELF); const INTVAL n = h->entries; - HashBucket *b; + HashBucket *b; if (idx < 0) idx += n; @@ -505,7 +538,7 @@ VTABLE void delete_keyed_int(INTVAL idx) { Hash * const h = (Hash *)PMC_struct_val(SELF); const INTVAL n = h->entries; - HashBucket *b; + HashBucket *b; if (idx < 0) idx += n; @@ -515,16 +548,22 @@ b = h->bs + idx; - if (b) - b->key = NULL; + if (!b) + return; + + b->key = NULL; + b->value = NULL; } VTABLE void delete_keyed_str(STRING *key) { const Hash * const h = (Hash *)PMC_struct_val(SELF); HashBucket * const b = parrot_hash_get_bucket(INTERP, h, key); - if (b) - b->key = NULL; + if (!b) + return; + + b->key = NULL; + b->value = NULL; } /*