From a9fad0574b1b8967ee48a0708a7d46a9c113f919 Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Sat, 14 Jun 2008 21:11:16 +0200 Subject: [PATCH] Fix assembly bug: use only registers above r7 when restoring JOSP Using %[josp] as a loop counter while restoring JOSP in a loop nefore executing retj is bad - %[josp] can be one of r0-r7 and then after the first incjosp you cannot access it any more. Use one of high (above r7) registers. --- src/interp/engine/interp_jem.c | 60 ++++++++++++++++++++++++++---------------- 1 file changed, 37 insertions(+), 23 deletions(-) diff --git a/src/interp/engine/interp_jem.c b/src/interp/engine/interp_jem.c index 9def266..11f59c9 100644 --- a/src/interp/engine/interp_jem.c +++ b/src/interp/engine/interp_jem.c @@ -141,7 +141,7 @@ static int jem_throwException(struct jem_state *jem) return 0; } -static int methodReturn(struct jem_state *jem) +static int opc_return(struct jem_state *jem) { ExecEnv *ee = getExecEnv(); /* Set interpreter state to previous frame */ @@ -270,7 +270,7 @@ static int invokeMethod(struct jem_state *jem) return 0; } -static int invokesuper_quick(struct jem_state *jem) +static int opc_invokesuper_quick(struct jem_state *jem) { Operand *operand = &jem->operand; @@ -288,14 +288,13 @@ static int invokesuper_quick(struct jem_state *jem) return invokeMethod(jem); } -static int invokenonvirtual_quick(struct jem_state *jem) +static int opc_invokenonvirtual_quick(struct jem_state *jem) { Operand *operand = &jem->operand; - jam_printf("[OPC_INVOKENONVIRTUAL_QUICK]\n"); new_mb = (MethodBlock*)operand->pntr; - jam_printf("[OPC_INVOKENONVIRTUAL_QUICK] new methodblock %x with %d args\n", - new_mb, new_mb->args_count); + jam_printf("[OPC_INVOKENONVIRTUAL_QUICK] new methodblock %s (%x) with %d args\n", + new_mb->name, new_mb, new_mb->args_count); arg1 = (new_mb->args_count > 8) ? (ostack - (new_mb->args_count - 8)) : ((uintptr_t*)jos + (8 - new_mb->args_count)); jam_printf("[OP_INVOKENONVIRTUAL_QUICK] arg1 %x \n", *arg1); @@ -303,7 +302,7 @@ static int invokenonvirtual_quick(struct jem_state *jem) return invokeMethod(jem); } -static int invokespecial(struct jem_state *jem) +static int opc_invokespecial(struct jem_state *jem) { int idx, cache; Operand *operand = &jem->operand; @@ -319,18 +318,20 @@ static int invokespecial(struct jem_state *jem) if (exceptionOccured0(ee)) return jem_throwException(jem); + jam_printf("Resolved %s\n", new_mb->name); + /* Check if invoking a super method... */ if ((CLASS_CB(mb->class)->access_flags & ACC_SUPER) && ((new_mb->access_flags & ACC_PRIVATE) == 0) && (new_mb->name[0] != '<')) { operand->i = new_mb->method_table_index; - return invokesuper_quick(jem); + return opc_invokesuper_quick(jem); #if 0 /* FIXME: verify this whole "pc" chemistry is indeed unneeded */ OPCODE_REWRITE(OPC_INVOKESUPER_QUICK, cache, operand); #endif } else { operand->pntr = new_mb; - return invokenonvirtual_quick(jem); + return opc_invokenonvirtual_quick(jem); #if 0 /* FIXME: verify this whole "pc" chemistry is indeed unneeded */ OPCODE_REWRITE(OPC_INVOKENONVIRTUAL_QUICK, cache, operand); #endif @@ -352,7 +353,7 @@ static int JEM_PUSH(struct jem_state *jem, uint32_t value) return 0; } -static int new_quick(struct jem_state *jem) +static int opc_new_quick(struct jem_state *jem) { Operand *operand = &jem->operand; Class *class = (Class*)CP_INFO(cp, operand->uui.u1); @@ -365,7 +366,7 @@ static int new_quick(struct jem_state *jem) return JEM_PUSH(jem, (uintptr_t)obj); } -static int new(struct jem_state *jem) +static int opc_new(struct jem_state *jem) { Operand *operand = &jem->operand; int idx = operand->uui.u1 = jem->jecr & 0xffff; @@ -389,7 +390,7 @@ static int new(struct jem_state *jem) } } - return new_quick(jem); + return opc_new_quick(jem); } static int do_javaExceptions(struct jem_state *jem) @@ -528,11 +529,12 @@ uintptr_t *executeJava(void) /* This is temporary. As we implement more handlers, we'll think of a better * way to link them. */ - trap_handler_f[OPC_INVOKESPECIAL] = invokespecial; - trap_handler_f[OPC_INVOKESUPER_QUICK] = invokesuper_quick; - trap_handler_f[OPC_INVOKENONVIRTUAL_QUICK] = invokenonvirtual_quick; - trap_handler_f[OPC_NEW] = new; - trap_handler_f[OPC_NEW_QUICK] = new_quick; + trap_handler_f[OPC_INVOKESPECIAL] = opc_invokespecial; + trap_handler_f[OPC_INVOKESUPER_QUICK] = opc_invokesuper_quick; + trap_handler_f[OPC_INVOKENONVIRTUAL_QUICK] = opc_invokenonvirtual_quick; + trap_handler_f[OPC_NEW] = opc_new; + trap_handler_f[OPC_NEW_QUICK] = opc_new_quick; + trap_handler_f[OPC_RETURN] = opc_return; jem.josp = 0; @@ -543,14 +545,20 @@ uintptr_t *executeJava(void) #endif jem.jpc = (unsigned long)mb->code & ~3; - jam_printf("Entering java @ 0x%08x, this = %p\n", jem.jpc, this); do { int opcode; - jam_printf("Up to 8 first Loval Variables out of %d:\n", mb->max_locals); + jam_printf("About to enter JEM at 0x%08x, this = %p. Code:", jem.jpc, this); + for (i = 0; i < 32 && jem.jpc + i < mb->code + mb->code_size; i++) { + if (!(i & 0xf)) + jam_printf("\n0x%04x:", i); + jam_printf(" 0x%02x", ((char*)jem.jpc)[i]); + } + + jam_printf("\nUp to 8 first Local Variables out of %d:\n", mb->max_locals); for (i = 0; i < min(8, mb->max_locals); i++) - printf("LVAR_%d: 0x%08x\n", i, *(lvars - i)); + jam_printf("LVAR_%d: 0x%08x\n", i, *(lvars - i)); /* On entry we need last Java Operand Stack depth */ jem.josp &= 7; @@ -562,9 +570,10 @@ uintptr_t *executeJava(void) " mov lr, %[jpc]\n" " cp.w %[josp], 0\n" /* Test josp == 0 */ " breq 4f\n" - "5: incjosp 1\n" - " sub %[josp], 1\n" - " brne 5b\n" + " mov r11, %[josp]\n" /* Cannot use %[josp] */ + "5: incjosp 1\n" /* for loop counter, */ + " sub r11, 1\n" /* because it can be */ + " brne 5b\n" /* one of r0-r7 */ "4: lddpc r11, jos_p\n" " ldm r11, r0-r7\n" /* Restore Java Operands */ " popjc\n" /* Restore Local Variables */ @@ -615,6 +624,11 @@ uintptr_t *executeJava(void) done = exception_handler_f[jep >> 7](&jem); else if (trap_handler_f[opcode]) done = trap_handler_f[opcode](&jem); + else { + /* Unimplemented */ + jam_printf("Unimplemented Java Opcode 0x%02x\n", opcode); + exitVM(1); + } } while (done != JEM_TRAP_HANDLER_FINISH); return ostack; -- 2.11.4.GIT