At 10:35 AM +0200 7/20/04, Leopold Toetsch wrote:
Dan Sugalski <[EMAIL PROTECTED]> wrote:

 Leo, we've talked about this before. The sensible and straightforward
 thing to do in a case like this is to tag in the sub pmc which
 register frames are used by the sub.

And what, if the sub calls another sub?

That's straightforward, and I didn't flesh this out properly.

For this to work, you need two things:

1) A per-sub mask of register frames it uses
2) A currently dirty frame marker

When a sub is called (however it's called) we:

a) Do a logical and of the sub's used mask and the dirty mask
b) Save those frames
c) Set the mask to a logical or of the used and dirty mask

And yes, this will, with sufficient call depth, result in an all-bits-set dirty mask, which is also why we allow bytecode to *unset* bits in the dirty frame marker, but only if those bits are set in the sub's mask of frames it uses.

We probably need to move the sub-being-called PMC into a separate area and out of the P registers, the same way as we need to move the return continuation out.

This is P registers only. We have I0..I4. Should be preserved. S0 for
methods. We don't do it currently.

Since we're *caller* save, the only time those registers should be saved is if the *caller* cares about them, or the *caller* can't be sure. The only time the caller can't be sure is when we're calling into a vtable method. (If the caller fails to save registers on a regular sub or method call, that's their own problem) Those are relatively rare, and as such I'm not that inclined to optimize for them at the expense of mainline code.


Having said that, I think the scheme outlined above handles the issues of vtable calling and lets us toss the manual pushtop/savetop around sub and method calls if we choose to do that.

A illegal speed hack. And as said
(you are always snipping import things ;),

No, I snip when you head way off into the west. You tend to get too tied up in the details of the current implementation. I don't much give a damn about the implementation (other than at a meta-level--the code should be documented, commented, follow the coding conventions (which, yes, I'm sometimes guilty of not) and understandable) since it's often not relevant other than to point out places where the architecture has issues.


 whenever a subroutine or
method will use some native S or N registers, we end up saving 640
bytes. In *each* function call. And restore 640 bytes on each return.

My proposal did show a way, how to copy ~640 bytes *once* per subroutine
creation. You didn't even comment that.

Well, it seemed obviously wrong, and inefficient in most cases, so I didn't. If you don't like the scheme I outlined above I can go into more detail.


 > I'm not sure what you're thinking of with coroutines.

I'm thinking of using 2 continuations for jumping back and forth.

That can't work quite right as it stands, though I just realized what we need to do to make it work. Requires we have a return continuation slot in the interpreter structure separate from the P registers. (Which we've sorta planned on anyway) Otherwise exception handlers won't nest right.
--
Dan


--------------------------------------it's like this-------------------
Dan Sugalski                          even samurai
[EMAIL PROTECTED]                         have teddy bears and even
                                      teddy bears get drunk

Reply via email to