Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

ad #22717: CPS and more

9 views
Skip to first unread message

Leopold Toetsch

unread,
Jun 18, 2003, 11:07:51 AM6/18/03
to P6I, Dan Sugalski
[my last 2 f'ups didn't arrive at perl.perl6.internals, so I try again]

The patch is fine with two exceptions:
1) still breaks existing P6C tests WRT exceptions & rules
2) performance of CPS sucks

ad 1) I'd like to preserve the old style invoke/ret scheme too. incokecc
and friends could call a new ContSub[1] class, which is the same as
sub.pmc but doesn't put the return address on the control stack during
invoke.

ad 2) CPS subroutines are 3 times slower for calling the sub. There are
2 problems here:

2a) The main is: the continuation object is generated for each[2]
subroutine call. Replacing the invokecc with an explicit sequence of
constructing the return Continuation object once outside the loop brings
again the same speed as invoke/ret.

2b) There is still too much context copying going on AFAIK. The register
top and base pointers are copied too in {save,restore}context worth of 8
words, while just copying the 3 stacks (pad, control, user) should more
then be enough. The coroutine code only swaps these - BTW and doesn't
set them COW.

So we have currently:

sub.pmc (+ contsub.pmc), continuation.pmc, and coroutine.pmc do very
similar things. The only major difference is, where they branch on invoke.
The differences are:
- sub.pmc doesn't have an own context, it pushes the current lex_pad on
the interpreters pad_stack on invoke
- continuation.pmc saves/restores the whole context structure and marks
the 3 stacks COW
- coroutine.pmc swaps the 3 stacks and doesn't mark them COW

This leads to some questions:
- shouldn't these all preserve the same stack(s)?
- which stack(s): pad_stack only or control/user/intstack too?
- can we pull out the construction of the return continuation of the
loop like done below?
- what parts of current context structure should then be preserved
(registers are already out, why then deal with register backing store)?

Comments welcome
leo


[1] we could AFAIK reuse CSub, which is obsoleted by NCI.
(also most routines in method_utils.c seems to be obsolete)

[2]
new P10, .PerlUndef
set P10, 1000000
new P11, .PerlUndef
set P11, 0
new P0, .Sub
set_addr I12, func
set P0, I12
set I0, 0 # no prototype
set I2, 0 # no PMC params
set I3, 0 # void context
new P1, .Continuation ##
set_addr I12, ret ##
set P1, I12 ##
lp:
pushbottomp
invoke ## invokecc
ret:
popbottomp
inc P11
lt P11, P10, lp
end

func:
invoke P1


Jonathan Sillito

unread,
Jun 18, 2003, 1:02:43 PM6/18/03
to Leopold Toetsch, P6I
> -----Original Message-----
> From: Leopold Toetsch [mailto:l.to...@nextra.at]
>
> The patch is fine with two exceptions:
> 1) still breaks existing P6C tests WRT exceptions & rules
> 2) performance of CPS sucks
>
> ad 1) I'd like to preserve the old style invoke/ret scheme too. incokecc
> and friends could call a new ContSub[1] class, which is the same as
> sub.pmc but doesn't put the return address on the control stack during
> invoke.
>
> ad 2) CPS subroutines are 3 times slower for calling the sub. There are
> 2 problems here:
>
> 2a) The main is: the continuation object is generated for each[2]
> subroutine call. Replacing the invokecc with an explicit sequence of
> constructing the return Continuation object once outside the loop brings
> again the same speed as invoke/ret.

This is the reason for the new implementation of the invoke op which assumes
that the continuation has already been put in place. Also allowing the
invokecc to take an argument specifying the type of continuation to save may
be helpful:

invokecc .AddressOnlyContinuation # or something ...
invokecc .EverythingButTheKitchenSinkContinuation

> 2b) There is still too much context copying going on AFAIK. The register
> top and base pointers are copied too in {save,restore}context worth of 8
> words, while just copying the 3 stacks (pad, control, user) should more
> then be enough. The coroutine code only swaps these - BTW and doesn't
> set them COW.

I am not sure I follow this. Are you suggesting that the register stacks do
not need to be copied? Again different types of continuations would be good.

> So we have currently:
>
> sub.pmc (+ contsub.pmc), continuation.pmc, and coroutine.pmc do very
> similar things. The only major difference is, where they branch on invoke.
> The differences are:
> - sub.pmc doesn't have an own context, it pushes the current lex_pad on
> the interpreters pad_stack on invoke
> - continuation.pmc saves/restores the whole context structure and marks
> the 3 stacks COW
> - coroutine.pmc swaps the 3 stacks and doesn't mark them COW
>
> This leads to some questions:
> - shouldn't these all preserve the same stack(s)?
> - which stack(s): pad_stack only or control/user/intstack too?
> - can we pull out the construction of the return continuation of the
> loop like done below?
> - what parts of current context structure should then be preserved
> (registers are already out, why then deal with register backing store)?
>
> Comments welcome

As suggested in a previous email coroutine.pmc could just go away. Since
returning from an otherwise normal sub using:

invokecc P1

will save the appropriate context for a subsequent 'coroutine' call.

Leopold Toetsch

unread,
Jun 18, 2003, 1:38:10 PM6/18/03
to Jonathan Sillito, P6I, Dan Sugalski
Jonathan Sillito wrote:

>>-----Original Message-----
>>From: Leopold Toetsch [mailto:l.to...@nextra.at]
>>
>>The patch is fine with two exceptions:
>>1) still breaks existing P6C tests WRT exceptions & rules


You didn't mention this point. It might be only a small change in P6C
code, I didn't look at (4 tests are failing now due to invoke changes).


>>2) performance of CPS sucks

> This is the reason for the new implementation of the invoke op which assumes


> that the continuation has already been put in place.


Ok then we need a new opcode:

newsub Px, .Class, jump_or_ret_addr

This constructs a sub or continuation type subroutine PMC in Px of class
.Class and the referenced label - in one instruction.

> Also allowing the
> invokecc to take an argument specifying the type of continuation to save may
> be helpful:


No, don't think so. The type is specified by the PMC class. The invoke
of this class takes the appropriate action.


>>2b) There is still too much context copying going on AFAIK. The register
>>top and base pointers are copied too in {save,restore}context worth of 8
>>words, while just copying the 3 stacks (pad, control, user) should more
>>then be enough. The coroutine code only swaps these - BTW and doesn't
>>set them COW.

> I am not sure I follow this. Are you suggesting that the register stacks do
> not need to be copied? Again different types of continuations would be good.


I honestly don't know, what has to be copied. I just know that all now
do copy different things and if CPS is involved also restore different
things. Please look at sub/continuation/coroutine and their context
saving: all are different.


> As suggested in a previous email coroutine.pmc could just go away. Since
> returning from an otherwise normal sub using:
>
> invokecc P1


Not quite. It has the same functionality, but it does construct a new
continuation PMC for the address to continue. And as outline the
performance sucks.


> will save the appropriate context for a subsequent 'coroutine' call.


Yes for sure, but swapping 3 pointers is a lot faster.


Still a lot (almost all) of my original concerns are not addressed yet.


leo

Jonathan Sillito

unread,
Jun 18, 2003, 2:20:46 PM6/18/03
to Leopold Toetsch, P6I, Dan Sugalski
> -----Original Message-----
> From: Leopold Toetsch [mailto:l.to...@nextra.at]
>
> Jonathan Sillito wrote:
>
> >>-----Original Message-----
> >>From: Leopold Toetsch [mailto:l.to...@nextra.at]
> >>
> >>The patch is fine with two exceptions:
> >>1) still breaks existing P6C tests WRT exceptions & rules
>
>
> You didn't mention this point. It might be only a small change in P6C
> code, I didn't look at (4 tests are failing now due to invoke changes).

Sorry I haven't looked at this yet.

> >>2) performance of CPS sucks
>
> > This is the reason for the new implementation of the invoke op
> which assumes
> > that the continuation has already been put in place.
>
>
> Ok then we need a new opcode:
>
> newsub Px, .Class, jump_or_ret_addr

Sounds fine to me. At one point the following worked:

new Px, .Class, address

> This constructs a sub or continuation type subroutine PMC in Px of class
> .Class and the referenced label - in one instruction.
>
> > Also allowing the
> > invokecc to take an argument specifying the type of
> continuation to save may
> > be helpful:
>
>
> No, don't think so. The type is specified by the PMC class. The invoke
> of this class takes the appropriate action.

I agree that constructing the continuation separately is functionally
equivalent:

new P1 .SomeContinuationClass, label # or newsub
invoke
label:
# return's to here

however I think a common case is made more convenient using:

invokecc .SomeContinuationClass # assumes expr NEXT()
# return's to here

though, either way is fine with me.

> >>2b) There is still too much context copying going on AFAIK. The register
> >>top and base pointers are copied too in {save,restore}context worth of 8
> >>words, while just copying the 3 stacks (pad, control, user) should more
> >>then be enough. The coroutine code only swaps these - BTW and doesn't
> >>set them COW.
>
> > I am not sure I follow this. Are you suggesting that the
> register stacks do
> > not need to be copied? Again different types of continuations
> would be good.
>
>
> I honestly don't know, what has to be copied. I just know that all now
> do copy different things and if CPS is involved also restore different
> things. Please look at sub/continuation/coroutine and their context
> saving: all are different.

I guess this needs some reworking see below.

[snip]

> Still a lot (almost all) of my original concerns are not addressed yet.

And performance and consistency are the main concerns, correct? Following
are some ideas that may address theses.

(1) A continuation is an invokable pmc that contains some context and an
address to jump to. The context can vary and I suggest that we provide
several continuation types to support this. I think the following may make
sense (ordered from fastest to slowest).

- no context (just an address)
- just the pad stack
- three stacks (pad, control and user)
- three stacks plus register stacks

I suppose other variations could be added as well. I am not sure what names
to give each of these, but probably the "no context" pmc could be the base
extended by the others.

(2) Could the Parrot_Context struct be reworked such that the register
stacks are only one pointer each? This would make the save and restore
slightly more efficient.

(3) One other efficiency thought: I wonder if the interpreter's context
could be changed to a pointer to struct Parrot_Context? This would make
accessing the stacks slightly slower but would of course make restoring the
context very quick. Just a thought ...

What do you think?
--
Jonathan Sillito

Leopold Toetsch

unread,
Jun 18, 2003, 8:34:19 PM6/18/03
to Jonathan Sillito, P6I, Dan Sugalski
Jonathan Sillito wrote:

>>-----Original Message-----
>>From: Leopold Toetsch [mailto:l.to...@nextra.at]
>>Ok then we need a new opcode:
>>
>> newsub Px, .Class, jump_or_ret_addr
>
> Sounds fine to me. At one point the following worked:
>
> new Px, .Class, address


Extending the C<new> opcode or doing a new one isn't much difference.
Thinking in imcc POV and register allocation I'd prefer a distinct opcode.


> invokecc .SomeContinuationClass # assumes expr NEXT()


Still this one doesn't work - or yes works but only with additional
overhead: invoke and such are called on a specific PMCs invoke() method.
So I don't see any need to pay an additional penalty for a) an
additional parameter (opcode) and b) some "if" inside the invoke() to
decide what todo according to that param. This should just be a
different class that implements a possibly slightly different invoke().


> And performance and consistency are the main concerns, correct? Following
> are some ideas that may address theses.


Yep exactly.
WRT performance: Constructing the return continuation solves this -
thats totally ok, albeit, and this was one questions, I don't know, if
its totally equivalent to construct the return continuation at C<invoke>
time or where "newsub" is called.

Issues regarding current inconsistencies remain:
E.g. with this scheme a coroutine or continuation may return and restore
different items from "context" what the caller did preserve.


> (1) A continuation is an invokable pmc that contains some context and an
> address to jump to. The context can vary and I suggest that we provide
> several continuation types to support this. I think the following may make
> sense (ordered from fastest to slowest).
>
> - no context (just an address)
> - just the pad stack
> - three stacks (pad, control and user)
> - three stacks plus register stacks


Thats all ok. But I think, we currently need some background, what is
really "some context" that is and shall preserved:
Intstack? Register backing store? User stack? And if when one of these
and why ...
This are just my current concerns.


> (2) Could the Parrot_Context struct be reworked such that the register
> stacks are only one pointer each?


The primary questions is what to preserve (and restore) when.


> (3) One other efficiency thought: I wonder if the interpreter's context
> could be changed to a pointer to struct Parrot_Context? This would make
> accessing the stacks slightly slower but would of course make restoring the
> context very quick. Just a thought ...


Yes. This could be fine. OTOH, when "context" comes out as being just
the lexical pad, that's one pointer. Dunno.


> Jonathan Sillito

leo

Melvin Smith

unread,
Jun 18, 2003, 10:23:58 PM6/18/03
to Leopold Toetsch, Jonathan Sillito, P6I, Dan Sugalski
At 02:34 AM 6/19/2003 +0200, Leopold Toetsch wrote:

>Jonathan Sillito wrote:
>>(3) One other efficiency thought: I wonder if the interpreter's context
>>could be changed to a pointer to struct Parrot_Context? This would make
>>accessing the stacks slightly slower but would of course make restoring the
>>context very quick. Just a thought ...

I tried this, and there was a distinct slowdown on accessing the regs
through the dereference. Dan and I debated this because I had the same
idea, but after profiling I proved Dan right. I think it is best optimized to
the common case which is register access, not context switches.

-Melvin

Dan Sugalski

unread,
Jun 18, 2003, 10:29:53 PM6/18/03
to Leopold Toetsch, P6I
At 5:07 PM +0200 6/18/03, Leopold Toetsch wrote:
>[my last 2 f'ups didn't arrive at perl.perl6.internals, so I try again]
>
>The patch is fine with two exceptions:
>1) still breaks existing P6C tests WRT exceptions & rules

Yeah, that needs fixing.

>2) performance of CPS sucks

Are you sure? Tell us what you *really* think... :)

>ad 1) I'd like to preserve the old style invoke/ret scheme too. incokecc
>and friends could call a new ContSub[1] class, which is the same as
>sub.pmc but doesn't put the return address on the control stack during
>invoke.

Sure, it's a useful thing. Only subs/methods/whatever that need to
conform to the calling conventions absolutely must use PDD03 style
calling conventions, though this *will* be all the Perl, Python, and
Ruby subs, as well as any sub or method that can be called from them.

>ad 2) CPS subroutines are 3 times slower for calling the sub. There are
>2 problems here:
>
>2a) The main is: the continuation object is generated for each[2]
>subroutine call. Replacing the invokecc with an explicit sequence of
>constructing the return Continuation object once outside the loop brings
>again the same speed as invoke/ret.

That's definitely doable. A continuation object, once created, should
probably be considered immutable, though there are definitely things
to be gained from being able to mess around with the stacks hanging
off the continuation object.

Reusing these things should be considered OK, though they couldn't be
reused without being reinitialized after any sort of stack
manipulation on return, since COW will make pointers change.

I am fully, 100% OK with the interpreter core having evil deep
knowledge of continuation PMCs, and unmercifully stuffing data into
them directly. We don't have to jump through the continuation vtable
or anything. Not that this will necessarily

>2b) There is still too much context copying going on AFAIK. The register
>top and base pointers are copied too in {save,restore}context worth of 8
>words, while just copying the 3 stacks (pad, control, user) should more
>then be enough. The coroutine code only swaps these - BTW and doesn't
>set them COW.

I tossed the base pointers entirely--they're flat-out wrong in most
cases, so they're gone. Unfortunately a few more things, like the
opcode table pointer and global pointer, needs to move into the
context structure, so I think it'll ultimately have more things in it.

>So we have currently:
>
>sub.pmc (+ contsub.pmc), continuation.pmc, and coroutine.pmc do very
>similar things. The only major difference is, where they branch on invoke.

We need to unify them. Each of them sort of dates to a different
period so they're not quite matching. Yet. :)
--
Dan

--------------------------------------"it's like this"-------------------
Dan Sugalski even samurai
d...@sidhe.org have teddy bears and even
teddy bears get drunk

Dan Sugalski

unread,
Jun 18, 2003, 10:36:50 PM6/18/03
to Melvin Smith, Leopold Toetsch, Jonathan Sillito, P6I

Oh, right, that. (I should keep up to speed here ;)

Yeah, the registers in the interpreter were originally Daniel's idea.
The first design had an indirect pointer to them and had it so the
registers were always on the register stack--when you pushed a frame
you just moved the register pointer a bit, which made pushes really
fast. When Daniel started in on the JIT he asked if they could be in
a fixed location, since that made accessing the registers faster,
especially with interpreter-specific JITted code. (Direct, absolute
addressing. Darned snappy) It turned out that accessing the registers
in the interpreter, not just via the JIT, was faster too, more than
outweighing the extra cost to push a frame, given that we access
registers much more often than pushing frames.

Context switches and frame pushes will be relatively rare, at least
relative to accessing registers. Adding a cycle to each register
access to save (say) 70 or 100 cycles on a context switch isn't worth
it unless we're doing *far* more context switches than I'm thinking
we'll end up doing.

Leopold Toetsch

unread,
Jun 19, 2003, 7:47:29 AM6/19/03
to Dan Sugalski, P6I
Dan Sugalski wrote:

> At 5:07 PM +0200 6/18/03, Leopold Toetsch wrote:
>> 2) performance of CPS sucks
>
> Are you sure? Tell us what you *really* think... :)


Exactly that, what I've outlined. But, when its ok, to generate the
Continuation outside of a possible loop, then its as fast as using the
control stack (or faster ;-).


>> ad 1) I'd like to preserve the old style invoke/ret scheme too.

> Sure, it's a useful thing. Only subs/methods/whatever that need to

> conform to the calling conventions absolutely must use PDD03 style
> calling conventions, though this *will* be all the Perl, Python, and
> Ruby subs, as well as any sub or method that can be called from them.


Then we barely need an invoke/ret functionality too, except for reparing
P6C's closure tests.


>> sub.pmc (+ contsub.pmc), continuation.pmc, and coroutine.pmc do very
>> similar things. The only major difference is, where they branch on
>> invoke.

> We need to unify them. Each of them sort of dates to a different period
> so they're not quite matching. Yet. :)

So all these subroutine types should have probably this structure:

typedef struct Parrot_Sub {
struct Parrot_Context ctx;
opcode_t *address;
} * parrot_sub_t;

On *construction* they would do:

all: save_context(); // like in new_continuation
sub, coro: push_current_lexpad_on_own_ctx(); // like new_coroutine

On invoke they do:
sub: copy ctx to interpreter = restore_ctx
coroutine: swap_ctx
continuation: restore_ctx

Is that correct?

leo

BTW I've added 2 new ops, which makes code using CPS much simpler.

Jonathan Sillito

unread,
Jun 19, 2003, 1:02:49 PM6/19/03
to Leopold Toetsch, Dan Sugalski, Melvin Smith, P6I
> -----Original Message-----
> From: Melvin Smith [mailto:mrjol...@mindspring.com]
>
> I tried this, and there was a distinct slowdown on accessing the regs
> through the dereference. Dan and I debated this because I had the same
> idea, but after profiling I proved Dan right. I think it is best
> optimized to
> the common case which is register access, not context switches.

However now the registers are no longer in the Parrot_Context struct, so it
may be worth revisiting this ...

> -----Original Message-----
> From: Leopold Toetsch [mailto:l.to...@nextra.at]

[snip]

> So all these subroutine types should have probably this structure:
>
> typedef struct Parrot_Sub {
> struct Parrot_Context ctx;
> opcode_t *address;
> } * parrot_sub_t;

Or a PMC with SELF->data pointing to a Parrot_Context struct and
SELF->cache.int_val holding the address?

> On *construction* they would do:
>
> all: save_context(); // like in new_continuation
> sub, coro: push_current_lexpad_on_own_ctx(); // like new_coroutine

[snip]

Here is what I think. All of these things need an address and some amount of
context which is saved on construction and restored on invoke. The different
types the context to be saved and restored[1]:

sublite[2]:
none - just address

sub:
pointer to a lex pad

coroutine:
whole Parrot_Context[3] - i.e same as ...

continuation for cps approach:
whole Parrot_Context[3]

Sound correct?

--
Jonathan Sillito

[1] This is not considering other context information that Dan has been
talking about.
[2] This does not exist but could if we wanted to support subs that are not
closures - many are not.
[3] This is in the worst case, and I would like to see variations that are
more optimized.

Leopold Toetsch

unread,
Jun 19, 2003, 1:44:16 PM6/19/03
to Dan Sugalski, P6I
Dan Sugalski wrote:

>
> Reusing these things should be considered OK, though they couldn't be
> reused without being reinitialized after any sort of stack manipulation
> on return, since COW will make pointers change.

Thinking some time about this (and looking at the last sub.t [1]), IMHO
best will be a sequence:

newsub .Sub, .Continuation, _func, ret

This creates the 2 needed PMCs and sets their address.

Later on, possibly inside a loop:

invokecc

This (different to now) establishes the return context in P1 and calls
the sub in P0.

[1] one sub is calling another (not tail), so it has to preserve at
least P1. This un-COWs the already copied register stack, which is
*suboptimal*.

leo

Leopold Toetsch

unread,
Jun 19, 2003, 2:25:55 PM6/19/03
to Jonathan Sillito, Dan Sugalski, Melvin Smith, P6I
Jonathan Sillito wrote:

>>-----Original Message-----
>>From: Melvin Smith [mailto:mrjol...@mindspring.com]
>>
>>I tried this, and there was a distinct slowdown on accessing the regs
>>through the dereference.
>

> However now the registers are no longer in the Parrot_Context struct, so it
> may be worth revisiting this ...


Yep. Though, when register access had a slow down, ctx member access
will have too - probably.


>>From: Leopold Toetsch [mailto:l.to...@nextra.at]
>>
>
> [snip]
>
>
>>So all these subroutine types should have probably this structure:
>>
>>typedef struct Parrot_Sub {
>> struct Parrot_Context ctx;
>> opcode_t *address;
>>} * parrot_sub_t;
>>
>
> Or a PMC with SELF->data pointing to a Parrot_Context struct and
> SELF->cache.int_val holding the address?


Dunno yet, but could be probably.


> sublite[2]:
> none - just address
>
> sub:
> pointer to a lex pad
>
> coroutine:
> whole Parrot_Context[3] - i.e same as ...
>
> continuation for cps approach:
> whole Parrot_Context[3]
>
> Sound correct?


The primary question is: Why do we save and restore what part of
context. For restore (the continuation part) it seems clear:
[ I don't know the answer, but guesses are: ]
- stack pointers: to be save against unpaired push/pop
- opfunc tables: when a different languages changes them on the fly (not
yet)

WRT saving:
A non nested sub doesn't have parents lexicals. So the Sub_lite thingy
should be ok.

OTOH: we might put distinct stacks in place. If we don't, these stacks
might grow very deep. This would have linear function call performance
penalty going with the call depth, as we over and over have to
stack_copy more and more stack frames.

leo


Dan Sugalski

unread,
Jun 19, 2003, 3:03:59 PM6/19/03
to Leopold Toetsch, Jonathan Sillito, Melvin Smith, P6I
At 8:25 PM +0200 6/19/03, Leopold Toetsch wrote:
>The primary question is: Why do we save and restore what part of context.

Very good question:

*) System stack gets saved since we have important info on it.
(Exception handlers when they're done, along with other control
information)
*) User stack and register stacks, because all stacks need to be saved
*) Lexical pad pointer because we'll be entering (potentially) a new
lexical scope and need to save the old one
*) Global namespace pointer since we have chained namespaces and the
namespace chain for the sub we're using may not be the same as the
sub we're calling
*) Opcode function table because we may have different opcode
functions in the new sub
*) Current bytecode segment pointer since we may be entering a new
bytecode segment with a new constant table and such
*) Interp flags (maybe, I'm not sure)
*) Warnings, since warnings are lexically scoped
*) Permission and privilege info (which we don't have yet)

I think that's about it, but there might be some more.

Leopold Toetsch

unread,
Jun 22, 2003, 6:05:02 AM6/22/03
to Dan Sugalski, Jonathan Sillito, P6I
Dan Sugalski wrote:

> At 8:25 PM +0200 6/19/03, Leopold Toetsch wrote:
>
>> The primary question is: Why do we save and restore what part of context.
>
>
> Very good question:


Thanks for the detailed list.


> *) System stack

> *) User stack and register stacks

> *) Lexical pad pointer

Ok, these we already have.


> *) Global namespace pointer

This would require a new opcode e.g. B<new_global_table Sx> to be
useful. Also the global table handling as of pdd06 is missing. This
global table stuff in pdd06 looks like we need a hash of hashes for the
globals. Saving such a HoH seems rather expensive, we don't have COW
hashes, so, with current data structures this would be a nested
hash_clone() call.


> *) Opcode function table because we may have different opcode functions
> in the new sub

This probably can wait some time.


> *) Current bytecode segment pointer since we may be entering a new
> bytecode segment with a new constant table and such

Needs still some work in the packfile code, which currently is some PITA
because of the compat stuff for assemble.pl Either we toss it or it has
to use pack*.c.


> *) Interp flags (maybe, I'm not sure)

Changing run cores needs restart opcodes. Just restoring the flags isn't
very useful.


> *) Warnings, since warnings are lexically scoped

Yep. Is there any reason that the warning flags are malloced instead of
using an UINTVAL?


> *) Permission and privilege info (which we don't have yet)

Yep

leo

Dan Sugalski

unread,
Jun 23, 2003, 1:42:21 PM6/23/03
to Leopold Toetsch, Jonathan Sillito, P6I
At 12:05 PM +0200 6/22/03, Leopold Toetsch wrote:

>Dan Sugalski wrote:
>*) Global namespace pointer
>
>This would require a new opcode e.g. B<new_global_table Sx> to be
>useful. Also the global table handling as of pdd06 is missing. This
>global table stuff in pdd06 looks like we need a hash of hashes for
>the globals. Saving such a HoH seems rather expensive, we don't have
>COW hashes, so, with current data structures this would be a nested
>hash_clone() call.

We don't so much need a hash of hashes as a linked list of hashes.
And yeah, it'll definitely have a performance impact on global
lookups.

>>*) Opcode function table because we may have different opcode
>>functions in the new sub
>
>This probably can wait some time.

I'm of two minds on this one--on the one hand I agree that we don't
need it now. On the other, I'm concerned that if we don't have it in
now we'll do something that makes it very difficult later.

>>*) Current bytecode segment pointer since we may be entering a new
>>bytecode segment with a new constant table and such
>
>Needs still some work in the packfile code, which currently is some
>PITA because of the compat stuff for assemble.pl Either we toss it
>or it has to use pack*.c.

I'd be perfectly happy to see assemble.pl go and have parrot itself
be capable of generating bytecode from input assembly.

>>*) Interp flags (maybe, I'm not sure)
>
>Changing run cores needs restart opcodes. Just restoring the flags
>isn't very useful.

Fair enough. Scratch that one from the list.

>>*) Warnings, since warnings are lexically scoped
>
>Yep. Is there any reason that the warning flags are malloced instead
>of using an UINTVAL?

I think this is in part a result of the experiences we had with
perl's warnings. Warnings and warning classes multiply at an amazing
rate, and it's pretty easy to blow through a UINTVAL's worth of bits.

Leopold Toetsch

unread,
Jun 23, 2003, 5:31:15 PM6/23/03
to Dan Sugalski, Jonathan Sillito, P6I
Dan Sugalski wrote:

> At 12:05 PM +0200 6/22/03, Leopold Toetsch wrote:
>
>> Dan Sugalski wrote:
>> *) Global namespace pointer

> We don't so much need a hash of hashes as a linked list of hashes. And
> yeah, it'll definitely have a performance impact on global lookups.

Fine. Then we just need to save the linx chain and reset it to the saved
end-pointer or so, *if* that sub does use globals.


>>> *) Opcode function

>> This probably can wait some time.
>
> I'm of two minds on this one--on the one hand I agree that we don't need
> it now. On the other, I'm concerned that if we don't have it in now
> we'll do something that makes it very difficult later.

Ok. Then please have (again) a look at my proposal:
Subject: [RfC] a scheme for core.ops extending
Date: Wed, 05 Feb 2003 12:28:21 +0100
This basically does extend loaded opfunc tables. Existing tables are
still valid. A core func table would provide basic functionality and
adding e.g. math.ops or trig.ops would append these. The added functions
get just an offset depending on the load sequence - no absoult values.
This of cource requires that assembler and runtime are in sync of the
modules that require new oplibs. But IMHO we do need such behavior
anyway for Perl6 so that e.g. BEGIN and runtime are in sync.
(If archives dont have the attached proof of concept I can repost it)

Anyway I think, this would make saving/resetting opfunc tables an
operation of storing the current highest opcode number.


>>> *) Current bytecode segment pointer
>>

>> Needs still some work in the packfile code, which currently is some
>> PITA because of the compat stuff for assemble.pl Either we toss it or
>> it has to use pack*.c.
>
> I'd be perfectly happy to see assemble.pl go and have parrot itself be
> capable of generating bytecode from input assembly.

Could be a first - and already longer proposed - step: just move
languages/imcc into $root/imcc and s/imcc/parrot/ + some Makefile and
test hacks.


>>> *) Warnings, since warnings are lexically scoped
>> Yep. Is there any reason that the warning flags are malloced instead
>> of using an UINTVAL?
> I think this is in part a result of the experiences we had with perl's
> warnings. Warnings and warning classes multiply at an amazing rate, and
> it's pretty easy to blow through a UINTVAL's worth of bits.

Albeit most of the warning will come out of $perl6-parser, this is might
for sure happen. Shouldn't be to expensive, to setup a warnings
structure once per new callee and (eventually if the sub messes with the
flags) update the area at invoke time.
leo

0 new messages