Good idea. This would make define_method free in a lot of common cases. It would also give rise to optimizations in Ruby code that are kinda unpleasant (to make blocks faster, don't use local variables), but hey... -- Yehuda
On Tue, Jul 28, 2009 at 9:37 PM, Thomas E Enebo <tom.en...@gmail.com> wrote: > On Wed, Jul 29, 2009 at 7:55 AM, Charles Oliver > Nutter<head...@headius.com> wrote: > > On Sat, Jul 25, 2009 at 10:37 PM, Thomas E Enebo<tom.en...@gmail.com> > wrote: > >> Hotspot will synthesize types based on runtime profiling for things > >> like interfaces so that it can internally perform static dispatch (or > >> so I have been told). They also have guards to deopt if their type > >> assumptions are wrong. We could do something similar since as others > >> have noted at some point Ruby classes hit an unchanging state in 99% > >> of all applications (yes, I made that number up but I will stand by it > >> :) ). > > > > I think this idea has a lot of promise, especially if we can cleanly > > generate synthetic interfaces at runtime and slowly raise object types > > to new class types that implement those interfaces. So one scenario > > could be that if you have: > > > > class Foo > > def bar; end > > end > > > > And we generate a synthetic "bar" interface open first seeing the > > method in the compiler, then we can later lift the Foo class into a > > real Java class that implements "bar" and do a simple interface > > dispatch from then on. Or if we've got enough information from a > > single pass compile of a file, generate such interfaces and > > implementations right away, using them for static interface dispatch > > wherever possible. > > > > There's a lot of weird and unwieldy tools, but I think there's some > > combination that can get us really excellent perf. > > > >> c is probably the grail for good closure performance. > >> > >> The cases for whether you can or need to keep variables around is > >> probably the most interesting discussion. I think it could be broken > >> into at least one thread by itself. I think collectively we can > >> identify many special cases where we don't need to capture all > >> variables. Of course that assume we can track changes to target > >> classes method. If it changes for some reason we need to be able to > >> deopt. > > ... > >> My bigger question is can we figure out whether these things (send, > >> eval, binding) are actually the nasty methods rather than just > >> assuming anything with these names are the nasty methods? I know the > >> answer is yes, but I think internally we should have some systemic way > >> of tracking dangerous entities so we have one framework to use for > >> various optimizations.... > > > > We can do so at runtime, of course. If we just use the name as a > > trigger that "runtime analysis is required" then we can have a simple > > guard on those calls that first checks if it's *actually* the bad > > version of the method, and at that point branches to a slow-path > > version of the code with all local variables lifted to the heap. So > > something like this: > > > > Ruby code: > > def stringer(local1) > > local2 = "to_s" > > local1.send(local2) > > end > > > > Rough generated pseudo-java > > public IRubyObject _optimized_stringer_(IRubyObject local1) { > > IRubyObject local2 > > local2 = newString("to_s"); > > > > DynamicMethod sendMethod = local1.getMethod("send"); > > if (sendMethod.needsHeapAccess()) { > > return _deoptimized_stringer_line_2(local1, local2); > > } > > return sendMethod.call(local1, local2); > > } > > > > public IRubyObject _deoptimized_stringer_line_2(IRubyObject local1, > > IRubyObject local2) { > > DynamicScope scope = newScope(local1, local2); > > > > // proceed with "bad" send with heap scope appropriately provided > > } > > > > This obviously incurs a lot of overhead for those bad methods, since > > we need the deopt path to be present, and we need to generate perhaps > > one deoptimized code body per "evil" method called. But those methods > > all incur their own overhead that impacts performance in the best of > > cases, so they're going to be problematic no matter what. This would > > at least reduce the overhead when they're not one of the bad methods. > > > > And if we're able to propagate throughout a method that the "eval" > > we're getting back is always a "friendly" one, we only need to check > > once. > > > >>> 6. Dynamic/Late binding: This is where the execution context comes from > an > >>> explicit binding argument (proc, binding, closure). This is something > I was > >>> not aware of till recently. > >> > >> Yucky stuff. There are some times when we can probably optimize based > >> on knowing how the binding/proc/closure is used. As Charlie notes, > >> AOT-defined Ruby methods we fully understand like core method impls > >> can be optimized. I think we can even make arbitrary ruby methods > >> optimize by indicating on compilation whether they do wacky stuff. > >> Some chicken and egg stuff in my mind....we need to know that a block > >> will be passed to a method and that that method is not using the block > >> in a strange way before creating the block itself. > > > > Yehuda's idea would probably work well for us; we'll just add some > > additional informational flags about a target DynamicMethod to the > > DynamicMethod superclass, and use that to do a similar deopt as > > above... targetMethod.isCapturingBlock() or something. > > Yeah once we know which target method will be receiving the block we > can know how the block can be abused by some flags on the method. > This seems like a great idea. Similiarly (as we have talked about > before), if we know that a block is not capturing any information we > could just convert it to be a DynamicMethod itself and then inline the > callsite to that 'new' method (that is assuming the block does not > only have a single local parameter). <-- Subbu: block parameter > assignment is another interesting place to study if you have not > already. > > -Tom > > -- > blog: http://blog.enebo.com twitter: tom_enebo > mail: tom.en...@gmail.com > > --------------------------------------------------------------------- > To unsubscribe from this list, please visit: > > http://xircles.codehaus.org/manage_email > > > -- Yehuda Katz Developer | Engine Yard (ph) 718.877.1325