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.