+2006-04-07 Klaus Treichel <ktreichel@web.de>
+
+ * 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 <ademakov@gmail.com>
+
+ * 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 <ademakov@gmail.com>
* tools/gen-rules-scanner.l:
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.
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)
*/
#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.
*/
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 */
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;
}
#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));
/* 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;
}
return 0;
}
}
+ *struct_return = 0;
return 1;
}
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
};
/*