[armedbear-devel] Inline primitives as static method calls

Alessio Stalla alessiostalla at gmail.com
Tue Nov 10 09:12:32 UTC 2009

On Tue, Nov 10, 2009 at 9:01 AM,  <logicmoo at gmail.com> wrote:
> Alessio,
> Excellent Work!
> Your .patch is what I meant.


>> 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, 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);

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.


More information about the armedbear-devel mailing list