"Mike Lambert" wrote: > I know Dan's proposed solution has already been committed, but I'd > like to add my support for this. In addition to providing a counter per > opcode to ensure that we don't prematurely GC data, this field could also > be reused to calculate the generation of a particular buffer, to help sort > it into a correct generational pool (if/when we do get that).
I have almost convinced myself this is essential, due to the problem I am currently fighting (the excessive memory usage in programs like zip and quicksort - see below for more explanation). Unfortunately, there is a fairly major performance impact (on my system, anyway). Perhaps a few volunteers could add the patch below and do before and after mops, life, whatever benchmarks and post the results? This code just adds the overhead of the cycle counter without any benefits. The excess memory usage problem is caused partially because of the decoupling of dead object detection and memory pool compaction. Some of the recent changes have been aimed at improving performance by reducing the frequency of DOD runs, since these are quite slow. However, we can then get the situation where a large number of string allocations take place without running out of free headers, so we never do a DOD run; compaction runs therefore can't reclaim anything, because no strings have been declared dead recently. My preferred solution to this is to trigger DOD runs during memory allocation, to see whether we can find reclaimable memory - this however presents an infant mortality nightmare, which could be addressed using the birthdate technique. As an alternative to this, I am currently testing a scheme using flags, so that the memory allocation system can request that a DOD run occur at the next suitable opportunity, and possible vice versa. > Another proposal is to walk the C stack. In runops (or some similar This is more in line with standard GC systems, which have no option since the program is assumed to be non-cooperative. It would probably require a major rewrite of the memory manager, so, although it needs to considered, I think it should become part of a separate project to design a next generation memory management system from scratch, which can be plugged in later - unless later has to be sooner to accomodate problems that can't be resolved, albeit not optimally, in the current version. -- Peter Gibbs EmKel Systems Index: include/parrot/interpreter.h =================================================================== RCS file: /home/perlcvs/parrot/include/parrot/interpreter.h,v retrieving revision 1.45 diff -u -r1.45 interpreter.h --- include/parrot/interpreter.h 15 May 2002 07:25:37 -0000 1.45 +++ include/parrot/interpreter.h 26 May 2002 08:57:58 -0000 @@ -162,6 +162,7 @@ requests are there? */ UINTVAL GC_block_level; /* How many outstanding GC block requests are there? */ + UINTVAL cycle; /* Opcode cycle counter */ } Interp; #define PCONST(i) PF_CONST(interpreter->code, (i)) Index: lib/Parrot/OpsFile.pm =================================================================== RCS file: /home/perlcvs/parrot/lib/Parrot/OpsFile.pm,v retrieving revision 1.24 diff -u -r1.24 OpsFile.pm --- lib/Parrot/OpsFile.pm 12 May 2002 18:57:43 -0000 1.24 +++ lib/Parrot/OpsFile.pm 26 May 2002 08:59:42 -0000 @@ -325,6 +325,9 @@ $body =~ s/\$(\d+)/{{\@$1}}/mg; +# GC Experimental +$body = " interpreter->cycle++;\n{\n" . $body . "}"; + if ($ENV{PARROT_NO_LINE}) { $op->body($body); } else {