[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?
As you foresee, for cases like #'APPLY/#'FUNCALL etc  and from the interpreter
it is done on the fly.

Previous code that read:

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:

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
(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:


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