[armedbear-devel] 0.18 and beyond

logicmoo at gmail.com logicmoo at gmail.com
Fri Nov 6 07:24:04 UTC 2009


Dissregared the last email there was a Hypelink that I misspelled as well as rewrote my last post to make clearer



----- Original Message ----- 
From: "Ville Voutilainen" <ville.voutilainen at gmail.com>
To: <dmiles at users.sourceforge.net>
Cc: "Armed Bear" <armedbear-devel at common-lisp.net>
Sent: Thursday, November 05, 2009 9:57 PM
Subject: Re: [armedbear-devel] 0.18 and beyond


> 2009/11/6  <logicmoo at gmail.com>:
>>>> Other java lisps define each Primitive execute as a single static function
>>>> in a trampolines file.
>>>> The Primitive itself just calls the static function in the trampolines (
>>>This is a useful technique to speed up compiled code. It could also
>>>speed up startup times as long as you don't invoke such primitives
>> Indeed
>
> The translation looks like there's no longer a Primitive that extends
> LispObject.

No longer a "requirement" for the compiler to *have to* use a Primitive

> Do we generate wrappers on the fly?
Correct
As you foresee, for cases like #'APPLY/#'FUNCALL etc  and from the interpreter
it is done on the fly.


Previous code that read:
      declareFunction(myName,"primitive_CHAR_LESS_THAN_execute_1_0_false","CHAR<",1,0,false);
      declareFunction(myName,"primitive_CHAR_LESS_THAN_execute_2_0_false","CHAR<",2,0,false);
      declareFunction(myName,"primitive_CHAR_LESS_THAN_execute_0_0_true","CHAR<",0,0,true);

Does actually create 5 objects:

One Symbol:  Symbol s = intern("CHAR<",pkg);

One Primtive subclass called a FunctorIndexer

FunctorIndexer p = new FunctorIndexer(s);

One Primtive is placed inside the symbol-function: s.setSymbolFunction(p);


Three Functors:
p.Add( new  ForwardFunctor(s,myName,"primitive_CHAR_LESS_THAN_execute_1_0_false","CHAR<",1,0,false));
p.Add  ( new  ForwardFunctor(s,myName,"primitive_CHAR_LESS_THAN_execute_2_0_false","CHAR<",2,0,false));
p.Add(  new  ForwardFunctor(s,myName,"primitive_CHAR_LESS_THAN_execute_0_0_true","CHAR<",0,0,true));

 This will later be used to index the call sigs to the best ForwardFunctor.


So far we have made 5 objects:     s,p,f0,f1,f2
------------------------------------------------------------------------------------------
On first use: lets say:

(funcall 'char< #\a #\b #\c)

thats 3 args ins .. the best match is f2 -


This  transistion is handled in here:
http://larkc.svn.sourceforge.net/viewvc/larkc/trunk/platform/src/com/cyc/tool/subl/jrtl/nativeCode/type/operator/FixedArityFunctor.java?revision=254&view=markup

It creates one class that implments processArgs(LispObject r0,LispObject r1,LispObject r2)
And loads the arity3Cache of the  FunctorIndexer which physically calls the static function:

      return primitive_CHAR_LESS_THAN_execute_0_0_true(new LispObject[]{r0,r1,r2});

-----------------------
So far we have made 6 objects
-----------------------

Note though this machinery is only used in FUNCALL and interpreted code

    When hitting the functor generator .. it should be considered "worse case"

But serves a better way case than hitting the reflection on line 62 of
http://larkc.svn.sourceforge.net/viewvc/larkc/trunk/platform/src/com/cyc/tool/subl/jrtl/nativeCode/type/operator/SubLCompiledFunction.java?revision=254&view=markup
(But this 2ndary wrapper technique still isn't that bad. )


> How do you then pass the primitive as one? Like passing EQ/EQUAL/EQUALP
> to FIND/POSITION family of functions?
You find-or-create the Symbol like    findSymbol("EQ",pgk).getSymbolFunction().execue(a0,a1,etc); like before.

".getSymbolFunction()"  is where the new magic takes place


> Or user-defined functions that take
> functions, and you don't know the type and must box it (aka pass it as
> a LispObject)?

Currently all execute(..,.,.,.) signatures take LispObject as before.

However with not much more work it is possible to make a cache of unboxed versions like...

public final static LispObject primitive_CHAR_LESS_THAN_execute_2_0_false_nobox(char req0, char req1) {
    return req0 < req1? T : NIL;
}


Registered the same way to the interpreter and compiler:

    declareFunction(myName,"primitive_CHAR_LESS_THAN_execute_2_0_false_unboxed","CHAR<",2,0,false);





Actually if you want, is even simplier to not go thru the explicit "registration process" but using Annotations

@InlineCompiler(symbolname="CHAR<", package="COMMON-LISP");
public final static LispObject primitive_CHAR_LESS_THAN_execute_2_0_false_nobox(char req0, char req1) {
    return req0 < req1? T : NIL;
}





More information about the armedbear-devel mailing list