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

Reply via email to