diff -aruN shujit-0.7.5/ChangeLog shujit/ChangeLog --- shujit-0.7.5/ChangeLog Fri Sep 21 22:08:48 2001 +++ shujit/ChangeLog Wed Oct 17 16:39:16 2001 @@ -1,5 +1,36 @@ $Id$ +[20011017] + +#define DIRECT_INVOCATION の場合、 +invocationHelper() -> compileAndInvokeMethod() -> invokeJITCompiledMethod() +という呼び出しを辿ると、本来してはいけないにも関わらず、 +JVM のスタックからネイティブスタックへの restack をしてしまっていた。 +これが起きないように修整した。 +Jython 2.0 で発覚。 +これまで、JIT 生成コードから呼び出された印として +ee->current_frame->returnpc を -1 に設定する処理は、 +#undef DIRECT_INVOCATION の場合にのみ JIT 生成コード中で行っていた。 +それを、invocationHelper() (runtime.c) で行うようにした。 +そして、invokeJITCompiledMethod() 中で restack をスキップするか否かの +判定を returnpc を見て常に行うようにした。 +[Thanks 宮城涼さん ] +(runtime.c, invoker.c, code.c) + +0.7.6 リリース。 + +[20010922] + +無限ループの実行中に Thread#stop() された場合でも +きちんと ThreadDeath (非同期例外) が throw されたことを検出するようにした。 +例外が throw されているかどうか調べる内部命令 exc_check を追加した。 +ある条件を満たした後方ジャンプの前に exc_check 命令を挿入するようにした。 +この条件チェックはさぼったいい加減なものなので、完全な動作は保証しない。 +compiler.h 中のマクロ EXC_CHECK_IN_LOOP で、 +このチェックを行うかどうかを制御できる。 +Kaffe 1.0.6 の test/regression/ThreadStop がきちんと動作終了することを確認。 +(opcodes_internal.h, code.c, compile.c) + [20010921] クラスを JIT 向けに初期化する際 (initializeClassForJIT()) に、 diff -aruN shujit-0.7.5/README shujit/README --- shujit-0.7.5/README Sat Sep 22 02:36:32 2001 +++ shujit/README Wed Oct 17 16:12:12 2001 @@ -1,21 +1,21 @@ shuJIT - JIT compiler for x86 http://www.shudo.net/jit/ - Kazuyuki Shudo + Kazuyuki Shudo * What this is -ShuJIT is a Java Just-in-Time compiler (JIT) which -works with Sun Microsystems' Classic Virtual Machine -such as JDK and JRE on Intel x86 processors. +ShuJIT is a Java Just-in-Time compiler for Sun Microsystems' Classic VM +(i.e. JDK, Java 2 SDK, JRE) and Intel x86 processors. +It supports Linux, FreeBSD and NetBSD. * Platforms Working on the following platforms is confirmed. - Linux - - Blackdown JDK 1.3.1 FCS, gcc 2.95.2, glibc 2.2.4 and Linux 2.4.9-ac12 - - Blackdown JDK 1.2.2 FCS, gcc 2.95.2, glibc 2.2.4 and Linux 2.4.9-ac12 - - JDK 1.1.8v3, gcc 2.95.2, glibc 2.2.4 and Linux 2.4.9-ac12 + - Blackdown JDK 1.3.1 FCS, gcc 2.95.2, glibc 2.2.4 and Linux 2.4.12-ac3 + - Blackdown JDK 1.2.2 FCS, gcc 2.95.2, glibc 2.2.4 and Linux 2.4.12-ac3 + - JDK 1.1.8v3, gcc 2.95.2, glibc 2.2.4 and Linux 2.4.12-ac3 - JDK 1.1.7v1a, egcs 1.1.2, libc 5.4.38 and Linux 2.0.35 - FreeBSD diff -aruN shujit-0.7.5/code.c shujit/code.c --- shujit-0.7.5/code.c Thu Sep 20 20:01:23 2001 +++ shujit/code.c Wed Oct 17 15:56:17 2001 @@ -713,6 +713,18 @@ } +#ifdef EXC_CHECK_IN_LOOP + // check whether an exception has been thrown + CODE(opc_exc_check, exc_check, STANY, STSTA, OPC_NONE) { + // eax = !exceptionOccurred(ee) + asm("movl %0,%%edi" : : "m" (ee)); // edi = ee + EE_EXCEPTIONKIND_EAX(%edi); + asm("testl %eax,%eax\n\t" + ".short 0x850f\n\t.long " STR(ADDR_EXC)); // jnz + } +#endif // EXC_CHECK_IN_LOOP + + // nop CODE(opc_nop, nop, STANY, STSTA, OPC_NONE) {} @@ -4193,8 +4205,6 @@ asm("inv_core_invoke_done:") #else // DIRECT_INVOCATION # define INVCORE_INVOKE \ - /* cur_frame->returnpc = -1 */\ - asm("movl $-1," FRAME_RETURNPC(%edi));\ /* cur_frame->lastpc = cur_frame->current_method->code + bytepcoff */\ asm("movl " FRAME_CURRENTMETHOD(%edi) ",%ecx\n\t"\ "movl " METHOD_CODE(%ecx) ",%ecx");\ diff -aruN shujit-0.7.5/compile.c shujit/compile.c --- shujit-0.7.5/compile.c Sat Sep 22 02:33:42 2001 +++ shujit/compile.c Wed Oct 17 11:35:36 2001 @@ -1828,9 +1828,31 @@ tgtentry = pctableGetByPC(cc, tgtpc); sysAssert(tgtentry != NULL); pcentrySetBlockHead(tgtentry); + if (loopp) { pcentrySetLoopHead(tgtentry); pcentrySetLoopTail(entry); +#ifdef EXC_CHECK_IN_LOOP + for (j = tgtpc; j < i; j++) { + int checked_opcode = cc->pctable[j].opcode; + if ((checked_opcode == opc_inv_head) || + (checked_opcode == opc_athrow)) + // don't generate exc_check insn + // if there is `inv_head' or `athrow' insn + goto exc_check_done; + } + +# ifdef COMPILE_DEBUG + if (compile_debug) { + printf(" insert exc_check\n"); + fflush(stdout); + } +# endif + pctableInsert(cc, i, opc_exc_check, -1/* operand */, + entry->byteoff, -1/* state */, -1/* native off */); + i++; + exc_check_done: +#endif // EXC_CHECK_IN_LOOP } } else if (opcode == opc_jsr) { @@ -2404,7 +2426,7 @@ } // code_statetoX pctableInsert(cc, i + 1, - opc_stateto0 + tgtstate, -1/* as operand */, pctable->byteoff, + opc_stateto0 + tgtstate, -1/* operand */, pctable->byteoff, last_state, nextoff); i++; writeToBuffer(cc, @@ -2426,7 +2448,7 @@ // internal opcodes: goto, jsr, ret // code_sattetoX pctableInsert(cc, i + 1, - opc_stateto0 + tgtstate, -1/* as operand */, pctable->byteoff, + opc_stateto0 + tgtstate, -1/* operand */, pctable->byteoff, last_state, nextoff); i++; writeToBuffer(cc, (unsigned char *)assembledCode + transcodep->offset, diff -aruN shujit-0.7.5/compiler.h shujit/compiler.h --- shujit-0.7.5/compiler.h Fri Sep 21 22:37:09 2001 +++ shujit/compiler.h Wed Oct 17 16:21:19 2001 @@ -94,6 +94,7 @@ #undef PATCH_ON_JUMP #undef INITCLASS_IN_COMPILATION +#define EXC_CHECK_IN_LOOP #define METHOD_INLINING #define DIRECT_INVOCATION #define EAGER_COMPILATION @@ -775,6 +776,9 @@ // wrapper must be a function, not a macro #endif extern void showStackFrames(ExecEnv *ee); +#ifdef RUNTIME_DEBUG +extern void showArguments(struct methodblock *mb, stack_item *vars); +#endif #if defined(RUNTIME_DEBUG) || defined(COMPILE_DEBUG) extern void showExcStackTrace(JHandle *throwable); #endif diff -aruN shujit-0.7.5/invoker.c shujit/invoker.c --- shujit-0.7.5/invoker.c Sat Sep 22 02:36:23 2001 +++ shujit/invoker.c Wed Oct 17 16:06:32 2001 @@ -363,12 +363,10 @@ // call -#ifndef DIRECT_INVOCATION if (((int)old_frame->returnpc) == -1) { // called by compiled method var_base = var_base_read_only; goto restack2native_done; } -#endif // called by normal Java or native method // restack from JVM stack to native stack @@ -407,48 +405,7 @@ printf(" code size: 0x%08x\n", (info ? info->code_size : 0)); fflush(stdout); - { - stack_item *vars = var_base; - char *sig; - int i; - - if (args_size > 0) { - printf(" args:\n"); - i = 0; - if (!(mb->fb.access & ACC_STATIC)) { - printf(" 0x%08x @ 0x%08x ", (int)vars[0].h, (int)vars); - showObjectBody("L;", vars[0].h); - printf("\n"); - i++; - } - sig = mb->fb.signature; - if (sig[0] == '(') sig++; - - for (; i < args_size; i++) { - JHandle *arg = vars[-i].h; - if ((sig[0] == 'J') || (sig[0] == 'D')) { - stack_item *argp; - - i++; - argp = vars - i; - - if (sig[0] == 'J') - printf(" %lld,0x%llx", *((long long *)argp)); - else - printf(" %10g", *((double *)argp)); - printf(" @ 0x%08x\n", argp); - - sig++; - } - else { - printf(" 0x%08x @ 0x%08x ", (int)arg, (int)(vars - i)); - sig = showObjectBody(sig, arg); - printf("\n"); - } - } - } - fflush(stdout); - } + showArguments(mb, var_base); } #endif // RUNTIME_DEBUG @@ -575,7 +532,7 @@ if (!mb) return FALSE; -#if 0 +#if 1 if ((!strcmp(cbName(fieldclass(&mb->fb)), "java/lang/Compiler"))) debugp = TRUE; else if ((!strcmp(cbName(fieldclass(&mb->fb)), "java/lang/Object")) @@ -608,7 +565,6 @@ debugp = TRUE; # endif #endif - return debugp; } diff -aruN shujit-0.7.5/opcodes_internal.h shujit/opcodes_internal.h --- shujit-0.7.5/opcodes_internal.h Mon Jul 16 01:08:53 2001 +++ shujit/opcodes_internal.h Sat Sep 22 20:47:40 2001 @@ -53,6 +53,8 @@ #define opc_invokeignored_static 251 // 0xfb #define opc_invokeignored_static_quick 252 +#define opc_exc_check 253 + // 254 and 255 are reserved for VM specific instructions #define opc_impdep1 254 // 0xfe #define opc_impdep2 255 // 0xff diff -aruN shujit-0.7.5/runtime.c shujit/runtime.c --- shujit-0.7.5/runtime.c Wed Sep 19 00:30:00 2001 +++ shujit/runtime.c Wed Oct 17 17:00:11 2001 @@ -43,10 +43,14 @@ ) { void *invoker; CodeInfo *info; - JavaFrame *cur_frame; // ee->current_frame + JavaFrame *cur_frame = ee->current_frame; int retsize; int access; + // mark as invoked by JIT compiled code + cur_frame->returnpc = (unsigned char *)-1; + + // get CompiledCodeInfo info = (CodeInfo *)method->CompiledCodeInfo; #ifdef RUNTIME_DEBUG if (!info) { @@ -71,7 +75,6 @@ access = method->fb.access; - cur_frame = ee->current_frame; cur_mb = cur_frame->current_method; sig = method->fb.signature; @@ -1267,6 +1270,52 @@ frame = frame->prev; } } + + +#ifdef RUNTIME_DEBUG +void showArguments(struct methodblock *mb, stack_item *vars) { + char *sig = mb->fb.signature; + int args_size = mb->args_size; + int i = 0; + + if (args_size > 0) { + printf(" args:\n"); + + if (!(mb->fb.access & ACC_STATIC)) { + printf(" 0x%08x @ 0x%08x ", (int)vars[0].h, (int)vars); + showObjectBody("L;", vars[0].h); + printf("\n"); + i++; + } + + sig = mb->fb.signature; + if (sig[0] == '(') sig++; + + for (; i < args_size; i++) { + stack_item *argp = vars - i; + + if ((sig[0] == 'J') || (sig[0] == 'D')) { + i++; + argp -= 1; + + if (sig[0] == 'J') + printf(" %lld,0x%llx", *((long long *)argp)); + else + printf(" %10g", *((double *)argp)); + printf(" @ 0x%08x\n", argp); + + sig++; + } + else { + printf(" 0x%08x @ 0x%08x ", (int)argp->h, (int)argp); + sig = showObjectBody(sig, argp->h); + printf("\n"); + } + } + } + fflush(stdout); +} +#endif // RUNTIME_DEBUG #if defined(RUNTIME_DEBUG) || defined(COMPILE_DEBUG) diff -aruN shujit-0.7.5/txt/memo shujit/txt/memo --- shujit-0.7.5/txt/memo Thu Sep 20 21:07:50 2001 +++ shujit/txt/memo Wed Oct 17 16:20:07 2001 @@ -1,4 +1,7 @@ Todo + - Thread#stop() 対応のために行っているループ中の例外ポーリングは + 性能的なペナルティがあるため、これを解決する。 + このポーリングはマクロ EXC_CHECK_IN_LOOP で有効になる。 - Native Threads だと Forte for Java 3.0 CE の起動中に 様々な箇所でデッドロックする。この問題を解決する。 TYA 1.7v3 でも同様。