X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=src%2Fvm%2Fjit%2Falpha%2Flinux%2Fmd-os.c;h=1cbe4d26e4e0f7158f6b4ec6c0097f7c07634815;hb=33dabc695b6d67fd7081dbfbb7e7c7c798a6dc50;hp=e9c02d40c4e9db5703431915e7e5977b753fe7fe;hpb=b6fbb1958c8971b06e87ea3c37be0deaff131768;p=cacao.git diff --git a/src/vm/jit/alpha/linux/md-os.c b/src/vm/jit/alpha/linux/md-os.c index e9c02d40c..1cbe4d26e 100644 --- a/src/vm/jit/alpha/linux/md-os.c +++ b/src/vm/jit/alpha/linux/md-os.c @@ -34,12 +34,15 @@ #include "vm/types.h" #include "vm/jit/alpha/codegen.h" +#include "vm/jit/alpha/md.h" #include "vm/jit/alpha/md-abi.h" #if defined(ENABLE_THREADS) # include "threads/native/threads.h" #endif +#include "vm/builtin.h" +#include "vm/exceptions.h" #include "vm/signallocal.h" #include "vm/jit/asmpart.h" @@ -55,7 +58,6 @@ void md_signal_handler_sigsegv(int sig, siginfo_t *siginfo, void *_p) { - stackframeinfo sfi; ucontext_t *_uc; mcontext_t *_mc; u1 *pv; @@ -83,9 +85,9 @@ void md_signal_handler_sigsegv(int sig, siginfo_t *siginfo, void *_p) mcode = *((u4 *) xpc); - d = M_MEM_GET_A(mcode); - s1 = M_MEM_GET_B(mcode); - disp = M_MEM_GET_DISP(mcode); + d = M_MEM_GET_Ra(mcode); + s1 = M_MEM_GET_Rb(mcode); + disp = M_MEM_GET_Memory_disp(mcode); val = _mc->sc_regs[d]; @@ -95,6 +97,13 @@ void md_signal_handler_sigsegv(int sig, siginfo_t *siginfo, void *_p) /* we use the exception type as load displacement */ type = disp; + + if (type == EXCEPTION_HARDWARE_COMPILER) { + /* The XPC is the RA minus 1, because the RA points to the + instruction after the call. */ + + xpc = ra - 4; + } } else { /* This is a normal NPE: addr must be NULL and the NPE-type @@ -104,24 +113,44 @@ void md_signal_handler_sigsegv(int sig, siginfo_t *siginfo, void *_p) type = (int) addr; } - /* create stackframeinfo */ + /* Handle the type. */ + + p = signal_handle(type, val, pv, sp, ra, xpc, _p); - stacktrace_create_extern_stackframeinfo(&sfi, pv, sp, ra, xpc); + /* Set registers. */ - /* Handle the type. */ + switch (type) { + case EXCEPTION_HARDWARE_COMPILER: + if (p != NULL) { + _mc->sc_regs[REG_PV] = (uintptr_t) p; + _mc->sc_pc = (uintptr_t) p; + break; + } + + /* Get and set the PV from the parent Java method. */ - p = signal_handle(xpc, type, val); + pv = md_codegen_get_pv_from_pc(ra); - /* remove stackframeinfo */ + _mc->sc_regs[REG_PV] = (uintptr_t) pv; - stacktrace_remove_stackframeinfo(&sfi); + /* Get the exception object. */ - /* set registers */ + p = builtin_retrieve_exception(); - if (p != NULL) { - _mc->sc_regs[REG_ITMP1_XPTR] = (intptr_t) p; - _mc->sc_regs[REG_ITMP2_XPC] = (intptr_t) xpc; - _mc->sc_pc = (intptr_t) asm_handle_exception; + assert(p != NULL); + + /* fall-through */ + + case EXCEPTION_HARDWARE_PATCHER: + if (p == NULL) + break; + + /* fall-through */ + + default: + _mc->sc_regs[REG_ITMP1_XPTR] = (uintptr_t) p; + _mc->sc_regs[REG_ITMP2_XPC] = (uintptr_t) xpc; + _mc->sc_pc = (uintptr_t) asm_handle_exception; } } @@ -199,14 +228,18 @@ void md_replace_executionstate_read(executionstate_t *es, void *context) es->pc = (u1 *) _mc->sc_pc; es->sp = (u1 *) _mc->sc_regs[REG_SP]; es->pv = (u1 *) _mc->sc_regs[REG_PV]; + es->ra = (u1 *) _mc->sc_regs[REG_RA]; /* read integer registers */ for (i = 0; i < INT_REG_CNT; i++) es->intregs[i] = _mc->sc_regs[i]; /* read float registers */ - for (i = 0; i < FLT_REG_CNT; i++) - es->fltregs[i] = _mc->sc_fpregs[i]; + /* Do not use the assignment operator '=', as the type of + * the _mc->sc_fpregs[i] can cause invalid conversions. */ + + assert(sizeof(_mc->sc_fpregs) == sizeof(es->fltregs)); + memcpy(&es->fltregs, &_mc->sc_fpregs, sizeof(_mc->sc_fpregs)); } #endif @@ -232,13 +265,17 @@ void md_replace_executionstate_write(executionstate_t *es, void *context) _mc->sc_regs[i] = es->intregs[i]; /* write float registers */ - for (i = 0; i < FLT_REG_CNT; i++) - _mc->sc_fpregs[i] = es->fltregs[i]; + /* Do not use the assignment operator '=', as the type of + * the _mc->sc_fpregs[i] can cause invalid conversions. */ + + assert(sizeof(_mc->sc_fpregs) == sizeof(es->fltregs)); + memcpy(&_mc->sc_fpregs, &es->fltregs, sizeof(_mc->sc_fpregs)); /* write special registers */ - _mc->sc_pc = es->pc; + _mc->sc_pc = (ptrint) es->pc; _mc->sc_regs[REG_SP] = (ptrint) es->sp; _mc->sc_regs[REG_PV] = (ptrint) es->pv; + _mc->sc_regs[REG_RA] = (ptrint) es->ra; } #endif