On Sat, Jul 25, 2009 at 11:49 AM, Yehuda Katz <[email protected]> wrote:
> It seems to me that *all* calls to "dangerous methods" are basically leaf > calls, because you only need to grab the "frame" information one frame above > where the information was added. > So you should be able to have each Ruby *thread* allocate a single > thread-local slot per "frame" variable plus a flag slot. > I am not sure if this is true, since you can store procs and blocks, pass them around, and call them whenever, wherever. In addition, you can have multiple instances of a frame for a method be active at the same time, i.e. if foo is a method, you could have 100 different instances of foo's execution environment in 100 unique frame objects which means you have to allocate them on a heap and subject them to GC like any other java object. Or did I misunderstand what you said here? Subbu. > A call through the "frame" protocol would look like this: > > call method > look in flag slot > if flag on > copy frame variables into local context > end > > This effectively means that calling a method through the protocol when the > method turns out to not be dangerous just adds a single boolean check, which > should be incredibly cheap. > > Also, if someone aliases a dangerous method, it's probably ok to just flush > all compiled bytecode (because it basically never happens and when it does > it's reasonably to take a big hit). > > -- Yehuda > > On Sat, Jul 25, 2009 at 3:44 PM, Charles Oliver Nutter < > [email protected]> wrote: > >> I was talking with Yehuda today and I think we came up with a couple >> solutions for eliminating frames. >> >> The cases where we have problems are: >> >> * All methods that read or write backref >> * All methods that read or write lastline >> * All methods that read or write visibility >> * All methods that have arbitrary access to the binding (eval, binding, >> ...) >> * Methods that have closures that do any of these things, or where the >> closure is used as a binding elsewhere >> >> The first three cases could be solved as follows: >> >> Backref and lastline can only be read or written in one of two ways: >> via a Java-implemented core class methods, or via the syntactic >> constructs $~ for backref or $_ for lastline. Visibility can only be >> written by public/private/protected method calls, and only gets read >> by Java code that handles plumbing new methods. All three are scoped >> at the nearest "hard" scoping boundary, like a method or a class, and >> closures within that scope share the same slot (this last point is a >> little fuzzy, but it's good enough for illustration purposes). >> >> Currently, all Ruby code bodies prepare a heap-based structure (Frame) >> for every call, just in case it might be needed. This is in large part >> a reason for remaining slowness in Ruby execution, since even in >> compiled mode we have to prepare this structure on the way in and drop >> it on the way out, even if it's never used. >> >> However it turns out that the methods that read/write >> backref/lastline/visibility are *leaf* methods; there's exactly one >> hop to get to the native code that manipulates them. >> >> I believe it's time we had an additional call path that can include a >> "Blob" object that contains these fields. With this call path, any >> time one of these "potentially dangerous" method names is seen in >> code, we could *lazily* prepare the Blob and pass it down the call >> path. It would eventually arrive in the target method and be used to >> do the read/write as though it were an "out" variable. So this >> immediately isolates those frame fields' overhead to cases where >> they're potentially going to be called (barring aliasing effects). >> >> If we lifted the lookup of the target method all the way to the call >> site, we could physically inspect it to see if it *is* one of those >> "dangerous methods" and only pass the Blob in those cases. >> >> If we also added construction and passing of this Blob into the IR, we >> could see whether the Blob is ever subsequently read from or written >> to, and potentially *never* allocate it whatsoever. >> >> I think this is a very simple way for us to safely eliminate some >> framing cost. I'll try to make the idea a bit more concrete. >> >> - Charlie >> >> --------------------------------------------------------------------- >> To unsubscribe from this list, please visit: >> >> http://xircles.codehaus.org/manage_email >> >> >> > > > -- > Yehuda Katz > Developer | Engine Yard > (ph) 718.877.1325 >
