On 7/17/06, Ola Bini <[EMAIL PROTECTED]> wrote:
I can't really see where you would put that allocateFrame, if you don't
do it on a per-call basis. Actually, maybe I'm using bad names in my
code, but I'm not talking about a heavyweight real object-Frame, but a
frame which is a an array, so the most we'll ever allocate is an array
with enough space for all local vars. The problem with not having one
each is that you can't really pop the locals vars from the stack when
you're finished with them, unless you keep a count of local vars and
then walk up again popping each one. I'm not sure you save much by doing
this. Having a List<RubyObject[]> stack or a RubyObject[] stack doesn't
seem to make much difference, and being able to pop a full frame out of
existence seem to be worth something. I guess, basically the tradeof is
between reallocating and copying the whole stack once in a while, and
popping by decrementing and setting to null (we have to set null on used
parts so we can GC), or to have a LinkedList or Stack where adding a new
frame is fast, but allocating a new small array all the time... Hmm.
Hard to say what's best, actually.

When we get down to something as lightweight as a single array, it may or may not make much difference. A single large array allows much lower-level machine design, since we can more accurately approximate a stack-based machine, but it's possible (likely?) that with closures and blocks Ruby does not entirely fit into a traditional stack machine model. At any rate, even an array-per-call would be far lighter-weight than what we have now.

However, as far as popping vars off the stack:

Arrays.fill(stack, base, base + count - 1, runtime.getNil())
// stack.top becomes base behind the scenes

...is pretty fast too.

Regarding real procs/lambdas and how handle closures I think I may have
some ideas. It's not really a hard problem, but it's best compile those
parts in two passes, so you can save away the variables used on a
separate closure space for that block. Most of this could probably made
static at runtime.

Closures are definitely made easier by having vars in multiple IRubyObject[]...all they'd have to do is hold a reference to that frame. If the method ends before the closure is called, it's no longer on the Ruby frame stack...but it's still accessible in its final state to any instantiated closures. The thought behind a single large stack was that we could avoid reallocating that array every time to give some benefit to blocks, but that benefit may not be enough to warrant additional complexity (and may be incompatible with real closures).

--
Charles Oliver Nutter @ headius.blogspot.com
JRuby Developer @ www.jruby.org
Application Architect @ www.ventera.com
-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys -- and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
_______________________________________________
Jruby-devel mailing list
Jruby-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/jruby-devel

Reply via email to