diff -aruN shujit-0.2.1/ChangeLog shujit/ChangeLog --- shujit-0.2.1/ChangeLog Mon Sep 28 19:43:16 1998 +++ shujit/ChangeLog Sat Oct 3 19:09:06 1998 @@ -1,10 +1,34 @@ $Id$ +[19981003] + +dlopen(..., RTLD_LAZY) で得た関数の本当のアドレスを、 +その関数を実行する前に得られるか (Linux libc5)、得られないか (FreeBSD) に +依存しないコードとした。変数 `sym_関数名' の導入。 +(compiler.c, compiler.h, compile.c) + +libc5 の環境では dlopen(), dlsym() でアドレスを得た関数のコードを +書き換えられるので、あらかじめ関数のアドレスを解決、書き込んでいたが、 +書き換え可能を仮定するのを止めた。 +マクロ RESOLVE_SYMBOL_ON_CODE を #undef。 +glibc2 対応の一環でもある。 +(compiler.h) + +0.2.2 リリース。 + +[19981001] + +呼び出されたメソッドがコンパイルされる際、コンパイル中に +起こる別のメソッド呼び出しによって引数が破壊されることがある問題に対処。 +(invoker.c) + [19980928] FreeBSD で関数 fmod() のアドレスを解決できていなかったので、 libc と同様に libm もあらかじめ sysAddDLSegment() しておくようにした。 (compiler.c) + +0.2.1 リリース。 [19980927] diff -aruN shujit-0.2.1/README shujit/README --- shujit-0.2.1/README Mon Sep 28 19:57:13 1998 +++ shujit/README Sat Oct 3 18:49:28 1998 @@ -1,18 +1,25 @@ -shuJIT: JIT compiler for JDK/x86 +shuJIT: JIT compiler for Sun JVM/x86 http://www.shudo.net/shujit/ SHUDO Kazuyuki +* What this is + +ShuJIT is a Just In Time bytecode compiler (JIT) which +works with Sun Microsystems' Java(tm) Virtual Machine +(JVM) such as JDK and JRE on Intel x86 processors. + * Platforms Working on the following platforms is confirmed. - Linux - - JDK 1.1.6v2 (ported by Steve Byrne) and Linux 2.1.117 - - JDK 1.1.5v5 and Linux 2.0.35 + - JDK 1.1.6v2 (ported by Steve Byrne), libc5.4.44 and Linux 2.1.117 + - JDK 1.1.6v2, libc5.4.38 and Linux 2.0.35 + - JDK 1.1.6v1, glibc2.0.7 and Linux 2.0.33 - Not tested on 1.1.6v3a, 1.1.6v4a, but runs with that releases. - FreeBSD - - JDK 1.1.6 (jdk1.1.6.V98-8-14.tar.gz) and FreeBSD 2.2.7R + - JDK 1.1.6 (V98-9-23) and FreeBSD 2.2.7R * Installation @@ -58,16 +65,16 @@ * Copying This is free software which is copyrighted by Kazuyuki -SHUDO. You may distrribute and modify it under the terms -version 2 of the GNU General Public License. See GPL.txt -for more details. +SHUDO. You may distribute and modify it under the terms +in version 2 of the GNU General Public License. See +GPL.txt for more details. * Thanks Thanks all folks around me and the following people: -MIURA Toshitaka (preparation of FreeBSD) -TANAKA Keishiro (testing on FreeBSD) +OHARA Takuzo (compilation of GNU binutils) +TANAKA Keishiro (testing on FreeBSD) and my wife Mari. diff -aruN shujit-0.2.1/compile.c shujit/compile.c --- shujit-0.2.1/compile.c Fri Sep 25 15:10:43 1998 +++ shujit/compile.c Sat Oct 3 10:57:20 1998 @@ -125,12 +125,8 @@ mb->fb.access |= ACC_MACHINE_COMPILED; mb->invoker = -#ifdef CAN_REF_SYM_BEFORE_EXEC - invokeCompiledMethod; -#else (bool_t (*)(JHandle *, struct methodblock *, int, struct execenv *)) - sysDynamicLink("invokeCompiledMethod"); -#endif + sym_invokeCompiledMethod; /* invokeCompiledMethod() is in invoker.c */ /* write code size */ diff -aruN shujit-0.2.1/compiler.c shujit/compiler.c --- shujit-0.2.1/compiler.c Mon Sep 28 19:42:09 1998 +++ shujit/compiler.c Sat Oct 3 11:25:54 1998 @@ -25,6 +25,11 @@ int opt_codesize = 0; int opt_dontcmplvmcls = 0; +void *sym_compileAndInvokeMethod; +void *sym_invokeCompiledMethod; +void *sym_invokeJavaMethod; +void *sym_invokeSynchronizedJavaMethod; + /* * Local Functions @@ -44,7 +49,7 @@ #define INITIALIZE_METHOD(MB) \ {\ (MB)->fb.access |= ACC_MACHINE_COMPILED;\ - (MB)->invoker = compileAndInvokeMethod;\ + (MB)->invoker = sym_compileAndInvokeMethod;\ } @@ -80,7 +85,7 @@ opt_outcode = 1; else if (!strncmp(opt, "codesize", 9)) opt_codesize = 1; - else if (!strncmp(opt, "dontcmplvmcls", 12)) + else if (!strncmp(opt, "dontcmplvmcls", 14)) opt_dontcmplvmcls = 1; opt = strtok(NULL, ", "); } @@ -135,7 +140,25 @@ } #endif + /* resolve some symbols */ + sym_compileAndInvokeMethod = + (void *)sysDynamicLink("compileAndInvokeMethod"); + sym_invokeCompiledMethod = (void *)sysDynamicLink("invokeCompiledMethod"); + sym_invokeJavaMethod = (void *)sysDynamicLink("invokeJavaMethod"); + sym_invokeSynchronizedJavaMethod = + (void *)sysDynamicLink("invokeSynchronizedJavaMethod"); +#ifdef COMPILE_DEBUG + printf("symbols:\n"); + printf(" compileAndInvokeMethod: 0x%08x\n", + (int)sym_compileAndInvokeMethod); + printf(" invokeCompiledMethod: 0x%08x\n", (int)sym_invokeCompiledMethod); + printf(" invokeJavaMethod: 0x%08x\n", (int)sym_invokeJavaMethod); + printf(" invokeSynchronizedJavaMethod: 0x%08x\n", + (int)sym_invokeSynchronizedJavaMethod); +#endif + #ifdef RESOLVE_SYMBOL_ON_CODE + /* resolve function symbols in pre-assembled code (compiledCode()) */ initFunctionSymbols(); #endif @@ -160,7 +183,7 @@ /* set up link vector */ *(char **)vector[1] = (char *)initializeClass; - *(char **)vector[2] = (char *)invokeCompiledMethod; + *(char **)vector[2] = (char *)sym_invokeCompiledMethod; *(char **)vector[3] = (char *)signalHandler; *(char **)vector[4] = (char *)freeClass; *(char **)vector[5] = (char *)compileClass; diff -aruN shujit-0.2.1/compiler.h shujit/compiler.h --- shujit-0.2.1/compiler.h Sun Sep 27 14:17:07 1998 +++ shujit/compiler.h Sat Oct 3 18:53:26 1998 @@ -79,15 +79,13 @@ /* * OS dependent macro definition */ +# undef RESOLVE_SYMBOL_ON_CODE #if defined (linux) # define EXECUTEJAVA_IN_ASM -# define CAN_REF_SYM_BEFORE_EXEC #elif defined (__FreeBSD__) # undef EXECUTEJAVA_IN_ASM -# undef CAN_REF_SYM_BEFORE_EXEC #else # undef EXECUTEJAVA_IN_ASM -# undef CAN_REF_SYM_BEFORE_EXEC #endif @@ -153,20 +151,20 @@ unsigned int finish_return_nativeoff; /* buffer for compiled code */ -#define DEFAULT_BUF_SIZE 4096 +#define DEFAULT_BUF_SIZE 8192 unsigned char *buffer; int buf_size; unsigned char *bufp; int lastbufp_off; /* program counter table */ -#define DEFAULT_PCTABLE_SIZE 50 +#define DEFAULT_PCTABLE_SIZE 100 int pctablesize; int pctablelen; pcentry *pctable; /* jump instruction table */ -#define DEFAULT_JPTABLE_SIZE 50 +#define DEFAULT_JPTABLE_SIZE 100 int jptablesize; int jptablelen; jpentry *jptable; @@ -189,6 +187,12 @@ extern int opt_dontcmplvmcls; /* suppress compilation classes which is already loaded when JIT is initialized */ + +extern void *sym_compileAndInvokeMethod; +extern void *sym_invokeCompiledMethod; +extern void *sym_invokeJavaMethod; +extern void *sym_invokeSynchronizedJavaMethod; + /* * Global Functions diff -aruN shujit-0.2.1/invoker.c shujit/invoker.c --- shujit-0.2.1/invoker.c Fri Sep 25 15:13:27 1998 +++ shujit/invoker.c Thu Oct 1 20:45:16 1998 @@ -36,18 +36,24 @@ #ifdef COMPILE_DEBUG printf(" now compiling.\n"); fflush(stdout); #endif + + ee->current_frame->optop += args_size; /* to save real args */ + /* not to be broken args by method invocation during compilation */ + if (compileMethod(mb)) { /* fail to compile.. */ + ee->current_frame->optop -= args_size; /* restore real optop */ #ifdef COMPILE_DEBUG printf(" compilation failed...\n"); fflush(stdout); #endif mb->invoker = (bool_t (*)(JHandle*,struct methodblock *,int,ExecEnv*)) access2invoker(mb->fb.access); - monitorExit(key); - return mb->invoker(o, mb, args_size, ee); + goto candi_method_done; } + ee->current_frame->optop -= args_size; /* restore real optop */ } +candi_method_done: #ifdef COMPILE_DEBUG printf("compileAndInvokeMethod(): now call invoker.\n"); fflush(stdout); @@ -83,8 +89,8 @@ # if 1 runtime_debug = 1; # else - if ((!strcmp(cbName(mb->fb.clazz), "sun/tools/java/Scanner")) - && (!strcmp(mb->fb.name, "scanNumber"))) + if ((!strcmp(cbName(mb->fb.clazz), "sun/io/CharToByteISO8859_1")) + && (!strcmp(mb->fb.name, "convert"))) runtime_debug = 1; else if ((!strcmp(cbName(mb->fb.clazz), "java/lang/FloatingDecimal")) && (!strcmp(mb->fb.name, "toJavaFormatString"))) @@ -132,7 +138,8 @@ prev_method = old_frame->current_method; if (!prev_method) goto restack; - if (prev_method->CompiledCode) { + if (prev_method->fb.access & ACC_MACHINE_COMPILED) { + /* is expected to be equal to if (prev_method->CompiledCode) */ /* called by compiled method */ frame->vars = (stack_item *)old_frame->returnpc; goto restack_done; diff -aruN shujit-0.2.1/memo shujit/memo --- shujit-0.2.1/memo Sat Sep 26 15:51:15 1998 +++ shujit/memo Sat Oct 3 18:53:57 1998 @@ -17,6 +17,7 @@ [ifa]store{,_N}, [ifa]load{,_N} で、メモリからの読みだしを省く。 - invoke(Synchronized)JavaMethod() の代替を用意、処理を軽減する。 - CompilerContext をむやみに free(), malloc() しない。 + 排他制御が必要。-> thread library を使ってしまう。 - native 命令列の書き換え。 invoke -> invokevirtual*object* 相当など。 obj_array_methodtable() ではなく obj_methodtable() が使える。 @@ -25,14 +26,13 @@ - 例外ハンドラを offset ではなく絶対アドレスで扱う。 - lookupswitch 命令の検索アルゴリズムを改良する。 - Address Generation Interlock(AGI) (MMX 本 pp.95,99) を避ける。 + - ジャンプ先を 8バイト境界に align。 - invokeignored_quick にて、スタックのキャッシュ内容を無駄に push している。 Todo - - FreeBSD, Win32 に移植。 + - Win32 に移植。 - よりハードなテスト。 MC のコンパイルなど。 - - credit を考える。 - - __{mul,div,mod}di3 を呼び出さないようにする。 - SignalError() の第 3引数として文字列を渡しているものをチェック。 - JMP 命令の、E9 (引数 4 バイト) から EB (引数 1 バイト) への書き換え - UseLosslessQuickOpcodes = TRUE でよいようにする。 @@ -51,6 +51,9 @@ javac の、フックをかけられる箇所を探す。 Done + - __{mul,div,mod}di3 を呼び出さないようにする。 + 64bit 整数の乗算、__muldi3 は自前のコードを用意した。 + 除、剰余算は inline で生成するとコードサイズが大きくなってしまう。 - compiled code のサイズの表を作成、表示 CODESIZE_DEBUG - invokeignored_quick で pc[2] == 0 の場合、null check コードを省く。 @@ -67,12 +70,20 @@ 移植時の注意 - Linux のように、dlopen(..., RTLD_LAZY) なライブラリ中の 関数のアドレスを関数実行前に得られるか、FreeBSD のように得られないか。 + ^- この性質に依存しないコードにした。 + - dlopen() でロードしたライブラリ中の関数のコードを書き換えられるか。 + Linux (libc5) でのみ可能。 - Linux の JDK のように、libc 中の関数のアドレスを sysDynamicLink() で 得られるか、FreeBSD の JDK のように得られないか。 - 関数名シンボルが funcname か _funcname か。 gentable.rb の挙動を変える。 - JVM の new 命令の self modify 時の offset 例: Linux では 0x35, FreeBSD では 0x3a + +autoconf に向けて + - libc5, glibc2 の判別 + マクロ RESOLVE_SYMBOL_ON_CODE を変える。 + - 関数名のシンボルがの頭に `_' が付くか付かないか。 注記 - code.c の NEW_REWRITE_OFFSET_# は、code.h のマクロ CODE() の定義に diff -aruN shujit-0.2.1/runtime.c shujit/runtime.c --- shujit-0.2.1/runtime.c Sun Sep 27 14:08:05 1998 +++ shujit/runtime.c Sat Oct 3 10:58:25 1998 @@ -68,12 +68,12 @@ #ifdef RUNTIME_DEBUG /* let user know calling normal Java method */ - if ((void *)method->invoker == (void *)invokeJavaMethod) { + if ((void *)method->invoker == sym_invokeJavaMethod) { printf("call normal Java method: %s#%s\n", cbName(method->fb.clazz), method->fb.name); fflush(stdout); } - else if ((void *)method->invoker == (void *)invokeSynchronizedJavaMethod) { + else if ((void *)method->invoker == sym_invokeSynchronizedJavaMethod) { printf("call normal sync. Java method: %s#%s\n", cbName(method->fb.clazz), method->fb.name); fflush(stdout);