memory. All functions writing values into the data area return the offset
relative the begin of the code area (start of procedure).
- $Id: codegen-common.c 7674 2007-04-05 13:27:11Z michi $
+ $Id: codegen-common.c 7797 2007-04-23 20:12:39Z michi $
*/
#include "threads/threads-common.h"
+#include "vm/builtin.h"
#include "vm/exceptions.h"
#include "vm/stringlocal.h"
# include "vmcore/statistics.h"
+#if defined(ENABLE_VMLOG)
+#include <vmlog_cacao.h>
+#endif
+
/* in this tree we store all method addresses *********************************/
cd->linenumbertablestartpos = 0;
cd->linenumbertab = 0;
- cd->maxstack = m->maxstack;
-
#if defined(ENABLE_THREADS)
cd->threadcritcurrent.next = NULL;
cd->threadcritcount = 0;
if (CODEGENDATA_HAS_FLAG_ERROR(cd)) {
/* check for long-branches flag, if it is set we recompile the
method */
+
+#if !defined(NDEBUG)
+ if (compileverbose)
+ log_message_method("Re-generating code: ", jd->m);
+#endif
+
/* XXX maybe we should tag long-branches-methods for recompilation */
if (CODEGENDATA_HAS_FLAG_LONGBRANCHES(cd)) {
else {
vm_abort("codegen_generate: unknown error occurred during codegen_emit: flags=%x\n", cd->flags);
}
+
+#if !defined(NDEBUG)
+ if (compileverbose)
+ log_message_method("Re-generating code done: ", jd->m);
+#endif
}
/* reallocate the memory and finish the code generation */
void codegen_branch_label_add(codegendata *cd, s4 label, s4 condition, s4 reg, u4 options)
{
- list *list;
+ list_t *list;
branch_label_ref_t *br;
s4 mpc;
if (mte == NULL) {
/* No method was found. Let's dump a stacktrace. */
+#if defined(ENABLE_VMLOG)
+ vmlog_cacao_signl("SIGSEGV");
+#endif
+
log_println("We received a SIGSEGV and tried to handle it, but we were");
log_println("unable to find a Java method at:");
log_println("");
#if defined(ENABLE_THREADS)
/* XXX michi: This should be available even without threads! */
- threads_print_stacktrace(THREADOBJECT);
+ threads_print_stacktrace();
#endif
vm_abort("Exiting...");
}
-/* codegen_createnativestub ****************************************************
+/* codegen_generate_stub_compiler **********************************************
+
+ Wrapper for codegen_emit_stub_compiler.
+
+ Returns:
+ pointer to the compiler stub code.
+
+*******************************************************************************/
+
+u1 *codegen_generate_stub_compiler(methodinfo *m)
+{
+ jitdata *jd;
+ codegendata *cd;
+ ptrint *d; /* pointer to data memory */
+ u1 *c; /* pointer to code memory */
+ s4 dumpsize;
+
+ /* mark dump memory */
+
+ dumpsize = dump_size();
+
+ /* allocate required data structures */
+
+ jd = DNEW(jitdata);
+
+ jd->m = m;
+ jd->cd = DNEW(codegendata);
+ jd->flags = 0;
+
+ /* get required compiler data */
+
+ cd = jd->cd;
+
+ /* allocate code memory */
+
+ c = CNEW(u1, 3 * SIZEOF_VOID_P + COMPILERSTUB_CODESIZE);
+
+ /* set pointers correctly */
+
+ d = (ptrint *) c;
+
+ cd->mcodebase = c;
+
+ c = c + 3 * SIZEOF_VOID_P;
+ cd->mcodeptr = c;
+
+ /* NOTE: The codeinfo pointer is actually a pointer to the
+ methodinfo (this fakes a codeinfo structure). */
+
+ d[0] = (ptrint) asm_call_jit_compiler;
+ d[1] = (ptrint) m;
+ d[2] = (ptrint) &d[1]; /* fake code->m */
+
+ /* call the emit function */
+
+ codegen_emit_stub_compiler(jd);
+
+#if defined(ENABLE_STATISTICS)
+ if (opt_stat)
+ count_cstub_len += 3 * SIZEOF_VOID_P + COMPILERSTUB_CODESIZE;
+#endif
+
+ /* flush caches */
+
+ md_cacheflush(cd->mcodebase, 3 * SIZEOF_VOID_P + COMPILERSTUB_CODESIZE);
+
+ /* release dump memory */
+
+ dump_release(dumpsize);
+
+ /* return native stub code */
+
+ return c;
+}
+
+
+/* codegen_generate_stub_builtin ***********************************************
- Wrapper for createnativestub.
+ Wrapper for codegen_emit_stub_builtin.
+
+ Returns:
+ Pointer to the entrypoint of the stub.
+
+*******************************************************************************/
+
+void codegen_generate_stub_builtin(builtintable_entry *bte)
+{
+ jitdata *jd;
+ codeinfo *code;
+ s4 dumpsize;
+
+ /* mark dump memory */
+
+ dumpsize = dump_size();
+
+ jd = DNEW(jitdata);
+
+ jd->m = NULL;
+ jd->cd = DNEW(codegendata);
+ jd->rd = NULL;
+ jd->flags = 0;
+
+ /* Allocate codeinfo memory from the heap as we need to keep them. */
+
+ jd->code = code_codeinfo_new(NULL);
+
+ /* get required compiler data */
+
+ code = jd->code;
+
+ /* setup code generation stuff */
+
+ codegen_setup(jd);
+
+ /* generate the code */
+
+#if defined(ENABLE_JIT)
+# if defined(ENABLE_INTRP)
+ if (!opt_intrp)
+# endif
+ codegen_emit_stub_builtin(jd, bte);
+#endif
+
+ /* reallocate the memory and finish the code generation */
+
+ codegen_finish(jd);
+
+ /* set the stub entry point in the builtin table */
+
+ bte->stub = code->entrypoint;
+
+#if defined(ENABLE_STATISTICS)
+ if (opt_stat)
+ count_nstub_len += code->mcodelength;
+#endif
+
+ /* release memory */
+
+ dump_release(dumpsize);
+}
+
+
+/* codegen_generate_stub_native ************************************************
+
+ Wrapper for codegen_emit_stub_native.
Returns:
the codeinfo representing the stub code.
*******************************************************************************/
-codeinfo *codegen_createnativestub(functionptr f, methodinfo *m)
+codeinfo *codegen_generate_stub_native(methodinfo *m, functionptr f)
{
jitdata *jd;
codeinfo *code;
#if defined(ENABLE_JIT)
# if defined(ENABLE_INTRP)
if (opt_intrp)
- code->entrypoint = intrp_createnativestub(f, jd, nmd);
+ intrp_createnativestub(f, jd, nmd);
else
# endif
- code->entrypoint = createnativestub(f, jd, nmd);
+ codegen_emit_stub_native(jd, nmd, f);
#else
- code->entrypoint = intrp_createnativestub(f, jd, nmd);
+ intrp_createnativestub(f, jd, nmd);
#endif
+ /* reallocate the memory and finish the code generation */
+
+ codegen_finish(jd);
+
#if defined(ENABLE_STATISTICS)
if (opt_stat)
count_nstub_len += code->mcodelength;
#endif
+/* codegen_stub_builtin_enter **************************************************
+
+ Prepares the stuff required for a builtin function call:
+
+ - adds a stackframe info structure to the chain, for stacktraces
+
+ The layout of the builtin stub stackframe should look like this:
+
+ +---------------------------+ <- SP (of parent Java function)
+ | return address |
+ +---------------------------+
+ | |
+ | stackframe info structure |
+ | |
+ +---------------------------+
+ | |
+ | arguments (if any) |
+ | |
+ +---------------------------+ <- SP (native stub)
+
+*******************************************************************************/
+
+void codegen_stub_builtin_enter(u1 *datasp, u1 *pv, u1 *sp, u1 *ra)
+{
+ stackframeinfo *sfi;
+
+ /* get data structures from stack */
+
+ sfi = (stackframeinfo *) (datasp - sizeof(stackframeinfo));
+
+ /* add a stackframeinfo to the chain */
+
+ stacktrace_create_native_stackframeinfo(sfi, pv, sp, ra);
+
+#if defined(ENABLE_THREADS) && defined(ENABLE_GC_CACAO)
+ /* set the native world flag */
+
+ THREADOBJECT->flags |= THREAD_FLAG_IN_NATIVE;
+#endif
+}
+
+
+/* codegen_stub_builtin_exit ***************************************************
+
+ Removes the stuff required for a builtin function call.
+
+*******************************************************************************/
+
+void codegen_stub_builtin_exit(u1 *datasp)
+{
+ stackframeinfo *sfi;
+ stackframeinfo **psfi;
+
+ /* get data structures from stack */
+
+ sfi = (stackframeinfo *) (datasp - sizeof(stackframeinfo));
+
+ /* remove current stackframeinfo from chain */
+
+ psfi = &STACKFRAMEINFO;
+
+ *psfi = sfi->prev;
+
+#if defined(ENABLE_THREADS) && defined(ENABLE_GC_CACAO)
+ /* clear the native world flag */
+
+ THREADOBJECT->flags &= ~THREAD_FLAG_IN_NATIVE;
+#endif
+}
+
+
/* codegen_start_native_call ***************************************************
Prepares the stuff required for a native (JNI) function call:
{
stackframeinfo *sfi;
stackframeinfo **psfi;
+#if defined(ENABLE_JAVASE)
localref_table *lrt;
localref_table *plrt;
s4 localframes;
+#endif
java_objectheader *e;
/* get data structures from stack */
sfi = (stackframeinfo *) (datasp - sizeof(stackframeinfo));
- lrt = (localref_table *) (datasp - sizeof(stackframeinfo) -
- sizeof(localref_table));
#if defined(ENABLE_THREADS) && defined(ENABLE_GC_CACAO)
/* clear the native world flag */