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
>

Reply via email to