Nicholas Clark <[EMAIL PROTECTED]> wrote:

> +void *
> +Parrot_Embed_PMC_get_pointer(Parrot_Interp interp, Parrot_PMC pmc) {
> +    if(interp->lo_var_ptr) {
> +        return Parrot_PMC_get_pointer(interp, pmc);
> +    } else {
> +        void *result; /* Doubles up as an indicator of stack top.  */
> +        interp->lo_var_ptr=&result;
> +        result = Parrot_PMC_get_pointer(interp, pmc);

This shouldn't really be necessary. A pointer fetch shouldn't trigger
DOD. Except you attach enough magic to the PMC so that it starts running
a piece of code on a call to C<get_pointer> :)

> +Parrot_PMC
> +Parrot_Embed_PMC_new(Parrot_INTERP interp, Parrot_Int type) {
> +    if(interp->lo_var_ptr) {
> +        return Parrot_PMC_new(interp, type);
> +    } else {
> +        Parrot_PMC result;
> +        interp->lo_var_ptr=&result;
> +        result = Parrot_PMC_new(interp, type);
> +        interp->lo_var_ptr=NULL;

And the other usage of these stacktop setting is still somewhat
debatable, but it depends.

There are several issues 2) might be considered a bug:

1) Parrot does not walk the CPU stack, if lo_var_ptr isn't set.

2) Not walking the stack currently implies that the hardware CPU
   registers are *not* marked. Parrot does basically[1] a setjmp(3),
   which places CPU registers into a local on the CPU stack and then
   scans the whole stack that now includes these CPU registers.

3) Setting the lo_var_ptr at this level of the stack doesn't protect
   anything above (assuming a grow down stack). So you are better off
   with just setting the stack top once to anything above that level and
   not reset the limit (this might not work for the situations with
   callbacks only that Arthur described). But if you have a more linear
   program flow, or if you have a place somewhere above in the stack
   then the stack top should be set there.

4) When you start entering a run loop for the first time the stack top
   is automatically set by Parrot at the run loop level, except
   you did call Parrot_init_stacktop, which resets the RESUME_INITIAL
   flag.

5) Any PMC[2] above that lo_var_ptr that *is not* anchored otherwise,
   has to be anchored somehow. But Parrot_register_pmc /
   dod_register_pmc is rather expensive, it's a hash operation.

6) If you are e.g. stuffing PMCs into a PMC array and the array is
   anchored, the array items shouldn't be additionally anchored with
   Parrot_register_pmc. The mark function of the array marks it's
   items anyway. But this somehow depends on the usage of the
   array. Dunno if it can happen, that you have other references[3] to
   array items around and the array itself goes out of scope.

7) Parrot_register_pmc/Parrot_unregister_pmc otherwise work like an
   increment/decrement of a refcount. When the count reaches zero,
   the PMCs address gets deleted from the C<DOD_registry> hash.


leo

[1] there is some extra code e.g. for IA64 register files and sparc.
    see cpu_dep.c
[2] should be any PObj, but dod_register_pmc has a PMC* function
    signature. Albeit passing in e.g. a STRING wouldn't harm.

[3] unachored PMC* pointers.

Reply via email to