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