Bill Coffman <[EMAIL PROTECTED]> wrote:

[ Dan answered already, so I'll provide just a few additional notes ]

> reg_alloc.c uses malloc().

Yep, there are still a few malloc()s around, they should be
mem_sys_allocate(), which is just a macro for malloc() mostly, but leaves
us the chance to do our own implementation.

> ...I saw alloca() used in the CVS tree
> earlier, but it's gone now.  What is the correct way to allocate
> memory in Parrot?

Not inside Parrot. Oh well:

$ find . -name '*.c' | xargs grep -w alloca
./ast/astparser.c:/* The parser invokes alloca or malloc;  \
  define the necessary symbols.  */
...

The yacc, bison, whatever defines some macros for extending internal
tables that might get triggered or not. I trust that piece of code to
use a different strategy, if alloca isn't available.

Inside the Parrot tree, we don't use alloca().

> [Leo]* the Dbg and Dbg2 debug macros aren't needed.

> I notice an IMC_TRACE macro, as well as the associated debug stuff.
> Debug looks like it has a lot of overhead, even when turned off.

There is a bit of overhead if useed inside a loop or such. You can
always wrap #ifndef NDEBUG around it.

> ... , because I couldn't figure out
> how to handle variable number of arguments,

The debug() function handles variable arguments as well as different
debugging verbosity levels.

> assert() would be much nicer.

assert() is usable as is, just include <assert.h>. But assert() is of
course a different thing. First is: make it working correctly. We'll
optimize out the possible debug stuff later. Inside loops place NDEBUG
macros around it.

> [Leo] * all functions should have an Interp* and a IMC_Unit* argument

> I'm not quite sure I understand this.  I get that each function call
> has (interpreter,unit) as parameters.  But why is this?  Parrot
> handles interrupts,

It's not because of interrupts. We'll never run that code from a signal
handler. But imagine, we have not only one parser that calls the
register allocation stuff, we have more parsers handling even different
languages.

E.g. You are creating code for

  BEGIN { bar = 2; foo() };

or some such. During compiling that, a different compiler is invoked that
compiles the "foo" function. This compiler may run in a separate thread
and starts overwriting global state inmidst of compiling the first
piece of code.

Having the state in an interpreter variable prevents from that.
C<interpreter> is not really needed inside most of these functions
currently, but is e.g.  badly needed, if we change mem_sys_allocate() to
use interpreter-internal memory allocation. C<IMC_Unit> holds the state
of the current function or unit. So these are needed function arguments.

We already had tons of patches, to bring these arguments to the most
functions used inside imcc, but that's not finished and the reason for
some nasty issues with state in globals. It's a PITA.

So for new code just use these 2 additional function arguments.

> ...  Does this also mean that there should be
> no other data structures, except those pointed to by interpreter or
> unit?

No. You can use all possible data structures you need. Register
allocation is done per unit, just hang your needed structure(s) off
IMC_Unit defined in F<imcc/unit.h>.

> - Bill

thanks,
leo

Reply via email to