Alien-LibJIT
view release on metacpan or search on metacpan
libjit/doc/libjit.texi view on Meta::CPAN
IBM, Intel, and others have done a lot of research into JIT implementation
techniques over the years. If you are interested in working on the
internals of @code{libjit}, then you may want to make yourself familiar
with the relevant literature (this is by no means a complete list):
@quotation
IBM's Jikes RVM (Research Virtual Machine), @*
@uref{http://www-124.ibm.com/developerworks/oss/jikesrvm/}.
Intel's ORP (Open Runtime Platform), @*
@uref{http://orp.sourceforge.net/}.
@end quotation
@c -----------------------------------------------------------------------
@node Features, Tutorials, Introduction, Top
@chapter Features of libjit
@cindex Features
@itemize
@item
The primary interface is in C, for maximal reusability. Class
interfaces are available for programmers who prefer C++.
@item
Designed for portability to all major 32-bit and 64-bit platforms.
@item
Simple three-address API for library users, but opaque enough that other
representations can be used inside the library in future without
affecting existing users.
@item
Up-front or on-demand compilation of any function.
@item
In-built support to re-compile functions with greater optimization,
automatically redirecting previous callers to the new version.
@item
Fallback interpreter for running code on platforms that don't
have a native code generator yet. This reduces the need for
programmers to write their own interpreters for such platforms.
@item
Arithmetic, bitwise, conversion, and comparison operators for 8-bit,
16-bit, 32-bit, or 64-bit integer types; and 32-bit, 64-bit, or longer
floating point types. Includes overflow detecting arithmetic for
integer types.
@item
Large set of mathematical and trigonometric operations
(sqrt, sin, cos, min, abs, etc) for inlining floating-point library functions.
@item
Simplified type layout and exception handling mechanisms, upon which a
variety of different object models can be built.
@item
Support for nested functions, able to access their parent's local variables
(for implementing Pascal-style languages).
@end itemize
@c -----------------------------------------------------------------------
@node Tutorials, Tutorial 1, Features, Top
@chapter Tutorials in using libjit
@cindex Tutorials
In this chapter, we describe how to use @code{libjit} with a number of
short tutorial exercises. Full source for these tutorials can be found
in the @code{tutorial} directory of the @code{libjit} source tree.
For simplicity, we will ignore errors such as out of memory conditions,
but a real program would be expected to handle such errors.
@menu
* Tutorial 1:: Tutorial 1 - mul_add
* Tutorial 2:: Tutorial 2 - gcd
* Tutorial 3:: Tutorial 3 - compiling on-demand
* Tutorial 4:: Tutorial 4 - mul_add, C++ version
* Tutorial 5:: Tutorial 5 - gcd, with tail calls
* Dynamic Pascal:: Dynamic Pascal - A full JIT example
@end menu
@c -----------------------------------------------------------------------
@node Tutorial 1, Tutorial 2, Tutorials, Tutorials
@section Tutorial 1 - mul_add
@cindex mul_add tutorial
In the first tutorial, we will build and compile the following function
(the source code can be found in @code{tutorial/t1.c}):
@example
int mul_add(int x, int y, int z)
@{
return x * y + z;
@}
@end example
@noindent
To use the JIT, we first include the @code{<jit/jit.h>} file:
@example
#include <jit/jit.h>
@end example
All of the header files are placed into the @code{jit} sub-directory,
to separate them out from regular system headers. When @code{libjit}
is installed, you will typically find these headers in
@code{/usr/local/include/jit} or @code{/usr/include/jit}, depending upon
how your system is configured. You should also link with the
@code{-ljit} option.
@noindent
Every program that uses @code{libjit} needs to call @code{jit_context_create}:
@example
jit_context_t context;
libjit/doc/libjit.texi view on Meta::CPAN
@example
jit_value_t temp2;
jit_label_t label2 = jit_label_undefined;
...
temp2 = jit_insn_lt(function, x, y);
jit_insn_branch_if_not(function, temp2, &label2);
@end example
At this point, we need to call the @code{gcd} function with the
arguments @code{x} and @code{y - x}. The code for this is
fairly straight-forward. The @code{jit_insn_call} instruction calls
the function listed in its third argument. In this case, we are calling
ourselves recursively:
@example
jit_value_t temp_args[2];
jit_value_t temp3;
...
temp_args[0] = x;
temp_args[1] = jit_insn_sub(function, y, x);
temp3 = jit_insn_call
(function, "gcd", function, 0, temp_args, 2, 0);
jit_insn_return(function, temp3);
@end example
The string @code{"gcd"} in the second argument is for diagnostic purposes
only. It can be helpful when debugging, but the @code{libjit} library
otherwise makes no use of it. You can set it to NULL if you wish.
In general, @code{libjit} does not maintain mappings from names to
@code{jit_function_t} objects. It is assumed that the front end will
take care of that, using whatever naming scheme is appropriate to
its needs.
@noindent
The final part of the @code{gcd} function is similar to the previous one:
@example
jit_value_t temp4;
...
jit_insn_label(function, &label2);
temp_args[0] = jit_insn_sub(function, x, y);
temp_args[1] = y;
temp4 = jit_insn_call
(function, "gcd", function, 0, temp_args, 2, 0);
jit_insn_return(function, temp4);
@end example
@noindent
We can now compile the function and execute it in the usual manner.
@c -----------------------------------------------------------------------
@node Tutorial 3, Tutorial 4, Tutorial 2, Tutorials
@section Tutorial 3 - compiling on-demand
@cindex On-demand compilation tutorial
In the previous tutorials, we compiled everything that we needed
at startup time, and then entered the execution phase. The real power
of a JIT becomes apparent when you use it to compile functions
only as they are called. You can thus avoid compiling functions
that are never called in a given program run, saving memory and
startup time.
We demonstrate how to do on-demand compilation by rewriting Tutorial 1.
The source code for the modified version is in @code{tutorial/t3.c}.
When the @code{mul_add} function is created, we don't create its function
body or call @code{jit_function_compile}. We instead provide a
C function called @code{compile_mul_add} that performs on-demand
compilation:
@example
jit_function_t function;
...
function = jit_function_create(context, signature);
jit_function_set_on_demand_compiler(function, compile_mul_add);
@end example
We can now call this function with @code{jit_function_apply}, and the
system will automatically call @code{compile_mul_add} for us if the
function hasn't been built yet. The contents of @code{compile_mul_add}
are fairly obvious:
@example
int compile_mul_add(jit_function_t function)
@{
jit_value_t x, y, z;
jit_value_t temp1, temp2;
x = jit_value_get_param(function, 0);
y = jit_value_get_param(function, 1);
z = jit_value_get_param(function, 2);
temp1 = jit_insn_mul(function, x, y);
temp2 = jit_insn_add(function, temp1, z);
jit_insn_return(function, temp2);
return 1;
@}
@end example
When the on-demand compiler returns, @code{libjit} will call
@code{jit_function_compile} and then jump to the newly compiled code.
Upon the second and subsequent calls to the function, @code{libjit}
will bypass the on-demand compiler and call the compiled code directly.
Note that in case of on-demand compilation @code{libjit} automatically
locks and unlocks the corresponding context with
@code{jit_context_build_start} and @code{jit_context_build_end} calls.
Sometimes you may wish to force a commonly used function to
be recompiled, so that you can apply additional optimization.
To do this, you must set the "recompilable" flag just after the
function is first created:
@example
jit_function_t function;
...
function = jit_function_create(context, signature);
jit_function_set_recompilable(function);
( run in 0.468 second using v1.01-cache-2.11-cpan-3d66aa2751a )