#25 JIT via lightning

closed-accepted
Sam Steingold
None
5
2013-11-28
2008-01-27
Yann N. Dauphin
No

Still incomplete JIT compiler for CLISP.

The jit compilation occurs at every function call(no reuse), so it runs slower for now.

Lightning is used because:
- It's portable. Can reportedly be ported under a day.
- It's simple. If the GNU lightning project was to stop, it wouldn't be a problem. Maintaining it is easy. Not so for LLVM.
- It's lean and mean. Code generation is straightforward, so very fast.

Tested on x86 with:

- Linux
- Mac OS X: Must 'export DYLD_BIND_AT_LAUNCH=' for now because the dynamic linker messes with jit function calls

The patch is too big for SF so:
http://www.step.polymtl.ca/~polyrad/polyrad/jit-clisp-2.43.patch

Discussion

1 2 > >> (Page 1 of 2)
  • Sam Steingold
    Sam Steingold
    2008-01-28

    Logged In: YES
    user_id=5735
    Originator: NO

    the patch is too big because it includes some binary files (.DS_Store) and the full sources for lightning.
    please assume that lightning is installed on the developer's machine.
    please include only the eval.d and jit.h, NOT lightning sources
    please do NOT use "//" comments

     
  • Sam Steingold
    Sam Steingold
    2008-01-28

    Logged In: YES
    user_id=5735
    Originator: NO

    it would be nice if you could elaborate on advantages of lightning over libjit http://freshmeat.net/projects/libjit/

     
  • Logged In: YES
    user_id=1993164
    Originator: YES

    jit-clisp-cvs-20080131.patch.gz:

    This new patch includes the clean ups from Reini and will work against a clean checkout from CVS.
    Please install the latest version of GNU lightning(at least 1.2b):
    http://git.savannah.gnu.org/gitweb/?p=lightning.git;a=snapshot;h=master

    It includes:
    - Modifying make file to add jit.d with jit.h as one of it's depedencies
    - Assuming GNU Lightning is installed
    - lispbibl sets USE_JIT if I80386 is set and registers are saved if !USE_JIT
    - Replacing all // comments with /**/ and tabs with spaces
    - Removed vestigial c source and jit_begin/end
    - Random cleanups

    News tests have been added to 'make check'. CLISP runs out of memory on one of the last ones, 'ctak'.
    This is because using longjmp can cause the memory of codeBuffer to leak. This is of course resolved by reusing the jit function.

    libjit vs lightning coming up.
    File Added: jit-clisp-cvs-20080131.patch.gz

     
  • Adds JIT Compiler to a clean CLISP dist from CVS

     
  • Sam Steingold
    Sam Steingold
    2008-02-04

    Logged In: YES
    user_id=5735
    Originator: NO

    thanks - I committed your patch.
    do codeBuffer & bcIndex have to be in constant memory (as in malloc) as opposed to lisp heap (movable by GC)?

     
  • Logged In: YES
    user_id=1993164
    Originator: YES

    codeBuffer and bcIndex have to be kept in constant memory because the operands of jump instructions in the JITed code are absolute positions.
    As a side-note, I do plan to remove the need to permanently store bcIndex. But that's not high priority.

    Thanks

     
  • Sam Steingold
    Sam Steingold
    2008-02-04

    • assigned_to: nobody --> haible
     
  • Sam Steingold
    Sam Steingold
    2008-02-04

    Logged In: YES
    user_id=5735
    Originator: NO

    then we are in trouble wrt re-using the compiled form.
    we need to store the compiled closure (codeBuffer + bcIndex &c) in the Cclosure as a Fpointer to a C structure.
    how do we release it when the Cclosure object is garbage collected?
    (a) the most direct way is to use finalize, but that would make GC very expensive.
    (b) we can add a 3rd phase between mark and copy - scan memory for dead cclosures and free the jit code (also expensive)
    (c) we can allocate Fpointers in a separate memory area and mark those who should be free()d with a special bit, i.e., special case finalizing Fpointers with free(), then the additional phase as in (b) has to be done only on that separate fpointer memory area. note that this feature may also be useful in other areas, e.g., FFI.
    Bruno, what do you think?

     
  • Sam Steingold
    Sam Steingold
    2008-02-05

    Logged In: YES
    user_id=5735
    Originator: NO

    oops - forgot that fpointers are usually immediate.
    we can have a chain of jit functions and mark them at gc_mark and then sweep them.
    this is a variation on the finaliser idea.

     
  • Sam Steingold
    Sam Steingold
    2008-02-13

    Logged In: YES
    user_id=5735
    Originator: NO

    OK, so the first stab at keeping JITC code with the closure is in the CVS head.
    Sorry about taking so long...

    Alas, I cannot really test it because lightning does not compile for me.
    what I observe now is when I compile lightning.c I see lots of errors and warnings, e.g.,

    lightning.c: In function 'jit_compile_':
    lightning.c:1304: warning: implicit declaration of function 'LEAQmr'
    lightning.c:1304: warning: value computed is not used
    lightning.c:1310: warning: value computed is not used
    lightning.c:1310: warning: value computed is not used
    lightning.c:1310: warning: value computed is not used
    lightning.c:1310: warning: value computed is not used
    lightning.c:1310: warning: value computed is not used
    lightning.c:1310: warning: value computed is not used
    lightning.c:1310: warning: value computed is not used
    lightning.c:1310: warning: value computed is not used
    lightning.c:1311: warning: value computed is not used
    lightning.c:1311: warning: value computed is not used
    lightning.c:1311: warning: value computed is not used
    lightning.c:1316: warning: implicit declaration of function 'jit_muli_ul'
    lightning.c:1316: warning: value computed is not used
    lightning.c:1324: error: 'cod_labels' undeclared (first use in this function)
    lightning.c:1324: error: (Each undeclared identifier is reported only once
    lightning.c:1324: error: for each function it appears in.)
    lightning.c:1324: error: expected ';' before ':' token
    lightning.c:1338: warning: value computed is not used
    lightning.c:1338: warning: value computed is not used
    lightning.c:1338: warning: value computed is not used
    lightning.c:1342: warning: value computed is not used
    lightning.c:1342: warning: value computed is not used
    lightning.c:1342: warning: value computed is not used
    lightning.c:1342: warning: value computed is not used
    lightning.c:1342: warning: value computed is not used
    lightning.c:1342: warning: value computed is not used
    lightning.c:1342: warning: value computed is not used
    lightning.c:1342: warning: value computed is not used
    lightning.c:1342: warning: value computed is not used
    lightning.c:1350: warning: value computed is not used
    lightning.c:1350: warning: value computed is not used
    lightning.c:1350: warning: value computed is not used
    lightning.c:1350: warning: value computed is not used
    lightning.c:1350: warning: value computed is not used
    lightning.c:1350: warning: value computed is not used
    lightning.c:1350: warning: value computed is not used
    lightning.c:1350: warning: value computed is not used
    lightning.c:1350: warning: value computed is not used
    lightning.c:1350: warning: value computed is not used
    lightning.c:1350: warning: value computed is not used
    lightning.c:1350: warning: value computed is not used
    lightning.c:1350: warning: cast from pointer to integer of different size
    lightning.c:1350: warning: implicit declaration of function '_s32P'
    lightning.c:1350: warning: value computed is not used
    lightning.c:1350: warning: value computed is not used
    lightning.c:1350: warning: cast from pointer to integer of different size
    lightning.c:1350: warning: value computed is not used
    lightning.c:1350: warning: value computed is not used
    lightning.c:1350: warning: cast from pointer to integer of different size
    lightning.c:1350: warning: value computed is not used
    lightning.c:1357: warning: value computed is not used

    also, you assume that object is a pointer type which it is not when SAFETY is 3 and OBJECT_STRUCT is defined.
    so, the ball is in your court is now:
    removing warnings
    supporting OBJECT_STRUCT
    testing the GC hooks

     
  • Adds OBJ_STRUCT support to CVS HEAD 2008-02-17

     
  • Logged In: YES
    user_id=1993164
    Originator: YES

    I attached a patch for OBJECT_STRUCT support.
    The 'value computed is not used' happen because some lightning macros return values when they shouldn't.
    For example jit_movi_p is defined as:
    '#define jit_movi_p(d, is) (jit_movi_ul((d), (long) (is)), _jit.x.pc)'
    I don't know why the expression returns '_jit.x.pc' yet. If there's no reason, I'll send a patch to the lightning ML.

    As for the other errors, what version of lighting do you use? What architecture are you on? What flags are on?

    When I redefine 'interpret_bytecode' to force jit execution, I get:
    ./lisp.run -B . -E 1:1 -Efile UTF-8 -Eterminal UTF-8 -norc -m 2MW -lp -x "(and (load \"init.lisp\") (sys::%saveinitmem) (ext::exit)) (ext::exit t)"
    [...]
    ;; Loading file /Users/lokee/clisp/src/compiler.lisp ...
    ;; Loaded file /Users/lokee/clisp/src/compiler.lisp
    ;; Loading file /Users/lokee/clisp/src/defs2.lisp ...make: *** [interpreted.mem] Segmentation fault

    Thank you,
    File Added: jit-objstruct.patch.gz

     
  • Sam Steingold
    Sam Steingold
    2008-02-22

    Logged In: YES
    user_id=5735
    Originator: NO

    >> '#define jit_movi_p(d, is) (jit_movi_ul((d), (long) (is)), _jit.x.pc)'

    in that case you should invoke jit_movi_p with a cast:
    (void)jit_movi_p(x,y)
    (unless, of course, you patch will be accepted by Paolo Bonzini)

     
  • Sam Steingold
    Sam Steingold
    2008-02-22

    Logged In: YES
    user_id=5735
    Originator: NO

    OK, your jit-objstruct.patch.gz patch finally got my attention. OUCH!
    the cavalier way you handle lisp objects is scary.
    this is actually my fault, I should have noticed this earlier. sorry...

    === memory management.
    you allocate Cons with malloc instead of the CLISP allocate_cons() function.
    1. where do you free it?
    2. why malloc? if you manage this data yourself and it lives a separate life from the Lisp heap, then there is no reason for you to use CLISP data structure - just define your own pair type.
    if this is supposed to link into (or be linked to from) the Lisp heap, then, given CLISP copying GC,
    you are bound to get segfaults.

    === lisp data field access.
    you write new_cell->cdr - use TheCdr() instead.
    you write (list != (Cons)as_oint(NIL)) - use !eq(list,NIL) or !nullp(list) instead

    thanks!

     
  • Sam Steingold
    Sam Steingold
    2008-02-26

    Logged In: YES
    user_id=5735
    Originator: NO

    also, it would be nice if your macros were named in a distinct way from the built-in lightning macros.
    both are named using "jit_" prefix now, and it is confusing.
    maybe clisp macros should be named "jitc_"?
    thanks.

     
  • Sam Steingold
    Sam Steingold
    2008-02-26

    Logged In: YES
    user_id=5735
    Originator: NO

    Paolo: on jit_movi_p returning a value:
    "yes [it is intentional], you can use the return value to patch a forward reference. if you don't need the value, you can use jit_movi_l, but you will still get warnings from e.g. the branch statements."
    I guess you have to cast it to (void) in your #defines.

     
  • Logged In: YES
    user_id=1993164
    Originator: YES

    Thanks, I'll make the necessary changes.
    Some other things are keeping me tied up right now, but I expect to send in a patch somewhere in the next week.

     
  • Sam Steingold
    Sam Steingold
    2008-03-11

    Logged In: YES
    user_id=5735
    Originator: NO

    any progress?

     
  • Logged In: YES
    user_id=1993164
    Originator: YES

    A little update,
    All clean-ups are done.
    A few changes to 'jit_compile' allows functions to be jit compiled and then executed directly. Previous errors are now fixed!

    The problem now is garbage collection:
    #> gdb lisp.run
    (gdb) run -m 2MW -lp -x "(and (load \"init.lisp\") (sys::%saveinitmem) (ext::exit))"
    ...
    ;; Loading file /Users/lokee/devel/clisp/clisp/src/compiler.lisp ...
    ;; Loaded file /Users/lokee/devel/clisp/clisp/src/compiler.lisp
    ;; Loading file /Users/lokee/devel/clisp/clisp/src/defs2.lisp ...
    ;; Loaded file /Users/lokee/devel/clisp/clisp/src/defs2.lisp
    Program received signal EXC_BAD_ACCESS, Could not access memory.
    Reason: KERN_INVALID_ADDRESS at address: 0x8019e8e1
    0x0001669a in gc_mark_jitc_object (ptr=0x8019e8e1) at lightning.c:73
    73 jo->jo_gc_mark = 1;

    We're close. I'll be investigating on this tomorrow.

    (See jit-clean-up.patch.gz for reference)

    Ciao
    File Added: jit-clean-up.patch.gz

     
  • Clean ups (includes jit-objstruct.patch.gz)

     
    Attachments
  • Logged In: YES
    user_id=1993164
    Originator: YES

    This problem has now been fixed.
    I can successfully make interpreted.mem
    The problem is now loading it.

    #> gdb lisp.run
    (gdb) run -B . -E 1:1 -Efile UTF-8 -Eterminal UTF-8 -norc -m 2MW -M interpreted.mem -q -c compiler.lisp -o ./
    Starting program: /Users/lokee/devel/clisp/clisp/src/lisp.run -B . -E 1:1 -Efile UTF-8 -Eterminal UTF-8 -norc -m 2MW -M interpreted.mem -q -c compiler.lisp -o ./
    Reading symbols for shared libraries .. done

    Program received signal EXC_BAD_ACCESS, Could not access memory.
    Reason: KERN_PROTECTION_FAILURE at address: 0x00000000
    0x00000000 in ?? ()
    (gdb) backtrace
    #0 0x00000000 in ?? ()
    #1 0x00017275 in jitc_run (closure=0x1a8dbc05, codeptr=0x1a8dbbe8, byteptr_in=0xa <Address 0xa out of bounds>) at lightning.c:5493
    ...

     
  • Sam Steingold
    Sam Steingold
    2008-03-16

    Logged In: YES
    user_id=5735
    Originator: NO

    thanks for the patch.
    now, there appears to be a lot of assembly copied verbatim from eval.d to lightning.c - is there a way to avoid it?
    since lightning.c is included by eval.d, maybe all those S_operand_ignore &friends could be re-used?

     
1 2 > >> (Page 1 of 2)