diff --git a/ChangeLog b/ChangeLog index c02440d6c..5d8ac8422 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,24 @@ +2013-02-11 Paulo Andrade + + * include/lightning.h, lib/lightning.c: Implement the new + jit_clear_state and jit_destroy_state calls. jit_clear_state + releases all memory not required during jit_execution; that + is, leaves only the mmap'ed data and code buffers allocated. + jit_destroy_state releases the mmap'ed buffers as well as + the jit_state_t object itself, that holds pointers to the + code and data buffers, as well as annotation pointers (for + disassembly or backtrace) in the data buffer. + + * lib/jit_note.c: Correct invalid vector offset access. + + * check/ccall.c, check/lightning.c, doc/ifib.c, doc/incr.c, + doc/printf.c, doc/rfib.c, doc/rpn.c: Use the new jit_clear_state + and jit_destroy_state calls, to demonstrate the new code to + release all jit memory. + + * doc/body.texi: Add basic documentation and usage description + of jit_clear_state and jit_destroy_state. + 2013-02-11 Paulo Andrade * include/lightning/jit_private.h, lib/jit_note.c, lib/lightning.c: diff --git a/check/ccall.c b/check/ccall.c index ac44cb66a..14ae7cf26 100644 --- a/check/ccall.c +++ b/check/ccall.c @@ -890,7 +890,11 @@ main(int argc, char *argv[]) jit_print(); jit_disassemble(); #endif + + jit_clear_state(); (*function)(); + jit_destroy_state(); + finish_jit(); printf("ok\n"); diff --git a/check/lightning.c b/check/lightning.c index 9722011fe..58bca38a4 100644 --- a/check/lightning.c +++ b/check/lightning.c @@ -3542,6 +3542,7 @@ parse(void) static int execute(int argc, char *argv[]) { + int result; label_t *label; function_t function; patch_t *patch, *next; @@ -3573,9 +3574,15 @@ execute(int argc, char *argv[]) jit_disassemble(); fprintf(stdout, " - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\n"); } + + jit_clear_state(); if (flag_disasm) - return (0); - return ((*function)(argc, argv)); + result = 0; + else + result = (*function)(argc, argv); + jit_destroy_state(); + + return (result); } static void * diff --git a/doc/body.texi b/doc/body.texi index 1c145441c..3eef13b47 100644 --- a/doc/body.texi +++ b/doc/body.texi @@ -615,10 +615,12 @@ int main(int argc, char *argv[]) jit_retr(JIT_R0); @rem{/* @t{ retr R0 } */} incr = jit_emit(); + jit_clear_state(); @rem{/* call the generated code@comma{} passing 5 as an argument */} printf("%d + 1 = %d\n", 5, incr(5)); + jit_destroy_state(); finish_jit(); return 0; @} @@ -682,11 +684,21 @@ This instruction is very important. It actually translates the code area out of the processor's instruction cache and return a pointer to the start of the code. +@item jit_clear_state(); +This call cleanups any data not required for jit execution. Note +that it must be called after any call to @code{jit_print} or +@code{jit_address}, as this call destroy the @lightning{} +intermediate representation. + @item printf("%d + 1 = %d", 5, incr(5)); Calling our function is this simple---it is not distinguishable from a normal C function call, the only difference being that @code{incr} is a variable. +@item jit_destroy_state(); +Releases all memory associated with the jit context. It should be +called after known the jit will no longer be called. + @item finish_jit(); This call cleanups any global state hold by @lightning{}, and is advisable to call it once jit code will no longer be generated. @@ -765,6 +777,7 @@ int main(int argc, char *argv[]) @rem{/* call the generated code@comma{} passing its size as argument */} myFunction((char*)jit_address(end) - (char*)jit_address(start)); + jit_clear_state(); jit_disassemble(); @@ -822,6 +835,11 @@ call must be done after the @code{emit} call or either a fatal error will happen (if @lightning{} is built with assertions enable) or an undefined value will be returned. +@item jit_clear_state(); +Note that @code{jit_clear_state} was called after executing jit in +this example. It was done because it must be called after any call +to @code{jit_address} or @code{jit_print}. + @item jit_disassemble(); @code{disassemble} will dump the generated code to standard output, unless @lightning{} was built with the disassembler disabled, in which @@ -948,6 +966,7 @@ int main(int argc, char *argv[]) (void)jit_emit(); c2f = (pifi)jit_address(nc); f2c = (pifi)jit_address(nf); + jit_clear_state(); printf("\nC:"); for (i = 0; i <= 100; i += 10) printf("%3d ", i); @@ -961,6 +980,7 @@ int main(int argc, char *argv[]) for (i = 32; i <= 212; i += 18) printf("%3d ", f2c(i)); printf("\n"); + jit_destroy_state(); finish_jit(); return 0; @} @@ -1049,7 +1069,9 @@ int main(int argc, char *argv[]) @rem{/* call the generated code@comma{} passing 32 as an argument */} fib = jit_emit(); + jit_clear_state(); printf("fib(%d) = %d\n", 32, fib(32)); + jit_destroy_state(); finish_jit(); return 0; @} @@ -1117,7 +1139,9 @@ int main(int argc, char *argv[]) @rem{/* call the generated code@comma{} passing 36 as an argument */} fib = jit_emit(); + jit_clear_state(); printf("fib(%d) = %d\n", 36, fib(36)); + jit_destroy_state(); finish_jit(); return 0; @} diff --git a/doc/ifib.c b/doc/ifib.c index 7e098cba4..769e4a942 100644 --- a/doc/ifib.c +++ b/doc/ifib.c @@ -38,7 +38,9 @@ int main(int argc, char *argv[]) /* call the generated code, passing 36 as an argument */ fib = jit_emit(); + jit_clear_state(); printf("fib(%d) = %d\n", 36, fib(36)); + jit_destroy_state(); finish_jit(); return 0; } diff --git a/doc/incr.c b/doc/incr.c index 5d5e438d0..88859a873 100644 --- a/doc/incr.c +++ b/doc/incr.c @@ -20,10 +20,12 @@ int main(int argc, char *argv[]) jit_retr(JIT_R0); /* @t{ retr R0 } */ incr = jit_emit(); + jit_clear_state(); /* call the generated code\, passing 5 as an argument */ printf("%d + 1 = %d\n", 5, incr(5)); + jit_destroy_state(); finish_jit(); return 0; } diff --git a/doc/printf.c b/doc/printf.c index 52bd2aa1f..85485412f 100644 --- a/doc/printf.c +++ b/doc/printf.c @@ -30,9 +30,11 @@ int main(int argc, char *argv[]) /* call the generated code, passing its size as argument */ myFunction((char*)jit_address(end) - (char*)jit_address(start)); + jit_clear_state(); jit_disassemble(); + jit_destroy_state(); finish_jit(); return 0; } diff --git a/doc/rfib.c b/doc/rfib.c index 1ce02d5a7..97d74f643 100644 --- a/doc/rfib.c +++ b/doc/rfib.c @@ -43,7 +43,9 @@ int main(int argc, char *argv[]) /* call the generated code, passing 32 as an argument */ fib = jit_emit(); + jit_clear_state(); printf("fib(%d) = %d\n", 32, fib(32)); + jit_destroy_state(); finish_jit(); return 0; } diff --git a/doc/rpn.c b/doc/rpn.c index f02cef35f..813148481 100644 --- a/doc/rpn.c +++ b/doc/rpn.c @@ -76,6 +76,7 @@ int main(int argc, char *argv[]) (void)jit_emit(); c2f = (pifi)jit_address(nc); f2c = (pifi)jit_address(nf); + jit_clear_state(); printf("\nC:"); for (i = 0; i <= 100; i += 10) printf("%3d ", i); @@ -89,6 +90,7 @@ int main(int argc, char *argv[]) for (i = 32; i <= 212; i += 18) printf("%3d ", f2c(i)); printf("\n"); + jit_destroy_state(); finish_jit(); return 0; } diff --git a/include/lightning.h b/include/lightning.h index 057b45a12..bd9e37d13 100644 --- a/include/lightning.h +++ b/include/lightning.h @@ -752,6 +752,10 @@ extern void init_jit(char*); extern void finish_jit(void); extern jit_state_t *jit_new_state(void); +#define jit_clear_state() _jit_clear_state(_jit) +extern void _jit_clear_state(jit_state_t*); +#define jit_destroy_state() _jit_destroy_state(_jit) +extern void _jit_destroy_state(jit_state_t*); #define jit_address(node) _jit_address(_jit, node) extern jit_pointer_t _jit_address(jit_state_t*, jit_node_t*); diff --git a/lib/jit_note.c b/lib/jit_note.c index 13ead7f95..284f02d38 100644 --- a/lib/jit_note.c +++ b/lib/jit_note.c @@ -177,12 +177,12 @@ _jit_set_note(jit_state_t *_jit, jit_note_t *note, else { line = note->lines + index; index = offset_insert_index(line, offset); - if (line->offsets[index] == offset) { + if (index < line->length && line->offsets[index] == offset) { /* common case if no code was generated for several source lines */ if (line->linenos[index] < lineno) line->linenos[index] = lineno; } - else if (line->linenos[index] == lineno) { + else if (index < line->length && line->linenos[index] == lineno) { /* common case of extending entry */ if (line->offsets[index] > offset) line->offsets[index] = offset; diff --git a/lib/lightning.c b/lib/lightning.c index a408cf9f0..59ab8a76e 100644 --- a/lib/lightning.c +++ b/lib/lightning.c @@ -539,6 +539,70 @@ jit_new_state(void) return (_jit); } +void +_jit_clear_state(jit_state_t *_jit) +{ + jit_word_t offset; + jit_function_t *function; + + /* release memory not required at jit execution time and set + * pointers to NULL to explicitly know they are released */ + _jit->head = _jit->tail = NULL; + + mpz_clear(_jit->blockmask); + + free(_jit->data.table); + _jit->data.table = NULL; + _jit->data.size = _jit->data.count = 0; + + free(_jit->spill); + _jit->spill = NULL; + free(_jit->gen); + _jit->gen = NULL; + free(_jit->values); + _jit->values = NULL; + + free(_jit->blocks.ptr); + _jit->blocks.ptr = NULL; + + free(_jit->patches.ptr); + _jit->patches.ptr = NULL; + _jit->patches.offset = _jit->patches.length = 0; + + for (offset = 0; offset < _jit->functions.offset; offset++) { + function = _jit->functions.ptr + offset; + free(function->regoff); + function->regoff = NULL; + } + free(_jit->functions.ptr); + _jit->functions.offset = _jit->functions.length = 0; + _jit->function = NULL; + + for (offset = 0; offset < _jit->pool.length; offset++) + free(_jit->pool.ptr[offset]); + free(_jit->pool.ptr); + _jit->pool.ptr = NULL; + _jit->pool.offset = _jit->pool.length = 0; + _jit->list = NULL; + + _jit->note.head = _jit->note.tail = + _jit->note.name = _jit->note.note = NULL; + _jit->note.base = NULL; + +#if __arm__ && DISASSEMBLER + free(_jit->data_info.ptr); + _jit->data_info.ptr = NULL; +#endif +} + +void +_jit_destroy_state(jit_state_t *_jit) +{ + munmap(_jit->code.ptr, _jit->code.length); + munmap(_jit->data.ptr, _jit->data.length); + free(_jit); +} + jit_node_t * _jit_new_node(jit_state_t *_jit, jit_code_t code) {