Thanks so much Curt for the detailed reply!

Shay.

On Sun, Oct 18, 2009 at 3:52 PM, Curt Hagenlocher <cu...@microsoft.com>wrote:

>  A dynamic call site is an object that takes a certain number of arguments
> and a kind of description of how to combine those arguments into a result.
> The "description" (also known as the call site binder) generates code that
> is stored in the call site and keyed on some property of the arguments --
> usually the type. So a call site that's used to perform a "less than"
> operation must be attached to code that knows how to look at two arguments
> and generate IL which will determine whether the first arg is less than the
> second one (or, if the comparison is not valid, IL which will throw an
> exception).
>
>
>
> Now let's say you have a bit of Ruby that says "c = a < b". When the
> IronRuby compiler generates code for this, it doesn't know what the types of
> "a" and "b" are, so it can't emit the actual comparison. Instead, it creates
> a call site that takes two arguments and returns a result, and it attaches
> this call site to a binder that says "call the < function that's defined on
> the first object". The first time the code is executed, a = 1 and b = 3. The
> binder looks at the type of a and determines that it should call Fixnum.<,
> so it creates code in the form of a delegate which will do that (let's name
> this "CALL1"), and will store that delegate in the call site along with a
> test ("TEST1") which indicates when that delegate is valid.
>
>
>
> The next time the code is executed, a = 3 and b = 7. The call site executes
> TEST1, which returns a positive result so it uses CALL1 to execute the
> comparison. The binder does not get involved.
>
>
>
> The third time the code is executed, a = "hello" and b = "world". TEST1
> fails, so the call site asks the binder to analyze the new situation and
> come up with a TEST2 and CALL2 that will call String.< for an argument of
> type string.
>
>
>
> All of this is basically DLR 101, so I'm sorry if it's stuff you already
> know :).
>
>
>
> Now it should be pretty obvious that a call site's performance degrades as
> it sees a greater variety of types. The site has more and more TEST methods
> to run before it gets a positive result or knows that it has to fall back to
> the binder to generate new code.
>
>
>
> Consider a method like Array.sort. This method needs to perform comparisons
> on individual array elements of arbitrary type. That means that a dynamic
> call site needs to be involved. In earlier versions of IronRuby, we only had
> two choices -- use a single call site that's shared between all calls to
> Array.sort, or create a new site each time sort is called. The former
> approach suffers from the problem of "going megamorphic", that is, having
> too many tests to be called for each comparison. But with the latter, we
> lose out on some efficiency because we need to create a new call site and
> run the binder code at least once for every call to sort.
>
>
>
> The CallSiteStorage mechanism adds a third option. It allows the library
> author to push the location of the call site cache up to the place where
> Array.sort is actually called. This then creates a situation that is much
> more like the one for "c = a < b"; there's a one-for-one relationship
> between the call site in user code and the call site cache. This is a good
> level for caching, because any given array in user code that calls "sort" is
> very likely to contain elements of only a single type or small number of
> types.
>
>
>
>
>
> So to answer your questions more specifically,
>
> 1. The IronRuby compiler automatically creates three BinaryOpStorage
> objects for each call to Array.sort -- one for each of the three parameters
> which have that type -- and emits code to insert those parameter onto the
> call stack before calling ArrayOps.Sort.
>
> 2. The BinaryOpStorage object is not tied to a specific operation at
> creation; it's just a cache. It's how the BinaryOpStorage is used that
> determines the kind of code stored in the cache.
>
> 3. Specifically, if you trace the code path into Protocols.Compare and
> Protocols.ConvertCompareResult, you'll see that these storages are
> initialized with calls to "<=>", "<" and ">", respectively.
>
> 4. The names of the parameters are irrelevant. :)
>
>
>
>
>
> There's a general lesson here -- the DLR is like porridge; it's best when
> it's neither too hot nor too cold.
>
>
>
>
>
> *From:* ironruby-core-boun...@rubyforge.org [mailto:
> ironruby-core-boun...@rubyforge.org] *On Behalf Of *Shay Friedman
> *Sent:* Saturday, October 17, 2009 11:14 PM
> *To:* ironruby-core@rubyforge.org
> *Subject:* [Ironruby-core] CallSiteStorage for [RubyMethod]
>
>
>
> Hi,
>
> I'm working on a native extension by writing an IronRuby library in C#. I
> hit the wall with the CallSiteStorage parameters that can optionally come as
> the first 0 or more parameters for a ruby method.
>
> What are they and what's their use? I tried to understand that from their
> current uses accross the code by I couldn't understand how IronRuby knows
> what to set there.
>
> For example, this is from ArrayOps:
> [RubyMethod("sort")]
> public static object Sort(
>   BinaryOpStorage/*!*/ comparisonStorage,
>   BinaryOpStorage/*!*/ lessThanStorage,
>   BinaryOpStorage/*!*/ greaterThanStorage,
>   BlockParam block, RubyArray/*!*/ self) {
>     ...
>     ...
> }
>
> How does IronRuby knows that the first should be a comparison storage, the
> second a less-than storage and the third a greater-than storage? is it
> because of the name of the parameter?
>
> Thanks!
> Shay.
>
> --
> --------------------------------------------------
> Shay Friedman
> Author of IronRuby Unleashed
> http://www.IronShay.com
> Follow me: http://twitter.com/ironshay
>
> _______________________________________________
> Ironruby-core mailing list
> Ironruby-core@rubyforge.org
> http://rubyforge.org/mailman/listinfo/ironruby-core
>
>


-- 
--------------------------------------------------
Shay Friedman
Author of IronRuby Unleashed
http://www.IronShay.com
Follow me: http://twitter.com/ironshay
_______________________________________________
Ironruby-core mailing list
Ironruby-core@rubyforge.org
http://rubyforge.org/mailman/listinfo/ironruby-core

Reply via email to