[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
The libjit
library provides a number of utility routines
that it itself uses internally, but which may also be useful to front ends.
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
The libjit
library provides an interface to the traditional
system malloc
routines. All heap allocation in libjit
goes through these functions. If you need to perform some other kind
of memory allocation, you can replace these functions with your
own versions.
Allocate size bytes of memory from the heap.
Allocate sizeof(type)
bytes of memory from the heap and
cast the return pointer to type *
. This is a macro that
wraps up the underlying jit_malloc
function and is less
error-prone when allocating structures.
Allocate num * size
bytes of memory from the heap and clear
them to zero.
Allocate sizeof(type)
bytes of memory from the heap and
cast the return pointer to type *
. The memory is cleared
to zero.
Re-allocate the memory at ptr to be size bytes in size.
The memory block at ptr must have been allocated by a previous
call to jit_malloc
, jit_calloc
, or jit_realloc
.
Free the memory at ptr. It is safe to pass a NULL pointer.
Allocate a block of memory that is read/write/executable. Such blocks
are used to store JIT'ed code, function closures, and other trampolines.
The size should be a multiple of jit_exec_page_size()
.
This will usually be identical to jit_malloc
. However,
some systems may need special handling to create executable code
segments, so this function must be used instead.
You must never mix regular and executable segment allocation. That is,
do not use jit_free
to free the result of jit_malloc_exec
.
Free a block of memory that was previously allocated by
jit_malloc_exec
. The size must be identical to the
original allocated size, as some systems need to know this information
to be able to free the block.
Flush the contents of the block at ptr from the CPU's data and instruction caches. This must be used after the code is written to an executable code segment, but before the code is executed, to prepare it for execution.
Get the page allocation size for the system. This is the preferred
unit when making calls to jit_malloc_exec
. It is not
required that you supply a multiple of this size when allocating,
but it can lead to better performance on some systems.
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
The following functions are provided to set, copy, compare, and search memory blocks.
Set the len bytes at dest to the value ch. Returns dest.
Copy the len bytes at src to dest. Returns dest. The behavior is undefined if the blocks overlap (use jit_memmove instead for that case).
Copy the len bytes at src to dest and handle overlapping blocks correctly. Returns dest.
Compare len bytes at s1 and s2, returning a negative, zero, or positive result depending upon their relationship. It is system-specific as to whether this function uses signed or unsigned byte comparisons.
Search the len bytes at str for the first instance of the value ch. Returns the location of ch if it was found, or NULL if it was not found.
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
The following functions are provided to manipulate NULL-terminated strings. It is highly recommended that you use these functions in preference to system functions, because the corresponding system functions are extremely non-portable.
Returns the length of str.
Copy the string at src to dest. Returns dest.
Copy the string at src to the end of the string at dest. Returns dest.
Copy at most len characters from the string at src to dest. Returns dest.
Allocate a block of memory using jit_malloc
and copy
str into it. Returns NULL if str is NULL or there
is insufficient memory to perform the jit_malloc
operation.
Allocate a block of memory using jit_malloc
and copy at most
len characters of str into it. The copied string is then
NULL-terminated. Returns NULL if str is NULL or there
is insufficient memory to perform the jit_malloc
operation.
Compare the two strings str1 and str2, returning a negative, zero, or positive value depending upon their relationship.
Compare the two strings str1 and str2, returning a negative, zero, or positive value depending upon their relationship. At most len characters are compared.
Compare the two strings str1 and str2, returning a negative, zero, or positive value depending upon their relationship. Instances of the English letters A to Z are converted into their lower case counterparts before comparison.
Note: this function is guaranteed to use English case comparison rules, no matter what the current locale is set to, making it suitable for comparing token tags and simple programming language identifiers.
Locale-sensitive string comparison is complicated and usually specific
to the front end language or its supporting runtime library. We
deliberately chose not to handle this in libjit
.
Compare the two strings str1 and str2, returning a negative, zero, or positive value depending upon their relationship. At most len characters are compared. Instances of the English letters A to Z are converted into their lower case counterparts before comparison.
Search str for the first occurrence of ch. Returns the address where ch was found, or NULL if not found.
Search str for the first occurrence of ch, starting at the end of the string. Returns the address where ch was found, or NULL if not found.
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Many of the structures in the libjit
library can have user-supplied
metadata associated with them. Metadata may be used to store dependency
graphs, branch prediction information, or any other information that is
useful to optimizers or code generators.
Metadata can also be used by higher level user code to store information about the structures that is specific to the user's virtual machine or language.
The library structures have special-purpose metadata routines associated
with them (e.g. jit_function_set_meta
, jit_block_get_meta
).
However, sometimes you may wish to create your own metadata lists and
attach them to your own structures. The functions below enable you
to do this:
Set a metadata value on a list. If the type is already present
in the list, then its previous value will be freed. The free_func
is called when the metadata value is freed with jit_meta_free
or jit_meta_destroy
. Returns zero if out of memory.
If pool_owner is not NULL, then the metadata value will persist until the specified function is finished building. Normally you would set this to NULL.
Metadata type values of 10000 or greater are reserved for internal use. They should never be used by external user code.
Get the value associated with type in the specified list. Returns NULL if type is not present.
Free the metadata value in the list that has the specified type. Does nothing if the type is not present.
Destroy all of the metadata values in the specified list.
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Sometimes all you have for a function is a pointer to it and a dynamic
description of its arguments. Calling such a function can be extremely
difficult in standard C. The routines in this section, particularly
jit_apply
, provide a convenient interface for doing this.
At other times, you may wish to wrap up one of your own dynamic functions
in such a way that it appears to be a regular C function. This is
performed with jit_closure_create
.
Call a function that has a particular function signature. If the signature has more than num_fixed_args arguments, then it is assumed to be a vararg call, with the additional arguments passed in the vararg argument area on the stack. The signature must specify the type of all arguments, including those in the vararg argument area.
Call a function, passing a set of raw arguments. This can only
be used if jit_raw_supported
returns non-zero for the signature.
The args value is assumed to be an array of jit_nint
values
that correspond to each of the arguments. Raw function calls
are slightly faster than their non-raw counterparts, but can
only be used in certain circumstances.
Determine if jit_apply_raw
can be used to call functions
with a particular signature. Returns zero if not.
Create a closure from a function signature, a closure handling function, and a user data value. Returns NULL if out of memory, or if closures are not supported. The func argument should have the following prototype:
void func (jit_type_t signature, void *result, void **args, void *user_data); |
If the closure signature includes variable arguments, then args
will contain pointers to the fixed arguments, followed by a
jit_closure_va_list_t
value for accessing the remainder of
the arguments.
The memory for the closure will be reclaimed when the context is destroyed.
Determine if this platform has support for closures.
Get the next value of a specific type from a closure's variable arguments.
Get a structure or union value of a specific type from a closure's variable arguments, and copy it into buf.
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
The functions in <jit/jit-walk.h>
allow the caller to walk
up the native execution stack, inspecting frames and return addresses.
Get the frame address for the call frame n levels up the stack. Setting n to zero will retrieve the frame address for the current function. Returns NULL if it isn't possible to retrieve the address of the specified frame.
Get the frame address for the current function. This may be more
efficient on some platforms than using jit_get_frame_address(0)
.
Returns NULL if it isn't possible to retrieve the address of
the current frame.
Get the address of the next frame up the stack from frame. Returns NULL if it isn't possible to retrieve the address of the next frame up the stack.
Get the return address from a specified frame. The address represents the place where execution returns to when the specified frame exits. Returns NULL if it isn't possible to retrieve the return address of the specified frame.
Get the return address for the current function. This may be more
efficient on some platforms than using jit_get_return_address(0)
.
Returns NULL if it isn't possible to retrieve the return address of
the current frame.
Determine if the stack frame that resides just above frame
contains a local variable whose address is mark. The mark
parameter should be the address of a local variable that is declared with
jit_declare_crawl_mark(name)
.
Crawl marks are used internally by libjit to determine where control passes between JIT'ed and ordinary code during an exception throw. They can also be used to mark frames that have special security conditions associated with them.
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
The following routines are supplied to help load and inspect dynamic
libraries. They should be used in place of the traditional
dlopen
, dlclose
, and dlsym
functions, which
are not portable across operating systems.
You must include <jit/jit-dynamic.h>
to use these routines,
and then link with -ljitdynamic -ljit
.
Opens the dynamic library called name, returning a handle for it.
Close a dynamic library.
Retrieve the symbol symbol from the specified dynamic library. Returns NULL if the symbol could not be found. This will try both non-prefixed and underscore-prefixed forms of symbol on platforms where it makes sense to do so, so there is no need for the caller to perform prefixing.
Enable or disable additional debug messages to stderr. Debugging is disabled by default. Normally the dynamic library routines will silently report errors via NULL return values, leaving reporting up to the caller. However, it can be useful to turn on additional diagnostics when tracking down problems with dynamic loading.
Get the preferred dynamic library suffix for this platform.
Usually something like so
, dll
, or dylib
.
Sometimes you want to retrieve a C++ method from a dynamic library
using jit_dynlib_get_symbol
. Unfortunately, C++ name mangling
rules differ from one system to another, making this process very
error-prone.
The functions that follow try to help. They aren't necessarily fool-proof, but they should work in the most common cases. The only alternative is to wrap your C++ library with C functions, so that the names are predictable.
The basic idea is that you supply a description of the C++ method that
you wish to access, and these functions return a number of candidate forms
that you can try with jit_dynlib_get_symbol
. If one form fails,
you move on and try the next form, until either symbol lookup succeeds
or until all forms have been exhausted.
The following code demonstrates how to resolve a global function:
jit_dynlib_handle_t handle; jit_type_t signature; int form = 0; void *address = 0; char *mangled; while((mangled = jit_mangle_global_function ("foo", signature, form)) != 0) { address = jit_dynlib_get_symbol(handle, mangled); if(address != 0) { break; } jit_free(mangled); ++form; } if(address) { printf("%s = 0x%lxn", mangled, (long)address); } else { printf("could not resolve foon"); } |
This mechanism typically cannot be used to obtain the entry points for
inline
methods. You will need to make other arrangements to
simulate the behaviour of inline methods, or recompile your dynamic C++
library in a mode that explicitly exports inlines.
C++ method names are very picky about types. On 32-bit systems,
int
and long
are the same size, but they are mangled
to different characters. To ensure that the correct function is
picked, you should use jit_type_sys_int
, jit_type_sys_long
, etc
instead of the platform independent types. If you do use a platform
independent type like jit_type_int
, this library will try to
guess which system type you mean, but the guess will most likely be wrong.
Mangle the name of a global C++ function using the specified form. Returns NULL if out of memory, or if the form is not supported.
Mangle the name of a C++ member function using the specified form. Returns NULL if out of memory, or if the form is not supported. The following flags may be specified to modify the mangling rules:
JIT_MANGLE_PUBLIC
The method has public
access within its containing class.
JIT_MANGLE_PROTECTED
The method has protected
access within its containing class.
JIT_MANGLE_PRIVATE
The method has private
access within its containing class.
JIT_MANGLE_STATIC
The method is static
.
JIT_MANGLE_VIRTUAL
The method is a virtual instance method. If neither
JIT_MANGLE_STATIC
nor JIT_MANGLE_VIRTUAL
are supplied,
then the method is assumed to be a non-virtual instance method.
JIT_MANGLE_CONST
The method is an instance method with the const
qualifier.
JIT_MANGLE_EXPLICIT_THIS
The signature includes an extra pointer parameter at the start
that indicates the type of the this
pointer. This parameter won't
be included in the final mangled name.
JIT_MANGLE_IS_CTOR
The method is a constructor. The name parameter will be ignored.
JIT_MANGLE_IS_DTOR
The method is a destructor. The name parameter will be ignored.
JIT_MANGLE_BASE
Fetch the "base" constructor or destructor entry point, rather than the "complete" entry point.
The class_name may include namespace and nested parent qualifiers
by separating them with ::
or .
. Class names that involve
template parameters are not supported yet.
[ << ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
This document was generated by Klaus Treichel on May, 11 2008 using texi2html 1.78.