Tuesday, 5 April 2011

Crazy JIT Prototype. Part 4.

Aloha


I'm little bit tired and doesn't have energy to write lengthly post about “Crazy JIT prototype”. And I didn't make a lot of progress since last post. But still there is some good news and some roadblocks.



Good news


Firstly — I reworked test suite for JIT to be little bit more robust. Just simple embedding of expected result into PIR file. Something like this:

.sub 'main' :main
    say "Answer"
    say 42
    say 3.1415926
.end

# BEGIN_RESULTS
# Answer
# 42
# 3.1415926
# END_RESULTS

Handling of this “embedded test” took only few lines of code:

# Embedded test results
my $pir_src := slurp($pir);
my $/       := $pir_src ~~ /
    '# BEGIN_RESULTS' \n
    [ '# ' (\N+ \n) ]+
    '# END_RESULTS'
/;
my $expected := $/[0].join('');

Perl6 version of regexps is awesome!

Second — register access and simple math. Still some work have to be done but most things are in place already. Not all of registers are covered in test suite, so “patches are welcome” :-)

Third — I actually implemented handling of local branches and now Ops::JIT can handle simple loops, etc.

Roadblocks


Further development will require some kind of “mostly full C compiler”. Let's take simple line of code from core.ops:

Parrot_pcc_set_signature(interp, CURRENT_CONTEXT(interp), call_sig);

Looks pretty trivial: call of function Parrot_pcc_set_signature, passing variable interp, result of call to CURRENT_CONTEXT, and another variable call_sig. Unfortunately life is more complex. CURRENT_CONTEXT is not a function. It's C macro #define CURRENT_CONTEXT(interp) ((interp)->ctx). Which is expanded to access field ctx within parrot_interp_t structure. To properly implement JITting of it we have to:
  1. Parse macro definitions and have some kind “cpp” step inside opsc to expand them.
  2. Parse structure definitions to map field to offset.
First task is quite big in terms of code. And it will be quite slow to parse all header files on startup. And I can't preparse them and just freeze objects to disk. Because there is some very annoying bug in parrot which prevent proper thawing of Objects. I didn't caught it yet.

Second one is bit smaller and can be implemented much easier in combination with first one.

But for now I'm little bit stuck in thinking “how to implement it without implementing good big proportion of C compiler”. Any ideas?