void* pv = (void*) _sc->arm_ip;
void* sp = (void*) _sc->arm_sp;
- u1* ra = (void*) _sc->arm_lr; // The RA is correct for leaf methods.
+ void* ra = (void*) _sc->arm_lr; // The RA is correct for leaf methods.
void* xpc = (void*) _sc->arm_pc;
// Get the exception-throwing instruction.
/* The XPC is the RA minus 4, because the RA points to the
instruction after the call. */
- xpc = ra - 4;
+ xpc = (void*) (((uintptr_t) ra) - 4);
}
// Handle the trap.
- void* p = trap_handle(type, val, pv, sp, ra, xpc, _p);
-
- if (type == TRAP_COMPILER) {
- if (p != NULL) {
- _sc->arm_ip = (uintptr_t) p; // set REG_PV correctly
- }
- else {
- /* Get and set the PV from the parent Java method. */
-
- pv = md_codegen_get_pv_from_pc(ra);
-
- _sc->arm_ip = (uintptr_t) pv;
- }
- }
+ trap_handle(type, val, pv, sp, ra, xpc, _p);
}
/* Include machine dependent trap stuff. */
+#include "md.h"
#include "md-trap.h"
#include "mm/memory.h"
stacktrace_stackframeinfo_remove(&sfi);
#if defined(__ARM__) || defined(__I386__) || defined(__X86_64__)
- /* Update execution state and write it back to the current context. */
+ /* Update execution state and set registers. */
/* AFTER: removing stackframeinfo */
- if (type == TRAP_COMPILER) {
- if (p == NULL) {
- java_handle_t *e = exceptions_get_and_clear_exception();
- es.intregs[REG_ITMP1_XPTR] = (uintptr_t) LLNI_DIRECT(e);
- es.intregs[REG_ITMP2_XPC] = (uintptr_t) xpc;
- es.pc = (uint8_t *) (uintptr_t) asm_handle_exception;
- } else {
- es.pc = (uint8_t *) (uintptr_t) p;
+ switch (type) {
+ case TRAP_COMPILER:
+ // The default case for a compiler trap is to jump directly to
+ // the newly compiled method.
+
+ if (p != NULL) {
+ es.pc = (uint8_t *) (uintptr_t) p;
+ es.pv = (uint8_t *) (uintptr_t) p;
+ break;
}
- } else {
+
+ // In case of an exception during JIT compilation, we fetch
+ // the exception here and proceed with exception handling.
+
+ java_handle_t *e = exceptions_get_and_clear_exception();
+ assert(e != NULL);
+
+ // Get and set the PV from the parent Java method.
+
+ es.pv = md_codegen_get_pv_from_pc(ra);
+
+ // XXX: Make the code below a fall-through to default case!
+
+ es.intregs[REG_ITMP1_XPTR] = (uintptr_t) LLNI_DIRECT(e);
+ es.intregs[REG_ITMP2_XPC] = (uintptr_t) xpc;
+ es.pc = (uint8_t *) (uintptr_t) asm_handle_exception;
+
+ break;
+
+ default:
if (p != NULL) {
- es.intregs[REG_ITMP1_XPTR] = (uintptr_t) p;
+ es.intregs[REG_ITMP1_XPTR] = (uintptr_t) LLNI_DIRECT(p);
es.intregs[REG_ITMP2_XPC] = (uintptr_t) xpc;
es.pc = (uint8_t *) (uintptr_t) asm_handle_exception;
}
}
+ /* Write back execution state to current context. */
+
md_executionstate_write(&es, context);
#endif