At 3:36 PM +0100 3/4/04, Leopold Toetsch wrote:
I've run these 2 tests below.Damn. Okay, I'm going to spend today digging into the object stuff to try and track down the leaks. Something's not right in there, as the DOD and GC ought to be reclaiming the dead memory.
Results don't look really good.
I've a patch now (attached) - runs all tests. Please have a look at it.
- GC was blocked during list.c:allocate_chunk(). I've removed that - it's very likely unneeded and wrong
- Parrot_new_class -> class_register allocates now a ParrotObject vtable
- with this the cloning during instantiation isn't needed anymore
- so the huge memory leak (~100 MB) for loop count 100.000 is gone
- not cloing the vtable saves about 10% execution time
Are these 2 programs somehow equivalent?
Yeah, they're about the same, though the class lookup is cached so it shouldn't have to be done every time through.
Good, makes it faster ;)
leo
--- parrot/classes/parrotclass.pmc Thu Mar 4 08:47:45 2004 +++ parrot-leo/classes/parrotclass.pmc Thu Mar 4 15:25:28 2004 @@ -84,7 +84,7 @@ */ - INTVAL isa(STRING * classname) { + INTVAL isa(STRING* classname) { PMC *class; if (SUPER(classname)) return 1; --- parrot/classes/parrotobject.pmc Thu Mar 4 08:47:45 2004 +++ parrot-leo/classes/parrotobject.pmc Thu Mar 4 16:10:38 2004 @@ -104,10 +104,41 @@ */ PMC* find_method(STRING* name) { - PMC *class = VTABLE_get_pmc_keyed_int(INTERP, (PMC *)PMC_data(SELF), 0); - return Parrot_find_method_with_cache(INTERP, class, name); + if (PObj_is_class_TEST(SELF)) + return SUPER(name); + pmc = VTABLE_get_pmc_keyed_int(INTERP, (PMC *)PMC_data(SELF), 0); + return SUPER(name); } + INTVAL type() { + if (PMC_data(SELF)) { + PMC *class = VTABLE_get_pmc_keyed_int(INTERP, + (PMC *)PMC_data(SELF), 0); + pmc = class; + return SUPER(); + } + return enum_class_ParrotObject; + } + + INTVAL can(STRING* name) { + if (PObj_is_class_TEST(SELF)) + return SUPER(name); + pmc = VTABLE_get_pmc_keyed_int(INTERP, (PMC *)PMC_data(SELF), 0); + return SUPER(name); + } + + INTVAL isa(STRING* classname) { + if (PObj_is_class_TEST(SELF)) { + /* newclass returns a PMC with a ParrotObject vtable + * but this object isn't yet an objects so: + */ + if (string_equal(INTERP, + const_string(INTERP, "ParrotObject"), + classname) == 0) + return 0; + } + return SUPER(classname); + } } /* --- parrot/src/list.c Thu Mar 4 13:08:54 2004 +++ parrot-leo/src/list.c Thu Mar 4 16:25:00 2004 @@ -230,7 +230,7 @@ List_chunk *chunk; Parrot_block_DOD(interpreter); - Parrot_block_GC(interpreter); + /*Parrot_block_GC(interpreter); - why */ chunk = (List_chunk *)new_bufferlike_header(interpreter, sizeof(*chunk)); chunk->items = items; chunk->n_chunks = 0; @@ -239,7 +239,7 @@ chunk->prev = NULL; Parrot_allocate_zeroed(interpreter, (Buffer *)chunk, size); Parrot_unblock_DOD(interpreter); - Parrot_unblock_GC(interpreter); + /*Parrot_unblock_GC(interpreter); */ return chunk; } @@ -769,17 +769,17 @@ chunk = chunk_list[ idx / MAX_ITEMS ] idx = idx % MAX_ITEMS done. - + chunk = first repeat if (index < chunk->items) done. - + if (index >= items_in_chunk_block) index -= items_in_chunk_block chunk += chunks_in_chunk_block continue - + calc chunk and index in this block done. @@ -1942,7 +1942,7 @@ Greater threshold before C<do_sparse()>. Setting initial size to avoid sparse -=item * 1.33 +=item * 1.33 04.07.2003 Use a SArray for user_data --- parrot/src/objects.c Wed Mar 3 15:18:05 2004 +++ parrot-leo/src/objects.c Thu Mar 4 16:29:04 2004 @@ -366,7 +366,15 @@ * good base to work from * XXX we are leaking this vtable */ +#if 0 new_vtable = Parrot_clone_vtable(interpreter, new_class->vtable); +#else + /* use a ParrotObject vtable so that cloning it in instantiate + * can be avoided + */ + new_vtable = Parrot_clone_vtable(interpreter, + Parrot_base_vtables[enum_class_ParrotObject]); +#endif /* register the class */ VTABLE_set_pmc_keyed_str(interpreter, interpreter->class_hash, @@ -406,19 +414,27 @@ INTVAL attrib_count; PMC *class_array; PMC *class; +#if 0 INTVAL class_enum; +#endif PMC *class_name; class = object->vtable->data; /* * remember PMC type */ +#if 0 class_enum = object->vtable->base_type; /* put in the real vtable * XXX we are leaking ths vtable + * the vtable currently only differs from ParrotObject's vtable + * by the base_type - implementing type in ParrotObject can + * handle that + * --leo */ object->vtable = Parrot_clone_vtable(interpreter, Parrot_base_vtables[enum_class_ParrotObject]); /* and set type of class */ object->vtable->base_type = class_enum; +#endif /* Grab the attribute count from the parent */ attrib_count = class->cache.int_val;