diff -aruN shujit-0.3.11/ChangeLog shujit/ChangeLog --- shujit-0.3.11/ChangeLog Fri Oct 1 13:41:58 1999 +++ shujit/ChangeLog Tue Oct 12 16:40:48 1999 @@ -1,5 +1,60 @@ $Id$ +[19991006] + +0.3.12 リリース。 + +[19991004] + +java.lang.Math#exp() の special inlining を止めた。 +用意したネイティブコードの挙動が、インタプリタなど他の処理系とは異なる。 +JDK 1.2 ではじめて発覚した。 +倍精度浮動小数点数を文字列に変換する方法が JDK 1.1 とは違うらしい。 +(compile.c) + +strictfp のための scale をあらかじめ FPU レジスタにロードするかしないか、 +マクロ STRICT_PRELOAD (compiler.h) で選べるようにした。 +何も考えずにプリロードしてしまうと、strictfp メソッドが +strictfp メソッドを呼ぶことで、FPU レジスタが溢れてまずいことになるので。 +これを改善できるまで、プリロードは凍結。 +(code.c, compiler.h) + +private, protected フィールドへのアクセスチェック (see [19991003]) は、 +JDK 1.2 以降でのみ行うようにした。JDK 1.1 ではチェックしない。 +JDK 1.1 の javac (sun.tools.{java.*,javac.*}) は、アクセサメソッドが +コンパイル時にインライン展開されてしまっており、 +チェックを厳しくすると IllegalAccessError で javac が動かない。 +(compile.c) + +[19991003] + +final フィールドへのアクセス (*field*) だけでなく (see [19990828])、 +次の場合にも IllegalAccessError が throw されるようにした。 +チェックに JDK 中の関数 VerifyFieldAccess() (classinitialize.c) を使用。 + - private フィールド、メソッドへのアクセス、呼び出し。 + - protected フィールド、メソッドへの別パッケージからのアクセス、呼び出し。 +ただし、呼び出しについて invokeinterface の場合を深く考察していない。 +(compile.c) + +strictfp のための scale down and up の処理を、x86 の +fscale 命令で行うようにした。ただし、これまでの乗算で行 +う方法と選択して (compiler.h のマクロ USE_FSCALE) コンパ +イルできるようにした。 +(code.c, compiler.h) + +[19990928] + +strictfp で、scale down and up のための scale を、 +メソッドの先頭であらかじめ FPU レジスタにロードしておくようにした。 +内部命令 strict{enter,exit} の処理 (丸め精度の設定) を +fppc_{save,restore} に移し、strict{enter,exit} でロードを行うようにした。 +これまでは必要なときにメモリからロードしていた。 +(code.c) + +dadd, dsub, dmul, ddiv 命令の pre-assembled コード中の命令順を変更。 +dmul, ddiv で若干の高速化。 +(code.c) + [19990925] JDK のインタプリタが assembly code 版か C 言語版かを、 diff -aruN shujit-0.3.11/README shujit/README --- shujit-0.3.11/README Fri Oct 1 13:42:38 1999 +++ shujit/README Sun Oct 10 15:37:07 1999 @@ -47,10 +47,9 @@ You need some tools to compile this JIT. - JDK 1.1.X or 1.2 -- EGCS (not experimental version such as 2.92.5-19981015) +- 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 - I've never tested with gcc 2.95. Currently, gcc 2.7.X will be not able to compile shuJIT. - objdump (in GNU binutils) Most Linux distributions and ELF FreeBSD systems have it. diff -aruN shujit-0.3.11/code.c shujit/code.c --- shujit-0.3.11/code.c Wed Sep 22 16:08:28 1999 +++ shujit/code.c Sun Oct 10 20:36:02 1999 @@ -36,14 +36,22 @@ /* * Global Variables */ -unsigned char double_scale_pos[10] = +/* 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) */ +#else +unsigned const char double_scale_pos[10] = { 0, 0, 0, 0, 0, 0, 0, 0x80, 0xff, 0x7b }; /* 2^ (16383 - 1023) */ -unsigned char double_scale_neg[10] = +unsigned const char double_scale_neg[10] = { 0, 0, 0, 0, 0, 0, 0, 0x80, 0xff, 0x03 }; /* 2^ -(16383 - 1023) */ -unsigned char single_scale_pos[10] = +unsigned const char single_scale_pos[10] = { 0, 0, 0, 0, 0, 0, 0, 0x80, 0x7f, 0x7f }; /* 2^ (16383 - 127) */ -unsigned char single_scale_neg[10] = +unsigned const char single_scale_neg[10] = { 0, 0, 0, 0, 0, 0, 0, 0x80, 0x7f, 0x00 }; /* 2^ -(16383 - 127) */ +#endif /* STRICT_USE_FSCALE */ #define COMPILEDCODE(DST) \ @@ -511,14 +519,40 @@ #endif } - /* enter strictfp method */ CODE(opc_strictenter, strictenter, STANY, STSTA, 0) { +#ifdef STRICT_PRELOAD + /* push scales into FPU register */ +# ifdef STRICT_USE_FSCALE + asm("fldl %0\n\t" : : "m" (single_scale_neg)); + asm("fldl %0\n\t" : : "m" (double_scale_neg)); +# else + asm("fldt %0\n\t" : : "m" (*single_scale_neg)); + asm("fldt %0\n\t" : : "m" (*single_scale_pos)); + asm("fldt %0\n\t" : : "m" (*double_scale_neg)); + asm("fldt %0\n\t" : : "m" (*double_scale_pos)); +# endif /* STRICT_USE_FSCALE */ +#endif /* STRICT_PRELOAD */ + } + + CODE(opc_strictexit, strictexit, STANY, STSTA, 0) { +#ifdef STRICT_PRELOAD + /* pop scales from FPU register */ +# ifdef STRICT_USE_FSCALE + asm("fstp %st(0)\n\tfstp %st(0)"); +# else + asm("fstp %st(0)\n\tfstp %st(0)\n\tfstp %st(0)\n\tfstp %st(0)"); +# endif /* STRICT_USE_FSCALE */ +#endif /* STRICT_PRELOAD */ + } + + /* save FPU rounding precision */ + CODE(opc_fppc_save, fppc_save, STANY, STSTA, 0) { /* save FPU control word */ asm("fstcw %0" : "=m" (preserved_fpucw)); } - /* exit strictfp method */ - CODE(opc_strictexit, strictexit, STANY, STSTA, 0) { + /* restore FPU rounding precision */ + CODE(opc_fppc_restore, fppc_restore, STANY, STSTA, 0) { /* restore FPU control word */ asm("fldcw %0" : : "m" (preserved_fpucw)); } @@ -534,7 +568,7 @@ CODE_FPPC(single, "andl $0xfcff,%eax"); CODE_FPPC(double, "andl $0xfcff,%eax\n\torl $0x0200,%eax"); - CODE_FPPC(ext, "orl $0x0300,%eax"); + CODE_FPPC(extended, "orl $0x0300,%eax"); /* throw IllegalAccessError */ #define CODE_ILLEGALACCESS(STATE) \ @@ -2201,6 +2235,7 @@ #define CODE_ARITH_FLOAT(VOP, ROP, SYM) \ CODE(opc_f##VOP, f##VOP, ST0, ST0, 0) {\ + ARITH_FLOAT_SCALE_PREPARE;\ ARITH_FLOAT_DEBUG1(SYM);\ asm("flds 4(%esp)");\ ARITH_FLOAT_SCALE_DOWN;\ @@ -2208,9 +2243,11 @@ "addl $4,%esp");\ ARITH_FLOAT_SCALE_UP;\ asm("fstps (%esp)");\ + ARITH_FLOAT_SCALE_SETTLE;\ ARITH_FLOAT_DEBUG2;\ }\ CODE(opc_f##VOP, f##VOP, ST1, ST0, 0) {\ + ARITH_FLOAT_SCALE_PREPARE;\ asm("flds (%esp)\n\t"\ "pushl %edx");\ ARITH_FLOAT_DEBUG1(SYM);\ @@ -2219,9 +2256,11 @@ "addl $4,%esp");\ ARITH_FLOAT_SCALE_UP;\ asm("fstps (%esp)");\ + ARITH_FLOAT_SCALE_SETTLE;\ ARITH_FLOAT_DEBUG2;\ }\ CODE(opc_f##VOP, f##VOP, ST2, ST0, 0) {\ + ARITH_FLOAT_SCALE_PREPARE;\ asm("pushl %edx\n\t"\ "flds (%esp)\n\t"\ "pushl %ecx");\ @@ -2231,9 +2270,11 @@ "addl $4,%esp");\ ARITH_FLOAT_SCALE_UP;\ asm("fstps (%esp)");\ + ARITH_FLOAT_SCALE_SETTLE;\ ARITH_FLOAT_DEBUG2;\ }\ CODE(opc_f##VOP, f##VOP, ST3, ST0, 0) {\ + ARITH_FLOAT_SCALE_PREPARE;\ asm("flds (%esp)\n\t"\ "pushl %ecx");\ ARITH_FLOAT_DEBUG1(SYM);\ @@ -2242,9 +2283,11 @@ "addl $4,%esp");\ ARITH_FLOAT_SCALE_UP;\ asm("fstps (%esp)");\ + ARITH_FLOAT_SCALE_SETTLE;\ ARITH_FLOAT_DEBUG2;\ }\ CODE(opc_f##VOP, f##VOP, ST4, ST0, 0) {\ + ARITH_FLOAT_SCALE_PREPARE;\ asm("pushl %ecx\n\t"\ "flds (%esp)\n\t"\ "pushl %edx");\ @@ -2254,25 +2297,52 @@ "addl $4,%esp");\ ARITH_FLOAT_SCALE_UP;\ asm("fstps (%esp)");\ + ARITH_FLOAT_SCALE_SETTLE;\ ARITH_FLOAT_DEBUG2;\ } +#define ARITH_FLOAT_SCALE_PREPARE #define ARITH_FLOAT_SCALE_DOWN #define ARITH_FLOAT_SCALE_UP +#define ARITH_FLOAT_SCALE_SETTLE CODE_ARITH_FLOAT(add, add, "+"); CODE_ARITH_FLOAT(sub, sub, "-"); CODE_ARITH_FLOAT(mul, mul, "*"); CODE_ARITH_FLOAT(div, div, "/"); +#undef ARITH_FLOAT_SCALE_PREPARE #undef ARITH_FLOAT_SCALE_DOWN #undef ARITH_FLOAT_SCALE_UP -#define ARITH_FLOAT_SCALE_DOWN \ +#undef ARITH_FLOAT_SCALE_SETTLE +#ifdef STRICT_USE_FSCALE +# ifdef STRICT_PRELOAD +# define ARITH_FLOAT_SCALE_PREPARE asm("fld %st(1)") +# else +# define ARITH_FLOAT_SCALE_PREPARE \ + asm("fldl %0\n\t" : : "m" (single_scale_neg)) +# endif /* STRICT_PRELOAD */ +# define ARITH_FLOAT_SCALE_DOWN asm("fscale") +# define ARITH_FLOAT_SCALE_UP asm("fxch\n\t"\ + "fchs\n\t"\ + "fxch\n\t"\ + "fscale") +# define ARITH_FLOAT_SCALE_SETTLE asm("fstp %st(0)") +#else +# define ARITH_FLOAT_SCALE_PREPARE +# ifdef STRICT_PRELOAD +# define ARITH_FLOAT_SCALE_DOWN asm("fmul %st(4)") +# define ARITH_FLOAT_SCALE_UP asm("fmul %st(3)") +# else +# define ARITH_FLOAT_SCALE_DOWN \ asm("fldt %0\n\t"\ "fmulp" : : "m" (*single_scale_neg) : "edx","ecx","esi") -#define ARITH_FLOAT_SCALE_UP \ +# define ARITH_FLOAT_SCALE_UP \ asm("fldt %0\n\t"\ "fmulp" : : "m" (*single_scale_pos) : "edx","ecx","esi") +# endif /* STRICT_PRELOAD */ +# define ARITH_FLOAT_SCALE_SETTLE +#endif /* STRICT_USE_FSCALE */ CODE_ARITH_FLOAT(mul_strict, mul, "*"); CODE_ARITH_FLOAT(div_strict, div, "/"); @@ -2311,15 +2381,17 @@ #endif #define DOUBLE_ST24(ROP, OPTOP1_REG, OPTOP2_REG, SYM) \ + ARITH_DOUBLE_SCALE_PREPARE;\ ARITH_DOUBLE_DEBUG1(OPTOP1_REG, OPTOP2_REG, SYM);\ - asm("fldl (%esp)\n\t" /* load v1[0:63] */\ - "addl $8,%esp");\ + asm("fldl (%esp)"); /* load v1[0:63] */\ ARITH_DOUBLE_SCALE_DOWN;\ asm("pushl " #OPTOP2_REG "\n\t" /* v2[32:63] */\ "pushl " #OPTOP1_REG "\n\t" /* v2[0:31] */\ "f" #ROP "l (%esp)");\ + asm("addl $8,%esp");\ ARITH_DOUBLE_SCALE_UP;\ asm("fstpl (%esp)");\ + ARITH_DOUBLE_SCALE_SETTLE;\ ARITH_DOUBLE_DEBUG2 /* now state 0 */ @@ -2344,22 +2416,48 @@ DOUBLE_ST24(ROP, %edx, %ecx, SYM);\ } +#define ARITH_DOUBLE_SCALE_PREPARE #define ARITH_DOUBLE_SCALE_DOWN #define ARITH_DOUBLE_SCALE_UP +#define ARITH_DOUBLE_SCALE_SETTLE CODE_ARITH_DOUBLE(add, add, "+"); CODE_ARITH_DOUBLE(sub, sub, "-"); CODE_ARITH_DOUBLE(mul, mul, "*"); CODE_ARITH_DOUBLE(div, div, "/"); +#undef ARITH_DOUBLE_SCALE_PREPARE #undef ARITH_DOUBLE_SCALE_DOWN #undef ARITH_DOUBLE_SCALE_UP -#define ARITH_DOUBLE_SCALE_DOWN \ +#undef ARITH_DOUBLE_SCALE_SETTLE +#ifdef STRICT_USE_FSCALE +# ifdef STRICT_PRELOAD +# define ARITH_DOUBLE_SCALE_PREPARE asm("fld %st(0)") +# else +# define ARITH_DOUBLE_SCALE_PREPARE \ + asm("fldl %0\n\t" : : "m" (double_scale_neg)) +# endif /* STRICT_PRELOAD */ +# define ARITH_DOUBLE_SCALE_DOWN asm("fscale") +# define ARITH_DOUBLE_SCALE_UP asm("fxch\n\t"\ + "fchs\n\t"\ + "fxch\n\t"\ + "fscale") +# define ARITH_DOUBLE_SCALE_SETTLE asm("fstp %st(0)") +#else +# define ARITH_DOUBLE_SCALE_PREPARE +# ifdef STRICT_PRELOAD +# define ARITH_DOUBLE_SCALE_DOWN asm("fmul %st(2)") +# define ARITH_DOUBLE_SCALE_UP asm("fmul %st(1)") +# else +# define ARITH_DOUBLE_SCALE_DOWN \ asm("fldt %0\n\t"\ - "fmulp" : : "m" (*double_scale_neg) : "edx","ecx","esi") -#define ARITH_DOUBLE_SCALE_UP \ + "fmulp" : : "m" (*double_scale_neg) : "edx","ecx","esi") +# define ARITH_DOUBLE_SCALE_UP \ asm("fldt %0\n\t"\ - "fmulp" : : "m" (*double_scale_pos) : "edx","ecx","esi") + "fmulp" : : "m" (*double_scale_pos) : "edx","ecx","esi") +# endif /* STRICT_PRELOAD */ +# define ARITH_DOUBLE_SCALE_SETTLE +#endif /* STRICT_USE_FSCALE */ CODE_ARITH_DOUBLE(mul_strict, mul, "*"); CODE_ARITH_DOUBLE(div_strict, div, "/"); diff -aruN shujit-0.3.11/compile.c shujit/compile.c --- shujit-0.3.11/compile.c Wed Sep 22 16:50:10 1999 +++ shujit/compile.c Sun Oct 10 15:53:25 1999 @@ -346,13 +346,17 @@ if (processAnOpcode(cc, opc_methodhead, &dummy_byteoff)) return 1; - if (!is_fpupc_double && - (OPT_SETQ(OPT_FRCSTRICTFP) || - (!OPT_SETQ(OPT_IGNSTRICTFP) && (mb->fb.access & ACC_STRICT)))) { + if (OPT_SETQ(OPT_FRCSTRICTFP) || + (!OPT_SETQ(OPT_IGNSTRICTFP) && (mb->fb.access & ACC_STRICT))) { + if (!is_fpupc_double) { + if (processAnOpcode(cc, opc_fppc_save, &dummy_byteoff)) + return 1; + if (processAnOpcode(cc, opc_fppc_double, &dummy_byteoff)) + return 1; + } + if (processAnOpcode(cc, opc_strictenter, &dummy_byteoff)) return 1; - if (processAnOpcode(cc, opc_fppc_double, &dummy_byteoff)) - return 1; } if (mb->fb.access & ACC_SYNCHRONIZED) @@ -462,9 +466,13 @@ if (processAnOpcode(cc, opc_syncexit, &dummy_byteoff)) return 1; - if (!is_fpupc_double && - (OPT_SETQ(OPT_FRCSTRICTFP) || - (!OPT_SETQ(OPT_IGNSTRICTFP) && (mb->fb.access & ACC_STRICT)))) { + if (OPT_SETQ(OPT_FRCSTRICTFP) || + (!OPT_SETQ(OPT_IGNSTRICTFP) && (mb->fb.access & ACC_STRICT))) { + if (!is_fpupc_double) { + if (processAnOpcode(cc, opc_fppc_restore, &dummy_byteoff)) + return 1; + } + if (processAnOpcode(cc, opc_strictexit, &dummy_byteoff)) return 1; } @@ -725,28 +733,114 @@ } } - /* throwing IllegalAccessError if putfield or putstatic to final field */ - if ((code_opcode == opc_putfield) || (code_opcode == opc_putfield2) || - (code_opcode == opc_putstatic) || (code_opcode == opc_putstatic2)) { - if ((opcode == opc_putfield_quick) || (opcode == opc_putfield2_quick) || - (opcode == opc_putstatic_quick) || (opcode == opc_putstatic2_quick)) { -#ifdef COMPILE_DEBUG - printf( - "putfield*_quick found. cannot get an index of constant pool.\n"); + /* throwing IllegalAccessError if the access is not allowed */ + { + int opc_is_put = 0, opc_is_get = 0; + switch (code_opcode) { + case opc_getfield: case opc_getfield2: + case opc_getstatic: case opc_getstatic2: + opc_is_get = 1; break; + case opc_putfield: case opc_putfield2: + case opc_putstatic: case opc_putstatic2: + opc_is_put = 1; break; + } + + if (opc_is_get || opc_is_put) { + int index; struct fieldblock *fb; + struct methodblock *src_mb; + int fb_access; ClassClass *fb_class; + + switch (opcode) { + case opc_getfield_quick: case opc_getfield2_quick: + case opc_getstatic_quick: case opc_getstatic2_quick: + case opc_putfield_quick: case opc_putfield2_quick: + case opc_putstatic_quick: case opc_putstatic2_quick: + /* NOTREACHED */ +#ifdef COMPILE_DEBUG + printf( + "quick field access insn(0x%x,%d). found." + " cannot get an index of constant pool.\n", opcode, opcode); fflush(stdout); #endif - } - else { /* ..field, ..field_quick_w */ + break; + } + /* the field must be already resolved above */ - int index = GET_UINT16(bytepc + 1); - struct fieldblock *fb = constant_pool[index].fb; + index = GET_UINT16(bytepc + 1); + fb = constant_pool[index].fb; + + if (!(src_mb = cc->mb)) { + code_opcode = opc_throw_illegalaccess; + goto check_access_done; + } - if (fb->access & ACC_FINAL) { - struct methodblock *src_mb = cc->mb; - if (!src_mb || (fieldclass(&src_mb->fb) != fieldclass(fb))) + fb_access = fb->access; + fb_class = fieldclass(fb); + +#if JDK_VER >= 12 + /* check private and protected from other packages */ + if (!VerifyFieldAccess( + fieldclass(&src_mb->fb), fb_class, fb_access, FALSE)) { +#ifdef COMPILE_DEBUG + printf("IllegalAccessError: 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); + fflush(stdout); +#endif + code_opcode = opc_throw_illegalaccess; + goto check_access_done; + } +#endif /* JDK_VER */ + + if (opc_is_put) { + /* check final */ + if ((fb_access & ACC_FINAL) && (fieldclass(&src_mb->fb) != fb_class)) { +#ifdef COMPILE_DEBUG + printf("IllegalAccessError: A final field is accessed.\n"); + fflush(stdout); +#endif code_opcode = opc_throw_illegalaccess; + goto check_access_done; + } + } + } /* if (opc_is_get || opc_is_put) */ + check_access_done: + } + + /* throwing IllegalAccessError if invoke* final field */ + if ((code_opcode == opc_invokevirtual) || + (code_opcode == opc_invokespecial) || + (code_opcode == opc_invokestatic)) { + int index; + struct fieldblock *method_fb; + struct methodblock *src_mb; + + index = GET_UINT16(bytepc + 1); + if (!CONSTANT_POOL_TYPE_TABLE_IS_RESOLVED(type_table, index)) { + if (!ResolveClassConstantFromClass2(fieldclass(&mb->fb), + index, cc->ee, 1 << CONSTANT_Methodref, FALSE)) { + code_opcode = opc_throw_noclassdef; + exceptionClear(cc->ee); + + goto check_invoke_done; } } + + if (!(src_mb = cc->mb)) { + code_opcode = opc_throw_illegalaccess; + goto check_invoke_done; + } + method_fb = &constant_pool[index].mb->fb; + /* check private and protected from other packages */ + if (!src_mb || + (!VerifyFieldAccess( + fieldclass(&src_mb->fb), fieldclass(method_fb), + method_fb->access, FALSE))) { + code_opcode = opc_throw_illegalaccess; + goto check_invoke_done; + } + check_invoke_done: } #ifdef SPECIAL_INLINING @@ -780,7 +874,10 @@ else if (!strcmp(mname, "tan")) code_opcode = opc_tan; else if (!strcmp(mname, "atan2")) code_opcode = opc_atan2; else if (!strcmp(mname, "atan")) code_opcode = opc_atan; +#if 0 + /* behavior of pre-assembled code differs from an interpreter. */ else if (!strcmp(mname, "exp")) code_opcode = opc_exp; +#endif else if (!strcmp(mname, "log")) code_opcode = opc_log; else if (!strcmp(mname, "floor")) code_opcode = opc_floor; else if (!strcmp(mname, "ceil")) code_opcode = opc_ceil; @@ -2560,7 +2657,7 @@ fflush(stdout); #endif if (!funcptr) { - /* not reached */ + /* NOTREACHED */ fprintf(stderr, "FATAL: can't resolve a symbol `%s'\n", funcp->name); JVM_Exit(1); } @@ -2601,7 +2698,7 @@ funcptr = funcp->name; if (!funcptr) { - /* not reached. */ + /* NOTREACHED */ fprintf(stderr, "FATAL: symbol `%s' was not resolved.\n", funcp->name); JVM_Exit(1); diff -aruN shujit-0.3.11/compiler.c shujit/compiler.c --- shujit-0.3.11/compiler.c Thu Sep 9 14:00:27 1999 +++ shujit/compiler.c Mon Oct 4 14:00:42 1999 @@ -53,6 +53,7 @@ bool_t compiler_enabled = TRUE; #endif /* IGNORE_DISABLE */ +/* for strictfp */ bool_t is_fpupc_double = FALSE; #if (defined(EXC_BY_SIGNAL) || defined(GET_SIGCONTEXT)) && defined(SEARCH_SIGCONTEXT) @@ -321,18 +322,6 @@ } - /* check the FPU roundig precision */ - { - uint16_t cw; - asm("fstcw %0" : "=m" (cw)); - is_fpupc_double = ((cw & 0x0300) == 0x0200); -#if defined(RUNTIME_DEBUG) || defined(COMPILE_DEBUG) - printf("FPU rounding precision: %sdouble.\n", - (is_fpupc_double?"":"not ")); -#endif - } - - #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)); @@ -561,6 +550,19 @@ REMOTE_FLAG_ON(ee); } #endif + + + /* for strictfp */ + /* check the FPU roundig precision */ + { + uint16_t cw; + asm("fstcw %0" : "=m" (cw)); + is_fpupc_double = ((cw & 0x0300) == 0x0200); +#if defined(RUNTIME_DEBUG) || defined(COMPILE_DEBUG) + printf("FPU rounding precision: %sdouble.\n", + (is_fpupc_double?"":"not ")); +#endif + } #ifdef COMPILE_DEBUG diff -aruN shujit-0.3.11/compiler.h shujit/compiler.h --- shujit-0.3.11/compiler.h Fri Oct 1 12:54:16 1999 +++ shujit/compiler.h Sun Oct 10 20:27:49 1999 @@ -45,55 +45,57 @@ #define opc_strictenter 263 #define opc_strictexit 264 -#define opc_fppc_single 265 /* 0x109 */ -#define opc_fppc_double 266 -#define opc_fppc_ext 267 - -#define opc_throw_illegalaccess 268 -#define opc_throw_noclassdef 269 - -#define opc_fill_cache 270 /* 0x10e */ -#define opc_array_check 271 - -#define opc_invokeignored_static 272 /* 0x110 */ - -#define opc_fmul_strict 273 /* 0x111 */ -#define opc_dmul_strict 274 -#define opc_fdiv_strict 275 -#define opc_ddiv_strict 276 - -#define opc_getstatic2 277 /* 0x115 */ -#define opc_putstatic2 278 -#define opc_getfield2 279 -#define opc_putfield2 280 - -#define opc_iastore1 281 /* 0x119 */ -#define opc_lastore1 282 - -#define opc_stateto0 283 /* 0x11b */ -#define opc_stateto1 284 -#define opc_stateto2 285 -#define opc_stateto3 286 -#define opc_stateto4 287 - -#define opc_goto_st0 288 /* 0x120 */ -#define opc_goto_st1 289 -#define opc_goto_st2 290 -#define opc_goto_st3 291 -#define opc_goto_st4 292 - -#define opc_sqrt 293 /* 0x123 */ -#define opc_sin 294 -#define opc_cos 295 -#define opc_tan 296 -#define opc_atan2 297 -#define opc_atan 298 -#define opc_exp 299 -#define opc_log 300 -#define opc_floor 301 -#define opc_ceil 302 +#define opc_fppc_save 265 /* 0x109 */ +#define opc_fppc_restore 266 +#define opc_fppc_single 267 +#define opc_fppc_double 268 +#define opc_fppc_extended 269 + +#define opc_throw_illegalaccess 270 +#define opc_throw_noclassdef 271 + +#define opc_fill_cache 272 /* 0x110 */ +#define opc_array_check 273 + +#define opc_invokeignored_static 274 /* 0x112 */ + +#define opc_fmul_strict 275 /* 0x113 */ +#define opc_dmul_strict 276 +#define opc_fdiv_strict 277 +#define opc_ddiv_strict 278 + +#define opc_getstatic2 279 /* 0x117 */ +#define opc_putstatic2 280 +#define opc_getfield2 281 +#define opc_putfield2 282 + +#define opc_iastore1 283 /* 0x11b */ +#define opc_lastore1 284 + +#define opc_stateto0 285 /* 0x11d */ +#define opc_stateto1 286 +#define opc_stateto2 287 +#define opc_stateto3 288 +#define opc_stateto4 289 + +#define opc_goto_st0 290 /* 0x122 */ +#define opc_goto_st1 291 +#define opc_goto_st2 292 +#define opc_goto_st3 293 +#define opc_goto_st4 294 + +#define opc_sqrt 295 /* 0x125 */ +#define opc_sin 296 +#define opc_cos 297 +#define opc_tan 298 +#define opc_atan2 299 +#define opc_atan 300 +#define opc_exp 301 +#define opc_log 302 +#define opc_floor 303 +#define opc_ceil 304 -#define NOPCODES 303 /* 0x12f */ +#define NOPCODES 305 /* 0x131 */ /* offerred by Sun */ @@ -466,10 +468,20 @@ /* in code.c */ /* for strictfp */ -extern unsigned char double_scale_pos[10]; /* 2^ (16383 - 1023) */ -extern unsigned char double_scale_neg[10]; /* 2^ -(16383 - 1023) */ -extern unsigned char single_scale_pos[10]; /* 2^ (16383 - 127) */ -extern unsigned char single_scale_neg[10]; /* 2^ -(16383 - 127) */ +#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 */ #if 0 extern struct methodtable *object_methodtable; /* for the macro OBJ_ARRAY_METHODTABLE in code.h */ diff -aruN shujit-0.3.11/computil.c shujit/computil.c --- shujit-0.3.11/computil.c Tue Sep 7 23:15:59 1999 +++ shujit/computil.c Sat Oct 9 12:32:23 1999 @@ -480,7 +480,7 @@ if (*sig++ == 'L') while (*(sig++) != ';'); break; default: - /* not reached */ + /* NOTREACHED */ fprintf(stderr, "FATAL: invalid signature: %s.\n", method->fb.signature); JVM_Exit(1); diff -aruN shujit-0.3.11/gentable.rb shujit/gentable.rb --- shujit-0.3.11/gentable.rb Wed Sep 22 13:42:56 1999 +++ shujit/gentable.rb Mon Oct 4 14:57:32 1999 @@ -4,7 +4,7 @@ CONST_C_FNAME = 'constants.c' CONST_H_FNAME = 'constants.h' -NOPCODES = 303 +NOPCODES = 305 NSTATES = 5 STANY = 5 STSTA = 5 diff -aruN shujit-0.3.11/invoker.c shujit/invoker.c --- shujit-0.3.11/invoker.c Fri Oct 1 13:18:29 1999 +++ shujit/invoker.c Sun Oct 10 19:03:01 1999 @@ -528,6 +528,14 @@ else if ((!strcmp(cbName(mb->fb.clazz), "com/sun/media/protocol/file/DataSource")) && (!strcmp(mb->fb.name, "connect"))) runtime_debug = 1; + else if (!strcmp(mb->fb.name, "dtoa")) + runtime_debug = 1; + else if ((!strcmp(cbName(mb->fb.clazz), "java/lang/FloatingDecimal")) + && (!strcmp(mb->fb.name, ""))) + runtime_debug = 1; + else if ((!strcmp(cbName(mb->fb.clazz), "java/lang/FloatingDecimal")) + && (!strcmp(mb->fb.name, "developLongDigits"))) + runtime_debug = 1; #if 1 else if (!strcmp(mb->fb.name, "main")) runtime_debug = 1; diff -aruN shujit-0.3.11/linker.c shujit/linker.c --- shujit-0.3.11/linker.c Sun Jul 25 13:52:03 1999 +++ shujit/linker.c Sat Oct 9 12:32:13 1999 @@ -112,7 +112,7 @@ return NULL; symsys_error: - /* not reached */ + /* NOTREACHED */ printf("FATAL: symbolInSystemClassLoader()\n"); fflush(stdout); JVM_Exit(1); diff -aruN shujit-0.3.11/txt/memo shujit/txt/memo --- shujit-0.3.11/txt/memo Fri Oct 1 14:10:21 1999 +++ shujit/txt/memo Sun Oct 10 17:17:31 1999 @@ -1,6 +1,4 @@ Todo - - java.lang.Math#exp を inlining しないように戻す。 - x86 FPU と JDK 1.2 のインタプリタで結果が微妙に異なるので。 - 特定メソッドの inlining。 profiling (javac, Linpack 等) に基づいて。 System#arraycopy, Object#getClass, Object#hashCode @@ -97,6 +95,8 @@ javac の、フックをかけられる箇所を探す。-> Jikes を改造? Done + - java.lang.Math#exp を inlining しないように戻す。 + x86 FPU と JDK 1.2 のインタプリタで結果が微妙に異なるので。 - クラスが存在しなかった場合に、JIT コンパイルが失敗するのではなく、 ClassNotFoundException, NoClassDefFoundError を発生するコードを生成する。 - final フィールドへの putfield, putstatic で