X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=src%2Fvm%2Fjit%2Fcodegen-common.c;h=8a04bea20ebb5691c4520b1dea3534b9a95a5feb;hb=7a02f41c92dd7109c6ce1366de37b3c64dcb5e67;hp=cb7c544c8deab5645323f5077e49d74fea555e5e;hpb=f02ed17b806efe4e5b417365e9aac478b51b86d9;p=cacao.git diff --git a/src/vm/jit/codegen-common.c b/src/vm/jit/codegen-common.c index cb7c544c8..8a04bea20 100644 --- a/src/vm/jit/codegen-common.c +++ b/src/vm/jit/codegen-common.c @@ -54,6 +54,8 @@ # include "codegen.h" #endif +#include "md-abi.h" + #include "mm/memory.h" #include "toolbox/avl.h" @@ -61,9 +63,12 @@ #include "toolbox/logging.h" #include "native/jni.h" +#include "native/llni.h" #include "native/localref.h" #include "native/native.h" +#include "native/include/java_lang_Class.h" + #include "threads/threads-common.h" #include "vm/builtin.h" @@ -82,6 +87,7 @@ #include "vm/jit/emit-common.h" #include "vm/jit/jit.h" #include "vm/jit/md.h" +#include "vm/jit/methodheader.h" #include "vm/jit/patcher-common.h" #include "vm/jit/replace.h" #if defined(ENABLE_SSA) @@ -89,6 +95,7 @@ # include "vm/jit/optimizing/ssa.h" #endif #include "vm/jit/stacktrace.h" +#include "vm/jit/trace.h" #if defined(ENABLE_INTRP) #include "vm/jit/intrp/intrp.h" @@ -1187,13 +1194,11 @@ u1 *codegen_generate_stub_compiler(methodinfo *m) Wrapper for codegen_emit_stub_builtin. - Returns: - Pointer to the entrypoint of the stub. - *******************************************************************************/ -void codegen_generate_stub_builtin(builtintable_entry *bte) +void codegen_generate_stub_builtin(methodinfo *m, builtintable_entry *bte) { +#if defined(__ARM__) || defined(__ALPHA__) || defined(__I386__) || defined(__M68K__) || defined(__POWERPC__) || defined(__SPARC64__) || defined(__X86_64__) jitdata *jd; codeinfo *code; s4 dumpsize; @@ -1204,14 +1209,14 @@ void codegen_generate_stub_builtin(builtintable_entry *bte) jd = DNEW(jitdata); - jd->m = NULL; + jd->m = m; 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); + jd->code = code_codeinfo_new(m); /* XXX check allocation */ /* get required compiler data */ @@ -1225,9 +1230,13 @@ void codegen_generate_stub_builtin(builtintable_entry *bte) #if defined(ENABLE_JIT) # if defined(ENABLE_INTRP) - if (!opt_intrp) + if (!opt_intrp) { +# endif + assert(bte->fp != NULL); + codegen_emit_stub_native(jd, bte->md, bte->fp); +# if defined(ENABLE_INTRP) + } # endif - codegen_emit_stub_builtin(jd, bte); #endif /* reallocate the memory and finish the code generation */ @@ -1243,9 +1252,25 @@ void codegen_generate_stub_builtin(builtintable_entry *bte) size_stub_native += code->mcodelength; #endif +#if !defined(NDEBUG) && defined(ENABLE_DISASSEMBLER) + /* disassemble native stub */ + + if (opt_DisassembleStubs) { + codegen_disassemble_stub(m, + (u1 *) (ptrint) code->entrypoint, + (u1 *) (ptrint) code->entrypoint + (code->mcodelength - jd->cd->dseglen)); + + /* show data segment */ + + if (opt_showddatasegment) + dseg_display(jd); + } +#endif /* !defined(NDEBUG) && defined(ENABLE_DISASSEMBLER) */ + /* release memory */ dump_release(dumpsize); +#endif /* architecture list */ } @@ -1361,19 +1386,17 @@ codeinfo *codegen_generate_stub_native(methodinfo *m, functionptr f) size_stub_native += code->mcodelength; #endif -#if !defined(NDEBUG) +#if !defined(NDEBUG) && defined(ENABLE_DISASSEMBLER) /* disassemble native stub */ - if (opt_shownativestub) { -#if defined(ENABLE_DEBUG_FILTER) + if (opt_DisassembleStubs) { +# if defined(ENABLE_DEBUG_FILTER) if (m->filtermatches & SHOW_FILTER_FLAG_SHOW_METHOD) -#endif +# endif { -#if defined(ENABLE_DISASSEMBLER) - codegen_disassemble_nativestub(m, - (u1 *) (ptrint) code->entrypoint, - (u1 *) (ptrint) code->entrypoint + (code->mcodelength - jd->cd->dseglen)); -#endif + codegen_disassemble_stub(m, + (u1 *) (ptrint) code->entrypoint, + (u1 *) (ptrint) code->entrypoint + (code->mcodelength - jd->cd->dseglen)); /* show data segment */ @@ -1381,7 +1404,7 @@ codeinfo *codegen_generate_stub_native(methodinfo *m, functionptr f) dseg_display(jd); } } -#endif /* !defined(NDEBUG) */ +#endif /* !defined(NDEBUG) && defined(ENABLE_DISASSEMBLER) */ /* release memory */ @@ -1395,84 +1418,28 @@ codeinfo *codegen_generate_stub_native(methodinfo *m, functionptr f) /* codegen_disassemble_nativestub ********************************************** - Disassembles the generated native stub. + Disassembles the generated builtin or native stub. *******************************************************************************/ #if defined(ENABLE_DISASSEMBLER) -void codegen_disassemble_nativestub(methodinfo *m, u1 *start, u1 *end) +void codegen_disassemble_stub(methodinfo *m, u1 *start, u1 *end) { - printf("Native stub: "); - utf_fprint_printable_ascii_classname(stdout, m->class->name); + printf("Stub code: "); + if (m->class != NULL) + utf_fprint_printable_ascii_classname(stdout, m->class->name); + else + printf("NULL"); printf("."); utf_fprint_printable_ascii(stdout, m->name); utf_fprint_printable_ascii(stdout, m->descriptor); - printf("\n\nLength: %d\n\n", (s4) (end - start)); + printf("\nLength: %d\n\n", (s4) (end - start)); DISASSEMBLE(start, end); } #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); -} - - -/* 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; -} - - /* codegen_start_native_call *************************************************** Prepares the stuff required for a native (JNI) function call: @@ -1482,9 +1449,9 @@ void codegen_stub_builtin_exit(u1 *datasp) The layout of the native stub stackframe should look like this: - +---------------------------+ <- SP (of parent Java function) + +---------------------------+ <- java SP (of parent Java function) | return address | - +---------------------------+ + +---------------------------+ <- data SP | | | stackframe info structure | | | @@ -1494,34 +1461,112 @@ void codegen_stub_builtin_exit(u1 *datasp) | | +---------------------------+ | | + | saved registers (if any) | + | | + +---------------------------+ + | | | arguments (if any) | | | - +---------------------------+ <- SP (native stub) + +---------------------------+ <- current SP (native stub) *******************************************************************************/ -void codegen_start_native_call(u1 *datasp, u1 *pv, u1 *sp, u1 *ra) +java_handle_t *codegen_start_native_call(u1 *currentsp, u1 *pv) { stackframeinfo *sfi; localref_table *lrt; + codeinfo *code; + methodinfo *m; + int32_t framesize; + + uint8_t *datasp; + uint8_t *javasp; + uint8_t *javara; + uint64_t *arg_regs; + uint64_t *arg_stack; STATISTICS(count_calls_java_to_native++); + /* get information from method header */ + + code = *((codeinfo **) (pv + CodeinfoPointer)); + framesize = *((int32_t *) (pv + FrameSize)); + assert(code); + assert(framesize > sizeof(stackframeinfo) + sizeof(localref_table)); + + /* get the methodinfo */ + + m = code->m; + assert(m); + + /* calculate needed values */ + +#if defined(__ALPHA__) || defined(__ARM__) + datasp = currentsp + framesize - SIZEOF_VOID_P; + javasp = currentsp + framesize; + javara = *((uint8_t **) datasp); + arg_regs = (uint64_t *) currentsp; + arg_stack = (uint64_t *) javasp; +#elif defined(__MIPS__) || defined(__S390__) + /* MIPS and S390 always uses 8 bytes to store the RA */ + datasp = currentsp + framesize - 8; + javasp = currentsp + framesize; + javara = *((uint8_t **) datasp); +#elif defined(__I386__) || defined (__M68K__) || defined (__X86_64__) + datasp = currentsp + framesize; + javasp = currentsp + framesize + SIZEOF_VOID_P; + javara = *((uint8_t **) datasp); + arg_regs = (uint64_t *) currentsp; + arg_stack = (uint64_t *) javasp; +#elif defined(__POWERPC__) || defined(__POWERPC64__) + datasp = currentsp + framesize; + javasp = currentsp + framesize; + javara = *((uint8_t **) (datasp + LA_LR_OFFSET)); + arg_regs = (uint64_t *) (currentsp + LA_SIZE + 4 * SIZEOF_VOID_P); + arg_stack = (uint64_t *) javasp; +#else + /* XXX is was unable to do this port for SPARC64, sorry. (-michi) */ + /* XXX maybe we need to pass the RA as argument there */ + vm_abort("codegen_start_native_call: unsupported architecture"); +#endif + +#if !defined(NDEBUG) +# if defined(__POWERPC__) || defined (__X86_64__) + /* print the call-trace if necesarry */ + + if (opt_TraceJavaCalls) + trace_java_call_enter(m, arg_regs, arg_stack); +# endif +#endif + /* get data structures from stack */ sfi = (stackframeinfo *) (datasp - sizeof(stackframeinfo)); lrt = (localref_table *) (datasp - sizeof(stackframeinfo) - sizeof(localref_table)); - /* add a stackframeinfo to the chain */ - - stacktrace_create_native_stackframeinfo(sfi, pv, sp, ra); - #if defined(ENABLE_JNI) /* add current JNI local references table to this thread */ localref_table_add(lrt); #endif + +#if defined(ENABLE_HANDLES) + /* place all references into the local reference table */ + + localref_fill(m, arg_regs, arg_stack); +#endif + + /* add a stackframeinfo to the chain */ + + stacktrace_create_native_stackframeinfo(sfi, pv, javasp, javara); + + /* return a wrapped classinfo for static native methods */ + + if (m->flags & ACC_STATIC) + return LLNI_classinfo_wrap(m->class); + else + return NULL; } @@ -1533,11 +1578,59 @@ void codegen_start_native_call(u1 *datasp, u1 *pv, u1 *sp, u1 *ra) *******************************************************************************/ -java_object_t *codegen_finish_native_call(u1 *datasp) +java_object_t *codegen_finish_native_call(u1 *currentsp, u1 *pv) { - stackframeinfo *sfi; - stackframeinfo **psfi; - java_handle_t *e; + stackframeinfo *sfi; + java_handle_t *e; + java_object_t *o; + codeinfo *code; + methodinfo *m; + int32_t framesize; + + uint8_t *datasp; + uint64_t *ret_regs; + + /* get information from method header */ + + code = *((codeinfo **) (pv + CodeinfoPointer)); + framesize = *((int32_t *) (pv + FrameSize)); + assert(code); + + /* get the methodinfo */ + + m = code->m; + assert(m); + + /* calculate needed values */ + +#if defined(__ALPHA__) || defined(__ARM__) + datasp = currentsp + framesize - SIZEOF_VOID_P; + ret_regs = (uint64_t *) currentsp; +#elif defined(__MIPS__) || defined(__S390__) + /* MIPS and S390 always uses 8 bytes to store the RA */ + datasp = currentsp + framesize - 8; +#elif defined(__I386__) + datasp = currentsp + framesize; + ret_regs = (uint64_t *) (currentsp + 2 * SIZEOF_VOID_P); +#elif defined (__M68K__) || defined (__X86_64__) + datasp = currentsp + framesize; + ret_regs = (uint64_t *) currentsp; +#elif defined(__POWERPC__) || defined(__POWERPC64__) + datasp = currentsp + framesize; + ret_regs = (uint64_t *) (currentsp + LA_SIZE + 2 * SIZEOF_VOID_P); +#else + vm_abort("codegen_finish_native_call: unsupported architecture"); +#endif + + +#if !defined(NDEBUG) +# if defined(__POWERPC__) || defined (__X86_64__) + /* print the call-trace if necesarry */ + + if (opt_TraceJavaCalls) + trace_java_call_exit(m, ret_regs); +# endif +#endif /* get data structures from stack */ @@ -1545,9 +1638,16 @@ java_object_t *codegen_finish_native_call(u1 *datasp) /* remove current stackframeinfo from chain */ - psfi = &STACKFRAMEINFO; + stacktrace_remove_stackframeinfo(sfi); - *psfi = sfi->prev; + /* XXX unfill lrt here!!! */ + + /* get and unwrap the exception */ + /* ATTENTION: do the this _after_ the stackframeinfo was + removed but _before_ the localref_table gets removed! */ + + e = exceptions_get_and_clear_exception(); + o = LLNI_UNWRAP(e); #if defined(ENABLE_JNI) /* release JNI local references table for this thread */ @@ -1556,11 +1656,7 @@ java_object_t *codegen_finish_native_call(u1 *datasp) localref_table_remove(); #endif - /* get the exception and return it */ - - e = exceptions_get_and_clear_exception(); - - return e; + return o; }