[armedbear-devel] Inline primitives as static method calls

logicmoo at gmail.com logicmoo at gmail.com
Tue Nov 10 10:13:10 UTC 2009

> ----- Original Message ----- 
> From: "Alessio Stalla" <alessiostalla at gmail.com>
> To: <dmiles at users.sourceforge.net>
> Cc: "Armed Bear" <armedbear-devel at common-lisp.net>
> Sent: Tuesday, November 10, 2009 1:12 AM
> Subject: Re: [armedbear-devel] Inline primitives as static method calls
> On Tue, Nov 10, 2009 at 9:01 AM,  <logicmoo at gmail.com> wrote:
>> Alessio,
>> Excellent Work!
>> Your .patch is what I meant.
> Thanks!
>>> when compiled it is translated as a direct call to the static
>>> method, without passing through the symbol, which is faster than now
>> Perfect - Yeah
>> A Side note:
>>> When interpreted or passed as a higher-order function an
>>> InlinedPrimitive calls the static method through reflection, resulting
>>> in slower performance than now.
>> I wrote a workaround for this into LarKC because of the performance
>> degradation.
>> So later on....
>> Like after we have everything working/vetted calling static inlines as much
>> as possible.
>> And using InlinePrimtives to call reflection...
>> We'll have some options like: "FixedArityFunctor":
>> http://larkc.svn.sourceforge.net/viewvc/larkc/trunk/platform/src/com/cyc/tool/subl/jrtl/nativeCode/type/operator/FixedArityFunctor.java
>> What I did was created a new Class via ASM that contains a single
>> execute(a,b,c,d,e,f) signature per "args used".
>> That simply calls the static method .
>> So in InlinePrimitive later suplimented with some extras like:
>> //The methodWith0Args - methodWithNArgs is what that .java url above
>> generates.
>> LispObject execute() {
>> return methodWith0Args.evaluate();
>> }
>> LispObject execute(LispObject a0) {
>> return methodWith1Args.evaluate(a0);
>> }
>> LispObject execute(LispObject a0,LispObject a1) {
>> return methodWith2Args.evaluate(a0,a1);
>> }
>> etc
>> Figured I should mention the "FixedArityFunctor" so we dont get scared off
>> by any performance
>> degration of higher level calls before we learn all the benefits of inlining
>> static functions!
> Ok, I'm not sure I followed everything.

Oh the above was attempting to describe LarKC SubLisp implementation
of this article: http://www.ibm.com/developerworks/java/library/j-dyn0610/
I couldnt find it before sending the email!
The intial LarKC implemention used reflection in the same maner as InlinedPrimive does. The after reading that article, I found I 
could replace Method[] cache inside InlinedPrimive with generated methodStubs produced runtime for reflection performance.

> but consider also that the
> implementation through reflection is the default one, for convenience,
> but you can still override the various execute() methods and call the
> static method directly (of course, you have to make sure the method
> you call is the same as the one you pass in the constructor, or things
> start to behave differently in interpreted vs compiled code and that's
> definitely not good :D). Something like
> new InlinedPrimitive(My.class, "myMethod", ...) {
>    public LispObject execute(LispObject arg) {
>      return My.myMethod(arg);
>    }
> }

Yup, InlinePrimtive still leaves that option open.
If someone really wanted to, they can do that with a couple of their InlinedPrimtives if they noticed one particualtar method was 
getting called quite a bit.  Making the instance execute call the static function
(Like EQ/EQL/EQUAL for instance avoiding reflection.)

> The class I posted lacks the constructors taking the class and the
> method, because I have been lazy ;), but they can easily be added -
> with the caveat that, since the call to super() must be the first and
> for Function super() sometimes (always?) installs the function in a
> symbol (iirc), if you pass a wrong class/method to InlinedPrimitive
> and as a result an exception is thrown, you'll have a symbol pointing
> to an invalid function.

I realy do like how you did it as factory method:

    public static final Primitive COPY_TREE =
      "copyTree", Symbol.COPY_TREE,  "object");

And depending on safety/speed you could save the string name of the class and method name for later and not even try to resolve the 
method[] until first time call.. and signal an error then if not found.  This could be used like autoloading.

> Bye,
> Ale 

More information about the armedbear-devel mailing list