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 宮城涼さん <miyagi＠cell.semicon.sony.co.jp>]
+(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 <shudoh@computer.org>
+	Kazuyuki Shudo <shudo@computer.org>
 
 * 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 でも同様。
