/* Include machine dependent trap stuff. */
+#include "md.h"
#include "md-trap.h"
#include "mm/memory.h"
o = NULL;
m = NULL;
-#if defined(__I386__) || defined(__X86_64__)
+#if defined(__ALPHA__) || defined(__ARM__) || defined(__I386__) || defined(__POWERPC__) || defined(__POWERPC64__) || defined(__X86_64__)
# if !defined(NDEBUG)
/* Perform a sanity check on our execution state functions. */
stacktrace_stackframeinfo_remove(&sfi);
-#if defined(__I386__) || defined(__X86_64__)
- /* Update execution state and write it back to the current context. */
+#if defined(__ALPHA__) || defined(__ARM__) || defined(__I386__) || defined(__POWERPC__) || defined(__POWERPC64__) || defined(__X86_64__)
+ /* Update execution state and set registers. */
/* AFTER: removing stackframeinfo */
- if (type == TRAP_COMPILER) {
+ switch (type) {
+ case TRAP_COMPILER:
+ // The normal 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;
+ }
+
+ // 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;
+
+ case TRAP_PATCHER:
+ // The normal case for a patcher trap is to continue execution at
+ // the trap instruction. On some archs the PC may point after the
+ // trap instruction, so we reset it here.
+
if (p == NULL) {
- java_handle_t *e = exceptions_get_and_clear_exception();
- es.intregs[REG_ITMP1] = (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;
+ es.pc = (uint8_t *) (uintptr_t) xpc;
+ break;
}
- } else {
+
+ /* fall-through */
+
+ default:
if (p != NULL) {
- es.intregs[REG_ITMP1] = (uintptr_t) p;
- es.intregs[REG_ITMP2_XPC] = (uintptr_t) xpc;
- es.pc = (uint8_t *) (uintptr_t) asm_handle_exception;
+ 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