From: Aleksey Demakov Date: Thu, 6 Apr 2006 23:42:31 +0000 (+0000) Subject: Added function entry point indirector. Fixed tail call bug. X-Git-Tag: before.move.to.git~260 X-Git-Url: https://git.unchartedbackwaters.co.uk/w/?a=commitdiff_plain;h=a7192313efb18f09b6b1407904dda37d9c9f64db;p=francis%2Flibjit.git Added function entry point indirector. Fixed tail call bug. --- diff --git a/ChangeLog b/ChangeLog index 4ab7faf..7d2d775 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,17 @@ +2006-04-07 Klaus Treichel + + * jit/jit-internal.h (struct _jit_function): add indirector field. + * jit/jit-function.c (jit_function_compile, jit_function_create): + use indirector. + * jit/jit-apply-x86.h: define jit_indirector_size. + * jit/jit-apply-func.h, jit/jit-apply-x86.c (_jit_create_indirector): + add function that emits indirector code. + +2006-04-07 Aleksey Demakov + + * jit/jit-insn.c (create_call_setup_insns): zero struct_return + in case of tail calls (the problem was found by Klaus). + 2006-04-03 Aleksey Demakov * tools/gen-rules-scanner.l: diff --git a/jit/jit-apply-func.h b/jit/jit-apply-func.h index 46176eb..100c3fa 100644 --- a/jit/jit-apply-func.h +++ b/jit/jit-apply-func.h @@ -78,6 +78,12 @@ void _jit_create_closure(unsigned char *buf, void *func, void *_jit_create_redirector(unsigned char *buf, void *func, void *user_data, int abi); + +/* + * Create the indirector for the function. + */ +void *_jit_create_indirector(unsigned char *buf, void **entry); + /* * Pad a buffer with NOP instructions. Used to align code. * This will only be called if "jit_should_pad" is defined. diff --git a/jit/jit-apply-x86.c b/jit/jit-apply-x86.c index 04d20c8..ab87f7a 100644 --- a/jit/jit-apply-x86.c +++ b/jit/jit-apply-x86.c @@ -211,6 +211,16 @@ void *_jit_create_redirector(unsigned char *buf, void *func, return start; } +void *_jit_create_indirector(unsigned char *buf, void **entry) +{ + void *start = (void *)buf; + + /* Jump to the entry point. */ + x86_jump_mem(buf, entry); + + return start; +} + void _jit_pad_buffer(unsigned char *buf, int len) { while(len >= 6) diff --git a/jit/jit-apply-x86.h b/jit/jit-apply-x86.h index 4cc9234..d03949b 100644 --- a/jit/jit-apply-x86.h +++ b/jit/jit-apply-x86.h @@ -348,6 +348,12 @@ */ #define jit_redirector_size 32 +/* + * The number of bytes that are needed for a indirector stub. + * This includes any extra bytes that are needed for alignment. + */ +#define jit_indirector_size 8 + /* * We should pad unused code space with NOP's. */ diff --git a/jit/jit-function.c b/jit/jit-function.c index 6dc130a..2a23f1d 100644 --- a/jit/jit-function.c +++ b/jit/jit-function.c @@ -65,7 +65,12 @@ jit_function_t jit_function_create(jit_context_t context, jit_type_t signature) func->entry_point = _jit_create_redirector (func->redirector, (void *)_jit_function_compile_on_demand, func, jit_type_get_abi(signature)); +# if defined(jit_indirector_size) + func->closure_entry = _jit_create_indirector + (func->indirector, (void**) &(func->entry_point)); +# else func->closure_entry = func->entry_point; +# endif #endif /* Add the function to the context list */ @@ -571,7 +576,9 @@ int jit_function_compile(jit_function_t func) struct jit_gencode gen; jit_cache_t cache; void *start; +#if !defined(jit_redirector_size) || !defined(jit_indirector_size) || defined(JIT_BACKEND_INTERP) void *recompilable_start = 0; +#endif void *end; jit_block_t block; int result; @@ -691,12 +698,14 @@ int jit_function_compile(jit_function_t func) } #endif +#if !defined(jit_redirector_size) || !defined(jit_indirector_size) || defined(JIT_BACKEND_INTERP) /* If the function is recompilable, then we need an extra entry point to properly redirect previous references to the function */ if(func->is_recompilable) { recompilable_start = _jit_gen_redirector(&gen, func); } +#endif /* End the function's output process */ result = _jit_cache_end_method(&(gen.posn)); @@ -747,11 +756,19 @@ int jit_function_compile(jit_function_t func) /* Record the entry point */ func->entry_point = start; +#if !defined(jit_redirector_size) || !defined(jit_indirector_size) || defined(JIT_BACKEND_INTERP) if(recompilable_start) { func->closure_entry = recompilable_start; } else +#else + /* If the function is recompilable, then we keep closure_entry + point to indirector to properly redirect previous references + to the function, otherwise we make it equal to the function + start */ + if(!func->is_recompilable) +#endif { func->closure_entry = start; } diff --git a/jit/jit-insn.c b/jit/jit-insn.c index 19071b2..8a8127d 100644 --- a/jit/jit-insn.c +++ b/jit/jit-insn.c @@ -5213,6 +5213,7 @@ static int create_call_setup_insns return 0; } } + *struct_return = 0; return 1; } diff --git a/jit/jit-internal.h b/jit/jit-internal.h index 6c6a1d3..fe47a1d 100644 --- a/jit/jit-internal.h +++ b/jit/jit-internal.h @@ -394,6 +394,12 @@ struct _jit_function Redirectors are used to support on-demand compilation */ unsigned char redirector[jit_redirector_size]; #endif +#ifdef jit_indirector_size + /* Buffer that contains the indirector for this function. + The indirector is used to jump either to the function + redirector or the compiled function itself. */ + unsigned char indirector[jit_indirector_size]; +#endif }; /*