diff -aruN shujit-0.3.13/ChangeLog shujit/ChangeLog --- shujit-0.3.13/ChangeLog Sat Oct 16 18:51:07 1999 +++ shujit/ChangeLog Tue Dec 28 19:56:26 1999 @@ -1,5 +1,134 @@ $Id$ +[20000101] + +0.4.0 リリース。 + +[19991228] + +JIT のシグナルハンドラから目的の sigcontext まで到達する方法を、 +あらかじめ JIT 初期化時に求めておくようにした。 +examineSigcontextNestCount() を JIT のシグナルハンドラに設定し、 +int $0x3 で割り込みを発生させ、その関数内で到達法を求める。 +native threads と green threads で探し方が異なる。 +[Thanks to OpenJIT team ] +(signal.c, compiler.h) + +スタック上で目的の sigcontext を探す際、これまでは +セグメントレジスタ ds,es,fs,gs の値を手がかりにしていたが、 +%eip レジスタ (プログラムカウンタ) を手がかりに使うようにした。 +(signal.c) + +sigcontext を探す際の手がかり変更に伴って不要になった +変数 reg_[gfed]s およびその初期化処理を削除した。 +(compiler.h, compiler.c) + +JDK 1.1 で #include ARCH/sysmacros_md.h する際に、 +JDK_HOME/include(-old)/green_threads ディレクトリが存在するか否かによって +マクロ NATIVE を #define するかしないかを決めねばならない。 +そのために、configure で green_threads ディレクトリの有無を判定するようにした。 +(configure.in, config.h.in) + +Linux 2.2 が持っている を Linux 2.0 は持っていないので、 +このヘッダの存在を configure で調べるようにした。 +(configure.in, config.h.in) + +examineSigcontextNestCount() を実行するための割り込みを、 +0x3 から 0x10 にした。0x3 (SIGTRAP) を使うと、 +それ以降 gdb が処理を続けられなくなってしまうため。 +int $0x3 とそれ以外では、sigcontext.sc_eip の値 +(int $0x3 では次の命令を指す、他は int 命令を指す) や +命令のサイズ (int $0x3 は 1バイト、他は 2バイト) が異なるので注意。 +(compiler.c, signal.c) + +新しい (2.9.5.0.22) binutils になって、 +objdump による `call 即値' のディスアセンブル結果が変わった。 +次の行に `XXX: R_386_PC32 *ABS*' を表示するようになった。 +それに応じて、gentable.rb にて関数名 *ABS* をスキップするようにした。 +(gentable.rb) + +新しい binutils は jmp 0x707070 を jmp 0x70706c にアセンブルするので、 +対策として、ジャンプ先アドレスの格納先の pre-assembled code 中での表現法、 +つまり code.h のマクロ ADDR_* の値を変更し、gentable.rb もそれに対応させた。 +(code.h, gentable.rb) + +code.h のマクロ ADDR_* は例えば 0x70707010 としておいて、 +ディスアセンブル結果から /70 70 70/ を探すようにした。 +しかし binutils のバージョンによっては 3つめの 70 が次の行に表示されて +/70 70 70/ がマッチしなくなった。そのため、/70 70/ で探すようにした。 +(gentable.rb, code.h) + +[19991227] + +sigcontext の探し方を変更。単にスタックをなめていたところ、 +ベースポインタをたぐって探すようにした。 +ebp + 3 が sigcontext_t * 型かどうかで判定する。 +[Thanks to OpenJIT team ] +glibc 2.1.2 の LinuxThreads は sigcontext を 2つスタックに置いてしまい、 +ひとつめに見付かった sigcontext を変更しても、 +シグナルハンドラから戻った際に反映されない。 +そのため、最後に見付けた ebp を採用する。 +(compiler.c) + +signalHandler() から例外処理への復帰のために、これまでは目的のアドレスに +単にジャンプしていたところ、 +Linux では %ebp を設定して return するように、 +FreeBSD では sigreturn(sigcontext_t *) を使うようにした。 +[Thanks to OpenJIT team ] +FreeBSD で行っていたシグナルの unmask (sigprocmask(SIG_UNBLOCK, ...)) は +不要になった。 +(compiler.c) + +シグナルハンドラの再設定のための変数 +struct sigaction sigActForHandler を排した。 +(compiler.c) + +[19991223] + +copyright 表示の年に 2000 を加えた。 +ただし、MetaVM のための Java のソースコードは 1999 のままにした。 + +[19991222] + +JIT の初期化関数 java_lang_Compiler_start が +java.lang.Compiler クラスが再ロードによって複数回呼ばれてしまう問題への +対処法を変更。フラグで検出していたところ、Compiler クラスに sticky 属性を +付与することにした (CCSet(..., Sticky))。(see [990514]) +(compiler.c) + +[19991209] + +shuJIT では、フィールドアクセスだけでなく、メソッド呼び出しについても +きちんと VerifyFieldAccess でアクセス権限チェックを行っている。 +(see [19991003]) このチェックによって、inner クラスから/へのアクセスでも +IllegalAccessError が発生してしまっていた。 +inner クラスからみのアクセスを許すように穴をあけた。 +NetBeans 2.1.2 で問題になっていた。 +(compile.c) + +[19991204] + +JDK 1.2 の場合、シグナルハンドラから例外処理コードへのジャンプは +単に return TRUE すればよいはずが (see [19990725]) +JDK 1.2.2rc2 for Linux にて、return 後に +SIGSEGV が発生してしまうので、JDK 1.2 でも JDK 1.1 と同じ方法で +ジャンプするようにした。 +(compiler.c) + +[19991106] + +strictfp の scaling を fscale 命令で行う場合、 +scale を double 型(64bit) ではなく、int 型(32bit) で用意しておく方法を用意。 +マクロ STRICT_FSCALE_USE_INT で制御。 +FPU レジスタ - メモリ間のトラフィック削減を狙う +…が、遅くなった (on PentiumII)。ので却下。 +(compiler.h, code.c) + +int 型(32bit) をやめて、float 型(32bit) にした。 +マクロ STRICT_FSCALE_USE_FLOAT で制御。 +double 型(64bit) の場合と性能がほぼ変わらない。 +(compiler.h, code.c) + [19991016] 64bit 整数(long)型の 0除算で、__divdi3() 中で発生した SIGFPE を diff -aruN shujit-0.3.13/GNUmakefile shujit/GNUmakefile --- shujit-0.3.13/GNUmakefile Sat Oct 16 19:16:38 1999 +++ shujit/GNUmakefile Tue Dec 28 19:20:02 1999 @@ -10,15 +10,15 @@ # environment -JDK_VER = 11 -J_INCDIR = /usr/local/java/include +JDK_VER = 12 +J_INCDIR = /usr/local/java/include-old GCC27 = # command -CC = /usr/bin/egcs +CC = /usr/bin/gcc LD_DYNAMIC = ${CC} -shared# for GCC and GNU binutils #LD_DYNAMIC = ld -Bdynamic# for SunOS 4 ASFLAGS = @@ -65,7 +65,7 @@ TOOLSOBJ = codedbinfo.o # source code HDR = compiler.h code.h -OBJ = code.o compiler.o invoker.o computil.o opcodes.o compile.o\ +OBJ = code.o compiler.o signal.o invoker.o computil.o opcodes.o compile.o\ runtime.o x86tsc.o ifneq (${JDK_VER}, 11) OBJ += linker.o diff -aruN shujit-0.3.13/GNUmakefile.in shujit/GNUmakefile.in --- shujit-0.3.13/GNUmakefile.in Sat Oct 16 15:46:54 1999 +++ shujit/GNUmakefile.in Mon Dec 27 18:58:18 1999 @@ -65,7 +65,7 @@ TOOLSOBJ = codedbinfo.o # source code HDR = compiler.h code.h -OBJ = code.o compiler.o invoker.o computil.o opcodes.o compile.o\ +OBJ = code.o compiler.o signal.o invoker.o computil.o opcodes.o compile.o\ runtime.o x86tsc.o ifneq (${JDK_VER}, 11) OBJ += linker.o diff -aruN shujit-0.3.13/README shujit/README --- shujit-0.3.13/README Sat Oct 16 19:25:33 1999 +++ shujit/README Tue Dec 28 19:03:20 1999 @@ -13,24 +13,24 @@ Working on the following platforms is confirmed. - Linux - - JDK 1.2 pre-release 2, egcs 1.1.2, glibc2.1.1 and Linux 2.2.12 - - JDK 1.2 pre-release 2, egcs 1.0.3, glibc2.0.7 and Linux 2.2.12 - - JDK 1.1.7v3, egcs 1.1.2, glibc2.1.1 and Linux 2.2.12 + - Blackdown JDK 1.2.2 RC3, gcc 2.95.2, glibc2.1.2 and Linux 2.2.14pre16 + - JDK 1.2 pre-release 2, egcs 1.0.3, glibc2.0.7 and Linux 2.2.13pre7 + - JDK 1.1.8v1, gcc 2.95.2, glibc2.1.2 and Linux 2.2.14pre16 - JDK 1.1.7v1a, egcs 1.1.2, libc5.4.38 and Linux 2.0.35 - FreeBSD - - JDK 1.1.8 (ELF, V99-9-22), gcc 2.95.1, FreeBSD 3.2R + - JDK 1.1.8 (ELF, V1999-11-9), gcc 2.95.2, FreeBSD 3.3R * Installation With JDK 1.2, you must place the libshujit.so on -jdk1.2/jre/lib/i386/ or make a symbolic link into the +jdk1.2.2/jre/lib/i386/ or make a symbolic link into the directory. With JDK 1.1.X, copy the libshujit.so to the path in LD_LIBRARY_PATH variable or the path on which libjava.so exists -(ex. /usr/local/jdk1.1.7/lib/i686/green_threads/). +(ex. /usr/local/jdk1.1.8/lib/i686/green_threads/). * Run Java applications with JIT compiler. @@ -47,7 +47,7 @@ You need some tools to compile this JIT. -- JDK 1.1.X or 1.2 +- JDK 1.1.X or 1.2.X - gcc 2.95.X or EGCS (not experimental version such as 2.92.5-19981015) You can examine version of your `gcc' command with -v option. % gcc -v @@ -56,14 +56,14 @@ Most Linux distributions and ELF FreeBSD systems have it. - Ruby A script which generate some tables is written in Ruby. - http://www.netlab.co.jp/ruby/ + http://www.ruby-lang.org/ - GNU make 1. Run configure script. % ./configure - 2. Type `make'. You'll get libshujit.so + 2. Type `make'. You will get libshujit.so % make - You must use GNU make. On FreeBSD, type + Instead of above, on FreeBSD type to use GNU make. % gmake * Bugs and Problems diff -aruN shujit-0.3.13/code.c shujit/code.c --- shujit-0.3.13/code.c Sat Oct 16 18:24:33 1999 +++ shujit/code.c Tue Dec 28 18:15:34 1999 @@ -2,7 +2,7 @@ This file is part of shuJIT, Just In Time compiler for Sun Java Virtual Machine. - Copyright (C) 1998,1999 SHUDO Kazuyuki + Copyright (C) 1998,1999,2000 SHUDO Kazuyuki This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -38,10 +38,17 @@ */ /* for strictfp */ #ifdef STRICT_USE_FSCALE -double double_scale_pos = 15360.0; /* 16383 - 1023 */ -double double_scale_neg = -15360.0; /* -(16383 - 1023) */ -double single_scale_pos = 16256.0; /* 16383 - 127 */ -double single_scale_neg = -16256.0; /* -(16383 - 127) */ +# ifdef STRICT_FSCALE_USE_FLOAT +float double_scale_pos = 15360.0f; /* 16383 - 1023 */ +float double_scale_neg = -15360.0f; /* -(16383 - 1023) */ +float single_scale_pos = 16256.0f; /* 16383 - 127 */ +float single_scale_neg = -16256.0f; /* -(16383 - 127) */ +# else +double double_scale_pos = 15360.0; +double double_scale_neg = -15360.0; +double single_scale_pos = 16256.0; +double single_scale_neg = -16256.0; +# endif /* STRICT_FSCALE_USE_FLOAT */ #else unsigned const char double_scale_pos[10] = { 0, 0, 0, 0, 0, 0, 0, 0x80, 0xff, 0x7b }; /* 2^ (16383 - 1023) */ @@ -523,8 +530,13 @@ #ifdef STRICT_PRELOAD /* push scales into FPU register */ # ifdef STRICT_USE_FSCALE +# ifdef STRICT_FSCALE_USE_FLOAT + asm("flds %0\n\t" : : "m" (single_scale_neg)); + asm("flds %0\n\t" : : "m" (double_scale_neg)); +# else asm("fldl %0\n\t" : : "m" (single_scale_neg)); asm("fldl %0\n\t" : : "m" (double_scale_neg)); +# endif /* STRICT_FSCALE_USE_FLOAT */ # else asm("fldt %0\n\t" : : "m" (*single_scale_neg)); asm("fldt %0\n\t" : : "m" (*single_scale_pos)); @@ -2320,8 +2332,13 @@ # ifdef STRICT_PRELOAD # define ARITH_FLOAT_SCALE_PREPARE asm("fld %st(1)") # else -# define ARITH_FLOAT_SCALE_PREPARE \ +# ifdef STRICT_FSCALE_USE_FLOAT +# define ARITH_FLOAT_SCALE_PREPARE \ + asm("flds %0\n\t" : : "m" (single_scale_neg)) +# else +# define ARITH_FLOAT_SCALE_PREPARE \ asm("fldl %0\n\t" : : "m" (single_scale_neg)) +# endif /* STRICT_FSCALE_USE_FLOAT */ # endif /* STRICT_PRELOAD */ # define ARITH_FLOAT_SCALE_DOWN asm("fscale") # define ARITH_FLOAT_SCALE_UP asm("fxch\n\t"\ @@ -2435,8 +2452,13 @@ # ifdef STRICT_PRELOAD # define ARITH_DOUBLE_SCALE_PREPARE asm("fld %st(0)") # else -# define ARITH_DOUBLE_SCALE_PREPARE \ +# ifdef STRICT_FSCALE_USE_FLOAT +# define ARITH_DOUBLE_SCALE_PREPARE \ + asm("flds %0\n\t" : : "m" (double_scale_neg)) +# else +# define ARITH_DOUBLE_SCALE_PREPARE \ asm("fldl %0\n\t" : : "m" (double_scale_neg)) +# endif /* STRICT_FSCALE_USE_FLOAT */ # endif /* STRICT_PRELOAD */ # define ARITH_DOUBLE_SCALE_DOWN asm("fscale") # define ARITH_DOUBLE_SCALE_UP asm("fxch\n\t"\ diff -aruN shujit-0.3.13/code.h shujit/code.h --- shujit-0.3.13/code.h Sat Oct 16 18:22:55 1999 +++ shujit/code.h Tue Dec 28 19:52:03 1999 @@ -2,7 +2,7 @@ This file is part of shuJIT, Just In Time compiler for Sun Java Virtual Machine. - Copyright (C) 1998,1999 SHUDO Kazuyuki + Copyright (C) 1998,1999,2000 SHUDO Kazuyuki This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -80,11 +80,11 @@ #define CONST 0x606060 /* for exception handler */ #define BYTEPCOFF 0x626262 -#define ADDR_EXC 0x707070 +#define ADDR_EXC 0x707010 /* for jump instructions */ -#define ADDR_JP 0x727272 +#define ADDR_JP 0x727210 /* for *return instructions */ -#define ADDR_FIN 0x747474 +#define ADDR_FIN 0x747410 /* diff -aruN shujit-0.3.13/codedb.c shujit/codedb.c --- shujit-0.3.13/codedb.c Sun Jul 25 13:52:03 1999 +++ shujit/codedb.c Thu Dec 23 12:57:23 1999 @@ -2,7 +2,7 @@ This file is part of shuJIT, Just In Time compiler for Sun Java Virtual Machine. - Copyright (C) 1998,1999 SHUDO Kazuyuki + Copyright (C) 1998,1999,2000 SHUDO Kazuyuki This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff -aruN shujit-0.3.13/codedbinfo.c shujit/codedbinfo.c --- shujit-0.3.13/codedbinfo.c Sun Jul 25 13:52:03 1999 +++ shujit/codedbinfo.c Thu Dec 23 12:57:52 1999 @@ -2,7 +2,7 @@ This file is part of shuJIT, Just In Time compiler for Sun Java Virtual Machine. - Copyright (C) 1998,1999 SHUDO Kazuyuki + Copyright (C) 1998,1999,2000 SHUDO Kazuyuki This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff -aruN shujit-0.3.13/compile.c shujit/compile.c --- shujit-0.3.13/compile.c Sat Oct 16 16:52:00 1999 +++ shujit/compile.c Thu Dec 23 12:58:06 1999 @@ -2,7 +2,7 @@ This file is part of shuJIT, Just In Time compiler for Sun Java Virtual Machine. - Copyright (C) 1998,1999 SHUDO Kazuyuki + Copyright (C) 1998,1999,2000 SHUDO Kazuyuki This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -755,6 +755,10 @@ fb = constant_pool[index].fb; if (!(src_mb = cc->mb)) { +#ifdef COMPILE_DEBUG + printf("Illegal field access: methodblock is null.\n"); + fflush(stdout); +#endif code_opcode = opc_throw_illegalaccess; goto check_access_done; } @@ -767,7 +771,7 @@ if (!VerifyFieldAccess( fieldclass(&src_mb->fb), fb_class, fb_access, FALSE)) { #ifdef COMPILE_DEBUG - printf("IllegalAccessError: A private or protected field accessed.\n"); + printf("Illegal field access: a private or protected field accessed.\n"); printf("\tfrom: %s#%s\n", cbName(fieldclass(&src_mb->fb)), src_mb->fb.name); printf("\tto : %s#%s\n", cbName(fb_class), fb->name); @@ -793,13 +797,14 @@ check_access_done: } - /* throwing IllegalAccessError if invoke* final field */ + /* throwing IllegalAccessError if invoke* final method */ if ((code_opcode == opc_invokevirtual) || (code_opcode == opc_invokespecial) || (code_opcode == opc_invokestatic)) { int index; - struct fieldblock *method_fb; struct methodblock *src_mb; + struct fieldblock *method_fb; + ClassClass *src_clazz, *method_clazz; index = GET_UINT16(bytepc + 1); if (!CONSTANT_POOL_TYPE_TABLE_IS_RESOLVED(type_table, index)) { @@ -813,15 +818,69 @@ } if (!(src_mb = cc->mb)) { +#ifdef COMPILE_DEBUG + printf("Illegal method invocation: methodblock is null.\n"); + fflush(stdout); +#endif code_opcode = opc_throw_illegalaccess; goto check_invoke_done; } method_fb = &constant_pool[index].mb->fb; + + src_clazz = fieldclass(&src_mb->fb); + method_clazz = fieldclass(method_fb); + /* check private and protected from other packages */ if (!src_mb || (!VerifyFieldAccess( - fieldclass(&src_mb->fb), fieldclass(method_fb), + src_clazz, method_clazz, method_fb->access, FALSE))) { + char *src_clazz_name, *method_clazz_name; + char *src_p, *method_p; + int len = 0; + + src_clazz_name = cbName(src_clazz); + method_clazz_name = cbName(method_clazz); + +#ifdef COMPILE_DEBUG + printf("Illegal method invocation:\n"); fflush(stdout); + printf("\tfrom: %s#%s\n", + src_clazz_name, src_mb->fb.name); + printf("\tto : %s#%s\n", + method_clazz_name, method_fb->name); +#endif + + /* but, allow access to/from inner class */ + src_p = strchr(src_clazz_name, '$'); + method_p = strchr(method_clazz_name, '$'); + if (src_p) { + if (!method_p) len = src_p - src_clazz_name; + } + else { + if (method_p) len = method_p - method_clazz_name; + } + if (len && +#if JDK_VER >= 12 + (cbProtectionDomain(src_clazz) == cbProtectionDomain(method_clazz)) && + (cbLoader(src_clazz) == cbLoader(method_clazz)) +#else + TRUE +#endif /* JDK_VER >= 12 */ + ) { + if (!strncmp(src_clazz_name, method_clazz_name, len)) { +#ifdef COMPILE_DEBUG + printf(" VerifyFieldAccess returned FALSE, " + "but the access is to/from inner class.\n"); + fflush(stdout); +#endif + goto check_invoke_done; + } + } + +#ifdef COMPILE_DEBUG + printf(" A private or protected method invoked.\n"); + fflush(stdout); +#endif code_opcode = opc_throw_illegalaccess; goto check_invoke_done; } diff -aruN shujit-0.3.13/compiler.c shujit/compiler.c --- shujit-0.3.13/compiler.c Sat Oct 16 18:52:34 1999 +++ shujit/compiler.c Tue Dec 28 18:58:04 1999 @@ -2,7 +2,7 @@ This file is part of shuJIT, Just In Time compiler for Sun Java Virtual Machine. - Copyright (C) 1998,1999 SHUDO Kazuyuki + Copyright (C) 1998,1999,2000 SHUDO Kazuyuki This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -27,14 +27,14 @@ #include "compiler.h" -#if JDK_VER >= 12 -# include "jit.h" /* for JITInterface, JITInterface6 */ -#endif - #if defined(EXC_BY_SIGNAL) || defined(GET_SIGCONTEXT) # include #endif /* EXC_BY_SIGNAL || GET_SIGCONTEXT */ +#if JDK_VER >= 12 +# include "jit.h" /* for JITInterface, JITInterface6 */ +#endif + #ifdef CODE_DB # include /* for O_... */ # include /* for dl*() */ @@ -56,13 +56,6 @@ /* for strictfp */ bool_t is_fpupc_double = FALSE; -#if (defined(EXC_BY_SIGNAL) || defined(GET_SIGCONTEXT)) && defined(SEARCH_SIGCONTEXT) -unsigned short reg_gs; -unsigned short reg_fs; -unsigned short reg_es; -unsigned short reg_ds; -#endif /* (EXC_BY_SIGNAL || GET_SIGCONTEXT) && SEARCH_SIGCONTEXT */ - #ifdef CODE_DB # ifdef GDBM # include @@ -113,22 +106,11 @@ # endif #endif /* CODE_DB */ -#ifdef EXC_BY_SIGNAL -static struct sigaction sigActForHandler; -#endif - /* * Local Functions */ static void initializeClass(ClassClass *); -#ifdef __FreeBSD__ -static bool_t signalHandler(int sig, int code, struct sigcontext *uc); -#else -static bool_t signalHandler(int sig, void *info, void *uc); -#endif -#define fillFPUEnv(FPUENV) asm("fstenv %0" : "=m" (FPUENV)) -static void showFPUEnv(FILE *, char *indent, char fpuenv[28]); static void freeClass(ClassClass *); static unsigned char *compiledCodePC(JavaFrame *, struct methodblock *); static bool_t pcInCompiledCode(unsigned char *pc, struct methodblock *); @@ -157,8 +139,6 @@ JITInterface *jitinterface #endif ) { - static int already_called = 0; - ExecEnv *ee = EE(); MONITOR_T key; int version; @@ -169,15 +149,15 @@ fflush(stdout); #endif - key = obj_monitor((JHandle *)classJavaLangClass); - monitorEnter2(ee, key); - - if (already_called) { - monitorExit2(ee, key); - return; + /* prevent unloading of java.lang.Compiler class */ + { + ClassClass *compiler_cb = FindClass(ee, "java/lang/Compiler", TRUE); + if (!compiler_cb) { + printf("FATAL: cannot find the java.lang.Compiler class.\n"); + JVM_Exit(1); + } + CCSet(compiler_cb, Sticky); } - already_called = 1; - monitorExit2(ee, key); /* version check */ @@ -322,45 +302,6 @@ } -#if (defined(EXC_BY_SIGNAL) || defined(GET_SIGCONTEXT))&& defined(SEARCH_SIGCONTEXT) - asm("movw %%gs,%0" : "=m" (reg_gs)); - asm("movw %%fs,%0" : "=m" (reg_fs)); - asm("movw %%es,%0" : "=m" (reg_es)); - asm("movw %%ds,%0" : "=m" (reg_ds)); -#ifdef RUNTIME_DEBUG - printf("segment registers (gs,fs,es,ds): %04x, %04x, %04x, %04x\n", - reg_gs, reg_fs, reg_es, reg_ds); - fflush(stdout); -#endif -#endif /* (EXC_BY_SIGNAL || GET_SIGCONTEXT) && SEARCH_SIGCONTEXT */ - -#ifdef EXC_BY_SIGNAL - /* prepare struct sigaction for signalHandler() */ -#ifdef SA_SIGINFO - sigActForHandler.sa_handler = NULL; - sigActForHandler.sa_sigaction = - (void (*)(int,siginfo_t *,void *))signalHandler; -#else - sigActForHandler.sa_handler = (void (*)(int))signalHandler; -#endif - sigemptyset(&sigActForHandler.sa_mask); - sigaddset(&sigActForHandler.sa_mask, SIGPIPE); - sigActForHandler.sa_flags = 0; -#ifdef SA_SIGINFO - sigActForHandler.sa_flags |= SA_SIGINFO; -#endif -#ifdef SA_RESTART - sigActForHandler.sa_flags |= SA_RESTART; -#endif -#ifdef SA_ONSTACK - sigActForHandler.sa_flags &= ~SA_ONSTACK; /* not needed. */ -#endif -#ifdef SA_RESETHAND - sigActForHandler.sa_flags |= SA_RESETHAND; -#endif -#endif - - /* resolve function symbols in the func_table */ initFunctionSymbols(); @@ -431,6 +372,33 @@ UseLosslessQuickOpcodes = TRUE; + /* initialize for signal handler */ +#if (defined(EXC_BY_SIGNAL) || defined(GET_SIGCONTEXT)) && defined(SEARCH_SIGCONTEXT) +# if JDK_VER < 12 + *(char **)vector[3] = (char *)examineSigcontextNestCount; +# else + *((JITInterface6 *)jitinterface)->p_CompiledCodeSignalHandler = + examineSigcontextNestCount; +# endif + + asm(".global exam_point\n\t" + "exam_point: int $0x10"); + +# if JDK_VER < 12 + *(char **)vector[3] = NULL; +# else + *((JITInterface6 *)jitinterface)->p_CompiledCodeSignalHandler = NULL; +# endif + + { + if (sc_nest < 0) { + printf("FATAL: cannot examine the offset of signal context.\n"); + JVM_Exit(1); + } + } +#endif /* SEARCH_SIGCONTEXT */ + + /* set up link vector */ #if JDK_VER < 12 *(char **)vector[1] = (char *)initializeClass; @@ -630,363 +598,6 @@ printf("initializeClass(%s) done.\n", cbName(cb)); fflush(stdout); #endif -} - - -#ifdef __FreeBSD__ -static bool_t signalHandler(int sig, int code, struct sigcontext *uc) { -#else -static bool_t signalHandler(int sig, void *info, void *uc) { -#endif -#if defined(EXC_BY_SIGNAL) || defined(GET_SIGCONTEXT) -# ifdef SEARCH_SIGCONTEXT - static int sc_offset = 0; - int32_t *ptr = ((int32_t *)&sig) + 1; -# endif /* SEARCH_SIGCONTEXT */ - SIGCONTEXT *sc = NULL; - struct methodblock *mb; - CodeInfo *codeinfo; - uint32_t native_off; -#endif /* EXC_BY_SIGNAL || GET_SIGCONTEXT */ -#ifdef EXC_BY_SIGNAL - throwentry *tentry; - uint32_t jump_target = 0; -#endif /* EXC_BY_SIGNAL */ - -#if 0 -#if 1 - signal(sig, SIG_DFL); -#else - { - struct sigaction sigAct; - sigAct.sa_handler = SIG_DFL; - sigemptyset(&sigAct.sa_mask); - sigaction(sig, &sigAct, (struct sigaction *)NULL); - } -#endif -#endif - -#if defined(RUNTIME_DEBUG) || defined(COMPILE_DEBUG) - printf("Signal handler: %d (sys_thread_t: %x)\n", sig, (int)sysThreadSelf()); -#endif - - -#if defined(EXC_BY_SIGNAL) || defined(GET_SIGCONTEXT) -#ifndef SEARCH_SIGCONTEXT - sc = (SIGCONTEXT *)uc; -#else - /* get signal context */ - sc = (SIGCONTEXT *)(ptr + sc_offset); - -# ifdef __FreeBSD__ - if ( !(sc->SC_GS & 0xffff == reg_gs) || !(sc->SC_FS & 0xffff == reg_fs) || - !(sc->SC_ES & 0xffff == reg_es) || !(sc->SC_DS & 0xffff == reg_ds) ) { -# else - if ( !(sc->SC_GS == reg_gs) || !(sc->SC_FS == reg_fs) || - !(sc->SC_ES == reg_es) || !(sc->SC_DS == reg_ds) ) { -# endif /* __FreeBSD__ */ - /* search signal context */ -#ifdef RUNTIME_DEBUG - printf("sc_offset(%d) is obsolete, search.\n", sc_offset); - fflush(stdout); -#endif -#define SC_SEARCH_WIDTH 100 - for (sc_offset = 0; sc_offset < SC_SEARCH_WIDTH; sc_offset++) { -# ifdef __FreeBSD__ - if ( (((SIGCONTEXT *)ptr)->SC_GS & 0xffff == reg_gs) && - (((SIGCONTEXT *)ptr)->SC_FS & 0xffff == reg_fs) && - (((SIGCONTEXT *)ptr)->SC_ES & 0xffff == reg_es) && - (((SIGCONTEXT *)ptr)->SC_DS & 0xffff == reg_ds) ) -# else - if ( (((SIGCONTEXT *)ptr)->SC_GS == reg_gs) && - (((SIGCONTEXT *)ptr)->SC_FS == reg_fs) && - (((SIGCONTEXT *)ptr)->SC_ES == reg_es) && - (((SIGCONTEXT *)ptr)->SC_DS == reg_ds) ) -# endif /* __FreeBSD__ */ - break; - else - ptr += 1; - } - if (sc_offset >= SC_SEARCH_WIDTH) { - printf("FATAL: cannot find signal context on stack."); - JVM_Exit(1); - } -#if defined(RUNTIME_DEBUG) || defined(COMPILE_DEBUG) - printf("sc_offset: %d\n", sc_offset); -#endif - sc = (SIGCONTEXT *)ptr; - } -#endif /* SEARCH_SIGCONTEXT*/ - -#if defined(RUNTIME_DEBUG) || defined(COMPILE_DEBUG) || (defined(GET_SIGCONTEXT) && !defined(EXC_BY_SIGNAL)) - printf("sigcontext: 0x%08x\n", (int)sc); fflush(stdout); - showSigcontext(sc); -#endif -#endif /* EXC_BY_SIGNAL || GET_SIGCONTEXT */ - - -#if defined(EXC_BY_SIGNAL) || defined(GET_SIGCONTEXT) - if ((sig != SIGSEGV) && (sig != SIGFPE)) return FALSE; - - mb = EE()->current_frame->current_method; - if (!mb) return FALSE; -#if defined(RUNTIME_DEBUG) || defined(COMPILE_DEBUG) - printf("method(0x%x)", (int)mb); fflush(stdout); - printf(": %s#%s %s\n", cbName(mb->fb.clazz), mb->fb.name, mb->fb.signature); - fflush(stdout); -#endif - if (!mb->CompiledCode) return FALSE; /* not compiled */ - native_off = - ((uint32_t)sc->SC_EIP) - ((uint32_t)mb->CompiledCode); -#ifdef RUNTIME_DEBUG - printf("native off: 0x%x\n", native_off); - fflush(stdout); -#endif -#ifndef EXC_BY_SIGNAL - return FALSE; -#else - codeinfo = (CodeInfo *)(mb->CompiledCodeInfo); - tentry = throwtableGet(codeinfo, native_off); - -#define IP_SEARCH_COUNT 3 - if (!tentry) { /* search EIP in native code */ - uint32_t *ebp; - int i; -#if defined(RUNTIME_DEBUG) || defined(COMPILE_DEBUG) - printf("throwentry is null !\n"); fflush(stdout); -#endif /* RUNTIME_DEBUG || COMPILE_DEBUG */ - - ebp = (uint32_t *)sc->SC_EBP; - - for (i = 0; i < IP_SEARCH_COUNT; i++) { - uint32_t *sp = ebp + 1; - - native_off = *sp - (uint32_t)mb->CompiledCode; - if ((native_off >= 0) && (native_off <= codeinfo->code_size)) { - tentry = throwtableGet(codeinfo, native_off); - if (tentry) { -#ifdef ARITHEXC_BY_SIGNAL - if (sig == SIGFPE) { - int opc = tentry->opcode; - if ((opc != opc_idiv) && (opc != opc_irem) && - (opc != opc_ldiv) && (opc != opc_lrem)) - continue; - } -#endif /* ARITHEXC_BY_SIGNAL */ - sc->SC_ESP = (uint32_t)(sp + 1); /* stack top in the frame */ - sc->SC_EIP = *sp; /* %eip on the native code */ - goto tentry_is_found; - } - } - ebp = (uint32_t *)*ebp; - } /* for (i = 0; i < IP_SEARCH_COUNT; ... */ - goto signal_handler_error; - tentry_is_found: - } -#if defined(RUNTIME_DEBUG) || defined(COMPILE_DEBUG) - printf("throwentry: "); - fflush(stdout); - if (tentry) - printf("start: 0x%x, len: 0x%x, byteoff: 0x%x\n", - tentry->start, tentry->len, tentry->byteoff); - else - printf("(null)\n"); - fflush(stdout); -#endif /* RUNTIME_DEBUG || COMPILE_DEBUG */ - -#ifdef NULLEXC_BY_SIGNAL - if (sig == SIGSEGV) { - /* NullPointerException occurred */ - SignalError(NULL, JAVAPKG "NullPointerException", 0); - /* set ee->exception.exc, exception object */ - } -#endif -#if defined(NULLEXC_BY_SIGNAL) && defined(ARITHEXC_BY_SIGNAL) - else -#endif -#ifdef ARITHEXC_BY_SIGNAL - if (sig == SIGFPE) { - if ((tentry->opcode == opc_idiv) || (tentry->opcode == opc_irem)) { - if (sc->SC_ECX /* divisor */ == 0) { - /* ArithmeticException occurred */ - SignalError(NULL, JAVAPKG "ArithmeticException", "/ by zero"); - } - else if ((sc->SC_EAX /* dividend */ == 0x80000000) && - (sc->SC_ECX /* divisor */ == -1)) { - /* idiv insn. of x86 causes it: 0x80000000 / -1 */ - sc->SC_EAX = 0x80000000; - sc->SC_EDX = 0; - jump_target = sc->SC_EIP + 2; /* `+ 2' skips idiv `0xf7 0xXX' */ - } - else { - float dividend, divisor; - memcpy(÷nd, &(sc->SC_EAX), 4); - memcpy(&divisor, &(sc->SC_ECX), 4); - printf("FATAL: SIGFPE occurred in %s: %e %s %e.\n", - ((tentry->opcode == opc_idiv)?"idiv":"irem"), - (double)dividend, ((tentry->opcode == opc_idiv)?"/":"%"), - (double)divisor); - fflush(stdout); - - goto signal_handler_error; - } - } - else if ((tentry->opcode == opc_ldiv) || (tentry->opcode == opc_lrem)) { - uint32_t *sp = (uint32_t *)sc->SC_ESP; - sc->SC_ESP += 24; - /* `back up'ed registers in ldiv */ - sc->SC_EBP = *(sp + 4); /* *(sp + 4) is %ebp */ - sc->SC_ESI = *(sp + 5); /* *(sp + 5) is %esi */ - - /* dividend: (*(sp + 1) << 32) | *sp - divisor : (*(sp + 3) << 32) | *(sp + 2) */ - - if (!((*(sp + 2)) | (*(sp + 3)))) { - /* ArithmeticException occurred */ - SignalError(NULL, JAVAPKG "ArithmeticException", "/ by zero"); - } -#if 0 - /* In this case, - functions called by ldiv (__divdi3(),__moddi3()) don't cause SIGFPE */ - else if ((*sp == 0) && (*(sp + 1) == 0x80000000) && - ((*(sp +2) & *(sp + 3)) == 0xffffffff)) { - } -#endif - } - else { - printf("FATAL: SIGFPE occured in %s.", - ((tentry->opcode == opc_ldiv)?"ldiv":"lrem")); - fflush(stdout); - - goto signal_handler_error; - } - } /* if (sig == SIGFPE) */ -#endif /* ARITHEXC_BY_SIGNAL */ -#if defined(NULLEXC_BY_SIGNAL) || defined(ARITHEXC_BY_SIGNAL) - else -#endif - { - return FALSE; - } - - - /* jump to exc_new or exc_handler in compiled code */ - - /* re-initialize signal handler - associated with raised signal */ - { - struct sigaction sigAct = sigActForHandler; - sigaction(sig, &sigAct, (struct sigaction *)NULL); - } - -#ifdef __FreeBSD__ - /* unmask the signal */ - { - sigset_t sigmask; - sigemptyset(&sigmask); - sigaddset(&sigmask, sig); - sigprocmask(SIG_UNBLOCK, &sigmask, NULL); - } -#endif /* __FreeBSD__ */ - - - /* set (int32_t)bytepcoff (local variable in assembledCode) */ - *(((int32_t *)sc->SC_EBP) - 1) = tentry->byteoff; - - - /* JDK 1.2: set program counter to jump to exception handler */ - /* JDK 1.1: jump to exception handler */ -# if JDK_VER >= 12 - { - uint32_t exc_handler; - exc_handler = jump_target ? jump_target : - (uint32_t)(mb->CompiledCode + codeinfo->exc_handler_nativeoff); - sc->SC_EIP = exc_handler; - } - - return TRUE; -# else - { - register uint32_t exc_handler asm("edi"); - register SIGCONTEXT *sc_ptr asm("edx"); - - exc_handler = jump_target ? jump_target : - (uint32_t)(mb->CompiledCode + codeinfo->exc_handler_nativeoff); - sc_ptr = sc; - asm("movl %0,%%esi" : : "m" (sc_ptr->SC_ESI)); - asm("movl %0,%%ebp" : : "m" (sc_ptr->SC_EBP)); - asm("movl %0,%%esp" : : "m" (sc_ptr->SC_ESP)); - - asm("movl %0,%%eax" : : "m" (sc_ptr->SC_EAX)); - asm("movl %0,%%edx" : : "m" (sc_ptr->SC_EDX)); - - asm("jmp *%0" : : "r" (exc_handler)); - } -# endif /* JDK_VER */ - /* jump to exception handler */ - -#endif /* EXC_BY_SIGNAL */ -#endif /* EXC_BY_SIGNAL || GET_SIGCONTEXT */ - - return FALSE; - -signal_handler_error: - fprintf(stderr, "Signal %d\n", sig); - fflush(stderr); -#if defined(EXC_BY_SIGNAL) || defined(GET_SIGCONTEXT) - if (sc) { - struct methodblock *sig_mb = methodByPC((unsigned char *)sc->SC_EIP); - fprintf(stderr, " in "); - if (sig_mb) { - uint32_t nativepc = - (uint32_t)sc->SC_EIP - (uint32_t)sig_mb->CompiledCode; - CodeInfo *info = (CodeInfo *)sig_mb->CompiledCodeInfo; - fprintf(stderr, "%s#%s %s\n", - cbName(fieldclass(&sig_mb->fb)), - sig_mb->fb.name, sig_mb->fb.signature); - fprintf(stderr, " native PC: 0x%x(%d)\n", nativepc, nativepc); -#ifdef EXC_BY_SIGNAL - if (info) { - throwentry *tentry = throwtableGet(info, nativepc); - if (tentry) { - int bytepc = tentry->byteoff; - fprintf(stderr, " byte PC: 0x%x(%d)\n", bytepc, bytepc); - } - } -#endif /* EXC_BY_SIGNAL */ - } - { - char fpuenv[28]; - fillFPUEnv(fpuenv); - showFPUEnv(stderr, " ", fpuenv); - } - fprintf(stderr, "\n"); - fflush(stderr); - - showSigcontext(sc); - - fprintf(stderr, "\n"); - fflush(stderr); - } -#endif - JVM_Exit(1); -} - - -static void showFPUEnv(FILE *fp, char *indent, char fpuenv[28]) { - if (!indent) indent = ""; - if (!fp) fp = stdout; - - fprintf(fp, "%sFPU control word: 0x%04x\n", indent, - *((int16_t *)(fpuenv + 0))); - fprintf(fp, "%sFPU status word: 0x%04x\n", indent, - *((int16_t *)(fpuenv + 4))); - fprintf(fp, "%sFPU tag word: 0x%04x\n", indent, - *((int16_t *)(fpuenv + 8))); - fprintf(fp, "%sFPU FIP : 0x%08x\n", indent, - *((int32_t *)(fpuenv + 12))); - - fflush(fp); } diff -aruN shujit-0.3.13/compiler.h shujit/compiler.h --- shujit-0.3.13/compiler.h Sat Oct 16 17:30:38 1999 +++ shujit/compiler.h Tue Dec 28 16:24:53 1999 @@ -2,7 +2,7 @@ This file is part of shuJIT, Just In Time compiler for Sun Java Virtual Machine. - Copyright (C) 1996,1997,1998,1999 SHUDO Kazuyuki + Copyright (C) 1996,1997,1998,1999,2000 SHUDO Kazuyuki This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -276,13 +276,20 @@ * Complement macros */ #if 1 +# ifndef HAVE_GREENTHR_HEADER +# define NATIVE /* for Linux/JDK 1.1.8v1 */ +# endif # include "sys_api.h" +# undef NATIVE #else # define sysMalloc malloc # define sysFree free # define sysCalloc calloc # define sysRealloc realloc #endif +#if JDK_VER < 12 && !defined(sysThreadSelf) +# define sysThreadSelf threadSelf +#endif #if JDK_VER < 12 # define ACC_STRICT 0x0800 /* ACC_XXUNUSED1*/ /* strictfp */ @@ -310,7 +317,11 @@ #endif /* JDK_VER */ #if 1 +# ifndef HAVE_GREENTHR_HEADER +# define NATIVE /* for Linux/JDK 1.1.8v1 */ +# endif # include "monitor.h" /* for monitor{Enter,Exit}() and macro BINCLASS_*() */ +# undef NATIVE #else typedef struct sys_mon sys_mon_t; extern sys_mon_t *_binclass_lock; @@ -331,7 +342,7 @@ #else # define SYS_NAME "shuJIT" #endif -# define CREDIT " " SYS_NAME " for Sun JVM/IA-32 Copyright 1998,1999 by SHUDO Kazuyuki\n" +# define CREDIT " " SYS_NAME " for Sun JVM/IA-32 Copyright 1998,1999,2000 by SHUDO Kazuyuki\n" #if JDK_VER < 12 # define COMPILER_VERSION 5 @@ -467,22 +478,18 @@ extern bool_t is_fpupc_double; /* Is the FPU rounding precision double? */ +/* in signal.c */ +#if (defined(EXC_BY_SIGNAL) || defined(GET_SIGCONTEXT)) && defined(SEARCH_SIGCONTEXT) +extern int sc_nest; +#endif; + /* in code.c */ /* for strictfp */ #undef STRICT_PRELOAD /* It has a preload to preload scales into FPU register yet. */ #define STRICT_USE_FSCALE -#ifdef STRICT_USE_FSCALE -extern double double_scale_pos; /* 16383 - 1023 */ -extern double double_scale_neg; /* -(16383 - 1023) */ -extern double single_scale_pos; /* 16383 - 127 */ -extern double single_scale_neg; /* -(16383 - 127) */ -#else -extern unsigned const char double_scale_pos[10];/* 2^ (16383 - 1023) */ -extern unsigned const char double_scale_neg[10];/* 2^ -(16383 - 1023) */ -extern unsigned const char single_scale_pos[10];/* 2^ (16383 - 127) */ -extern unsigned const char single_scale_neg[10];/* 2^ -(16383 - 127) */ -#endif /* STRICT_USE_FSCALE */ +#define STRICT_FSCALE_USE_FLOAT + #if 0 extern struct methodtable *object_methodtable; /* for the macro OBJ_ARRAY_METHODTABLE in code.h */ @@ -493,19 +500,6 @@ extern struct methodtable *proxy_methodtable; #endif /* METAVM */ -#if (defined(EXC_BY_SIGNAL) || defined(GET_SIGCONTEXT)) && defined(SEARCH_SIGCONTEXT) -# ifdef linux -extern unsigned short reg_gs; -extern unsigned short reg_fs; -# endif -extern unsigned short reg_es; -extern unsigned short reg_ds; -# ifdef __FreeBSD__ -extern unsigned short reg_cs; -extern unsigned short reg_ss; -# endif -#endif /* (EXC_BY_SIGNAL || GET_SIGCONTEXT) && SEARCH_SIGCONTEXT */ - #ifdef CODE_DB # ifdef GDBM # include @@ -577,6 +571,23 @@ /* * Global Functions */ +/* in signal.c */ +#if (defined(EXC_BY_SIGNAL) || defined(GET_SIGCONTEXT)) && defined(SEARCH_SIGCONTEXT) +#ifdef __FreeBSD__ +bool_t examineSigcontextNestCount(int sig, int code, struct sigcontext *uc); +#else +bool_t examineSigcontextNestCount(int sig, void *info, void *uc); +#endif +#endif /* SEARCH_SIGCONTEXT */ +#ifdef __FreeBSD__ +bool_t signalHandler(int sig, int code, struct sigcontext *uc); +#else +bool_t signalHandler(int sig, void *info, void *uc); +#endif +#if defined(EXC_BY_SIGNAL) || defined(GET_SIGCONTEXT) +extern void showSigcontext(SIGCONTEXT *sc); +#endif /* EXC_BY_SIGNAL || GET_SIGCONTEXT */ + /* in code.c */ extern volatile void assembledCode( JHandle *o, struct methodblock *mb, int args_size, ExecEnv *ee, @@ -663,9 +674,6 @@ #endif /* CODE_DB */ /* in runtime.c */ -#if defined(EXC_BY_SIGNAL) || defined(GET_SIGCONTEXT) -extern void showSigcontext(SIGCONTEXT *sc); -#endif /* EXC_BY_SIGNAL || GET_SIGCONTEXT */ extern int invocationHelper( JHandle *obj, struct methodblock *method, int args_size, ExecEnv *ee, stack_item *var_base, int retsize diff -aruN shujit-0.3.13/computil.c shujit/computil.c --- shujit-0.3.13/computil.c Sat Oct 9 12:32:23 1999 +++ shujit/computil.c Thu Dec 23 12:58:41 1999 @@ -2,7 +2,7 @@ This file is part of shuJIT, Just In Time compiler for Sun Java Virtual Machine. - Copyright (C) 1998,1999 SHUDO Kazuyuki + Copyright (C) 1998,1999,2000 SHUDO Kazuyuki This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff -aruN shujit-0.3.13/config.h.in shujit/config.h.in --- shujit-0.3.13/config.h.in Fri Oct 1 13:19:13 1999 +++ shujit/config.h.in Tue Dec 28 13:33:28 1999 @@ -15,10 +15,19 @@ /* assembly code or C, which version of interpreter is used */ #undef EXECUTEJAVA_IN_ASM +/* whether the exists */ +#undef HAVE_UCONTEXT_H + +/* whether the JDK_HOME/include(-old)/green_threads exists */ +#undef HAVE_GREENTHR_HEADER + /* defined if the code DB function is enabled */ #undef CODE_DB /* defined if DB library for code DB is gdbm */ #undef GDBM + +/* defined if shuJIT supports thread migration */ +#undef MOBA /* defined if shuJIT is built to support MetaVM */ #undef METAVM diff -aruN shujit-0.3.13/configure shujit/configure --- shujit-0.3.13/configure Fri Oct 1 13:09:55 1999 +++ shujit/configure Tue Dec 28 15:19:55 1999 @@ -14,6 +14,9 @@ ac_help="$ac_help --disable-codedb disable code DB " ac_help="$ac_help + --enable-moba + support thread migration " +ac_help="$ac_help --enable-metavm-no-array enable MetaVM and arrays are passed by value " ac_help="$ac_help @@ -582,7 +585,7 @@ fi echo $ac_n "checking host system type""... $ac_c" 1>&6 -echo "configure:586: checking host system type" >&5 +echo "configure:589: checking host system type" >&5 host_alias=$host case "$host_alias" in @@ -603,7 +606,7 @@ echo "$ac_t""$host" 1>&6 echo $ac_n "checking target system type""... $ac_c" 1>&6 -echo "configure:607: checking target system type" >&5 +echo "configure:610: checking target system type" >&5 target_alias=$target case "$target_alias" in @@ -621,7 +624,7 @@ echo "$ac_t""$target" 1>&6 echo $ac_n "checking build system type""... $ac_c" 1>&6 -echo "configure:625: checking build system type" >&5 +echo "configure:628: checking build system type" >&5 build_alias=$build case "$build_alias" in @@ -654,7 +657,7 @@ # Extract the first word of "libgdbm.so", so it can be a program name with args. set dummy libgdbm.so; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:658: checking for $ac_word" >&5 +echo "configure:661: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_ac_libgdbm'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -691,7 +694,7 @@ # Extract the first word of "libndbm.so", so it can be a program name with args. set dummy libndbm.so; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:695: checking for $ac_word" >&5 +echo "configure:698: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_ac_libndbm'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -738,6 +741,21 @@ +# Check whether --enable-moba or --disable-moba was given. +if test "${enable_moba+set}" = set; then + enableval="$enable_moba" + + ac_moba=yes + cat >> confdefs.h <<\EOF +#define MOBA 1 +EOF + + +fi + + + + # Check whether --enable-metavm_no_array or --disable-metavm_no_array was given. if test "${enable_metavm_no_array+set}" = set; then enableval="$enable_metavm_no_array" @@ -774,7 +792,7 @@ echo $ac_n "checking whether ${MAKE-make} sets \${MAKE}""... $ac_c" 1>&6 -echo "configure:778: checking whether ${MAKE-make} sets \${MAKE}" >&5 +echo "configure:796: checking whether ${MAKE-make} sets \${MAKE}" >&5 set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_prog_make_${ac_make}_set'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -801,7 +819,7 @@ fi echo $ac_n "checking C compiler""... $ac_c" 1>&6 -echo "configure:805: checking C compiler" >&5 +echo "configure:823: checking C compiler" >&5 ac_cc=no if test -n "$CC"; then if test -f "$CC"; then @@ -810,7 +828,7 @@ # Extract the first word of "$CC", so it can be a program name with args. set dummy $CC; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:814: checking for $ac_word" >&5 +echo "configure:832: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_path_ac_cc'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -851,7 +869,7 @@ # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:855: checking for $ac_word" >&5 +echo "configure:873: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_path_ac_cc'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -905,7 +923,7 @@ # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:909: checking for $ac_word" >&5 +echo "configure:927: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_path_ac_objdump'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -943,12 +961,12 @@ if test "$ac_ruby" = no; then - { echo "configure: error: Compilation need objdump (provided by GNU binutils)." 1>&2; exit 1; } + { echo "configure: error: Compilation needs objdump (provided by GNU binutils)." 1>&2; exit 1; } fi # Extract the first word of "ruby", so it can be a program name with args. set dummy ruby; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:952: checking for $ac_word" >&5 +echo "configure:970: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_path_ac_ruby'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -981,14 +999,14 @@ echo "$ac_t""no" 1>&6 fi - if test "$ac_ruby" = no; then - { echo "configure: error: Compilation need ruby." 1>&2; exit 1; } + { echo "configure: error: Compilation needs ruby (see http://www.ruby-lang.org/)." 1>&2; exit 1; } fi + # Extract the first word of "ci", so it can be a program name with args. set dummy ci; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:992: checking for $ac_word" >&5 +echo "configure:1010: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_path_ac_ci'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -1025,7 +1043,7 @@ # Extract the first word of "co", so it can be a program name with args. set dummy co; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:1029: checking for $ac_word" >&5 +echo "configure:1047: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_path_ac_co'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -1062,7 +1080,7 @@ # Extract the first word of "mv", so it can be a program name with args. set dummy mv; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:1066: checking for $ac_word" >&5 +echo "configure:1084: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_path_ac_mv'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -1099,7 +1117,7 @@ # Extract the first word of "rm", so it can be a program name with args. set dummy rm; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:1103: checking for $ac_word" >&5 +echo "configure:1121: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_path_ac_rm'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -1136,7 +1154,7 @@ # Extract the first word of "wc", so it can be a program name with args. set dummy wc; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:1140: checking for $ac_word" >&5 +echo "configure:1158: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_path_ac_wc'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -1173,7 +1191,7 @@ # Extract the first word of "etags", so it can be a program name with args. set dummy etags; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:1177: checking for $ac_word" >&5 +echo "configure:1195: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_path_ac_etags'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -1211,7 +1229,7 @@ # Extract the first word of "which", so it can be a program name with args. set dummy which; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:1215: checking for $ac_word" >&5 +echo "configure:1233: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_path_ac_which'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -1249,7 +1267,7 @@ # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:1253: checking for $ac_word" >&5 +echo "configure:1271: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_path_ac_grep'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -1288,7 +1306,7 @@ # Extract the first word of "sed", so it can be a program name with args. set dummy sed; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:1292: checking for $ac_word" >&5 +echo "configure:1310: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_path_ac_sed'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -1321,12 +1339,12 @@ echo "$ac_t""no" 1>&6 fi -for ac_prog in mawk gawk nawk awk +for ac_prog in gawk mawk nawk awk do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:1330: checking for $ac_word" >&5 +echo "configure:1348: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_AWK'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -1358,19 +1376,19 @@ echo $ac_n "checking version of gcc""... $ac_c" 1>&6 -echo "configure:1362: checking version of gcc" >&5 +echo "configure:1380: checking version of gcc" >&5 ac_ccver_string=`$ac_cc -v 2>&1 | $ac_grep 'gcc version' | $AWK '{print $3}'` case "$ac_ccver_string" in 3-9*|2.9*) - echo "$ac_t""recognized: gcc >= 2.95" 1>&6 + echo "$ac_t""gcc >= 2.95" 1>&6 ac_gcc27= ;; egcs*) - echo "$ac_t""recognized: egcs" 1>&6 + echo "$ac_t""egcs" 1>&6 ac_gcc27= ;; 2.7*|2.6*|2.5*|2.4*) - echo "$ac_t""recognized: gcc 2.X (X <= 7)" 1>&6 + echo "$ac_t""gcc <= 2.7" 1>&6 cat >> confdefs.h <<\EOF #define GCC27 1 EOF @@ -1385,7 +1403,7 @@ echo $ac_n "checking install path of JDK""... $ac_c" 1>&6 -echo "configure:1389: checking install path of JDK" >&5 +echo "configure:1407: checking install path of JDK" >&5 # Check whether --with-jdk or --without-jdk was given. if test "${with_jdk+set}" = set; then withval="$with_jdk" @@ -1403,7 +1421,7 @@ # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:1407: checking for $ac_word" >&5 +echo "configure:1425: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_path_ac_java'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -1439,11 +1457,14 @@ done test -n "$ac_java" || ac_java="no" +if test "$ac_java" = no; then + { echo "configure: error: java command is not found." 1>&2; exit 1; } +fi # Extract the first word of "javac", so it can be a program name with args. set dummy javac; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:1447: checking for $ac_word" >&5 +echo "configure:1468: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_path_ac_javac'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -1480,7 +1501,7 @@ # Extract the first word of "javah", so it can be a program name with args. set dummy javah; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:1484: checking for $ac_word" >&5 +echo "configure:1505: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_path_ac_javah'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -1517,7 +1538,7 @@ # Extract the first word of "jar", so it can be a program name with args. set dummy jar; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:1521: checking for $ac_word" >&5 +echo "configure:1542: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_path_ac_jar'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -1554,7 +1575,7 @@ # Extract the first word of "javadoc", so it can be a program name with args. set dummy javadoc; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:1558: checking for $ac_word" >&5 +echo "configure:1579: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_path_ac_javadoc'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -1590,16 +1611,16 @@ echo $ac_n "checking version of JDK""... $ac_c" 1>&6 -echo "configure:1594: checking version of JDK" >&5 +echo "configure:1615: checking version of JDK" >&5 ac_jver_string=`$ac_java -green -Djava.compiler= -version 2>&1` case "$ac_jver_string" in *\"1.1*) ac_jver=11 - echo "$ac_t""recognized: JDK 1.1" 1>&6 + echo "$ac_t""JDK 1.1" 1>&6 ;; *\"1.2*) ac_jver=12 - echo "$ac_t""recognized: JDK 1.2" 1>&6 + echo "$ac_t""JDK 1.2" 1>&6 ;; *) { echo "configure: error: unrecognized." 1>&2; exit 1; } @@ -1619,7 +1640,7 @@ echo $ac_n "checking asm or C, which version of interpreter is used""... $ac_c" 1>&6 -echo "configure:1623: checking asm or C, which version of interpreter is used" >&5 +echo "configure:1644: checking asm or C, which version of interpreter is used" >&5 # Check whether --enable-c-interpreter or --disable-c-interpreter was given. if test "${enable_c_interpreter+set}" = set; then enableval="$enable_c_interpreter" @@ -1644,21 +1665,21 @@ fi if test "$ac_executejava_in_asm" = "yes"; then - echo "$ac_t""recognized: assembly code version" 1>&6 + echo "$ac_t""assembly code version" 1>&6 cat >> confdefs.h <<\EOF #define EXECUTEJAVA_IN_ASM 1 EOF else - echo "$ac_t""recognized: C version" 1>&6 + echo "$ac_t""C version" 1>&6 fi echo $ac_n "checking version of libc""... $ac_c" 1>&6 -echo "configure:1660: checking version of libc" >&5 +echo "configure:1681: checking version of libc" >&5 echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6 -echo "configure:1662: checking how to run the C preprocessor" >&5 +echo "configure:1683: checking how to run the C preprocessor" >&5 # On Suns, sometimes $CPP names a directory. if test -n "$CPP" && test -d "$CPP"; then CPP= @@ -1673,13 +1694,13 @@ # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. cat > conftest.$ac_ext < Syntax Error EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:1683: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:1704: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then : @@ -1690,13 +1711,13 @@ rm -rf conftest* CPP="${CC-cc} -E -traditional-cpp" cat > conftest.$ac_ext < Syntax Error EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:1700: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:1721: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then : @@ -1707,13 +1728,13 @@ rm -rf conftest* CPP="${CC-cc} -nologo -E" cat > conftest.$ac_ext < Syntax Error EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:1717: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:1738: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then : @@ -1738,7 +1759,7 @@ echo "$ac_t""$CPP" 1>&6 cat > conftest.$ac_ext < @@ -1753,18 +1774,19 @@ rm -f conftest* if test "$ac_glibc2" = "yes"; then - echo "$ac_t""recognized: glibc2" 1>&6 + echo "$ac_t""glibc2" 1>&6 cat >> confdefs.h <<\EOF #define GLIBC2 1 EOF else - echo "$ac_t""recognized: not glibc2" 1>&6 + echo "$ac_t""not glibc2" 1>&6 fi + echo $ac_n "checking type of an argument of monitorEnter()""... $ac_c" 1>&6 -echo "configure:1768: checking type of an argument of monitorEnter()" >&5 +echo "configure:1790: checking type of an argument of monitorEnter()" >&5 ac_monitor_t=`$ac_grep monitorEnter $ac_jincdir/monitor.h | $ac_sed 's/(/ /' | $ac_sed "s/.* \(.*\));.*/\1/"` echo "$ac_t""$ac_monitor_t" 1>&6 cat >> confdefs.h < header exists""... $ac_c" 1>&6 +echo "configure:1799: checking whether the header exists" >&5 +if test -f "/usr/include/asm/ucontext.h"; then + echo "$ac_t""exists" 1>&6 + cat >> confdefs.h <<\EOF +#define HAVE_UCONTEXT_H 1 +EOF + +else + echo "$ac_t""does not exist" 1>&6 +fi + +echo $ac_n "checking whether the JDK_HOME/include/green_threads directory exists""... $ac_c" 1>&6 +echo "configure:1811: checking whether the JDK_HOME/include/green_threads directory exists" >&5 +if test -d "$ac_jincdir/green_threads"; then + echo "$ac_t""exists" 1>&6 + cat >> confdefs.h <<\EOF +#define HAVE_GREENTHR_HEADER 1 +EOF + +else + echo "$ac_t""does not exist" 1>&6 +fi + @@ -1925,6 +1971,7 @@ s%@ac_libgdbm@%$ac_libgdbm%g s%@ac_libndbm@%$ac_libndbm%g s%@ac_codedb@%$ac_codedb%g +s%@ac_moba@%$ac_moba%g s%@ac_metavm@%$ac_metavm%g s%@ac_metavm_no_array@%$ac_metavm_no_array%g s%@SET_MAKE@%$SET_MAKE%g diff -aruN shujit-0.3.13/configure.in shujit/configure.in --- shujit-0.3.13/configure.in Fri Oct 1 13:09:53 1999 +++ shujit/configure.in Tue Dec 28 15:19:53 1999 @@ -29,6 +29,17 @@ AC_SUBST(ac_libgdbm) +AC_ARG_ENABLE(moba, + [ --enable-moba + support thread migration ], + [ + ac_moba=yes + AC_DEFINE(MOBA) + ], + []) +AC_SUBST(ac_moba) + + AC_ARG_ENABLE(metavm_no_array, [ --enable-metavm-no-array enable MetaVM and arrays are passed by value ], @@ -78,13 +89,13 @@ AC_PATH_PROGS(ac_objdump, objdump, no) AC_SUBST(ac_objdump) if test "$ac_ruby" = no; then - AC_MSG_ERROR(Compilation need objdump (provided by GNU binutils).) + AC_MSG_ERROR(Compilation needs objdump (provided by GNU binutils).) fi AC_PATH_PROG(ac_ruby, ruby, no) -AC_SUBST(ac_ruby) if test "$ac_ruby" = no; then - AC_MSG_ERROR(Compilation need ruby.) + AC_MSG_ERROR(Compilation needs ruby (see http://www.ruby-lang.org/).) fi +AC_SUBST(ac_ruby) AC_PATH_PROG(ac_ci, ci, no) AC_SUBST(ac_ci) AC_PATH_PROG(ac_co, co, no) @@ -108,15 +119,15 @@ ac_ccver_string=`$ac_cc -v 2>&1 | $ac_grep 'gcc version' | $AWK '{print $3}'` case "$ac_ccver_string" in [3-9]*|2.9*) - AC_MSG_RESULT(recognized: gcc >= 2.95) + AC_MSG_RESULT(gcc >= 2.95) ac_gcc27= ;; egcs*) - AC_MSG_RESULT(recognized: egcs) + AC_MSG_RESULT(egcs) ac_gcc27= ;; 2.7*|2.6*|2.5*|2.4*) - AC_MSG_RESULT(recognized: gcc 2.X (X <= 7)) + AC_MSG_RESULT(gcc <= 2.7) AC_DEFINE(GCC27) ac_gcc27=yes ;; @@ -137,6 +148,9 @@ ac_jbin="$ac_jhome/bin" AC_PATH_PROGS(ac_java, java jre, no, $ac_jbin) +if test "$ac_java" = no; then + AC_MSG_ERROR(java command is not found.) +fi AC_SUBST(ac_java) AC_PATH_PROG(ac_javac, javac, no, $ac_jbin) AC_SUBST(ac_javac) @@ -152,11 +166,11 @@ case "$ac_jver_string" in *\"1.1*) ac_jver=11 - AC_MSG_RESULT(recognized: JDK 1.1) + AC_MSG_RESULT(JDK 1.1) ;; *\"1.2*) ac_jver=12 - AC_MSG_RESULT(recognized: JDK 1.2) + AC_MSG_RESULT(JDK 1.2) ;; *) AC_MSG_ERROR(unrecognized.) @@ -193,10 +207,10 @@ esac ]) if test "$ac_executejava_in_asm" = "yes"; then - AC_MSG_RESULT(recognized: assembly code version) + AC_MSG_RESULT(assembly code version) AC_DEFINE(EXECUTEJAVA_IN_ASM) else - AC_MSG_RESULT(recognized: C version) + AC_MSG_RESULT(C version) fi @@ -210,18 +224,35 @@ ], ac_glibc2=yes) if test "$ac_glibc2" = "yes"; then - AC_MSG_RESULT(recognized: glibc2) + AC_MSG_RESULT(glibc2) AC_DEFINE(GLIBC2) else - AC_MSG_RESULT(recognized: not glibc2) + AC_MSG_RESULT(not glibc2) fi + dnl Checks for header files. AC_MSG_CHECKING(type of an argument of monitorEnter()) ac_monitor_t=`$ac_grep monitorEnter $ac_jincdir/monitor.h | $ac_sed 's/(/ /' | $ac_sed "s/.* \(.*\));.*/\1/"` AC_MSG_RESULT($ac_monitor_t) AC_DEFINE_UNQUOTED(MONITOR_T, $ac_monitor_t) + +AC_MSG_CHECKING(whether the header exists) +if test -f "/usr/include/asm/ucontext.h"; then + AC_MSG_RESULT(exists) + AC_DEFINE(HAVE_UCONTEXT_H) +else + AC_MSG_RESULT(does not exist) +fi + +AC_MSG_CHECKING(whether the JDK_HOME/include/green_threads directory exists) +if test -d "$ac_jincdir/green_threads"; then + AC_MSG_RESULT(exists) + AC_DEFINE(HAVE_GREENTHR_HEADER) +else + AC_MSG_RESULT(does not exist) +fi dnl Checks for typedefs, structures, and compiler characteristics. diff -aruN shujit-0.3.13/gentable.rb shujit/gentable.rb --- shujit-0.3.13/gentable.rb Mon Oct 4 14:57:32 1999 +++ shujit/gentable.rb Tue Dec 28 19:51:44 1999 @@ -169,7 +169,7 @@ chomp!() elems = split() funcname = elems.pop() - if funcname =~ /^%/ # %register + if funcname =~ /^%/ || funcname == '*ABS*' # %register or `*ABS*' next end max_func_off = off if off > max_func_off @@ -243,10 +243,10 @@ else bytepc_table[opcode][init_state] = array end - elsif /70 70 70/ # jump to exception handler + elsif /70 70/ # jump to exception handler i = 1 i += 1 while elems[i] != '70' - off = elems[0].chop().hex() + i - 1 - code_addr + off = elems[0].chop().hex() + i - 2 - code_addr max_jumpexc_off = off if off > max_jumpexc_off #print "jump to exception handler: #{off}\n" if init_state == STANY @@ -266,10 +266,10 @@ else jumpexc_table[opcode][init_state] = array end -# elsif /72 72 72/ # jump instruction +# elsif /72 72/ # jump instruction # i = 1 # i += 1 while elems[i] != '72' -# off = elems[0].chop().hex() + i - 1 - code_addr +# off = elems[0].chop().hex() + i - 2 - code_addr # #print "jump instruction: #{off}\n" # if init_state == STANY # array = jump_table[opcode][0]; @@ -288,10 +288,10 @@ # else # jump_table[opcode][init_state] = array # end - elsif /74 74 74/ # return instruction + elsif /74 74/ # return instruction i = 1 i += 1 while elems[i] != '74' - off = elems[0].chop().hex() + i - 1 - code_addr + off = elems[0].chop().hex() + i - 2 - code_addr #print "return instruction: #{off}\n" if init_state == STANY array = jumpret_table[opcode][0]; diff -aruN shujit-0.3.13/invoker.c shujit/invoker.c --- shujit-0.3.13/invoker.c Sat Oct 16 18:25:57 1999 +++ shujit/invoker.c Tue Dec 28 18:51:50 1999 @@ -2,7 +2,7 @@ This file is part of shuJIT, Just In Time compiler for Sun Java Virtual Machine. - Copyright (C) 1998,1999 SHUDO Kazuyuki + Copyright (C) 1998,1999,2000 SHUDO Kazuyuki This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff -aruN shujit-0.3.13/linker.c shujit/linker.c --- shujit-0.3.13/linker.c Sat Oct 9 12:32:13 1999 +++ shujit/linker.c Thu Dec 23 12:58:53 1999 @@ -2,7 +2,7 @@ This file is part of shuJIT, Just In Time compiler for Sun Java Virtual Machine. - Copyright (C) 1999 SHUDO Kazuyuki + Copyright (C) 1999,2000 SHUDO Kazuyuki This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff -aruN shujit-0.3.13/metavm/GNUmakefile shujit/metavm/GNUmakefile --- shujit-0.3.13/metavm/GNUmakefile Sat Oct 16 19:16:38 1999 +++ shujit/metavm/GNUmakefile Tue Dec 28 19:20:02 1999 @@ -3,12 +3,12 @@ # environment -JDK_VER = 11 -J_INCDIR = /usr/local/java/include +JDK_VER = 12 +J_INCDIR = /usr/local/java/include-old # command -CC = /usr/bin/egcs +CC = /usr/bin/gcc CI = /usr/bin/ci CO = /usr/bin/co MV = /bin/mv diff -aruN shujit-0.3.13/runtime.c shujit/runtime.c --- shujit-0.3.13/runtime.c Sat Oct 16 17:30:47 1999 +++ shujit/runtime.c Mon Dec 27 18:58:44 1999 @@ -2,7 +2,7 @@ This file is part of shuJIT, Just In Time compiler for Sun Java Virtual Machine. - Copyright (C) 1998,1999 SHUDO Kazuyuki + Copyright (C) 1998,1999,2000 SHUDO Kazuyuki This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -31,56 +31,6 @@ extern long JavaStackSize; /* declared in threads.h */ -#if defined(EXC_BY_SIGNAL) || defined(GET_SIGCONTEXT) -/* - * show contents of structure sigcontext - */ -void showSigcontext(SIGCONTEXT *sc) { - printf("SS: %04x, CS: %04x, DS: %04x, ES: %04x, FS: %04x, GS: %04x\n", -#if defined(__FreeBSD__) - sc->sc_ss & 0xffff, sc->sc_cs & 0xffff, - sc->sc_ds & 0xffff, sc->sc_es & 0xffff, - sc->sc_fs & 0xffff, sc->sc_gs & 0xffff -#else - sc->ss, sc->cs, sc->ds, sc->es, sc->fs, sc->gs -#endif - ); - - printf("EAX: %08x, ECX: %08x, EDX: %08x, EBX: %08x\n", - sc->SC_EAX, sc->SC_ECX, sc->SC_EDX, sc->SC_EBX); - - printf("ESI: %08x, EDI: %08x\n", - sc->SC_ESI, sc->SC_EDI); - - printf("ESP: %08x, EBP: %08x EIP: %08x\n", - sc->SC_ESP, sc->SC_EBP, sc->SC_EIP); - -#if defined(linux) - printf("ESP at signal: %08x\n", sc->esp_at_signal); -#endif - - { - uint32_t *esp = (uint32_t *)sc->SC_ESP; - if (esp) - printf("(ESP+4): %08x, (ESP): %08x\n", *(esp+1), *esp); - } - { - unsigned char *eip = (unsigned char *)sc->SC_EIP; - if (eip) - printf("(EIP): %02x %02x %02x %02x %02x %02x %02x %02x" - " %02x %02x %02x %02x %02x %02x %02x %02x\n", - *eip,*(eip+1),*(eip+2),*(eip+3),*(eip+4),*(eip+5),*(eip+6),*(eip+7), - *(eip+8),*(eip+9),*(eip+10),*(eip+11),*(eip+12),*(eip+13), - *(eip+14),*(eip+15)); - } - - printf("trapno: %02x\n", sc->SC_TRAPNO); - - fflush(stdout); -} -#endif /* EXC_BY_SIGNAL || GET_SIGCONTEXT */ - - /* * returns: TRUE if success, FALSE if failure. */ @@ -1055,6 +1005,9 @@ , int runtime_debug #endif ) { +#if 1 + int runtime_debug = 1; +#endif ClassClass *methodClazz; cp_item_type *constant_pool; unsigned char *type_table; diff -aruN shujit-0.3.13/signal.c shujit/signal.c --- shujit-0.3.13/signal.c Thu Jan 1 09:00:00 1970 +++ shujit/signal.c Tue Dec 28 18:55:03 1999 @@ -0,0 +1,536 @@ +/* + This file is part of shuJIT, + Just In Time compiler for Sun Java Virtual Machine. + + Copyright (C) 1998,1999,2000 SHUDO Kazuyuki + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + $Id$ +*/ + +#include "compiler.h" + +#if defined(EXC_BY_SIGNAL) || defined(GET_SIGCONTEXT) +# include +# if defined(linux) && defined(HAVE_UCONTEXT_H) +# if (__GLIBC__ == 2) && (__GLIBC_MINOR__ == 0) +typedef struct sigaltstack stack_t; + /* glibc 2.0 needs stack_t type. but cannot include */ +# endif /* glibc 2.0 */ +# include /* neither nor */ +# endif +#endif /* EXC_BY_SIGNAL || GET_SIGCONTEXT */ + + +/* + * Local Functions + */ +static void showFPUEnv(FILE *, char *indent, char fpuenv[28]); +#define fillFPUEnv(FPUENV) asm("fstenv %0" : "=m" (FPUENV)) + + +/* + * Definitions + */ +/* return from signal handler */ +/* JDK 1.2: set program counter to jump to exception handler + JDK 1.1: jump to exception handler */ +#if JDK_VER >= 12 +# define SIGRETURN(SC, EBP) return TRUE; +#else +# if defined(__FreeBSD__) +# define SIGRETURN(SC, EBP) sigreturn(SC); +# elif defined(sun) +# define SIGRETURN(SC, EBP) sigcontext(SC); +# else /* linux */ +# define SIGRETURN(SC, EBP) \ + {\ + register int eax asm("eax");\ + asm("movl %1,%%ebp" : "=a" (eax) : "m" (EBP));\ + return eax;\ + } +# endif /* os */ +#endif /* JDK_VER */ + + + +/* + * Variables + */ +#if (defined(EXC_BY_SIGNAL) || defined(GET_SIGCONTEXT)) && defined(SEARCH_SIGCONTEXT) +int sc_nest = -1; /* -1: invalid */ +static int ucontext_used = 0; +#endif + + +#if (defined(EXC_BY_SIGNAL) || defined(GET_SIGCONTEXT)) && defined(SEARCH_SIGCONTEXT) +#ifdef __FreeBSD__ +bool_t examineSigcontextNestCount(int sig, int code, struct sigcontext *uc0) { +#else +bool_t examineSigcontextNestCount(int sig, void *info, void *uc0) { +#endif + SIGCONTEXT *sc, *found_sc; + uint32_t *ebp, *found_ebp = 0; + int i; + +#if defined(RUNTIME_DEBUG) || defined(COMPILE_DEBUG) + printf("examineSigcontextNestCount: sig %d (sys_thread_t: %x)\n", + sig, (int)sysThreadSelf()); +#endif + + asm("movl %%ebp,%0" : "=r" (ebp)); + +#define SC_SEARCH_WIDTH 10 + for (i = 0; i < SC_SEARCH_WIDTH; i++) { + extern void exam_point(); /* in compiler.c */ + + sc = (SIGCONTEXT *)(ebp + 3); +#ifdef RUNTIME_DEBUG + printf(" i:%d, eip:%x\n", i, sc->SC_EIP); + fflush(stdout); +#endif +#define INT_INSN_SIZE 2 /* size of int $0x10 */ + if ((sc->SC_EIP == ((uint32_t)exam_point))) { /* found */ + sc_nest = i; + ucontext_used = 0; /* false */ + found_sc = sc; + found_ebp = ebp; +#ifdef RUNTIME_DEBUG + printf(" sc_nest: %d, ucontext is not used.\n", sc_nest); + fflush(stdout); +#endif + /* break; */ + /* must not do break to use last found sigcontext + with LinuxThreads in glibc 2.1.2 */ + } +#ifdef HAVE_UCONTEXT_H + else { /* not found */ + struct ucontext *uc; + uc = (struct ucontext *)ebp[4]; + if ((ebp < (uint32_t *)uc) && ((uint32_t *)uc < ebp + 0x100)) { + sc = (SIGCONTEXT *)&uc->uc_mcontext; + if (sc->SC_EIP == ((uint32_t)exam_point)) { /* found */ + sc_nest = i; + ucontext_used = 1; /* true */ + found_sc = sc; + found_ebp = ebp; +#ifdef RUNTIME_DEBUG + printf(" sc_nest: %d, ucontext is used.\n", sc_nest); + fflush(stdout); +#endif + break; + } + } + } +#endif /* HAVE_UCONTEXT_H */ + + ebp = (uint32_t *)ebp[0]; + } + + if (sc_nest < 0) { + printf("FATAL: cannot examine the offset of signal context.\n"); + JVM_Exit(1); + } + +#if defined(RUNTIME_DEBUG) || defined(COMPILE_DEBUG) + printf("sigcontext: 0x%08x\n", (int)found_sc); fflush(stdout); + showSigcontext(found_sc); +#endif + + found_sc->SC_EIP += INT_INSN_SIZE; + SIGRETURN(found_sc, found_ebp); +} +#endif /* (EXC_BY_SIGNAL || GET_SIGCONTEXT) && SEARCH_SIGCONTEXT */ + + +#ifdef __FreeBSD__ +bool_t signalHandler(int sig, int code, struct sigcontext *uc0) { +#else +bool_t signalHandler(int sig, void *info, void *uc0) { +#endif +#if defined(EXC_BY_SIGNAL) || defined(GET_SIGCONTEXT) +# ifdef SEARCH_SIGCONTEXT + uint32_t *ebp; +# endif /* SEARCH_SIGCONTEXT */ + SIGCONTEXT *sc = NULL; + struct methodblock *mb; + CodeInfo *codeinfo; + uint32_t native_off; +#endif /* EXC_BY_SIGNAL || GET_SIGCONTEXT */ +#ifdef EXC_BY_SIGNAL + throwentry *tentry; + uint32_t jump_target = 0; +#endif /* EXC_BY_SIGNAL */ + int i; + +#if 0 +#if 1 + signal(sig, SIG_DFL); +#else + { + struct sigaction sigAct; + sigAct.sa_handler = SIG_DFL; + sigemptyset(&sigAct.sa_mask); + sigaction(sig, &sigAct, (struct sigaction *)NULL); + } +#endif +#endif /* 0 */ + +#if defined(RUNTIME_DEBUG) || defined(COMPILE_DEBUG) + printf("Signal handler: sig %d (sys_thread_t: %x)\n", + sig, (int)sysThreadSelf()); +#endif + + +#if defined(EXC_BY_SIGNAL) || defined(GET_SIGCONTEXT) +#ifndef SEARCH_SIGCONTEXT +# ifdef __FreeBSD__ + sc = (SIGCONTEXT *)uc0; +# else /* linux */ + sc = (SIGCONTEXT *) &((struct ucontext *)uc0)->uc_mcontext; +# endif +#else + /* get signal context */ + asm("movl %%ebp,%0" : "=r" (ebp)); + for (i = 0; i < sc_nest; i++) { + ebp = (uint32_t *)ebp[0]; + } + if (!ucontext_used) { + sc = (SIGCONTEXT *)(ebp + 3); + } +#ifdef HAVE_UCONTEXT_H + else { + sc = (SIGCONTEXT *) &((struct ucontext *)ebp[4])->uc_mcontext; + } +#endif /* HAVE_UCONTEXT_H */ +#endif /* SEARCH_SIGCONTEXT*/ + +#if defined(RUNTIME_DEBUG) || defined(COMPILE_DEBUG) || (defined(GET_SIGCONTEXT) && !defined(EXC_BY_SIGNAL)) + printf("sigcontext: 0x%08x\n", (int)sc); fflush(stdout); + showSigcontext(sc); +#endif +#endif /* EXC_BY_SIGNAL || GET_SIGCONTEXT */ + + +#if defined(EXC_BY_SIGNAL) || defined(GET_SIGCONTEXT) + if ((sig != SIGSEGV) && (sig != SIGFPE)) return FALSE; + + mb = EE()->current_frame->current_method; + if (!mb) return FALSE; +#if defined(RUNTIME_DEBUG) || defined(COMPILE_DEBUG) + printf("method(0x%x)", (int)mb); fflush(stdout); + printf(": %s#%s %s\n", cbName(mb->fb.clazz), mb->fb.name, mb->fb.signature); + fflush(stdout); +#endif + if (!mb->CompiledCode) return FALSE; /* not compiled */ + native_off = + ((uint32_t)sc->SC_EIP) - ((uint32_t)mb->CompiledCode); +#ifdef RUNTIME_DEBUG + printf("native off: 0x%x\n", native_off); + fflush(stdout); +#endif +#ifndef EXC_BY_SIGNAL + return FALSE; +#else + codeinfo = (CodeInfo *)(mb->CompiledCodeInfo); + tentry = throwtableGet(codeinfo, native_off); + +#define IP_SEARCH_COUNT 3 + if (!tentry) { /* search EIP in native code */ + uint32_t *ebp; +#if defined(RUNTIME_DEBUG) || defined(COMPILE_DEBUG) + printf("throwentry is null !\n"); fflush(stdout); +#endif /* RUNTIME_DEBUG || COMPILE_DEBUG */ + + ebp = (uint32_t *)sc->SC_EBP; + + for (i = 0; i < IP_SEARCH_COUNT; i++) { + uint32_t *sp = ebp + 1; + + native_off = *sp - (uint32_t)mb->CompiledCode; + if ((native_off >= 0) && (native_off <= codeinfo->code_size)) { + tentry = throwtableGet(codeinfo, native_off); + if (tentry) { +#ifdef ARITHEXC_BY_SIGNAL + if (sig == SIGFPE) { + int opc = tentry->opcode; + if ((opc != opc_idiv) && (opc != opc_irem) && + (opc != opc_ldiv) && (opc != opc_lrem)) + continue; + } +#endif /* ARITHEXC_BY_SIGNAL */ + sc->SC_ESP = (uint32_t)(sp + 1); /* stack top in the frame */ + sc->SC_EIP = *sp; /* %eip on the compiled code */ + sc->SC_EBP = ebp[0]; /* return one more frame */ + goto tentry_is_found; + } + } + ebp = (uint32_t *)ebp[0]; + } /* for (i = 0; i < IP_SEARCH_COUNT; ... */ + goto signal_handler_error; + tentry_is_found: + } +#if defined(RUNTIME_DEBUG) || defined(COMPILE_DEBUG) + printf("throwentry: "); + fflush(stdout); + if (tentry) + printf("start: 0x%x, len: 0x%x, byteoff: 0x%x\n", + tentry->start, tentry->len, tentry->byteoff); + else + printf("(null)\n"); + fflush(stdout); +#endif /* RUNTIME_DEBUG || COMPILE_DEBUG */ + +#ifdef NULLEXC_BY_SIGNAL + if (sig == SIGSEGV) { + /* NullPointerException occurred */ + SignalError(NULL, JAVAPKG "NullPointerException", 0); + /* set ee->exception.exc, exception object */ + } +#endif +#if defined(NULLEXC_BY_SIGNAL) && defined(ARITHEXC_BY_SIGNAL) + else +#endif +#ifdef ARITHEXC_BY_SIGNAL + if (sig == SIGFPE) { + if ((tentry->opcode == opc_idiv) || (tentry->opcode == opc_irem)) { + if (sc->SC_ECX /* divisor */ == 0) { + /* ArithmeticException occurred */ + SignalError(NULL, JAVAPKG "ArithmeticException", "/ by zero"); + } + else if ((sc->SC_EAX /* dividend */ == 0x80000000) && + (sc->SC_ECX /* divisor */ == -1)) { + /* idiv insn. of x86 causes it: 0x80000000 / -1 */ + sc->SC_EAX = 0x80000000; + sc->SC_EDX = 0; + jump_target = sc->SC_EIP + 2; /* `+ 2' skips idiv `0xf7 0xXX' */ + } + else { + float dividend, divisor; + memcpy(÷nd, &(sc->SC_EAX), 4); + memcpy(&divisor, &(sc->SC_ECX), 4); + printf("FATAL: SIGFPE occurred in %s: %e %s %e.\n", + ((tentry->opcode == opc_idiv)?"idiv":"irem"), + (double)dividend, ((tentry->opcode == opc_idiv)?"/":"%"), + (double)divisor); + fflush(stdout); + + goto signal_handler_error; + } + } + else if ((tentry->opcode == opc_ldiv) || (tentry->opcode == opc_lrem)) { + uint32_t *sp = (uint32_t *)sc->SC_ESP; + sc->SC_ESP += 24; + /* `back up'ed registers in ldiv */ + sc->SC_EBP = *(sp + 4); /* *(sp + 4) is %ebp */ + sc->SC_ESI = *(sp + 5); /* *(sp + 5) is %esi */ + + /* dividend: (*(sp + 1) << 32) | *sp + divisor : (*(sp + 3) << 32) | *(sp + 2) */ + + if (!((*(sp + 2)) | (*(sp + 3)))) { + /* ArithmeticException occurred */ + SignalError(NULL, JAVAPKG "ArithmeticException", "/ by zero"); + } +#if 0 + /* In this case, + functions called by ldiv (__divdi3(),__moddi3()) don't cause SIGFPE */ + else if ((*sp == 0) && (*(sp + 1) == 0x80000000) && + ((*(sp +2) & *(sp + 3)) == 0xffffffff)) { + } +#endif + } + else { + printf("FATAL: SIGFPE occured in %s.", + ((tentry->opcode == opc_ldiv)?"ldiv":"lrem")); + fflush(stdout); + + goto signal_handler_error; + } + } /* if (sig == SIGFPE) */ +#endif /* ARITHEXC_BY_SIGNAL */ +#if defined(NULLEXC_BY_SIGNAL) || defined(ARITHEXC_BY_SIGNAL) + else +#endif + { + return FALSE; + } + + +#ifdef RUNTIME_DEBUG + /* examine whether the signal is pending */ + { + sigset_t pending_set; + if ((sigpending(&pending_set)) < 0) perror("sigpending"); + else { + printf("signal %d is pending: %s\n", + sig, (sigismember(&pending_set, sig) ? "TRUE":"FALSE")); + fflush(stdout); + } + } +#endif + + + /* jump to exc_new or exc_handler in compiled code */ + +#if 0 + /* re-initialize signal handler + associated with raised signal */ + { + struct sigaction sigAct = sigActForHandler; + sigaction(sig, &sigAct, (struct sigaction *)NULL); + } + +#ifdef __FreeBSD__ + /* unmask the signal */ + { + sigset_t sigmask; + sigemptyset(&sigmask); + sigaddset(&sigmask, sig); + sigprocmask(SIG_UNBLOCK, &sigmask, NULL); + } +#endif /* __FreeBSD__ */ +#endif /* 0 */ + + + /* set (int32_t)bytepcoff (local variable in assembledCode) */ + *(((int32_t *)sc->SC_EBP) - 1) = tentry->byteoff; + + + { + uint32_t exc_handler; + exc_handler = jump_target ? jump_target : + (uint32_t)(mb->CompiledCode + codeinfo->exc_handler_nativeoff); +#ifdef RUNTIME_DEBUG + printf("jump to 0x%x\n", exc_handler); fflush(stdout); +#endif + sc->SC_EIP = exc_handler; + } + + SIGRETURN(sc, ebp); +#endif /* EXC_BY_SIGNAL */ +#endif /* EXC_BY_SIGNAL || GET_SIGCONTEXT */ + + return FALSE; + +signal_handler_error: + fprintf(stderr, "Signal %d\n", sig); + fflush(stderr); +#if defined(EXC_BY_SIGNAL) || defined(GET_SIGCONTEXT) + if (sc) { + struct methodblock *sig_mb = methodByPC((unsigned char *)sc->SC_EIP); + fprintf(stderr, " in "); + if (sig_mb) { + uint32_t nativepc = + (uint32_t)sc->SC_EIP - (uint32_t)sig_mb->CompiledCode; + CodeInfo *info = (CodeInfo *)sig_mb->CompiledCodeInfo; + fprintf(stderr, "%s#%s %s\n", + cbName(fieldclass(&sig_mb->fb)), + sig_mb->fb.name, sig_mb->fb.signature); + fprintf(stderr, " native PC: 0x%x(%d)\n", nativepc, nativepc); +#ifdef EXC_BY_SIGNAL + if (info) { + throwentry *tentry = throwtableGet(info, nativepc); + if (tentry) { + int bytepc = tentry->byteoff; + fprintf(stderr, " byte PC: 0x%x(%d)\n", bytepc, bytepc); + } + } +#endif /* EXC_BY_SIGNAL */ + } + { + char fpuenv[28]; + fillFPUEnv(fpuenv); + showFPUEnv(stderr, " ", fpuenv); + } + fprintf(stderr, "\n"); + fflush(stderr); + + showSigcontext(sc); + + fprintf(stderr, "\n"); + fflush(stderr); + } +#endif + JVM_Exit(1); +} + + +static void showFPUEnv(FILE *fp, char *indent, char fpuenv[28]) { + if (!indent) indent = ""; + if (!fp) fp = stdout; + + fprintf(fp, "%sFPU control word: 0x%04x\n", indent, + *((int16_t *)(fpuenv + 0))); + fprintf(fp, "%sFPU status word: 0x%04x\n", indent, + *((int16_t *)(fpuenv + 4))); + fprintf(fp, "%sFPU tag word: 0x%04x\n", indent, + *((int16_t *)(fpuenv + 8))); + fprintf(fp, "%sFPU FIP : 0x%08x\n", indent, + *((int32_t *)(fpuenv + 12))); + + fflush(fp); +} + + +#if defined(EXC_BY_SIGNAL) || defined(GET_SIGCONTEXT) +/* + * show contents of structure sigcontext + */ +void showSigcontext(SIGCONTEXT *sc) { + printf("SS: %04x, CS: %04x, DS: %04x, ES: %04x, FS: %04x, GS: %04x\n", +#if defined(__FreeBSD__) + sc->sc_ss & 0xffff, sc->sc_cs & 0xffff, + sc->sc_ds & 0xffff, sc->sc_es & 0xffff, + sc->sc_fs & 0xffff, sc->sc_gs & 0xffff +#else + sc->ss, sc->cs, sc->ds, sc->es, sc->fs, sc->gs +#endif + ); + + printf("EAX: %08x, ECX: %08x, EDX: %08x, EBX: %08x\n", + sc->SC_EAX, sc->SC_ECX, sc->SC_EDX, sc->SC_EBX); + + printf("ESI: %08x, EDI: %08x\n", + sc->SC_ESI, sc->SC_EDI); + + printf("ESP: %08x, EBP: %08x EIP: %08x\n", + sc->SC_ESP, sc->SC_EBP, sc->SC_EIP); + +#if defined(linux) + printf("ESP at signal: %08x\n", sc->esp_at_signal); +#endif + + { + uint32_t *esp = (uint32_t *)sc->SC_ESP; + if (esp) + printf("(ESP+4): %08x, (ESP): %08x\n", *(esp+1), *esp); + } + { + unsigned char *eip = (unsigned char *)sc->SC_EIP; + if (eip) + printf("(EIP): %02x %02x %02x %02x %02x %02x %02x %02x" + " %02x %02x %02x %02x %02x %02x %02x %02x\n", + *eip,*(eip+1),*(eip+2),*(eip+3),*(eip+4),*(eip+5),*(eip+6),*(eip+7), + *(eip+8),*(eip+9),*(eip+10),*(eip+11),*(eip+12),*(eip+13), + *(eip+14),*(eip+15)); + } + + printf("trapno: %02x\n", sc->SC_TRAPNO); + + fflush(stdout); +} +#endif /* EXC_BY_SIGNAL || GET_SIGCONTEXT */ diff -aruN shujit-0.3.13/tsctest/x86tsc.c shujit/tsctest/x86tsc.c --- shujit-0.3.13/tsctest/x86tsc.c Sun Jul 25 13:52:03 1999 +++ shujit/tsctest/x86tsc.c Thu Dec 23 12:59:05 1999 @@ -2,7 +2,7 @@ This file is part of shuJIT, Just In Time compiler for Sun Java Virtual Machine. - Copyright (C) 1998,1999 SHUDO Kazuyuki + Copyright (C) 1998,1999,2000 SHUDO Kazuyuki This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff -aruN shujit-0.3.13/tsctest/x86tsc.h shujit/tsctest/x86tsc.h --- shujit-0.3.13/tsctest/x86tsc.h Sun Feb 14 19:49:14 1999 +++ shujit/tsctest/x86tsc.h Thu Dec 23 12:59:10 1999 @@ -2,7 +2,7 @@ This file is part of shuJIT, Just In Time compiler for Sun Java Virtual Machine. - Copyright (C) 1998,1999 SHUDO Kazuyuki + Copyright (C) 1998,1999,2000 SHUDO Kazuyuki This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff -aruN shujit-0.3.13/txt/header shujit/txt/header --- shujit-0.3.13/txt/header Sun Feb 14 20:39:20 1999 +++ shujit/txt/header Thu Dec 23 13:02:53 1999 @@ -2,7 +2,7 @@ This file is part of shuJIT, Just In Time compiler for Sun Java Virtual Machine. - Copyright (C) 1998,1999 SHUDO Kazuyuki + Copyright (C) 1998,1999,2000 SHUDO Kazuyuki This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff -aruN shujit-0.3.13/txt/jvmdi shujit/txt/jvmdi --- shujit-0.3.13/txt/jvmdi Thu Jan 1 09:00:00 1970 +++ shujit/txt/jvmdi Sun Oct 17 23:51:18 1999 @@ -0,0 +1,9 @@ +JVMDI + +- JNI に追加された型 + jthread + jthreadGroup + jframeID + スタックフレームひとつを表すポインタ + jlocation + 64bit, メソッド中の executable position diff -aruN shujit-0.3.13/txt/memo shujit/txt/memo --- shujit-0.3.13/txt/memo Sat Oct 16 18:12:52 1999 +++ shujit/txt/memo Mon Oct 18 01:58:43 1999 @@ -10,7 +10,7 @@ スタック積み直しを削減。 native method を呼ぶ際に restack を減らせる? JIT の frame にする。 - - JVM profiler interface に対応。 + - JVM Debugger Interface, JVMProfiler Interface の各種イベントを発生させる。 #ifdef HPROF if (jvmpi_event_flags & JVMPI_EVENT_METHOD_ENTRY_ON) { jvmpi_method_entry(ee, o); diff -aruN shujit-0.3.13/txt/moba shujit/txt/moba --- shujit-0.3.13/txt/moba Sun Jul 11 23:25:43 1999 +++ shujit/txt/moba Mon Nov 1 10:32:41 1999 @@ -1,35 +1,127 @@ 実行状態の非同期移送に対応した実行時コンパイラ ネイティブコードの実行を許す異機種間非同期実行状態移送方式 -- externalize だけでなく、internalize も考える必要がある。 - インタプリタ上の実行状態から、ネイティブコードの実行状態を作り出す必要あり。 +- to be considered + - suspend() にて、compiled code 用の suspend 処理をするかしないかを + 決める方法。 + - 近いうちに opc_suspend_check が実行される見込みがあれば、 + opc_suspend_check 向けの処理を行う。-> migration safe な suspend + - migration safe な suspend なるべく行いたい。 + - suspend が migration safe だったかどうかを知る方法。 + - +- 実行状態の変換: JVM <-> JIT + - 他のスレッドにやらせた方がよいか。 + - externalize だけでなく、internalize も考える必要がある。 + JVM -> JIT の変換。 + - スタックのコピーのために、型情報が要る。64bit か 32bit か。 + reference か即値か、を知る必要があるのは移送システム(MOBA) のみ。 + +- suspend 方法。 + - MobaThread#suspend(), resume() を用意する。 + - Thread#suspend(), resume() をすげかえる。 + private native void suspend0(); + private native void resume0(); + +- 実行状態の変換 (JVM <-> JIT) を行うタイミング。 + - suspend された時点。 + × 無駄に変換をしてしまう。しかし、たいしたオーバヘッドではない? + - JVMDI 経由のアクセスをフックする。 + × JDK 1.2 でのみ動作。 + × フックなんて可能か? + +- JVM デフォルトの suspend, resume 方法 + JVM_SuspendThread (jvm.c) + threadSuspend (threads.c) + #define sysThreadSuspend(a) + hpi_thread_interface->ThreadSuspend(a) (sys_api.h) + hpi_thread_interface->ThreadSuspend = sysThreadSuspend (share/hpi/src/hpi.c) + sysThreadSuspend + (solaris/hpi/{native,green}_threads/src/threads_md.c) + - native_threads の場合 + np_suspend(); + np: Non-posix の略。 + thr_suspend (threads_solaris.c) + - green_threads の場合 + queueRemove(&runnable_queue, tid); + runnable キューから外す。 + +- suspend 時、考慮すべき事項 + - 自スレッドかそうでないか。 + - JIT compiled code かインタプリタか。 + +- suspend, resume の方式 + - スレッドごとに必要な storage + - フラグ x 1 + suspendReq + - モニタ x 1 + suspendCond + - 課題 + - Thread#interrupt に対応 + +boolean suspendReq; // suspend が要求されている。 +#if 0 +boolean jitSuspend; // JIT compiled code 実行中に suspend している。 +#endif +Object suspendCond; MobaThread#suspend() { - suspendReq = true; - try { + // 複数のスレッドから呼ばれることを考慮。要排他処理。 + 通常の suspend(); + if (JIT compiled method 実行中) { + // todo: この後、opc_suspend_check が無かったら… + suspendReq = true; synchronized (suspendCond) { - suspendCond.wait(); - } - } catch (InterruptedException e) {} -} + 通常の resume(); -MobaThread#resume() { - インタプリタ上のスタックをクリア; - synchronized (resumeCond) { - resumeCond.notify(); + boolean suspend_done = false; + while (!suspend_done) { + try { + suspendCond.wait(); + // 本当に suspend するまで caller は待つ。 + suspend_done = true; + } catch (InterruptedException e) {} + } + } } } opc_suspend_check: if (current_thread.suspendReq) { - インタプリタ上に実行状態をコピー; + インタプリタの実行状態を作成; current_thread.suspendReq = false; - current_thread.suspendCond.notifyAll(); + synchronized (suspendCond) { // suspender が wait() するまで待つ。 + current_thread.suspendCond.notifyAll(); + } + + synchronized (resumeCond) { +#if 1 + 通常の suspend; +#else + jitSuspend = true; - try { - synchronized (resumeCond) { - resumeCond.wait(); + boolean resume_done = false; + while (!resume_done) { + try { + resumeCond.wait(); + resume_done = true; + } catch (InterruptedException e) {} } - } catch (InterruptedException e) {} + } +#endif + インタプリタの実行状態をクリア; } + +MobaThread#resume() { +#if 1 + 通常の resume; +#else + if (jitSuspend) { + synchronized (resumeCond) { + resumeCond.notify(); + // resumeCond.wait() しているのは resume されているスレッドのみなので + // notifyAll() ではない。 + } + } +#endif +} diff -aruN shujit-0.3.13/txt/multiarray shujit/txt/multiarray --- shujit-0.3.13/txt/multiarray Thu Jan 1 09:00:00 1970 +++ shujit/txt/multiarray Mon Dec 13 11:19:37 1999 @@ -0,0 +1,161 @@ +リニアなメモリレイアウトの多次元配列 + +- 目的 + - JIT による sematic expansion でどこまでできるか。 + +- todo + - メモリレイアウトを決める。 + 次元ごとの配列長の格納場所など。 + +- 対処が要る処理 + - 配列の作成 + - multianewarray + - newarray, anewarray の組み合わせによる作成は無視? + - 次元ごとの配列長をどう保持するか? + - 配列アクセス + - aload i, (push index, aaload) x n回, + read : [ilfdabcs]aload + write: 何かを push(例: bipush), [ilfdabcs]astore + - 配列長の取得 (arraylength) + 1次元目の長さを返すようにする。 + - GC + +- データフロー解析 + - ローカル変数の型を知るためには、データフロー解析が要る… + - ある時点でスロット n 番に何が入っているか。 + LocalVariableTable を生成するか。 + - どうせならデータ依存解析までしたい…きりがない。 + +- 問題 + - sub-array へのアクセス + - あきらめる? + - 必要に応じて配列オブジェクトを作る。 + あるメモリ領域が複数オブジェクトから参照される。alias。 + GC が対応する必要あり。 + + +[資料] + +- オブジェクトを push する命令 + - フィールドから + getfield 等: getfield, getfield_quick, getfield2_quick, getfield_quick_w + - ローカル変数から + aload 等: aload, aload_[0-3] + - LocalVariableTable attribute がない限り、 + コンパイル時に型情報を得られない。-> データフロー解析が要る。 +( + - コンスタントプールから、は有り得ない。 + ldc 等: ldc, ldc_w (ldc2_w は long, double 型専用) + コンスタントプールに入り得るオブジェクトは String 型のみ。 +) + + +- Java コンパイラが生成するバイトコード列 + + - 生成 + new int[d0][d1]...[dn-1] + + push (iconst_* or bipush or sipush or ldc) d0 + ... d1 + ... + ... dn-1 + multianewarray クラス(2byte) 次元数(1byte) + + - write + array[d0][d1]...[dn-1] = v + + push array + push d0 + aaload + ... + push dn-2 + aaload + push dn-1 + ---------- 以上は write, read で共通 + push v + ?astore + + - read + array[d0][d1]...[dn-1] + + push d0 + aaload + push d1 + aaload + ... + push dn-2 + aaload + push dn-1 + ---------- 以上は write, read で共通 + ?aload + + +- 具体的なバイトコード + + - 生成 + int[][][][][] ary0 = new int[32768][32767][127][5][-1]; + + 0 ldc #1 + 2 sipush 32767 + 5 bipush 127 + 7 iconst_5 + 8 iconst_m1 + 9 multianewarray #5 dim #5 + 13 astore_1 + + - write + ary[i+2][i*3] = i/4; + --- - - aload_2, iload_1, iconst_2 + --- iadd + ------- aaload + - - iload_1, iconst_3 + --- imul + - - iload_1, iconst_4 + --- imul + ------------------- iastore + + 7 aload_2 + + 8 iload_1 + 9 iconst_2 + 10 iadd + + 11 aaload + + 12 iload_1 + 13 iconst_3 + 14 imul + + 15 iload_1 + 16 iconst_4 + 17 idiv + + 18 iastore + + - read + ary[3][4][5] + --- aload_1 + - iconst_3 + ----- aaload + - iconst_4 + -------- aaload + - iconst_5 + ----------- iaload + + 20 aload_1 + + 21 iconst_3 + 22 aaload + + 23 iconst_4 + 24 aaload + + 25 iconst_5 + 26 iaload + + +- 定数の push + iconst_*: -1 〜 5 + bipush: signed 8 bit + sipush: signed 16 bit + ldc: 絶対値がそれ以上 diff -aruN shujit-0.3.13/x86tsc.c shujit/x86tsc.c --- shujit-0.3.13/x86tsc.c Sun Jul 25 13:52:03 1999 +++ shujit/x86tsc.c Thu Dec 23 12:59:05 1999 @@ -2,7 +2,7 @@ This file is part of shuJIT, Just In Time compiler for Sun Java Virtual Machine. - Copyright (C) 1998,1999 SHUDO Kazuyuki + Copyright (C) 1998,1999,2000 SHUDO Kazuyuki This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff -aruN shujit-0.3.13/x86tsc.h shujit/x86tsc.h --- shujit-0.3.13/x86tsc.h Sun Feb 14 19:49:14 1999 +++ shujit/x86tsc.h Thu Dec 23 12:59:10 1999 @@ -2,7 +2,7 @@ This file is part of shuJIT, Just In Time compiler for Sun Java Virtual Machine. - Copyright (C) 1998,1999 SHUDO Kazuyuki + Copyright (C) 1998,1999,2000 SHUDO Kazuyuki This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by