mirror of
https://git.savannah.gnu.org/git/guile.git
synced 2025-05-15 18:20:42 +02:00
Add code to release all memory used by the jit state.
* 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.
This commit is contained in:
parent
6039794ec3
commit
8f020fe044
12 changed files with 138 additions and 4 deletions
21
ChangeLog
21
ChangeLog
|
@ -1,3 +1,24 @@
|
||||||
|
2013-02-11 Paulo Andrade <pcpa@gnu.org>
|
||||||
|
|
||||||
|
* 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 <pcpa@gnu.org>
|
2013-02-11 Paulo Andrade <pcpa@gnu.org>
|
||||||
|
|
||||||
* include/lightning/jit_private.h, lib/jit_note.c, lib/lightning.c:
|
* include/lightning/jit_private.h, lib/jit_note.c, lib/lightning.c:
|
||||||
|
|
|
@ -890,7 +890,11 @@ main(int argc, char *argv[])
|
||||||
jit_print();
|
jit_print();
|
||||||
jit_disassemble();
|
jit_disassemble();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
jit_clear_state();
|
||||||
(*function)();
|
(*function)();
|
||||||
|
jit_destroy_state();
|
||||||
|
|
||||||
finish_jit();
|
finish_jit();
|
||||||
|
|
||||||
printf("ok\n");
|
printf("ok\n");
|
||||||
|
|
|
@ -3542,6 +3542,7 @@ parse(void)
|
||||||
static int
|
static int
|
||||||
execute(int argc, char *argv[])
|
execute(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
|
int result;
|
||||||
label_t *label;
|
label_t *label;
|
||||||
function_t function;
|
function_t function;
|
||||||
patch_t *patch, *next;
|
patch_t *patch, *next;
|
||||||
|
@ -3573,9 +3574,15 @@ execute(int argc, char *argv[])
|
||||||
jit_disassemble();
|
jit_disassemble();
|
||||||
fprintf(stdout, " - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\n");
|
fprintf(stdout, " - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
jit_clear_state();
|
||||||
if (flag_disasm)
|
if (flag_disasm)
|
||||||
return (0);
|
result = 0;
|
||||||
return ((*function)(argc, argv));
|
else
|
||||||
|
result = (*function)(argc, argv);
|
||||||
|
jit_destroy_state();
|
||||||
|
|
||||||
|
return (result);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void *
|
static void *
|
||||||
|
|
|
@ -615,10 +615,12 @@ int main(int argc, char *argv[])
|
||||||
jit_retr(JIT_R0); @rem{/* @t{ retr R0 } */}
|
jit_retr(JIT_R0); @rem{/* @t{ retr R0 } */}
|
||||||
|
|
||||||
incr = jit_emit();
|
incr = jit_emit();
|
||||||
|
jit_clear_state();
|
||||||
|
|
||||||
@rem{/* call the generated code@comma{} passing 5 as an argument */}
|
@rem{/* call the generated code@comma{} passing 5 as an argument */}
|
||||||
printf("%d + 1 = %d\n", 5, incr(5));
|
printf("%d + 1 = %d\n", 5, incr(5));
|
||||||
|
|
||||||
|
jit_destroy_state();
|
||||||
finish_jit();
|
finish_jit();
|
||||||
return 0;
|
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
|
code area out of the processor's instruction cache and return a
|
||||||
pointer to the start of the code.
|
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));
|
@item printf("%d + 1 = %d", 5, incr(5));
|
||||||
Calling our function is this simple---it is not distinguishable from
|
Calling our function is this simple---it is not distinguishable from
|
||||||
a normal C function call, the only difference being that @code{incr}
|
a normal C function call, the only difference being that @code{incr}
|
||||||
is a variable.
|
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();
|
@item finish_jit();
|
||||||
This call cleanups any global state hold by @lightning{}, and is
|
This call cleanups any global state hold by @lightning{}, and is
|
||||||
advisable to call it once jit code will no longer be generated.
|
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 */}
|
@rem{/* call the generated code@comma{} passing its size as argument */}
|
||||||
myFunction((char*)jit_address(end) - (char*)jit_address(start));
|
myFunction((char*)jit_address(end) - (char*)jit_address(start));
|
||||||
|
jit_clear_state();
|
||||||
|
|
||||||
jit_disassemble();
|
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
|
will happen (if @lightning{} is built with assertions enable) or an
|
||||||
undefined value will be returned.
|
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();
|
@item jit_disassemble();
|
||||||
@code{disassemble} will dump the generated code to standard output,
|
@code{disassemble} will dump the generated code to standard output,
|
||||||
unless @lightning{} was built with the disassembler disabled, in which
|
unless @lightning{} was built with the disassembler disabled, in which
|
||||||
|
@ -948,6 +966,7 @@ int main(int argc, char *argv[])
|
||||||
(void)jit_emit();
|
(void)jit_emit();
|
||||||
c2f = (pifi)jit_address(nc);
|
c2f = (pifi)jit_address(nc);
|
||||||
f2c = (pifi)jit_address(nf);
|
f2c = (pifi)jit_address(nf);
|
||||||
|
jit_clear_state();
|
||||||
|
|
||||||
printf("\nC:");
|
printf("\nC:");
|
||||||
for (i = 0; i <= 100; i += 10) printf("%3d ", i);
|
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));
|
for (i = 32; i <= 212; i += 18) printf("%3d ", f2c(i));
|
||||||
printf("\n");
|
printf("\n");
|
||||||
|
|
||||||
|
jit_destroy_state();
|
||||||
finish_jit();
|
finish_jit();
|
||||||
return 0;
|
return 0;
|
||||||
@}
|
@}
|
||||||
|
@ -1049,7 +1069,9 @@ int main(int argc, char *argv[])
|
||||||
|
|
||||||
@rem{/* call the generated code@comma{} passing 32 as an argument */}
|
@rem{/* call the generated code@comma{} passing 32 as an argument */}
|
||||||
fib = jit_emit();
|
fib = jit_emit();
|
||||||
|
jit_clear_state();
|
||||||
printf("fib(%d) = %d\n", 32, fib(32));
|
printf("fib(%d) = %d\n", 32, fib(32));
|
||||||
|
jit_destroy_state();
|
||||||
finish_jit();
|
finish_jit();
|
||||||
return 0;
|
return 0;
|
||||||
@}
|
@}
|
||||||
|
@ -1117,7 +1139,9 @@ int main(int argc, char *argv[])
|
||||||
|
|
||||||
@rem{/* call the generated code@comma{} passing 36 as an argument */}
|
@rem{/* call the generated code@comma{} passing 36 as an argument */}
|
||||||
fib = jit_emit();
|
fib = jit_emit();
|
||||||
|
jit_clear_state();
|
||||||
printf("fib(%d) = %d\n", 36, fib(36));
|
printf("fib(%d) = %d\n", 36, fib(36));
|
||||||
|
jit_destroy_state();
|
||||||
finish_jit();
|
finish_jit();
|
||||||
return 0;
|
return 0;
|
||||||
@}
|
@}
|
||||||
|
|
|
@ -38,7 +38,9 @@ int main(int argc, char *argv[])
|
||||||
|
|
||||||
/* call the generated code, passing 36 as an argument */
|
/* call the generated code, passing 36 as an argument */
|
||||||
fib = jit_emit();
|
fib = jit_emit();
|
||||||
|
jit_clear_state();
|
||||||
printf("fib(%d) = %d\n", 36, fib(36));
|
printf("fib(%d) = %d\n", 36, fib(36));
|
||||||
|
jit_destroy_state();
|
||||||
finish_jit();
|
finish_jit();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,10 +20,12 @@ int main(int argc, char *argv[])
|
||||||
jit_retr(JIT_R0); /* @t{ retr R0 } */
|
jit_retr(JIT_R0); /* @t{ retr R0 } */
|
||||||
|
|
||||||
incr = jit_emit();
|
incr = jit_emit();
|
||||||
|
jit_clear_state();
|
||||||
|
|
||||||
/* call the generated code\, passing 5 as an argument */
|
/* call the generated code\, passing 5 as an argument */
|
||||||
printf("%d + 1 = %d\n", 5, incr(5));
|
printf("%d + 1 = %d\n", 5, incr(5));
|
||||||
|
|
||||||
|
jit_destroy_state();
|
||||||
finish_jit();
|
finish_jit();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,9 +30,11 @@ int main(int argc, char *argv[])
|
||||||
|
|
||||||
/* call the generated code, passing its size as argument */
|
/* call the generated code, passing its size as argument */
|
||||||
myFunction((char*)jit_address(end) - (char*)jit_address(start));
|
myFunction((char*)jit_address(end) - (char*)jit_address(start));
|
||||||
|
jit_clear_state();
|
||||||
|
|
||||||
jit_disassemble();
|
jit_disassemble();
|
||||||
|
|
||||||
|
jit_destroy_state();
|
||||||
finish_jit();
|
finish_jit();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,7 +43,9 @@ int main(int argc, char *argv[])
|
||||||
|
|
||||||
/* call the generated code, passing 32 as an argument */
|
/* call the generated code, passing 32 as an argument */
|
||||||
fib = jit_emit();
|
fib = jit_emit();
|
||||||
|
jit_clear_state();
|
||||||
printf("fib(%d) = %d\n", 32, fib(32));
|
printf("fib(%d) = %d\n", 32, fib(32));
|
||||||
|
jit_destroy_state();
|
||||||
finish_jit();
|
finish_jit();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -76,6 +76,7 @@ int main(int argc, char *argv[])
|
||||||
(void)jit_emit();
|
(void)jit_emit();
|
||||||
c2f = (pifi)jit_address(nc);
|
c2f = (pifi)jit_address(nc);
|
||||||
f2c = (pifi)jit_address(nf);
|
f2c = (pifi)jit_address(nf);
|
||||||
|
jit_clear_state();
|
||||||
|
|
||||||
printf("\nC:");
|
printf("\nC:");
|
||||||
for (i = 0; i <= 100; i += 10) printf("%3d ", i);
|
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));
|
for (i = 32; i <= 212; i += 18) printf("%3d ", f2c(i));
|
||||||
printf("\n");
|
printf("\n");
|
||||||
|
|
||||||
|
jit_destroy_state();
|
||||||
finish_jit();
|
finish_jit();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -752,6 +752,10 @@ extern void init_jit(char*);
|
||||||
extern void finish_jit(void);
|
extern void finish_jit(void);
|
||||||
|
|
||||||
extern jit_state_t *jit_new_state(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)
|
#define jit_address(node) _jit_address(_jit, node)
|
||||||
extern jit_pointer_t _jit_address(jit_state_t*, jit_node_t*);
|
extern jit_pointer_t _jit_address(jit_state_t*, jit_node_t*);
|
||||||
|
|
|
@ -177,12 +177,12 @@ _jit_set_note(jit_state_t *_jit, jit_note_t *note,
|
||||||
else {
|
else {
|
||||||
line = note->lines + index;
|
line = note->lines + index;
|
||||||
index = offset_insert_index(line, offset);
|
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 */
|
/* common case if no code was generated for several source lines */
|
||||||
if (line->linenos[index] < lineno)
|
if (line->linenos[index] < lineno)
|
||||||
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 */
|
/* common case of extending entry */
|
||||||
if (line->offsets[index] > offset)
|
if (line->offsets[index] > offset)
|
||||||
line->offsets[index] = offset;
|
line->offsets[index] = offset;
|
||||||
|
|
|
@ -539,6 +539,70 @@ jit_new_state(void)
|
||||||
return (_jit);
|
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_node_t *
|
||||||
_jit_new_node(jit_state_t *_jit, jit_code_t code)
|
_jit_new_node(jit_state_t *_jit, jit_code_t code)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue