Charles O Nutter wrote: > > - Rather than allocating a frame per-call, as you do with new > IRubyObject[1], there would be a single per-thread stack (implemented as > an array/list) from which we'd allocate our frame. This eliminates one > more object allocation per-call. Where today we instantiate a Frame, > which instantiates a Scope, which instantiates an IRubyObject[] that > contains the vars, we will then just index into that stack. Less memory > overhead, less object allocation overhead per-call, and a less garbage > to collect. > > int base = threadContext.allocateFrame(numOfLocals); > threadContext.getStack()[base + 1] // accesses second indexed variable > in the the locals > > - Blocks would then only need to know one thing, really, to access local > vars: the position of those vars in the stack. > - I haven't figured out the best way to handle procs and lambdas yet; > they introduce some interesting side effects. Currently, procs and > lambdas are no worse cost than blocks are...but blocks should be cheap, > like they are in Ruby. I need to understand the scoping of proc/lambda > as regards local vars a bit better before I come up with anything. > - You are correct about "real closures" being an issue...I don't have a > good answer for that yet, but I think sacrificing real closure speed to > make simple blocks faster would be a big win...blocks are used *so much* > more than real closures like proc and lambda. > > This is all still a bit theoretical, but I feel like eliminating > per-call allocations in favor of a thread-local stack machine would save > us a lot of overhead. >
Hi, 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. 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. -- Ola Bini (http://ola-bini.blogspot.com) JvYAML, RbYAML, JRuby and Jatha contributor System Developer, Karolinska Institutet (http://www.ki.se) OLogix Consulting (http://www.ologix.com) "Yields falsehood when quined" yields falsehood when quined. ------------------------------------------------------------------------- Using Tomcat but need to do more? Need to support web services, security? Get stuff done quickly with pre-integrated technology to make your job easier Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642 _______________________________________________ Jruby-devel mailing list Jruby-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/jruby-devel