diff -aruN shujit-0.2.3/ChangeLog shujit-0.2.4/ChangeLog --- shujit-0.2.3/ChangeLog Sat Oct 10 19:38:50 1998 +++ shujit-0.2.4/ChangeLog Thu Jan 7 15:54:59 1999 @@ -1,5 +1,135 @@ $Id$ +[19990107] + +関数 invokeCompiledMethod() を invokeJITCompiledMethod() に改名。 +(invoker.c, compiler.c, compiler.h, runtime.c) + +0.2.4 リリース。 + +[19990106] + +java_lang_Compiler_start() (compiler.c) が複数回呼ばれた場合に、 +2回目以降は初期化を実行しないようにした。 +クラス java.lang.Compiler が GC で回収されて再びロードされ、 +Compiler# -> Compiler#initialize() -> java_lang_Compiler_start() と +再び呼ばれてしまうことがあるため。 +Swing の javax.swing.UIManager#initialize() で +java.lang.Compiler#disable(),enable() を呼ぶために +java.lang.Compiler が再びロードされる。 +(compiler.c) + +オプション igndisable の挙動を変更。 +そもそも java.lang.Compiler#disable(), enable() が働かないようにした。 +(compiler.c, invoker.c, compile.c) + +bool_t UseLosslessQuickOpcodes を誤って FALSE にしていたところ、 +TRUE に直した。 +(compiler.c) + +java.lang.Compiler#disable(), enable() がきちんと働くようにした。 +余計なチェックの分、メソッド呼び出しの性能は若干低下する? +disable されている場合、 +compileAndInvokeMethod() (invoker.c) にて、バイトコードを呼び出し、 +invokeMethod() (runtime.c) にて、compileAndInvokeMethod() を呼ぶなら +restack するようにした。 +(invoker.c, runtime.c) + +[19990105] + +オプション igndisable を用意。 +java.lang.Compiler#disable() を無効化する。 +(compiler.c, compiler.h) + +compileAndInvokeMethod() (invoker.c) にて、JIT が disalble されていたら +JDK 内の invoke*Method() を呼ぶようにした。 + +変数 `sym_関数名' として、invokeAbstractMethod(), invokeLazyNativeMethod() の +アドレスを用意した。 +(compiler.c, compiler.h) + +access2invoker() (computil.c) で、invokeAbstractMethod など +直接関数のアドレスを利用する代わりに sysDynamicLink() で解決しておいた +sym_invokeAbstractMethod などを利用するようにした。 +(computil.c) + +[19990104] + +invokeMethod() (in runtime.c) 中で、static メソッド呼び出しの際に +クラスオブジェクトを得る処理を pre-assembled code (code.c) に移した。 +CaffeineMark 3.0 の Float, String の結果は向上、 +Linpack benchmark の結果は低下した ??? +(runtime.c, code.c) + +[19990103] + +クレジット、著作権表示に `1999' を追加。 + +FreeBSD, gcc 2.7.2.1 で make が通るように、 +GNUmakefile の code.s 周辺を修整。 +(GNUmakefile) + +invokeMethod() (in runtime.c) への変更で Linpack for +Java がかなり遅くなっていたのを、shujit-0.2.3 の +runtime.c を参考に修整。 +(runtime.c) + +[19981231] + +文字列のアドレスを push するコード (PUSH_CONSTSTR(...) in code.h) で、 +gcc 2.7.2.[13] では余計なレジスタ (esi) を使って内容を壊していた。 +egcs 1.0.3 の生成するコードでは問題がなかった。 +gcc 2.7.X で code.o を生成する際は、code.s を +ruby スクリプト (postcmpl.rb) で修整するようにした。 +(postcmpl.rb, GNUmakefile) + +[19981228] + +invokeMethod() などでの prepareCompiledCodeInfo() の呼び出しを +initializeClass(), compileClass() (compiler.c) に移動した。 +(runtime.c, compiler.c) + +[19981227] + +struct CatchFrame (oobj.h) にメンバ state を加えた +CatchFrame_w_state 型を用意。 +(compiler.h) + +exception_handler 中で、発見した例外ハンドラが仮定する state に +遷移するようにした。 +(code.c) + +[19981216] + +メソッドごとの例外ハンドラへのジャンプ (SIGNAL_ERROR* in code.h) で、 +state 0 に遷移しておくようにした。 +(code.h, code.c) + +[19981129] + +checkcast 命令で、 +対象オブジェクトが null の場合に is_instance_of() を呼ばないようにした。 + +[19981030] + +JITDO サーバ内の thread pool を作り直した。 +(NET/shudo/jitdo/{ThreadPool,JitdoServer,RequestServer}.java) + +[19981022] + +JVM に SIGQUIT を送ると内部状態をダンプするはずが SIGSEGV が発生していた。 +signalHandler() 中で、showStackFrames(EE()) を止めた。 +(compiler.c) + +JITDO サーバの枠組ができた。 +起動スクリプト jitdo/bin/jitdo を用意。 + +[19981017] + +Runtime Compiler による JVM の分散オブジェクト対応、 +JITDO (JIT Ditributed Object) 実装開始。 +(jitdo/, NET/shudo/jitdo/) + [19981010] 32bit 整数の除算 (idiv 命令) で、state 4 に限り、 @@ -11,6 +141,8 @@ EDX レジスタを無駄に 0 クリアしていたのを省いた。 (code.c) +0.2.3 リリース。 + [19981005] Linux では、libc の種類によって @@ -170,7 +302,7 @@ binutils 2.9.1.0.7 の as でアセンブルが通るように修整。 (code.c) -code.s の preprocess を止めた。 +code.s の postprocess を止めた。 C コンパイラを gcc 2.7.2.X から egcs 1.0.3 に変更したところ、 定数の push (マクロ PUSH_CONSTSTR()) のコードが変わったため。 diff -aruN shujit-0.2.3/GNUmakefile shujit-0.2.4/GNUmakefile --- shujit-0.2.3/GNUmakefile Thu Jan 1 09:00:00 1970 +++ shujit-0.2.4/GNUmakefile Wed Jan 6 23:31:03 1999 @@ -0,0 +1,90 @@ +# $Id$ + +include def.mk + +GENCONST = ./gentable.rb +POSTPROC = ./postcmpl.rb + +INCDIR = -I${J_HOME}/include -I${J_HOME}/include/genunix -I${J_HOME}/include/freebsd + +OPTFLAGS = -O2 +CDEBUGFLAGS =# -g -DRUNTIME_DEBUG -DCOMPILE_DEBUG# -DNO_CHECK +NOOPTCFLAGS = -pipe -fPIC ${CDEBUGFLAGS} ${INCDIR} +CFLAGS = ${OPTFLAGS} ${NOOPTCFLAGS} + +TARGET = libshujit.so +GENEDHDR = constants.h +GENEDOBJ = constants.o +# source code +HDR = compiler.h code.h +OBJ = code.o compiler.o invoker.o computil.o opcodes.o compile.o\ + runtime.o x86tsc.o +# subdirectories +SUBDIR = + +# for JIT Distributed Object +ifdef JITDO + SUBDIR += NET/shudo/jitdo jitdo + OBJ += jitdo/objectid.o jitdo/vmop.o jitdo/controller.o \ + jitdo/proxy.o jitdo/copyable.o + NOOPTCFLAGS += -DJITDO + CFLAGS += -DJITDO +endif + + +all: $(TARGET) + +${TARGET}: subdir ${OBJ} ${GENEDOBJ} + ${LD_DYNAMIC} -o $@ ${OBJ} ${GENEDOBJ} + +subdir: + @for subdir in ${SUBDIR}; do \ + (cd $$subdir && $(MAKE)) \ + done + + +# generate code.o +ifeq (${CC_VER},gcc27) +code.s: code.c ${POSTPROC} + ${CC} -S -DGCC27 ${NOOPTCFLAGS} -o tmp.s $< + ${POSTPROC} < tmp.s > $@ + ${RM} tmp.s +code.o: code.s +ifeq (${OSTYPE},FreeBSD) + /usr/bin/as -k -o $@ $< +else + ${CC} -c $< +endif +else +code.o: code.c + ${CC} ${NOOPTCFLAGS} -c $< +code.s: code.c code.h + ${CC} -S ${NOOPTCFLAGS} $< +endif + + +${GENEDHDR}: code.o ${GENCONST} + ${OBJDUMP} -dx $< | ${GENCONST} +${GENEDOBJ:.o=.c}: code.o ${GENCONST} + ${OBJDUMP} -dx $< | ${GENCONST} + +compile.o: compiler.h ${GENEDHDR} ${GENEDOBJ:.o=.c} + +compiler.o: compiler.c compiler.h + +runtime.o: runtime.c compiler.h + + +clean: subdirclean + ${RM} TAGS *~ ${TARGET} ${OBJ} ${GENEDHDR} ${GENEDOBJ} ${GENEDOBJ:.o=.c} *.s + +subdirclean: + @for subdir in ${SUBDIR}; do \ + (cd $$subdir && $(MAKE) clean) \ + done + +tag: + ${ETAGS} *.[hc] + +wc: + ${WC} ${OBJ:.o=.c} ${HDR} ${GENCONST} diff -aruN shujit-0.2.3/Makefile shujit-0.2.4/Makefile --- shujit-0.2.3/Makefile Sat Oct 10 19:29:23 1998 +++ shujit-0.2.4/Makefile Thu Jan 1 09:00:00 1970 @@ -1,76 +0,0 @@ -# $Id$ - -CC = gcc -LD_DYNAMIC = gcc -shared# for SunOS 5, Linux -#LD_DYNAMIC = ld -Bdynamic# for SunOS 4 - -OBJDUMP = objdump - -RM = rm -f -MV = mv -MKDIR = mkdir -p -LN = ln -AR = ar -RANLIB = ranlib -INSTALL = install -c -CO = co -CI = ci -WC = wc -TEE = tee -ETAGS = etags -RLOG = rlog -h - - -J_HOME = /usr/local/jdk1.1.6 -GENCONST = ./gentable.rb - -INCDIR = -I${J_HOME}/include -I${J_HOME}/include/genunix -I${J_HOME}/include/freebsd - -OPTFLAGS = -O2 -CDEBUGFLAGS =# -g -DRUNTIME_DEBUG -DCOMPILE_DEBUG# -DNO_CHECK -CFLAGS = -pipe -fPIC ${OPTFLAGS} ${CDEBUGFLAGS} ${INCDIR} -NOOPTCFLAGS = -pipe -fPIC ${CDEBUGFLAGS} ${INCDIR} - -TARGET = libshujit.so -GENEDHDR = constants.h -GENEDOBJ = constants.o -HDR = compiler.h code.h -OBJ = compiler.o invoker.o computil.o opcodes.o compile.o\ - code.o runtime.o x86tsc.o - - -all: $(TARGET) - -${TARGET}: ${OBJ} ${GENEDOBJ} - ${LD_DYNAMIC} -o $@ ${OBJ} ${GENEDOBJ} - - -code.s: code.c code.h - ${CC} -S ${NOOPTCFLAGS} code.c - -#code.o: code.s -# ${CC} -c $< - -code.o: code.c - ${CC} ${NOOPTCFLAGS} -c $< - -${GENEDHDR}: code.o ${GENCONST} - ${OBJDUMP} -dx code.o | ${GENCONST} -${GENEDOBJ:.o=.c}: code.o ${GENCONST} - ${OBJDUMP} -dx code.o | ${GENCONST} - -compile.o: compiler.h ${GENEDHDR} ${GENEDOBJ:.o=.c} - -compiler.o: compiler.h - -runtime.o: compiler.h - - -clean: - ${RM} TAGS *~ ${TARGET} ${OBJ} ${GENEDHDR} ${GENEDOBJ} ${GENEDOBJ:.o=.c} *.s - -tag: - ${ETAGS} *.[hc] - -wc: - ${WC} ${OBJ:.o=.c} ${HDR} ${GENCONST} diff -aruN shujit-0.2.3/README shujit-0.2.4/README --- shujit-0.2.3/README Sat Oct 10 19:41:10 1998 +++ shujit-0.2.4/README Thu Jan 7 13:53:06 1999 @@ -1,4 +1,4 @@ -shuJIT: JIT compiler for Sun JVM/x86 +shuJIT - JIT compiler for Sun JVM/x86 http://www.shudo.net/jit/ SHUDO Kazuyuki @@ -13,19 +13,17 @@ Working on the following platforms is confirmed. - Linux - - JDK 1.1.6v2 (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.6v4a (by Java-Linux Porting Team), glibc2.0.7 and Linux 2.0.33 - - Not tested on 1.1.6v3a, 1.1.6v4a, but runs with that releases. + - JDK 1.1.7v1a, egcs 1.0.3, glibc2.0.7 and Linux 2.0.36 + - JDK 1.1.7v1a, egcs 1.0.3, libc5.4.44 and Linux 2.1.124 - FreeBSD - - JDK 1.1.6 (V98-9-23) and FreeBSD 2.2.7R + - JDK 1.1.7 (V98-12-21) gcc 2.7.2.1 and FreeBSD 2.2.7R * Installation Copy the library libshujit.so to the path in LD_LIBRARY_PATH variable or the path on which libjava.so exists -(ex. /usr/local/jdk1.1.6/lib/i686/green_threads/). +(ex. /usr/local/jdk1.1.7/lib/i686/green_threads/). * Run Java applications with JIT compiler. @@ -43,19 +41,20 @@ You need some tools to compile this JIT. - JDK 1.1.X -- GCC2 or EGCS +- EGCS (not 2.92.5-19981015) or GCC 2.7.X - objdump (in GNU binutils) Most Linux distributions contains these utilities. - Ruby A script which generate some tables is written in Ruby. - 1.1c1 or later is needed. (You may not use 1.1c2) http://www.netlab.co.jp/ruby/ - 1. Edit J_HOME = ... line in Makefile. + 1. Edit J_HOME = ... line in def.mk. Write the path where you installed JDK. 2. Edit the first line of the script gentable.rb if you installed Ruby to the path is not standard. - 3. Type `make'. You'll get libshujit.so + 3. Define a macro CC_VER as gcc27 if you use GCC 2.7.X instead of EGCS. + You can examine which C compiler you use by the command `gcc -v' + 4. Type `make'. You'll get libshujit.so * Bugs and Problems @@ -72,7 +71,8 @@ Thanks all folks around me and the following people: -OHARA Takuzo (compilation of GNU binutils) +OHARA Takuzo (compilation on FreeBSD) +TAKAHASHI Hideaki (bug report and debug) TANAKA Keishiro (test on FreeBSD) MIURA Toshitaka (preparation of FreeBSD) and my wife Mari. diff -aruN shujit-0.2.3/benchmark shujit-0.2.4/benchmark --- shujit-0.2.3/benchmark Sun Oct 4 13:02:41 1998 +++ shujit-0.2.4/benchmark Thu Jan 1 09:00:00 1970 @@ -1,47 +0,0 @@ -JDK 1.1.6 for Linux (ported by Steve Byrne) - -TYA 1.0 付属 - - plain TYA shuJIT -Sieve 98 316 399 times -TestOpcodeField 4050 1285 1308 msec -TestOpcodeStatic 3085 557 257 msec -Iview Valetta.jpg 436 470 505 msec - -FIELD_ACC() から NULL_TEST() を省いた shuJIT で TestOpcodeField は 1201 - - -E2 1MB 暗号化 - - plain TYA shuJIT -128 789 318 370(291) msec -192 791 310 362(280) msec -256 791 311 367(289) msec - ()内は NO_CHECK 版 - -CaffeineMark 3.0 - - plain TYA -Sieve 434 820 -Loop 499 1564 -Logic 504 2990 -String 821 1479 -Float 444 1072 -Method 464 842 -Graphics791 729 -Image 162 560 -Dialog 93 95 -CM3 392 835 - - 8/18 NO_CHECK(8/19) -Sieve 895 960 *2 -Loop 1717 2048 *1 -Logic 2919 2902 -String 1034 1044 -Float 1038 1317 *1 -Method 120 138 -Graphics529 686 *2 -Image 503 226 ばらつく -Dialog 86 91 -CM3 618 628 - *1 効果大 *2 効果そこそこ diff -aruN shujit-0.2.3/cmd.mk shujit-0.2.4/cmd.mk --- shujit-0.2.3/cmd.mk Thu Jan 1 09:00:00 1970 +++ shujit-0.2.4/cmd.mk Sat Oct 17 15:42:56 1998 @@ -0,0 +1,18 @@ +# $Id$ + +#all:: $(SRC:.java=.class) + +clean: + $(RM) *.class *.o *~ *.bak + +co: + -$(CO) RCS/* + +ci: + -$(CI) -u RCS/* + +lock: + -$(CO) -l RCS/* + +wc: + $(WC) *.java diff -aruN shujit-0.2.3/code.c shujit-0.2.4/code.c --- shujit-0.2.3/code.c Sat Oct 10 19:32:51 1998 +++ shujit-0.2.4/code.c Wed Jan 6 23:10:14 1999 @@ -1,5 +1,5 @@ /* - * Copyright (C) 1998 + * Copyright (C) 1998,1999 * SHUDO Kazuyuki * * Permission to use, copy, modify and distribute this software @@ -14,6 +14,12 @@ #include "opcodes.h" #include "code.h" +#ifdef JITDO +#include "jitdo/jitdo.h" +#include "jitdo/NET_shudo_jitdo_Proxy_old.h" /* for type H...Proxy */ +#include "jitdo/NET_shudo_jitdo_VMAddress_old.h"/* for type H...VMAddress */ +#endif /* JITDO */ + volatile void assembledCode( JHandle *o, struct methodblock *mb, int args_size, ExecEnv *ee @@ -207,12 +213,35 @@ CODE(opc_methodhead, methodhead, STANY, STSTA) { __asm__("pushl %ebp\n\t" "movl %esp,%ebp\n\t" - "subl $0x50,%esp\n\t" /* 4 * #local_var */ + "subl $0x30,%esp\n\t" /* 4 * #local_var */ "pushl %ecx\n\t" "pushl %edx\n\t" "pushl %edi\n\t" "pushl %esi"); #ifdef RUNTIME_DEBUG + /* write class and method name */ + DEBUG_IN; + { + register struct methodblock *mb_reg asm("edi"); + mb_reg = mb; + + __asm__("movl " METHOD_NAME(%edi) ",%eax\n\t" + "testl %eax,%eax\n\t" + "jz methodhead_name_done\n\t" + "pushl %eax"); + METHOD_CLAZZ(%edi, %eax); + CB_NAME(%eax, %eax); /* break %edi */ + __asm__("pushl %eax"); + PUSH_CONSTSTR(" %s#%s\n"); + __asm__("call " SYMBOL(printf) "@PLT\n\t" + "addl $12,%esp"); + FFLUSH; + __asm__("methodhead_name_done:"); + } + DEBUG_OUT; +#endif /* RUNTIME_DEBUG */ + +#ifdef RUNTIME_DEBUG if (runtime_debug) { __asm__("pushl %eax\n\t" "movl %esp,%eax"); @@ -233,8 +262,7 @@ nativecode = mb->CompiledCode; - /* %esi = ee->current_frame->vars */ - { + { /* %esi = ee->current_frame->vars */ register ExecEnv *cur_ee asm("eax"); cur_ee = ee; } @@ -255,13 +283,13 @@ /* method tail */ CODE(opc_methodtail, methodtail, STANY, STSTA) { - __asm__("leal 0xffffffa0(%ebp),%esp"); - /* -4 * (#local_var + #registers_on_stack) */ + __asm__("leal 0xffffffc0(%ebp),%esp"); + /* -4 * (#local_var + #registers_on_stack) */ __asm__("popl %esi\n\t" "popl %edi\n\t" "popl %edx\n\t" - "popl %ecx"); - __asm__("leave\n\t" + "popl %ecx\n\t" + "leave\n\t" "ret"); } @@ -280,6 +308,7 @@ #else __asm__("addl $12,%esp"); #endif + /* eax is CatchFrame */ __asm__("testl %eax,%eax\n\t" "jz exc_through"); @@ -288,19 +317,56 @@ register unsigned char *esp asm("esp"); esp = ostack; } - { /* place the exception object - to candidates of TOS ((%esp), %edx, %ecx) */ - register ExecEnv *cur_ee asm("ecx"); + { /* place the exception object on TOS */ + register ExecEnv *cur_ee asm("edi"); register JHandle *excobj asm("edx"); cur_ee = ee; excobj = cur_ee->exception.exc; __asm__("pushl %edx"); - __asm__("movl %edx,%ecx"); + /* now state 0 */ + + cur_ee->exception.exc = NULL; } { - register struct CatchFrame *cf asm("eax"); + register struct CatchFrame_w_state *cf asm("eax"); register unsigned char *tgt asm("edi"); + register int32_t handler_state asm("ecx"); + + handler_state = cf->state; +#ifdef RUNTIME_DEBUG + DEBUG_IN; + printf(" exc handler state: %d\n", handler_state); + fflush(stdout); + DEBUG_OUT; +#endif + + /* shift to the state which handler assumes */ + __asm__("cmpl $0,%ecx\n\t" /* if (hanlder_state == 0) */ + "je exc_handler_shift_done\n\t" + "exc_handler_shift_1:\n\t" + "cmpl $1,%ecx\n\t" /* if (handler_state == 1) */ + "jne exc_handler_shift_2\n\t" + "popl %edx\n\t" + "jmp exc_handler_shift_done\n\t" + "exc_handler_shift_2:\n\t" + "cmpl $3,%ecx\n\t" /* if (handler_state == 3) */ + "jne exc_handler_shift_3\n\t" + "popl %ecx\n\t" + "jmp exc_hanlder_shift_done\n\t" + "exc_handler_shift_3:\n\t" + "cmpl $2,%ecx\n\t" /* if (handler_stat == 2) */ + "jne exc_handler_shift_4\n\t" + "popl %ecx\n\t" + "xorl %edx,%edx\n\t" + "jmp exc_handler_shift_done\n\t" + "exc_handler_shift_4:\n\t" + "cmpl $4,%ecx\n\t" /* if (handler_stat == 4) */ + "jne exc_handler_shift_done\n\t" + "popl %edx\n\t" + "xorl %ecx,%ecx\n\t" + "exc_handler_shift_done:"); + tgt = nativecode; tgt += (int)cf->compiled_CatchFrame; __asm__("jmp *%edi"); @@ -788,8 +854,8 @@ #endif #ifndef NO_CHECK -# define ARRAY_CHECK(HANDLE, INDEX, LABEL) \ - NULL_TEST(HANDLE, LABEL "_1");\ +# define ARRAY_CHECK(HANDLE, INDEX, LABEL, STATE) \ + NULL_TEST(HANDLE, LABEL "_1", STATE);\ \ ARRAY_CHECK_DEBUG1(INDEX);\ __asm__("testl " #INDEX "," #INDEX "\n\t"\ @@ -799,20 +865,20 @@ __asm__("cmpl %edi," #INDEX "\n\t"\ "jl " LABEL "_done");\ __asm__(LABEL "_exc:"); /* label */\ - SIGNAL_ERROR0(ArrayIndexOutOfBoundsException);\ + SIGNAL_ERROR0(ArrayIndexOutOfBoundsException, STATE);\ __asm__(LABEL "_done:") /* label */ #else -# define ARRAY_CHECK(HANDLE, INDEX, LABEL) \ +# define ARRAY_CHECK(HANDLE, INDEX, LABEL, STATE) \ OBJ_LENGTH(HANDLE, %edi); /* edi = obj_length(handle) */ #endif /* NO_CHECK */ /* destroy %edi */ /* edi = obj_length(handle) */ CODE(opc_array_check, array_check, ST2, ST2) { - ARRAY_CHECK(%edx, %ecx, "arychk_st2"); + ARRAY_CHECK(%edx, %ecx, "arychk_st2", 2); } CODE(opc_array_check, array_check, ST4, ST4) { - ARRAY_CHECK(%ecx, %edx, "arychk_st4"); + ARRAY_CHECK(%ecx, %edx, "arychk_st4", 4); } /* iaload */ @@ -1088,7 +1154,7 @@ __asm__("popl %eax");\ \ __asm__("jnz aastore_st" #STATE "_1");\ - SIGNAL_ERROR0(ArrayStoreException);\ + SIGNAL_ERROR0(ArrayStoreException, STATE);\ __asm__("aastore_st" #STATE "_1:") #else # define AASTORE_TEST(OBJ, STATE) @@ -1111,7 +1177,7 @@ CODE(opc_lastore, [ld]astore, ST##STATE, ST0) {\ __asm__("popl %eax\n\t"\ "movl (%esp),%edi");\ - ARRAY_CHECK(%edi, %eax, "lastore_st" #STATE);\ + ARRAY_CHECK(%edi, %eax, "lastore_st" #STATE, STATE);\ __asm__("popl %edi");\ UNHAND(%edi, %edi);\ __asm__("leal (%edi,%eax,8),%edi\n\t"\ @@ -1429,7 +1495,7 @@ #define INT_TEST(VOP, STATE, DIVIDER) \ __asm__("testl " #DIVIDER "," #DIVIDER "\n\t"\ "jnz i" #VOP "_st" #STATE "_1");\ - SIGNAL_ERROR0(ArithmeticException);\ + SIGNAL_ERROR0(ArithmeticException, STATE);\ __asm__("i" #VOP "_st" #STATE "_1:") #define CODE_ARITH_INT_TEST(VOP, RESULT_REG) \ @@ -1646,7 +1712,7 @@ __asm__("movl %edx,%eax\n\t"\ "orl %ecx,%eax\n\t"\ "jnz l" #VOP "_st" #STATE "_1");\ - SIGNAL_ERROR0(ArithmeticException);\ + SIGNAL_ERROR0(ArithmeticException, STATE);\ __asm__("l" #VOP "_st" #STATE "_1:") /* now state [24] */ @@ -2897,10 +2963,6 @@ __asm__("jmp *8(%edi)") -#if 0 - __asm__("jmp *8(%edi)") -#endif - CODE(opc_lookupswitch, lookupswitch, ST0, ST0) { __asm__("popl %edx"); /* now state 1 */ LUSW(%edx, 0); @@ -3098,75 +3160,175 @@ #ifndef NO_CHECK # define FIELD_ACC(HANDLE, VOP, STATE) \ __asm__("movl $" STR(CONST) ",%eax");\ - NULL_TEST(HANDLE, #VOP "_st" #STATE "_1") + /* slot: fb->u.offset / sizeof(OBJECT) */\ + NULL_TEST(HANDLE, #VOP "_st" #STATE "_1", STATE) #else # define FIELD_ACC(HANDLE, VOP, STATE) \ __asm__("movl $" STR(CONST) ",%eax") + /* fb->u.offset / sizeof(OBJECT) */ #endif /* NO_CHECK */ /* eax = index */ +#ifdef JITDO +# define JITDO_GETFIELD(HANDLE, TGT, LABEL) \ + JUMP_IF_NOT_REMOTE(LABEL "_local");\ + JUMP_IF_NOT_PROXY(HANDLE, LABEL "_local");\ + \ + __asm__("pushl %eax\n\t" /* slot */\ + "pushl " #HANDLE); /* obj (Proxy) */\ + __asm__("pushl %0" : : "m" (ee)); /* ee */\ + \ + __asm__("movl $" STR(CONST) ",%edi");\ + __asm__("testl %edi,%edi\n\t"\ + "jnz " LABEL "_obj\n\t"\ + "call " SYMBOL(proxy_get32field) "@PLT\n\t"\ + "jmp " LABEL "_remoteget_done\n\t"\ + LABEL "_obj:\n\t"\ + "call " SYMBOL(proxy_getobjfield) "@PLT\n\t"\ + LABEL "_remoteget_done:\n\t"\ +); DEBUG_IN;\ +__asm__("pushl %eax");\ +PUSH_CONSTSTR("JITDO_GETFIELD: 0x%08x\n");\ +__asm__("call printf@PLT\n\t"\ + "addl $8,%esp");\ +FFLUSH;\ +DEBUG_OUT; __asm__(\ + "addl $12,%esp\n\t"\ + "movl %eax," #TGT "\n\t"\ + "jmp " LABEL "_done\n\t"\ + LABEL "_local:") +#else +# define JITDO_GETFIELD(HANDLE, TGT, LABEL) +#endif /* JITDO */ + CODE(opc_getfield, getfield, ST0, ST3) { __asm__("popl %edx"); /* now state 1 */ FIELD_ACC(%edx, getfield, 0); + JITDO_GETFIELD(%edx, %ecx, "getfield_st0"); OBJ_GETSLOT(%edx, %eax, %ecx); + __asm__("getfield_st0_done:"); ILOAD_DEBUG1(%ecx); } CODE(opc_getfield, getfield, ST1, ST3) { FIELD_ACC(%edx, getfield, 1); + JITDO_GETFIELD(%edx, %ecx, "getfield_st1"); OBJ_GETSLOT(%edx, %eax, %ecx); + __asm__("getfield_st1_done:"); ILOAD_DEBUG1(%ecx); } CODE(opc_getfield, getfield, ST2, ST2) { FIELD_ACC(%ecx, getfield, 2); + JITDO_GETFIELD(%ecx, %ecx, "getfield_st2"); OBJ_GETSLOT(%ecx, %eax, %ecx); + __asm__("getfield_st2_done:"); ILOAD_DEBUG1(%ecx); } CODE(opc_getfield, getfield, ST3, ST1) { FIELD_ACC(%ecx, getfield, 3); + JITDO_GETFIELD(%ecx, %edx, "getfield_st3"); OBJ_GETSLOT(%ecx, %eax, %edx); + __asm__("getfield_st3_done:"); ILOAD_DEBUG1(%edx); } CODE(opc_getfield, getfield, ST4, ST4) { FIELD_ACC(%edx, getfield, 4); + JITDO_GETFIELD(%edx, %edx, "getfield_st4"); OBJ_GETSLOT(%edx, %eax, %edx); + __asm__("getfield_st4_done:"); ILOAD_DEBUG1(%edx); } +#ifdef JITDO +# define JITDO_GETFIELD2(HANDLE, TGT_LOW, TGT_HIGH, LABEL) \ + JUMP_IF_NOT_REMOTE(LABEL "_local");\ + JUMP_IF_NOT_PROXY(HANDLE, LABEL "_local");\ + \ + __asm__("pushl %eax\n\t" /* slot */\ + "pushl " #HANDLE); /* obj (Proxy) */\ + __asm__("pushl %0" : : "m" (ee)); /* ee */\ + \ + __asm__("call " SYMBOL(proxy_get64field) "@PLT\n\t"\ + "movl %edx," #TGT_HIGH "\n\t"\ + "addl $12,%esp\n\t"\ + "movl %eax," #TGT_LOW "\n\t"\ + "jmp " LABEL "_done\n\t"\ + LABEL "_local:") +#else +# define JITDO_GETFIELD2(HANDLE, TGT_LOW, TGT_HIGH, LABEL) +#endif /* JITDO */ + /* const: slot */ CODE(opc_getfield2, getfield2, ST0, ST2) { __asm__("popl %edx"); /* now state 1 */ FIELD_ACC(%edx, getfield2, 0); + JITDO_GETFIELD2(%edx, %ecx, %edx, "getfield2_st0"); OBJ_GETSLOT2(%edx, %eax, %ecx, %edx); + __asm__("getfield2_st0_done:"); LLOAD_DEBUG1(%ecx, %edx); } CODE(opc_getfield2, getfield2, ST1, ST2) { FIELD_ACC(%edx, getfield2, 1); + JITDO_GETFIELD2(%edx, %ecx, %edx, "getfield2_st1"); OBJ_GETSLOT2(%edx, %eax, %ecx, %edx); + __asm__("getfield2_st1_done:"); LLOAD_DEBUG1(%ecx, %edx); } CODE(opc_getfield2, getfield2, ST2, ST4) { __asm__("pushl %edx"); /* now state 3 */ FIELD_ACC(%ecx, getfield2, 2); + JITDO_GETFIELD2(%ecx, %edx, %ecx, "getfield2_st2"); OBJ_GETSLOT2(%ecx, %eax, %edx, %ecx); + __asm__("getfield2_st2_done:"); LLOAD_DEBUG1(%edx, %ecx); } CODE(opc_getfield2, getfield2, ST3, ST4) { FIELD_ACC(%ecx, getfield2, 3); + JITDO_GETFIELD2(%ecx, %edx, %ecx, "getfield2_st3"); OBJ_GETSLOT2(%ecx, %eax, %edx, %ecx); + __asm__("getfield2_st3_done:"); LLOAD_DEBUG1(%edx, %ecx); } CODE(opc_getfield2, getfield2, ST4, ST2) { __asm__("pushl %ecx"); /* now state 1 */ FIELD_ACC(%edx, getfield2, 4); + JITDO_GETFIELD2(%edx, %ecx, %edx, "getfield2_st4"); OBJ_GETSLOT2(%edx, %eax, %ecx, %edx); + __asm__("getfield2_st4_done:"); LLOAD_DEBUG1(%ecx, %edx); } /* putfield */ /* const: slot */ +#ifdef JITDO +# define JITDO_PUTFIELD(HANDLE, VAL, LABEL) \ + JUMP_IF_NOT_REMOTE(LABEL "_local");\ + JUMP_IF_NOT_PROXY(HANDLE, LABEL "_local");\ + \ + __asm__("pushl " #VAL "\n\t"/* value */\ + "pushl %eax\n\t" /* slot */\ + "pushl " #HANDLE); /* obj (Proxy) */\ + __asm__("pushl %0" : : "m" (ee)); /* ee */\ + \ + __asm__("movl $" STR(CONST) ",%edi");\ + __asm__("testl %edi,%edi\n\t"\ + "jnz " LABEL "_obj\n\t"\ + "call " SYMBOL(proxy_put32field) "@PLT\n\t"\ + "addl $16,%esp\n\t"\ + "jmp " LABEL "_done\n\t"\ + LABEL "_obj:\n\t"\ + "call " SYMBOL(proxy_putobjfield) "@PLT\n\t"\ + "addl $16,%esp\n\t"\ + "jmp " LABEL "_done\n\t"\ + LABEL "_local:") +#else +# define JITDO_PUTFIELD(HANDLE, VAL, LABEL) +#endif /* JITDO */ + #define PUTFIELD_ST24(OPTOP1_REG, OPTOP2_REG, STATE) \ FIELD_ACC(OPTOP2_REG, putfield, STATE);\ - OBJ_SETSLOT(OPTOP2_REG, %eax, OPTOP1_REG) + JITDO_PUTFIELD(OPTOP2_REG, OPTOP1_REG, "putfield_st" #STATE);\ + OBJ_SETSLOT(OPTOP2_REG, %eax, OPTOP1_REG);\ + __asm__("putfield_st" #STATE "_done:") CODE(opc_putfield, putfield, ST0, ST0) { __asm__("popl %ecx\n\t" @@ -3193,11 +3355,36 @@ ILOAD_DEBUG1(%edx); } +#ifdef JITDO +# define JITDO_PUTFIELD2(HANDLE, VAL_LOW, VAL_HIGH, LABEL) \ + __asm__("pushl %eax\n\tpushl %edi"); /* save */\ + JUMP_IF_NOT_REMOTE(LABEL "_local");\ + __asm__("movl (%esp),%eax"); /* %eax = TOS(%edi) */\ + JUMP_IF_NOT_PROXY(%eax, LABEL "_local"); /* 1st arg must not be %edi */\ + __asm__("popl %edi\n\tpopl %eax"); /* restore */\ + \ + __asm__("pushl " #VAL_HIGH "\n\t"/* value */\ + "pushl " #VAL_LOW "\n\t"/* value */\ + "pushl %eax\n\t" /* slot */\ + "pushl " #HANDLE); /* obj (Proxy) */\ + __asm__("pushl %0" : : "m" (ee)); /* ee */\ + \ + __asm__("call " SYMBOL(proxy_put64field) "@PLT\n\t"\ + "addl $20,%esp\n\t"\ + "jmp " LABEL "_done\n\t"\ + LABEL "_local:\n\t"\ + "popl %edi\n\tpopl %eax") /* restore */ +#else +# define JITDO_PUTFIELD2(HANDLE, VAL_LOW, VAL_HIGH, LABEL) +#endif /* JITDO */ + /* const: slot */ #define PUTFIELD2_ST24(OPTOP1_REG, OPTOP2_REG, STATE) \ __asm__("popl %edi"); /* edi = handle */\ FIELD_ACC(%edi, putfield2, STATE);\ - OBJ_SETSLOT2(%edi, %eax, OPTOP1_REG, OPTOP2_REG) + JITDO_PUTFIELD2(%edi, OPTOP1_REG, OPTOP2_REG, "putfield2_st" #STATE);\ + OBJ_SETSLOT2(%edi, %eax, OPTOP1_REG, OPTOP2_REG);\ + __asm__("putfild2_st" #STATE "_done:") CODE(opc_putfield2, putfield2, ST0, ST0) { __asm__("popl %ecx\n\t" @@ -3265,7 +3452,7 @@ CALL_INVOKEMETHOD_FUNC;\ CALL_INVOKEMETHOD_DEBUG1;\ \ - __asm__("popl %esi\n\tpopl %edi"); /* restore */\ + __asm__("popl %edi\n\tpopl %esi"); /* restore */\ \ __asm__("popl %ecx"); /* free local var space */\ __asm__("addl %ecx,%esp");\ @@ -3277,13 +3464,14 @@ eax: return value from invokeMethod()\ edi: arg_size */\ \ + __asm__(LABEL "_restack:");\ /* adjust optop */\ __asm__("leal (%esp,%edi,4),%esp");/* esp += (args_size * 4) */\ /* if (eax < 0) goto exception_handler */\ __asm__("testl %eax,%eax\n\t"\ "jl " STR(ADDR_EXC));\ \ - __asm__("jz " LABEL "_restack_done"); /* if (ret_size == 0) done */\ + __asm__("jz " LABEL "_done"); /* if (ret_size == 0) done */\ \ /* edi = ee->current_frame->optop */\ {\ @@ -3299,29 +3487,84 @@ __asm__("subl $8," FRAME_OPTOP(%ecx) "\n\t"\ "pushl -4(%edi)\n\t"\ "pushl -8(%edi)\n\t"\ - "jmp " LABEL "_restack_done\n\t"\ - LABEL "_1:");\ + "jmp " LABEL "_done\n\t"\ + LABEL "_1:");\ /* ret_size: 1 */\ __asm__("subl $4," FRAME_OPTOP(%ecx) "\n\t"\ "pushl -4(%edi)\n\t"\ - LABEL "_restack_done:\n\t") + LABEL "_done:") /* now state 0 */ + +#ifdef JITDO +# define JITDO_INVOKE(LABEL) \ + __asm__("movl %esp,%ecx"); /* save %esp to %ecx */\ + \ + __asm__("pushl %edi"); /* save */\ + JUMP_IF_NOT_REMOTE(LABEL "_local");\ + JUMP_IF_NOT_PROXY(%edx /* is obj */, LABEL "_local");\ + \ + /* call Proxy#* at local */\ + __asm__("pushl %eax"); /* save */\ + METHOD_CLAZZ(%eax,%eax);\ + CB_METHODTABLE(%eax,%eax);\ + __asm__("movl " SYMBOL(proxy_methodtable) "@GOT(%ebx),%edi");\ + __asm__("movl (%edi),%edi");\ +DEBUG_IN;\ +__asm__("pushl %edi\n\tpushl %eax");\ +PUSH_CONSTSTR("eax: 0x%08x, edi: 0x%08x\n");\ +__asm__("call printf@PLT\n\t"\ + "addl $12,%esp");\ +FFLUSH;\ +DEBUG_OUT;\ + __asm__("cmpl %eax,%edi\n\t"\ + "popl %eax\n\t" /* restore */\ + "jz " LABEL "_local");\ + \ + __asm__("pushl %esi");\ + \ + __asm__("pushl %ecx\n\t" /* stack pointer */\ + "pushl " METHOD_SIGNATURE(%eax) "\n\t"\ + "pushl " METHOD_NAME(%eax) "\n\t"\ + "pushl %edx"); /* obj (Proxy) */\ + __asm__("pushl %0" : : "m" (ee)); /* ee */\ + __asm__("call " SYMBOL(proxy_invoke) "@PLT\n\t"\ + "addl $20,%esp");\ + \ + __asm__("popl %esi\n\tpopl %edi");\ + /* %eax: ret_size, %edi: args_size */\ + \ + __asm__("jmp " LABEL "_restack\n\t"\ + LABEL "_local:");\ + __asm__("popl %edi") /* restore */ +#else +# define JITDO_INVOKE(LABEL) +#endif /* JITDO */ + #define INVOKE_ST0(VOP, LABEL) \ __asm__("movl $" STR(CONST) ",%edi"); /* edi = args_size */\ bytepcoff = BYTEPCOFF;\ - TGTOBJ_##VOP(LABEL); /* edx = obj */\ + \ + TGTOBJ_##VOP(LABEL, 0); /* edx = obj */\ + /* TGTOBJ_* performs null check, too */\ \ METHODBLOCK_##VOP(LABEL); /* eax = method */\ \ + JITDO_INVOKE_##VOP(LABEL);\ + \ VARSPACE_##VOP(LABEL); /* ecx = local var. space */\ \ __asm__("subl %ecx,%esp\n\t"\ "pushl %ecx\n\t"\ - "leal 4(%esp,%ecx),%ecx\n\t" /* ecx = original esp */\ - "pushl %edi\n\tpushl %esi"); /* save */\ + "leal 4(%esp,%ecx),%ecx"); /* ecx = original esp */\ \ - __asm__("pushl %ecx"); /* origianl %esp */\ + __asm__("pushl %esi\n\tpushl %edi"); /* save */\ + \ + /*\ + __asm__("leal -4(%ecx,%edi,4),%ecx");\ + /* ecx = original esp + (args_size * 4 - 1) */\ + \ + __asm__("pushl %ecx"); /* origianl esp */\ __asm__("pushl %0" : : "m" (bytepcoff)); /* bytepcoff */\ __asm__("pushl %eax\n\t" /* method */\ "pushl %edx"); /* obj */\ @@ -3351,15 +3594,57 @@ } -#define TGTOBJ_VIRTUAL(LABEL) \ +#define TGTOBJ_VIRTUAL(LABEL, STATE) \ __asm__("movl -4(%esp,%edi,4),%edx");\ - NULL_TEST(%edx, LABEL) + NULL_TEST(%edx, LABEL, STATE) +#ifdef JITDO +# define METHODBLOCK_VIRTUAL(LABEL) \ + __asm__("pushl %edi"); /* save */\ + OBJ_ARRAY_METHODTABLE(%edx, %ecx, LABEL); /* ecx = obj_array_..(obj) */\ + /* debug code */\ + \ + JUMP_IF_NOT_REMOTE(LABEL "_not_proxy");\ + \ + METHODTABLE_OF_PROXY(%edi);\ + __asm__("cmpl %ecx,%edi\n\t"\ + "jnz " LABEL "_not_proxy");\ +DEBUG_IN;\ +PUSH_CONSTSTR("METDODBLOCK_VIRTUAL: Proxy is found.\n");\ +__asm__("call printf@PLT\n\t"\ + "addl $4,%esp");\ +FFLUSH;\ +DEBUG_OUT;\ + PROXY_CLAZZ(%edx, %ecx); /* ecx = Proxy.clazz */\ +DEBUG_IN;\ +__asm__("pushl %ecx");\ +CB_NAME(%ecx, %ecx);\ +__asm__("pushl %ecx");\ +PUSH_CONSTSTR(" Proxy.clazz: %s 0x%08x\n");\ +__asm__("call printf@PLT\n\t"\ + "addl $12,%esp");\ +FFLUSH;\ +DEBUG_OUT;\ + CB_METHODTABLE(%ecx, %ecx); /* ecx = methodtable of Proxy.clazz*/\ +DEBUG_IN;\ +__asm__("pushl %ecx");\ +PUSH_CONSTSTR(" methodtable: 0x%08x\n");\ +__asm__("call printf@PLT\n\t"\ + "addl $8,%esp");\ +FFLUSH;\ +DEBUG_OUT;\ + \ + __asm__(LABEL "_not_proxy:");\ + __asm__("popl %edi"); /* restore */\ + __asm__("movl $" STR(CONST) ",%eax"); /* eax = methodIndex */\ + MT_SLOT(%ecx, %eax, %eax) /* eax = method */ +#else #define METHODBLOCK_VIRTUAL(LABEL) \ /* get methodblock */\ OBJ_ARRAY_METHODTABLE(%edx, %ecx, LABEL); /* ecx = obj_array_..(obj) */\ __asm__("movl $" STR(CONST) ",%eax"); /* eax = methodIndex */\ MT_SLOT(%ecx, %eax, %eax) /* eax = method */ +#endif /* JITDO */ #define VARSPACE_VIRTUAL(LABEL) \ /* allocate local var space */\ @@ -3372,15 +3657,22 @@ "xorl %ecx,%ecx\n\t" /* ecx = 0 */\ LABEL "_nlocal_done:") -#define TGTOBJ_SPECIAL(LABEL) TGTOBJ_VIRTUAL(LABEL) +#define JITDO_INVOKE_VIRTUAL(LABEL) JITDO_INVOKE(LABEL) + +#define TGTOBJ_SPECIAL(LABEL, STATE) TGTOBJ_VIRTUAL(LABEL, STATE) #define METHODBLOCK_SPECIAL(LABEL) __asm__("movl $" STR(CONST) ",%eax") #define VARSPACE_SPECIAL(LABEL) __asm__("movl $" STR(CONST) ",%ecx") +#define JITDO_INVOKE_SPECIAL(LABEL) JITDO_INVOKE(LABEL) -#define TGTOBJ_STATIC(LABEL) __asm__("xorl %edx,%edx") -#define METHODBLOCK_STATIC(LABEL) __asm__("movl $" STR(CONST) ",%eax") +#define TGTOBJ_STATIC(LABEL, STATE) + /* null instead of 0 clear (__asm__("xorl %edx,%edx")) */ +#define METHODBLOCK_STATIC(LABEL) \ + __asm__("movl $" STR(CONST) ",%eax");\ + METHOD_CLAZZ(%eax,%edx) /* edx = cbHandle(method->fb.clazz) */ #define VARSPACE_STATIC(LABEL) __asm__("movl $" STR(CONST) ",%ecx") +#define JITDO_INVOKE_STATIC(LABEL) /* nothing */ -#define TGTOBJ_INTERFACE(LABEL) TGTOBJ_VIRTUAL(LABEL) +#define TGTOBJ_INTERFACE(LABEL, STATE) TGTOBJ_VIRTUAL(LABEL, STATE) #define METHODBLOCK_INTERFACE(LABEL) \ /* get methodblock: call getInterfaceMethod() */\ @@ -3395,6 +3687,7 @@ __asm__("popl %edx\n\tpopl %edi") #define VARSPACE_INTERFACE(LABEL) VARSPACE_VIRTUAL(LABEL) +#define JITDO_INVOKE_INTERFACE(LABEL) JITDO_INVOKE(LABEL) #ifdef RUNTIME_DEBUG # define CALL_GETINTFMETHOD \ @@ -3477,7 +3770,7 @@ \ __asm__("testl %eax,%eax\n\t"\ "jnz " LABEL "_testok");\ - SIGNAL_ERROR0(IllegalAccessError);\ + SIGNAL_ERROR0(IllegalAccessError, STATE);\ __asm__(LABEL "_testok:") #else # define NEW_TEST(CB_REG, LABEL, STATE) @@ -3509,15 +3802,62 @@ # define NEW_DEBUG2(OBJ_REG) #endif +#ifdef JITDO +# define JITDO_NEW(CB_REG, DST_REG, LABEL, STATE) \ + JUMP_IF_NOT_REMOTE(LABEL "_local");\ + \ + { /* %edi = ee */\ + register ExecEnv *cur_ee asm("edi");\ + cur_ee = ee;\ + }\ + \ + /* local operation if remote VM addr is null */\ + __asm__("movl " EE_REMOTE_ADDR(%edi) ",%eax\n\t"\ + "testl %eax,%eax\n\t"\ + "jz " LABEL "_local");\ + \ + /* call isCopyable() */\ + __asm__("pushl %edi");\ + FUNCCALL_IN(STATE);\ + __asm__("pushl " #CB_REG "\n\t"\ + "pushl %edi\n\t"\ + "call " SYMBOL(isCopyable) "@PLT");\ + __asm__("addl $4,%esp\n\t"\ + "popl " #CB_REG);\ + FUNCCALL_OUT(STATE);\ + __asm__("popl %edi");\ + __asm__("testl %eax,%eax\n\t"\ + "jnz " LABEL "_local");\ + \ + /* call proxy_new() */\ + __asm__("pushl %edi");\ + FUNCCALL_IN(STATE);\ + __asm__("pushl " #CB_REG "\n\t"\ + "pushl " EE_REMOTE_ADDR(%edi) "\n\t"\ + "pushl %edi\n\t" /* ee */\ + "call " SYMBOL(proxy_new) "@PLT\n\t"\ + "addl $12,%esp");\ + FUNCCALL_OUT(STATE);\ + __asm__("popl %edi");\ + \ + JUMP_IF_EXC_HASNT_OCCURRED(%edi /* is ee */, LABEL "_done");\ + SIGNAL_ERROR_JUMP(STATE);\ + __asm__("jmp " LABEL "_done\n\t"\ + LABEL "_local:") +#else +# define JITDO_NEW(CB_REG, DST_REG, LABEL, STATE) +#endif /* JITDO */ + +/* stuff to rewrite code */ #if defined(linux) # ifdef RUNTIME_DEBUG -# define NEW_REWRITE_OFFSET_0 0x35 +# define NEW_REWRITE_OFFSET_0 0x32 # else # define NEW_REWRITE_OFFSET_0 5 # endif #elif defined(__FreeBSD__) # ifdef RUNTIME_DEBUG -# define NEW_REWRITE_OFFSET_0 0x3a +# define NEW_REWRITE_OFFSET_0 0x37 # else # define NEW_REWRITE_OFFSET_0 5 # endif @@ -3552,7 +3892,7 @@ CB_ACCESS(CB_REG, %eax);\ __asm__("testb $6,%al\n\t"\ "jz " LABEL);\ - SIGNAL_ERROR0(InstantiationError);\ + SIGNAL_ERROR0(InstantiationError, STATE);\ __asm__(LABEL ":");\ \ NEW_TEST(CB_REG, LABEL, STATE);\ @@ -3563,6 +3903,8 @@ \ NEW_DEBUG1(CB_REG);\ \ + /* instantiate */\ + JITDO_NEW(CB_REG, DST_REG, LABEL, STATE);\ /* call newobject() */\ FUNCCALL_IN(STATE);\ __asm__("pushl %0" : : "m" (ee)); /* ee */\ @@ -3572,8 +3914,10 @@ "addl $12,%esp");\ FUNCCALL_OUT(STATE);\ NEW_DEBUG2(%eax);\ + __asm__(LABEL "_done:");\ __asm__("movl %eax," #DST_REG) + CODE(opc_new, new, ST0, ST1) { NEW(%edx, %edx, NEW_REWRITE_OFFSET_0, "new_st0", 0); } @@ -3598,7 +3942,7 @@ # define NEWARRAY_TEST(OPTOP1_REG, LABEL, STATE) \ __asm__("testl " #OPTOP1_REG "," #OPTOP1_REG "\n\t"\ "jge " LABEL "_1");\ - SIGNAL_ERROR0(NegativeArraySizeException);\ + SIGNAL_ERROR0(NegativeArraySizeException, STATE);\ __asm__(LABEL "_1:") #else # define NEWARRAY_TEST(OPTOP1_REG, LABEL, STATE) @@ -3633,9 +3977,9 @@ "addl $8,%esp");\ FUNCCALL_OUT(STATE);\ __asm__("testl %eax,%eax\n\t"\ - "jnz " LABEL "_2");\ - SIGNAL_ERROR0(OutOfMemoryError);\ - __asm__(LABEL "_2:\n\t"\ + "jnz " LABEL "_done");\ + SIGNAL_ERROR0(OutOfMemoryError, STATE);\ + __asm__(LABEL "_done:\n\t"\ "movl %eax," #OPTOP1_REG) /* store to dst. */ CODE(opc_newarray, newarray, ST0, ST1) { @@ -3669,7 +4013,7 @@ FUNCCALL_OUT(STATE);\ __asm__("testl %eax,%eax\n\t"\ "jnz " LABEL "_2");\ - SIGNAL_ERROR0(OutOfMemoryError);\ + SIGNAL_ERROR0(OutOfMemoryError, STATE);\ __asm__(LABEL "_2:");\ \ UNHAND(%eax, %edi);\ @@ -3699,7 +4043,7 @@ # define ARRAYLENGTH_TEST(OPTOP1_REG, STATE) \ __asm__("testl " #OPTOP1_REG "," #OPTOP1_REG "\n\t"\ "jnz arylen_st" #STATE "_1");\ - SIGNAL_ERROR0(NullPointerException);\ + SIGNAL_ERROR0(NullPointerException, STATE);\ __asm__("arylen_st" #STATE "_1:") #else # define ARRAYLENGTH_TEST(OPTOP1_REG, STATE) @@ -3729,7 +4073,7 @@ /* athrow */ #define ATHROW(OPTOP1_REG, STATE) \ - NULL_TEST(OPTOP1_REG, "athrow_st" #STATE "_1");\ + NULL_TEST(OPTOP1_REG, "athrow_st" #STATE "_1", STATE);\ \ /* macro exceptionThrow(ee, obj) */\ {\ @@ -3763,71 +4107,123 @@ /* checkcast */ /* const: cb */ +#ifdef JITDO +# define JITDO_CHECKCAST(OPTOP1_REG, LABEL, STATE) \ + /* compare handle->methods with cb_of_Proxy->methodtable */\ + JUMP_IF_NOT_REMOTE(LABEL "_local");\ + JUMP_IF_NOT_PROXY(%##OPTOP1_REG, LABEL "_local");\ + {\ + register HNET_shudo_jitdo_Proxy *h asm(#OPTOP1_REG);\ + register ClassNET_shudo_jitdo_Proxy *edi asm("edi");\ + register Hjava_lang_Class *clz asm("eax");\ + \ + edi = unhand(h);\ + clz = edi->clazz;\ + } /* eax = Proxy.clazz */\ + __asm__("movl $" STR(CONST) ",%edi\n\t" /* cb */\ + "cmpl %eax,%edi\n\t"\ + "jnz " LABEL "_fail\n\t"\ + "jmp " LABEL "_done\n\t"\ + LABEL "_local:"); +#else +# define JITDO_CHECKCAST(OPTOP1_REG, LABEL, STATE) +#endif /* JITDO */ + #define CHECKCAST(OPTOP1_REG, LABEL, STATE) \ + __asm__("testl %" #OPTOP1_REG ",%" #OPTOP1_REG "\n\t"\ + "jz " LABEL "_done");\ + JITDO_CHECKCAST(OPTOP1_REG, LABEL, STATE);\ FUNCCALL_IN(STATE);\ __asm__("pushl %0" : : "m" (ee)); /* ee */\ __asm__("pushl $" STR(CONST) "\n\t" /* cb */\ - "pushl " #OPTOP1_REG "\n\t"\ + "pushl %" #OPTOP1_REG "\n\t"\ "call " SYMBOL(is_instance_of) "@PLT\n\t"\ "addl $12,%esp");\ FUNCCALL_OUT(STATE);\ __asm__("testl %eax,%eax\n\t"\ - "jnz " LABEL);\ - SIGNAL_ERROR0(ClassCastException);\ - __asm__(LABEL ":") + "jnz " LABEL "_done");\ + __asm__(LABEL "_fail:");\ + SIGNAL_ERROR0(ClassCastException, STATE);\ + __asm__(LABEL "_done:") CODE(opc_checkcast, checkcast, ST0, ST1) { __asm__("popl %edx"); /* now state 1 */ - CHECKCAST(%edx, "checkcast_st0", 1); + CHECKCAST(edx, "checkcast_st0", 1); } CODE(opc_checkcast, checkcast, ST1, ST1) { - CHECKCAST(%edx, "checkcast_st1", 1); + CHECKCAST(edx, "checkcast_st1", 1); } CODE(opc_checkcast, checkcast, ST2, ST2) { - CHECKCAST(%ecx, "checkcast_st2", 2); + CHECKCAST(ecx, "checkcast_st2", 2); } CODE(opc_checkcast, checkcast, ST3, ST3) { - CHECKCAST(%ecx, "checkcast_st3", 3); + CHECKCAST(ecx, "checkcast_st3", 3); } CODE(opc_checkcast, checkcast, ST4, ST4) { - CHECKCAST(%edx, "checkcast_st4", 4); + CHECKCAST(edx, "checkcast_st4", 4); } /* instanceof */ /* const: cb */ +#ifdef JITDO +# define JITDO_INSTANCEOF(OPTOP1_REG, LABEL, STATE) \ + /* compare handle->methods with cb_of_Proxy->methodtable */\ + JUMP_IF_NOT_PROXY(%##OPTOP1_REG, LABEL "_local");\ + {\ + register HNET_shudo_jitdo_Proxy *h asm(#OPTOP1_REG);\ + register ClassNET_shudo_jitdo_Proxy *edi asm("edi");\ + register Hjava_lang_Class *clz asm("eax");\ + \ + edi = unhand(h);\ + clz = edi->clazz;\ + } /* eax = Proxy.clazz */\ + __asm__("movl $" STR(CONST) ",%edi\n\t" /* cb */\ + "cmpl %eax,%edi\n\t"\ + "jz " LABEL "_false\n\t"\ + "movl $1,%" #OPTOP1_REG "\n\t"\ + "jmp " LABEL "_done\n\t"\ + LABEL "_false:"\ + "movl $0,%" #OPTOP1_REG "\n\t"\ + "jmp " LABEL "_done\n\t"\ + LABEL "_local:"); +#else +# define JITDO_INSTANCEOF(OPTOP1_REG, LABEL, STATE) +#endif /* JITDO */ + #define INSTANCEOF(OPTOP1_REG, LABEL, STATE) \ - __asm__("testl " #OPTOP1_REG "," #OPTOP1_REG "\n\t"\ + __asm__("testl %" #OPTOP1_REG ",%" #OPTOP1_REG "\n\t"\ "jz " LABEL "_done");\ + JITDO_INSTANCEOF(OPTOP1_REG, LABEL, STATE);\ FUNCCALL_IN(STATE);\ __asm__("pushl %0" : : "m" (ee)); /* ee */\ __asm__("pushl $" STR(CONST) "\n\t"\ - "pushl " #OPTOP1_REG "\n\t"\ + "pushl %" #OPTOP1_REG "\n\t"\ "call " SYMBOL(is_instance_of) "@PLT\n\t"\ "addl $12,%esp");\ FUNCCALL_OUT(STATE);\ - __asm__("movl %eax," #OPTOP1_REG "\n\t"\ + __asm__("movl %eax,%" #OPTOP1_REG "\n\t"\ LABEL "_done:") CODE(opc_instanceof, instanceof, ST0, ST1) { __asm__("popl %edx"); /* now state 1 */ - INSTANCEOF(%edx, "instanceof_st0", 1); + INSTANCEOF(edx, "instanceof_st0", 1); } CODE(opc_instanceof, instanceof, ST1, ST1) { - INSTANCEOF(%edx, "instanceof_st1", 1); + INSTANCEOF(edx, "instanceof_st1", 1); } CODE(opc_instanceof, instanceof, ST2, ST2) { - INSTANCEOF(%ecx, "instanceof_st2", 2); + INSTANCEOF(ecx, "instanceof_st2", 2); } CODE(opc_instanceof, instanceof, ST3, ST3) { - INSTANCEOF(%ecx, "instanceof_st3", 3); + INSTANCEOF(ecx, "instanceof_st3", 3); } CODE(opc_instanceof, instanceof, ST4, ST4) { - INSTANCEOF(%edx, "instanceof_st4", 4); + INSTANCEOF(edx, "instanceof_st4", 4); } /* monitorenter, monitorexit */ #define MONITOR(OPTOP1_REG, FUNCNAME, LABEL, STATE) \ - NULL_TEST(OPTOP1_REG, LABEL "_1");\ + NULL_TEST(OPTOP1_REG, LABEL "_1", STATE);\ OBJ_MONITOR(OPTOP1_REG, OPTOP1_REG);\ FUNCCALL_IN(STATE);\ __asm__("pushl " #OPTOP1_REG "\n\t"\ @@ -3861,11 +4257,11 @@ #define MULTIANEWARRAY_TEST(STATE) \ __asm__("cmpl $-1,%eax\n\t" /* eax is returned by multianewarray() */\ "jne mulary_st" #STATE "_1");\ - SIGNAL_ERROR0(NegativeArraySizeException);\ + SIGNAL_ERROR0(NegativeArraySizeException, STATE);\ __asm__("mulary_st" #STATE "_1:");\ __asm__("testl %eax,%eax\n\t"\ "jnz mulary_st" #STATE "_2");\ - SIGNAL_ERROR0(OutOfMemoryError);\ + SIGNAL_ERROR0(OutOfMemoryError, STATE);\ __asm__("mulary_st" #STATE "_2:") #ifdef RUNTIME_DEBUG @@ -3929,7 +4325,7 @@ "leal (%esp,%edi,4),%esp\n\t"\ "testl %eax,%eax\n\t"\ "jnz invign_st" #STATE "_done");\ - SIGNAL_ERROR0(NullPointerException);\ + SIGNAL_ERROR0(NullPointerException, STATE);\ __asm__("invign_st" #STATE "_done:") #define INVOKEIGNORED_NOCHECK_ST0(STATE) \ @@ -3995,19 +4391,19 @@ /* nonnull_quick */ CODE(opc_nonnull_quick, nonnull_quick, ST0, ST0) { __asm__("popl %edx"); /* now state 1 */ - NULL_TEST(%edx, "nonnull_quick_st0_1"); + NULL_TEST(%edx, "nonnull_quick_st0_1", 0); } CODE(opc_nonnull_quick, nonnull_quick, ST1, ST0) { - NULL_TEST(%edx, "nonnull_quick_st1_1"); + NULL_TEST(%edx, "nonnull_quick_st1_1", 1); } CODE(opc_nonnull_quick, nonnull_quick, ST2, ST1) { - NULL_TEST(%ecx, "nonnull_quick_st2_1"); + NULL_TEST(%ecx, "nonnull_quick_st2_1", 2); } CODE(opc_nonnull_quick, nonnull_quick, ST3, ST0) { - NULL_TEST(%ecx, "nonnull_quick_st3_1"); + NULL_TEST(%ecx, "nonnull_quick_st3_1", 3); } CODE(opc_nonnull_quick, nonnull_quick, ST4, ST3) { - NULL_TEST(%edx, "nonnull_quick_st4_1"); + NULL_TEST(%edx, "nonnull_quick_st4_1", 4); } CODEEND; diff -aruN shujit-0.2.3/code.h shujit-0.2.4/code.h --- shujit-0.2.3/code.h Mon Sep 28 19:42:09 1998 +++ shujit-0.2.4/code.h Sun Jan 3 17:27:04 1999 @@ -1,5 +1,5 @@ /* - * Copyright (C) 1998 + * Copyright (C) 1998,1999 * SHUDO Kazuyuki * * Permission to use, copy, modify and distribute this software @@ -83,8 +83,8 @@ * utilities */ -#if 0 -#define PUSH_CONSTSTR(STR) __asm__("PUSH %0" : : "m" (* STR)) +#ifdef GCC27 +#define PUSH_CONSTSTR(STR) __asm__("PUSH %0" : : "m" (STR)) #else #define PUSH_CONSTSTR(STR) __asm__("pushl %0" : : "m" (STR)) #endif @@ -138,27 +138,38 @@ #define FUNCCALL_OUT_4 __asm__("popl %edx\n\tpopl %ecx\n\tpopl %esi") -#define SIGNAL_ERROR_CORE(KIND) \ +#define STATETO00 +#define STATETO10 __asm__("pushl %edx") +#define STATETO20 __asm__("pushl %edx\n\tpushl %ecx") +#define STATETO30 __asm__("pushl %ecx") +#define STATETO40 __asm__("pushl %ecx\n\tpushl %edx") + +#define SIGNAL_ERROR_JUMP(STATE) \ + bytepcoff = 0x626262;\ + STATETO##STATE##0;\ + __asm__("jmp " STR(ADDR_EXC)) + +#define SIGNAL_ERROR_CORE(KIND, STATE) \ PUSH_CONSTSTR(JAVAPKG #KIND); /* char *ename */\ __asm__("pushl %0" : : "m" (ee)); /* ExecEnv *ee */\ __asm__("call " SYMBOL(SignalError) "@PLT\n\t"\ "addl $12,%esp");\ - bytepcoff = 0x626262;\ - __asm__("jmp " STR(ADDR_EXC)) + SIGNAL_ERROR_JUMP(STATE) -#define SIGNAL_ERROR0(KIND) \ +#define SIGNAL_ERROR0(KIND, STATE) \ __asm__("pushl $0"); /* char *DetailMessage */\ - SIGNAL_ERROR_CORE(KIND) + SIGNAL_ERROR_CORE(KIND, STATE) -#define SIGNAL_ERROR1(KIND, MSG) \ +#define SIGNAL_ERROR1(KIND, MSG, STATE) \ PUSH_CONSTSTR(MSG); /* char *DetailMessage */\ - SIGNAL_ERROR_CORE(KIND) + SIGNAL_ERROR_CORE(KIND, STATE) + #ifndef NO_CHECK -# define NULL_TEST(REG, LABEL) \ +# define NULL_TEST(REG, LABEL, STATE) \ __asm__("testl " #REG "," #REG "\n\t"\ "jnz " LABEL);\ - SIGNAL_ERROR0(NullPointerException);\ + SIGNAL_ERROR0(NullPointerException, STATE);\ __asm__(LABEL ":") #else # define NULL_TEST(REG, LABEL) @@ -175,20 +186,19 @@ #ifdef RUNTIME_DEBUG # define CODE_DEBUG(LABEL) \ - if (runtime_debug) {\ __asm__("pushl %eax\n\t"\ - "movl %esp,%eax\n\t"\ - "addl $4,%eax");\ - DEBUG_IN;\ - __asm__("pushl %eax"); /* %esp */\ - __asm__("pushl %0" : : "m" (ee));\ - PUSH_CONSTSTR(">" LABEL " %x %x\n");\ + "movl %esp,%eax");\ + DEBUG_IN;\ + if (runtime_debug) {\ + __asm__("addl $4,%eax\n\t"\ + "pushl %eax"); /* %esp */\ + PUSH_CONSTSTR(">" LABEL " %x\n");\ __asm__("call " SYMBOL(printf) "@PLT\n\t"\ - "addl $12,%esp");\ + "addl $8,%esp");\ FFLUSH;\ - DEBUG_OUT;\ - __asm__("popl %eax");\ - } + }\ + DEBUG_OUT;\ + __asm__("popl %eax"); #else # define CODE_DEBUG(LABEL) #endif @@ -217,18 +227,18 @@ #define OBJ_LENGTH(HANDLE, DST) \ __asm__("movl 4(" #HANDLE ")," #DST "\n\t"\ "shrl $5," #DST) -#define OBJ_METHODTABLE(HANDLE, DST, LABEL) \ +#define OBJ_METHODTABLE(HANDLE, DST) \ __asm__("movl 4(" #HANDLE ")," #DST) #define OBJ_ARRAY_METHODTABLE(HANDLE, DST, LABEL) \ __asm__("movl 4(" #HANDLE ")," #DST "\n\t"\ "movl " #DST ",%eax\n\t"\ "andl $31,%eax\n\t"\ "cmpl $" STR(T_NORMAL_OBJECT) ",%eax\n\t"\ - "je " LABEL "_done");\ + "je " LABEL "_mtdone");\ __asm__("movl %0,%" #DST : : "m" (classJavaLangObject));\ __asm__("movl (" #DST "),%eax\n\t"\ "movl 48(%eax)," #DST);\ - __asm__(LABEL "_done:") + __asm__(LABEL "_mtdone:") /* destroy %eax */ #define MT_SLOT(MTBL, SLOT, DST) \ @@ -279,6 +289,15 @@ "movl 48(%edi)," #DST) #define EE_CURRENTFRAME(EE) "4(" #EE ")" +#define EE_EXCEPTIONKIND(EE) "12(" #EE ")" + +#define JUMP_IF_EXC_HASNT_OCCURRED(EE, LABEL) \ + __asm__("movl " EE_EXCEPTIONKIND(EE) ",%edi\n\t"\ + "testl %edi,%edi\n\t"\ + "jz " LABEL) +#define EXCEPTION_CLEAR(EE) \ + __asm__("movl $0," EE_EXCEPTIONKIND(EE)); + #define FRAME_OPTOP(FRAME) "8(" #FRAME ")" #define FRAME_VARS(FRAME) "12(" #FRAME ")" #define FRAME_PREV(FRAME) "16(" #FRAME ")" @@ -286,11 +305,48 @@ #define FRAME_CURRENTMETHOD(FRAME) "28(" #FRAME ")" #define FRAME_OSTACK(FRAME) "40(" #FRAME ")" + + #define METHOD_NLOCALS(MB, DST) \ __asm__("movzwl 64(" #MB ")," #DST) #define METHOD_CLAZZ(MB, DST) \ __asm__("movl (" #MB ")," #DST) -#define METHOD_SIGNATURE(MB, DST) \ - __asm__("movl 4(" #MB ")," #DST) -#define METHOD_NAME(MB, DST) \ - __asm__("movl 8(" #MB ")," #DST) +#define METHOD_SIGNATURE(MB) "4(" #MB ")" +#define METHOD_NAME(MB) "8(" #MB ")" + + +#ifdef JITDO +/* + * JITDO related stuff + */ +#define EE_REMOTE_FLAG(EE) "61(" #EE ")" + /* ee->alloc_cache.cache_pad[0] */ +#define EE_REMOTE_ADDR(EE) "16(" #EE ")" + /* ee->exception.exc */ + +#define JUMP_IF_NOT_REMOTE(LABEL) \ + { /* %edi = ee */\ + register ExecEnv *cur_ee asm("edi");\ + cur_ee = ee;\ + }\ + __asm__("movsbl " EE_REMOTE_FLAG(%edi) ",%edi");\ + __asm__("testl %edi,%edi\n\t"\ + "jz " LABEL) + /* break %edi */ + +#define METHODTABLE_OF_PROXY(DST) \ + __asm__("movl " SYMBOL(proxy_methodtable) "@GOT(%ebx)," #DST "\n\t"\ + "movl (" #DST ")," #DST); + /* break no registers */ + +#define JUMP_IF_NOT_PROXY(HANDLE_REG /* must not be %edi */, LABEL) \ + METHODTABLE_OF_PROXY(%edi);\ + __asm__("cmpl 4(" #HANDLE_REG "),%edi\n\t"\ + "jnz " LABEL) + /* break %edi */ + +#define PROXY_CLAZZ(HANDLE, DST) \ + UNHAND(HANDLE, DST);\ + __asm__("movl 4(" #DST ")," #DST); + +#endif /* JITDO */ diff -aruN shujit-0.2.3/codesize shujit-0.2.4/codesize --- shujit-0.2.3/codesize Mon Sep 21 22:13:53 1998 +++ shujit-0.2.4/codesize Thu Jan 1 09:00:00 1970 @@ -1,44 +0,0 @@ -生成コードのサイズ - -methodhead (eb, 235) - 1f (31) -exception_handler (ec, 236) - 29 (41) -methodtail (ed, 237) - 9 (9) - -1. 次のクラスでテスト - class DoNothing { - public static void main(String[] argv) { - } - } - -* javac - -% javac -g -O DoNothing.java - -num of byte code inst: 29599 -byte code size (byte): 59544 -native code size (byte): 1069178 -native code size / num of inst: 36.1221 -native code size / byte code size: 17.9561 - -* 実行 - -% java DoNothing - -num of byte code inst: 346 -byte code size (byte): 590 -native code size (byte): 12053 -native code size / num of inst: 34.8353 -native code size / byte code size: 20.4288 - -2. E2 暗号化 - -% java EvalLargeData - -num of byte code inst: 9899 -byte code size (byte): 13133 -native code size (byte): 191170 -native code size / num of inst: 19.3121 -native code size / byte code size: 14.5565 diff -aruN shujit-0.2.3/compile.c shujit-0.2.4/compile.c --- shujit-0.2.3/compile.c Sun Oct 4 12:30:38 1998 +++ shujit-0.2.4/compile.c Thu Jan 7 14:19:23 1999 @@ -1,5 +1,5 @@ /* - * Copyright (C) 1998 + * Copyright (C) 1998,1999 * SHUDO Kazuyuki * * Permission to use, copy, modify and distribute this software @@ -49,7 +49,7 @@ */ int compileMethod(struct methodblock *mb) { CompilerContext *cc; - CodeInfo *info; + CodeInfo *info = (CodeInfo *)mb->CompiledCodeInfo; #ifdef COMPILE_DEBUG printf("\n"); @@ -72,6 +72,13 @@ fflush(stdout); #endif + + if (mb->fb.access & (ACC_ABSTRACT | ACC_NATIVE)) { + /* needless to compile */ + return 0; + } + + if (!compiler_enabled) { #ifdef COMPILE_DEBUG printf(" compiler has been disabled.\n return.\n"); @@ -80,23 +87,12 @@ return 0; } - if (mb->fb.access & (ACC_ABSTRACT | ACC_NATIVE)) { - /* needless to compile */ - return 0; - } - - cc = newCompilerContext(mb); #ifdef COMPILE_DEBUG showCompilerContext(cc); #endif - /* allocate mb->CompiledCodeInfo */ - info = (CodeInfo *)mb->CompiledCodeInfo; - if (!info) info = prepareCompiledCodeInfo(EE(), mb); - - if (makePCTable(cc)) goto compile_failed; /* an exception occurred. */ if (writeCode(cc)) goto compile_failed; /* an exception occurred. */ resolveJumpInstructions(cc); @@ -126,8 +122,8 @@ mb->fb.access |= ACC_MACHINE_COMPILED; mb->invoker = (bool_t (*)(JHandle *, struct methodblock *, int, struct execenv *)) - sym_invokeCompiledMethod; - /* invokeCompiledMethod() is in invoker.c */ + sym_invokeJITCompiledMethod; + /* invokeJITCompiledMethod() is in invoker.c */ /* write code size */ @@ -347,10 +343,10 @@ CodeTable *codep; #ifdef COMPILE_DEBUG - printf("processAnOpcode(): %s(0x%02x,%d), state: %d\n", + printf("procAnOpc(): %s(0x%02x,%d), st: %d\n", ((opcode > opc_nonnull_quick) ? "(null)" : opcode_symbol[opcode]), opcode, opcode, state); - printf(" bytepc offset: 0x%x(%d)\n", *byteoffp, *byteoffp); + printf(" b off: 0x%x(%d)\n", *byteoffp, *byteoffp); fflush(stdout); #endif @@ -550,7 +546,7 @@ } } #ifdef COMPILE_DEBUG - printf(" adjust opcode 0x%02x(%d) to 0x%02x(%d)\n", + printf(" adj opc 0x%02x(%d) to 0x%02x(%d)\n", opcode, opcode, code_opcode, code_opcode); fflush(stdout); #endif @@ -595,7 +591,7 @@ pctableAdd(cc, code_opcode, state, *byteoffp, -1); codep = &code_table[code_opcode][state]; #ifdef COMPILE_DEBUG - printf(" next state: %d\n", codep->after_state); fflush(stdout); + printf(" next st: %d\n", codep->after_state); fflush(stdout); #endif @@ -661,15 +657,17 @@ static void makeExcTable(CompilerContext *cc) { - struct CatchFrame *cf; + struct CatchFrame_w_state *cf; int i; - cf = cc->mb->exception_table; + cf = (CatchFrame_w_state *)cc->mb->exception_table; for (i = 0; i < cc->mb->exception_table_length; i++) { pcentry *table = pctableGet(cc, cf->handler_pc); int nativeoff = table->nativeoff; /* offset in byte code -> offset in native code */ cf->compiled_CatchFrame = (void *)nativeoff; + cf->state = table->state; + cf++; } } @@ -697,10 +695,10 @@ bytepc = mb->code + pctable->byteoff; #ifdef COMPILE_DEBUG - printf("writeCode(): %s(0x%02x,%d), state: %d\n", + printf("writeCode(): %s(0x%02x,%d), st: %d\n", ((opcode > opc_nonnull_quick) ? "(null)" : opcode_symbol[opcode]), opcode, opcode, state); - printf(" offset: byte 0x%x(%d), native 0x%x(%d)\n", + printf(" off: b 0x%x(%d) n 0x%x(%d)\n", pctable->byteoff, pctable->byteoff, nativeoff, nativeoff); fflush(stdout); @@ -708,7 +706,7 @@ codep = &code_table[opcode][state]; #ifdef COMPILE_DEBUG - printf(" length native: 0x%x(%d)\n", codep->length, codep->length); + printf(" len native: 0x%x(%d)\n", codep->length, codep->length); fflush(stdout); #endif @@ -1097,23 +1095,43 @@ # define CONST_GETMEMBER_DEBUG3 #endif +#ifdef JITDO + /* supply info. whether if field is object to generated native code */ +# define JITDO_CONST_GETMEMBER(vop) \ + if (opcode == opc_##vop) {\ + int32_t objp;\ + switch (*fb->name) {\ + case 'L': case '[':\ + objp = 1;\ + default:\ + objp = 0;\ + }\ + memcpy(bufp + constant_table[opcode][state][1], &objp, 4);\ + } +#else +# define JITDO_CONST_GETMEMBER(vop) +#endif + #define CONST_GETMEMBER(vop) \ case opc_##vop##:\ case opc_##vop##2:\ {\ + struct fieldblock *fb = NULL;\ int32_t slot;\ if ((*bytepc == opc_##vop##_quick) || (*bytepc == opc_##vop##2_quick))\ - /* after lossy translation */\ + /* after lossy translation (which is suppressed) */\ slot = bytepc[1];\ else { /* ..field, ..field_quick_w */\ int index = GET_UINT16(bytepc + 1);\ - struct fieldblock *fb = constant_pool[index].fb;\ + fb = constant_pool[index].fb;\ CONST_GETMEMBER_DEBUG1;\ slot = fb->u.offset / sizeof(OBJECT);\ }\ CONST_GETMEMBER_DEBUG2;\ memcpy(bufp + constant_table[opcode][state][0], &slot, 4);\ CONST_GETMEMBER_DEBUG3;\ + \ + JITDO_CONST_GETMEMBER(vop)\ }\ break @@ -1204,7 +1222,7 @@ uint32_t slot = bytepc[1]; int32_t localvar_space = 0; /* can't get this information !!! */ int32_t args_size = bytepc[2]; - int32_t ret_size = 0; /* can't get this information !!! */ + int32_t ret_size = 0; /* can't get this information !!! */ memcpy(bufp + constant_table[opcode][state][0], &args_size, 4); memcpy(bufp + constant_table[opcode][state][1], &localvar_space, 4); @@ -1221,8 +1239,7 @@ # define CONST_NEW_DEBUG2 #endif -#define CONST_NEW(vop, RESOLVE) \ - {\ +#define _CONST_NEW(vop, RESOLVE) \ int32_t index = GET_UINT16(bytepc + 1);\ ClassClass *cb;\ CONST_NEW_DEBUG1;\ @@ -1237,12 +1254,21 @@ }\ }\ cb = constant_pool[index].clazz;\ - CONST_NEW_DEBUG2;\ + CONST_NEW_DEBUG2; +#define CONST_NEW1(vop, RESOLVE) \ + {\ + _CONST_NEW(vop, RESOLVE);\ memcpy(bufp + constant_table[opcode][state][0], &cb, 4);\ } +#define CONST_NEW2(vop, RESOLVE) \ + {\ + _CONST_NEW(vop, RESOLVE);\ + memcpy(bufp + constant_table[opcode][state][0], &cb, 4);\ + memcpy(bufp + constant_table[opcode][state][1], &cb, 4);\ + } case opc_new: - CONST_NEW(new, 1); + CONST_NEW1(new, 1); #ifndef NO_REWRITE_NEW /* to rewrite self */ { @@ -1253,19 +1279,27 @@ break; case opc_new_quick: - CONST_NEW(new, 0); + CONST_NEW1(new, 0); break; case opc_anewarray: - CONST_NEW(anewarray, 1); + CONST_NEW1(anewarray, 1); break; case opc_checkcast: - CONST_NEW(checkcast, 1); +#ifdef JITDO + CONST_NEW2(checkcast, 1); +#else + CONST_NEW1(checkcast, 1); +#endif /* JITDO */ break; case opc_instanceof: - CONST_NEW(instanceof, 1); +#ifdef JITDO + CONST_NEW2(instanceof, 1); +#else + CONST_NEW1(instanceof, 1); +#endif /* JITDO */ break; case opc_newarray: @@ -1364,10 +1398,10 @@ int byteoff = pctable->byteoff; int nativeoff = pctable->nativeoff; - printf("resolveExcRetSw(): %s(0x%02x,%d), state: %d\n", + printf("resERS(): %s(0x%02x,%d), st: %d\n", ((opcode > opc_nonnull_quick) ? "(null)" : opcode_symbol[opcode]), opcode, opcode, state); - printf(" offset: byte 0x%x(%d), native 0x%x(%d)\n", + printf(" off: b 0x%x(%d) n 0x%x(%d)\n", byteoff, byteoff, nativeoff, nativeoff); fflush(stdout); } @@ -1380,7 +1414,7 @@ uint32_t byteoff = pctable->byteoff; while (bytepc_table[opcode][state][i] > 0) { #ifdef COMPILE_DEBUG - printf(" resolve bytecode PC at 0x%x(%d) + %d: 0x%x(%d)\n", + printf(" res. bytecode PC at 0x%x(%d) + %d: 0x%x(%d)\n", pctable->nativeoff, pctable->nativeoff, bytepc_table[opcode][state][i], byteoff, byteoff); fflush(stdout); @@ -1401,7 +1435,7 @@ arg_off = pctable->nativeoff + jumpexc_table[opcode][state][i]; relative_off = exc_off - (arg_off + 4); #ifdef COMPILE_DEBUG - printf(" resolve jump to exc.handler at 0x%x(%d) + %d\n", + printf(" res. jump to exc.handler at 0x%x(%d) + %d\n", pctable->nativeoff, pctable->nativeoff, jumpexc_table[opcode][state][i]); fflush(stdout); @@ -1421,7 +1455,7 @@ arg_off = pctable->nativeoff + jumpret_table[opcode][state][i]; relative_off = fin_off - (arg_off + 4); #ifdef COMPILE_DEBUG - printf(" resolve jump to fin.of method at 0x%x(%d) + %d\n", + printf(" res. jump to fin.of method at 0x%x(%d) + %d\n", pctable->nativeoff, pctable->nativeoff, jumpret_table[opcode][state][i]); fflush(stdout); @@ -1626,6 +1660,7 @@ #endif RESOLVE_SYMBOL_ON_CODE +#undef RES_FUNC_DEBUG static void resolveFunctionSymbols(CompilerContext *cc) { unsigned char *nativeCode = cc->mb->CompiledCode; @@ -1633,7 +1668,7 @@ pcentry *pctable_end = pctable + cc->pctablelen; FuncTable *funcp; -#ifdef COMPILE_DEBUG +#ifdef RES_FUNC_DEBUG printf("resolveFuncSym() called.\n"); fflush(stdout); #endif @@ -1655,8 +1690,8 @@ funcptr = (unsigned char *)sysDynamicLink(funcp->name); #endif -#ifdef COMPILE_DEBUG - printf(" symbol `%s': 0x%08x at 0x%x(%d) + %d\n", +#ifdef RES_FUNC_DEBUG + printf(" symb %s: 0x%08x at 0x%x(%d) + %d\n", funcp->name, (int)funcptr, pctable->nativeoff, pctable->nativeoff, funcp->offset); fflush(stdout); @@ -1669,7 +1704,7 @@ pctable++; } -#ifdef COMPILE_DEBUG +#ifdef RES_FUNC_DEBUG printf("resolveFuncSym() done.\n"); fflush(stdout); #endif } diff -aruN shujit-0.2.3/compiler.c shujit-0.2.4/compiler.c --- shujit-0.2.3/compiler.c Sat Oct 10 19:08:17 1998 +++ shujit-0.2.4/compiler.c Thu Jan 7 14:26:30 1999 @@ -1,5 +1,5 @@ /* - * Copyright (C) 1998 + * Copyright (C) 1998,1999 * SHUDO Kazuyuki * * Permission to use, copy, modify and distribute this software @@ -10,6 +10,11 @@ */ #include /* for getenv(3) */ +#ifdef EXC_BY_SIGNAL +# if defined(linux) +# include +# endif +#endif #include "monitor.h" /* for macro BINCLASS_{,UN}LOCK() */ #include "compiler.h" @@ -24,11 +29,14 @@ int opt_outcode = 0; int opt_codesize = 0; int opt_dontcmplvmcls = 0; +int opt_igndisable = 0; void *sym_compileAndInvokeMethod; -void *sym_invokeCompiledMethod; +void *sym_invokeJITCompiledMethod; void *sym_invokeJavaMethod; void *sym_invokeSynchronizedJavaMethod; +void *sym_invokeAbstractMethod; +void *sym_invokeLazyNativeMethod; /* @@ -37,9 +45,9 @@ static void initializeClass(ClassClass *); static void signalHandler(int sig, void *info, void *uc); static void freeClass(ClassClass *); -unsigned char *compiledCodePC(JavaFrame *, struct methodblock *); -bool_t pcInCompiledCode(unsigned char *pc, struct methodblock *); -JavaFrame *framePrev(JavaFrame *frame, JavaFrame *frame_buf); +static unsigned char *compiledCodePC(JavaFrame *, struct methodblock *); +static bool_t pcInCompiledCode(unsigned char *pc, struct methodblock *); +static JavaFrame *framePrev(JavaFrame *frame, JavaFrame *frame_buf); static void compilerEnable(); static void compilerDisable(); static bool_t compileClass(ClassClass *); @@ -58,6 +66,7 @@ * This method is called by JVM. */ void java_lang_Compiler_start(void ** vector) { + static int already_called = 0; int version; int javaVersion, javaMinorVersion, compilerVersion; @@ -65,6 +74,8 @@ printf("java_lang_Compiler_start() called.\n"); fflush(stdout); #endif + if (already_called) return; + already_called = 1; /* get options */ { @@ -73,20 +84,31 @@ if (opts) { #ifdef RUNTIME_DEBUG - printf("JAVA_COMPILER_OPT: %s\n", opts); + printf(" JAVA_COMPILER_OPT: %s\n", opts); fflush(stdout); #endif opt = strtok(opts, ", "); while (opt) { - if (!strncmp(opt, "quiet", 6)) + if (!strncmp(opt, "quiet", 6)) { opt_quiet = 1; - else if (!strncmp(opt, "outcode", 8)) + } + else if (!strncmp(opt, "outcode", 8)) { opt_outcode = 1; - else if (!strncmp(opt, "codesize", 9)) + if (!opt_quiet) printf(" option: outcode\n"); + } + else if (!strncmp(opt, "codesize", 9)) { opt_codesize = 1; - else if (!strncmp(opt, "dontcmplvmcls", 14)) + if (!opt_quiet) printf(" option: codesize\n"); + } + else if (!strncmp(opt, "dontcmplvmcls", 14)) { opt_dontcmplvmcls = 1; + if (!opt_quiet) printf(" option: dontcmplvmcls\n"); + } + else if (!strncmp(opt, "igndisable", 11)) { + opt_igndisable = 1; + if (!opt_quiet) printf(" option: igndisable\n"); + } opt = strtok(NULL, ", "); } } @@ -143,18 +165,26 @@ /* resolve some symbols */ sym_compileAndInvokeMethod = (void *)sysDynamicLink("compileAndInvokeMethod"); - sym_invokeCompiledMethod = (void *)sysDynamicLink("invokeCompiledMethod"); + sym_invokeJITCompiledMethod = + (void *)sysDynamicLink("invokeJITCompiledMethod"); sym_invokeJavaMethod = (void *)sysDynamicLink("invokeJavaMethod"); sym_invokeSynchronizedJavaMethod = (void *)sysDynamicLink("invokeSynchronizedJavaMethod"); + sym_invokeAbstractMethod = (void *)sysDynamicLink("invokeAbstractMethod"); + sym_invokeLazyNativeMethod = + (void *)sysDynamicLink("invokeLazyNativeMethod"); #ifdef COMPILE_DEBUG printf("symbols:\n"); printf(" compileAndInvokeMethod: 0x%08x\n", (int)sym_compileAndInvokeMethod); - printf(" invokeCompiledMethod: 0x%08x\n", (int)sym_invokeCompiledMethod); + printf(" invokeJITCompiledMethod: 0x%08x\n", + (int)sym_invokeJITCompiledMethod); printf(" invokeJavaMethod: 0x%08x\n", (int)sym_invokeJavaMethod); printf(" invokeSynchronizedJavaMethod: 0x%08x\n", (int)sym_invokeSynchronizedJavaMethod); + printf(" invokeAbstractMethod: 0x%08x\n", (int)sym_invokeAbstractMethod); + printf(" invokeLazyNativeMethod: 0x%08x\n", + (int)sym_invokeLazyNativeMethod); #endif #ifdef RESOLVE_SYMBOL_ON_CODE @@ -178,22 +208,35 @@ BINCLASS_UNLOCK(); } - UseLosslessQuickOpcodes = FALSE; /* prohibit generating lossy opcodes */ + /* prohibit generating lossy opcodes */ + UseLosslessQuickOpcodes = TRUE; /* set up link vector */ - *(char **)vector[1] = (char *)initializeClass; - *(char **)vector[2] = (char *)sym_invokeCompiledMethod; + *(char **)vector[2] = (char *)sym_invokeJITCompiledMethod; *(char **)vector[3] = (char *)signalHandler; *(char **)vector[4] = (char *)freeClass; *(char **)vector[5] = (char *)compileClass; *(char **)vector[6] = (char *)compileClasses; - *(char **)vector[7] = (char *)compilerEnable; - *(char **)vector[8] = (char *)compilerDisable; + if (!opt_igndisable) { + *(char **)vector[7] = (char *)compilerEnable; + *(char **)vector[8] = (char *)compilerDisable; + } *(char **)vector[10] = (char *)pcInCompiledCode; *(char **)vector[11] = (char *)compiledCodePC; *(char **)vector[70] = (char *)framePrev; +#ifdef COMPILE_DEBUG + { + int i; + for (i = 1; i <= 8; i++) + printf("*vector[%d]: 0x%08x\n", i, (int)*(char **)vector[i]); + printf("*vector[10]: 0x%08x\n", i, (int)*(char **)vector[10]); + printf("*vector[11]: 0x%08x\n", i, (int)*(char **)vector[11]); + printf("*vector[70]: 0x%08x\n", i, (int)*(char **)vector[70]); + fflush(stdout); + } +#endif #ifdef COMPILE_DEBUG printf("java_lang_Compiler_start() done.\n"); @@ -207,7 +250,7 @@ */ /* - * Initialization the compiler at the time a class is loaded. + * Initialize the class at the time one is loaded. */ void initializeClass(ClassClass *cb) { struct methodblock *mb, *mb_end; @@ -216,36 +259,104 @@ fflush(stdout); #endif - if (!compiler_enabled) { -#ifdef COMPILE_DEBUG - printf(" compiler has been disabled.\n return.\n"); - fflush(stdout); -#endif - return; - } - mb = cbMethods(cb); mb_end = mb + cbMethodsCount(cb); for (; mb < mb_end; mb++) { + /* initialize mb->CompiledCodeInfo */ + if (!(mb->CompiledCodeInfo)) prepareCompiledCodeInfo(EE(), mb); + if (mb->fb.access & (ACC_ABSTRACT | ACC_NATIVE)) /* methods not to be compiled */ continue; + INITIALIZE_METHOD(mb); } } static void signalHandler(int sig, void *info, void *uc) { - printf("Signal %d is caught.\n", sig); +#ifdef RUNTIME_DEBUG + printf("signalHandler for compiled code. (sig: %d)\n", sig); +#endif - showStackFrames(EE()); +#ifdef EXC_BY_SIGNAL +#define SEARCH_WIDTH 100 +#ifndef USER_DS +# define USER_DS __USER_DS +#endif + { + struct sigcontext *sc; +#if 0 + int *ptr = (int *)uc - SEARCH_WIDTH; + int i; + + for (i = 0; i < SEARCH_WIDTH - 3; i++) { + if (ptr[0] == USER_DS) + if (ptr[1] == USER_DS) + if (ptr[2] == USER_DS) + if (ptr[3] == USER_DS) + break; + else ptr += 4; + else ptr += 3; + else ptr += 2; + else ptr += 1; + } + if (i >= SEARCH_WIDTH - 3) { + printf("FATAL: struct sigcontext is not found."); + exit(1); + } + sc = (struct sigcontext *)ptr; +#else + printf("sizeof(struct sigcontext): %d\n", sizeof(struct sigcontext)); + sc = (struct sigcontext *)(((char *)uc) - sizeof(struct sigcontext)); + printf("uc, sc: 0x%08x, 0x%08x\n", (int)uc, (int)sc); +#endif + + showSigcontext(sc); + } + +#ifdef SA_SIGINFO + if (info) { + ExecEnv *ee = EE(); + siginfo_t *si = (siginfo_t *)info; + + printf("si_signo: %d\n", si->si_signo); + printf("si_errno: %d\n", si->si_errno); + printf("si_code: 0x%08x\n", si->si_code); + + switch (sig) { + case SIGILL: case SIGFPE: case SIGSEGV: case SIGBUS: + { + JavaFrame *frame; + struct methodblock *mb; + + frame = ee->current_frame; + if (frame) { + mb = frame->current_method; + + printf("%s#%s %s\n", cbName(fieldclass(&mb->fb)), + mb->fb.name, mb->fb.signature); + printf(" CompiledCode: 0x%08x\n", (int)mb->CompiledCode); + } + } + { + void *addr = si->si_addr; + printf("addr: 0x%08x\n", (int)addr); + } + break; + } + } +#endif +#endif /* EXC_BY_SIGNAL */ + + printf("Signal %d is caught.\n", sig); } /* * Freeing class staffs related to the compiler. */ -void freeClass(ClassClass *cb) { +static void freeClass(ClassClass *cb) { struct methodblock *mb = cbMethods(cb); struct methodblock *mb_end = mb + cbMethodsCount(cb); @@ -259,40 +370,45 @@ } -unsigned char *compiledCodePC(JavaFrame *frame, struct methodblock *mb) { +static unsigned char *compiledCodePC(JavaFrame *frame,struct methodblock *mb) { return (frame ? frame->lastpc : mb->code); } -bool_t pcInCompiledCode(unsigned char *pc, struct methodblock *mb) { +static bool_t pcInCompiledCode(unsigned char *pc, struct methodblock *mb) { unsigned int off = pc - mb->code; return (off < mb->code_length); } -JavaFrame *framePrev(JavaFrame *frame, JavaFrame *frame_buf) { +static JavaFrame *framePrev(JavaFrame *frame, JavaFrame *frame_buf) { return frame->prev; } /* - * Enable the compiler. + * Enable and Disable the compiler. */ static void compilerEnable() { +#ifdef RUNTIME_DEBUG + printf("compilerEnable() called.\n"); fflush(stdout); +#endif compiler_enabled = TRUE; } - /* - * Disable the compiler. + * Enable and Disable the compiler. */ static void compilerDisable() { +#ifdef RUNTIME_DEBUG + printf("compilerDisable() called.\n"); fflush(stdout); +#endif compiler_enabled = FALSE; } /* - * Compile the class. + * Compile the class. Not only initialization. */ static bool_t compileClass(ClassClass *cb) { struct methodblock *mb, *mb_end; @@ -314,6 +430,9 @@ mb = cbMethods(cb); mb_end = mb + cbMethodsCount(cb); for (; mb < mb_end; mb++) { + /* initialize mb->CompiledCodeInfo */ + if (!(mb->CompiledCodeInfo)) prepareCompiledCodeInfo(EE(), mb); + if (!(mb->code)) { #ifdef COMPILE_DEBUG printf("code is empty: %s %s\n", mb->fb.name, mb->fb.signature); @@ -322,6 +441,7 @@ INITIALIZE_METHOD(mb); continue; } + if (compileMethod(mb)) return FALSE; } diff -aruN shujit-0.2.3/compiler.h shujit-0.2.4/compiler.h --- shujit-0.2.3/compiler.h Mon Oct 5 11:50:26 1998 +++ shujit-0.2.4/compiler.h Thu Jan 7 14:26:09 1999 @@ -1,5 +1,5 @@ /* - * Copyright (C) 1996,1997,1998 + * Copyright (C) 1996,1997,1998,1999 * SHUDO Kazuyuki * * Permission to use, copy, modify and distribute this software @@ -79,6 +79,8 @@ /* * OS dependent macro definition */ +#undef EXC_BY_SIGNAL /* not implemented yet */ + #if defined (linux) # define EXECUTEJAVA_IN_ASM # if defined __GLIBC__ && __GLIBC__ >= 2 @@ -95,6 +97,16 @@ #endif +#ifdef EXC_BY_SIGNAL +# if defined(linux) +# include /* for struct sigcontext */ +# include /* for macro __USER_DS */ +# elif defined(__FreeBSD__) +# include /* for struct sigcontext */ +# endif +#endif + + /* * Select appropriate malloc library */ @@ -108,19 +120,12 @@ * Macros */ -#define CREDIT " shuJIT for Sun JVM/IA32 Copyright (c) 1998 SHUDO Kazuyuki\n" +#define CREDIT " shuJIT for Sun JVM/IA-32 Copyright 1998,1999 by SHUDO Kazuyuki\n" #define COMPILER_VERSION 5 #define CODESIZE_FNAME "jit_codesize" -#ifndef MIN -# define MIN(a,b) ((a)<(b)?(a):(b)) -#endif -#ifndef MAX -# define MAX(a,b) ((a)>(b)?(a):(b)) -#endif - /* STR(macro) is permuted to "value of the macro" */ #define _STR(T) #T #define STR(MACRO) _STR(MACRO) @@ -130,6 +135,18 @@ * Type definition */ +/* CatchFrame_w_state is based on CatchFrame */ +/* Requirement for C compiler: + sizeof(CatchFrame_w_state) equals sizeof(CatchFrame) */ +typedef struct CatchFrame_w_state { + long start_pc, end_pc; + long handler_pc; + void* compiled_CatchFrame; + short catchType; + short state; /* added by SHUDO */ +} CatchFrame_w_state; + + typedef struct compiled_code_info { int code_size; int ret_size; @@ -193,11 +210,20 @@ extern int opt_dontcmplvmcls; /* suppress compilation classes which is already loaded when JIT is initialized */ +extern int opt_igndisable; + /* make java.lang.Compiler#disable() void */ extern void *sym_compileAndInvokeMethod; -extern void *sym_invokeCompiledMethod; +extern void *sym_invokeJITCompiledMethod; extern void *sym_invokeJavaMethod; extern void *sym_invokeSynchronizedJavaMethod; +extern void *sym_invokeAbstractMethod; +extern void *sym_invokeLazyNativeMethod; + +#ifdef JITDO +/* in proxy.c */ +extern struct methodtable *proxy_methodtable; /* in proxy.c */ +#endif /* JITDO */ /* @@ -238,7 +264,7 @@ /* in invoker.c */ extern bool_t compileAndInvokeMethod( JHandle *o, struct methodblock *mb, int args_size, ExecEnv *ee); -extern bool_t invokeCompiledMethod( +extern bool_t invokeJITCompiledMethod( JHandle *o, struct methodblock *mb, int args_size, ExecEnv *ee); /* in compile.c */ @@ -249,6 +275,9 @@ #endif /* in runtime.c */ +#ifdef EXC_BY_SIGNAL +extern void showSigcontext(struct sigcontext *sc); +#endif extern int invokeMethod( #ifdef RUNTIME_DEBUG int runtime_debug, @@ -281,5 +310,25 @@ extern void showExcStackTrace(JHandle *throwable); extern char *showObjectBody(char *sig, JHandle *obj); #endif + +#ifdef JITDO +/* in proxy.c */ +#include "jitdo/NET_shudo_jitdo_VMAddress_old.h" +extern JHandle *proxy_new(ExecEnv *ee, + HNET_shudo_jitdo_VMAddress *addr, ClassClass *cb); + +extern int32_t proxy_get32field(ExecEnv *, JHandle *proxy, int32_t slot); +extern int64_t proxy_get64field(ExecEnv *, JHandle *proxy, int32_t slot); +extern JHandle *proxy_getobjfield(ExecEnv *, JHandle *proxy, int32_t slot); +extern void proxy_set32field(ExecEnv *, JHandle *p, int32_t slot, int32_t v); +extern void proxy_set64field(ExecEnv *, JHandle *p, int32_t slot, int64_t v); +extern void proxy_setobjfield(ExecEnv *, JHandle *p, int32_t slot, JHandle *v); + +extern int proxy_invoke(ExecEnv *ee, JHandle *proxy, + char *name, char *sig, stack_item *stackpointer); + +/* in copyable.c */ +extern bool_t isCopyable(ExecEnv *ee, ClassClass *clazz); +#endif /* JITDO */ #endif /* _COMPILER_H_ */ diff -aruN shujit-0.2.3/computil.c shujit-0.2.4/computil.c --- shujit-0.2.3/computil.c Sun Aug 16 20:45:00 1998 +++ shujit-0.2.4/computil.c Wed Jan 6 21:13:54 1999 @@ -1,5 +1,5 @@ /* - * Copyright (C) 1998 + * Copyright (C) 1998,1999 * SHUDO Kazuyuki * * Permission to use, copy, modify and distribute this software @@ -17,13 +17,32 @@ void *access2invoker(int access) { - if (access & ACC_ABSTRACT) - return (void *)invokeAbstractMethod; - else if (access & ACC_NATIVE) - return (void *)invokeLazyNativeMethod; - else - return (void *)((access & ACC_SYNCHRONIZED) ? - invokeSynchronizedJavaMethod : invokeJavaMethod); + if (access & ACC_ABSTRACT) { +#ifdef RUNTIME_DEBUG + printf("acc2inv: invokeAbstractMethod\n"); fflush(stdout); +#endif + return (void *)sym_invokeAbstractMethod; + } + else if (access & ACC_NATIVE) { +#ifdef RUNTIME_DEBUG + printf("acc2inv: invokeLazyNativeMethod\n"); fflush(stdout); +#endif + return (void *)sym_invokeLazyNativeMethod; + } + else { + if (access & ACC_SYNCHRONIZED) { +#ifdef RUNTIME_DEBUG + printf("acc2inv: invokeSynchronizedJavaMethod\n"); fflush(stdout); +#endif + return (void *)sym_invokeSynchronizedJavaMethod; + } + else { +#ifdef RUNTIME_DEBUG + printf("acc2inv: invokeJavaMethod\n"); fflush(stdout); +#endif + return (void *)sym_invokeJavaMethod; + } + } } diff -aruN shujit-0.2.3/def.mk shujit-0.2.4/def.mk --- shujit-0.2.3/def.mk Thu Jan 1 09:00:00 1970 +++ shujit-0.2.4/def.mk Thu Jan 7 13:42:55 1999 @@ -0,0 +1,56 @@ +J_HOME = /usr/local/jdk1.1.7 +#J_HOME = /usr/local/jdk117_v1a +#J_HOME = /usr/local/jdk1.1.6 + +# for GCC 2.7.X or older +#CC_VER = gcc27 + +# for JIT Distributed Object +# not implemented yet +#JITDO = 1 + + +CC = gcc +LD_DYNAMIC = gcc -shared# for SunOS 5, Linux +#LD_DYNAMIC = ld -Bdynamic# for SunOS 4 + +OBJDUMP = objdump + +RM = rm -f +MV = mv +MKDIR = mkdir -p +LN = ln +AR = ar +RANLIB = ranlib +INSTALL = install -c +TOUCH = touch +CO = co +CI = ci +WC = wc +TEE = tee +ETAGS = etags +RLOG = rlog -h + +JAVA = java +#JAVA = /usr/local/harissa/bin/hi +JAVAC = javac +JAVAH = javah +JAVAH_JNI = $(JAVAH) -jni +JAR = jar +JAVADOC = javadoc + + +# Defaults + +COMPILE.java = $(JAVAC) $(JFLAGS) + +# Rules +.java.class: + $(COMPILE.java) $< + +%.class: %.java + $(COMPILE.java) $< + +# for 'make classname' +%: %.java + $(COMPILE.java) $< diff -aruN shujit-0.2.3/develop/acc_to_frame shujit-0.2.4/develop/acc_to_frame --- shujit-0.2.3/develop/acc_to_frame Thu Aug 27 13:16:13 1998 +++ shujit-0.2.4/develop/acc_to_frame Thu Jan 1 09:00:00 1970 @@ -1,71 +0,0 @@ -access to JavaFrame - -code.c - -l.235 methodhead - %esi = ee->current_frame->vars; -l.2902 ireturn - %edi = ee->current_frame->prev->optop; -l.2934 lretrun - %edi = ee->current_frame->prev->optop; -l.3267 invoke* - %edi = ee->current_frame->optop; -l.3438 new - %eax = ee->current_frame->current_method; - -invoker.c - -invokeCompiledMethod() -l.113 - showStackFrames(ee); -l.117 create new frame - invoke*JavaMethod(); -l.124 - frame = ee->current_frame; -l.135 restack - prev = frame->prev; -l.141 if called by compiled method - frame->vars = (stack_item *)prev->returnpc; -l.157 restack - args = frame->vars; /* points to JVM stack */ -l.159 restack - frame->vars = native_vars; -l.187 RUNTIME_DEBUG - ee->current_frame->vars; -l.224 monitor exit - if (frame->monitor) -l.226 - ee->current_frame = frame->prev; - -runtime.c - -invokeMethod() -l.35 - ee->current_frame->lastpc = - ee->current_frame->current_method->code + bytepcoff; -l.91 if call compiled method - ee->current_frame->returnpc = (unsigned char *)stackpointer; -l.95 if call normal Java method - optop = ee->current_frame->optop; -l.172 if call normal Java method - cur_frame = ee->current_frame; -l.175 - if (cur_frame->monitor) -l.178 - cur_frame = cur_frame->prev; - ee->current_frame = cur_frame; -l.185 - optop = cur_frame->optop; -l.192 - cur_frame->optop = optop; -l.199 - optop = ee->current_frame->optop; - -multianewarray() -l.300 - optop = ee->current_frame->optop; - -searchCatchFrame() -l.426 /* push exception object */ - ee->current_frame->optop = ee->current_frame->ostack; - (ee->current_frame->optop++)->h = ee->exception.exc; diff -aruN shujit-0.2.3/develop/invoker.c-frame_on_stack shujit-0.2.4/develop/invoker.c-frame_on_stack --- shujit-0.2.3/develop/invoker.c-frame_on_stack Thu Aug 27 13:15:18 1998 +++ shujit-0.2.4/develop/invoker.c-frame_on_stack Thu Jan 1 09:00:00 1970 @@ -1,300 +0,0 @@ -/* - * Copyright (C) 1998 - * SHUDO Kazuyuki - * - * Permission to use, copy, modify and distribute this software - * and its documentation for non-commercial purposes and without - * fee is hereby granted provided this copyright notice. - * - * $Id$ - */ - -#include /* for strcmp() */ - -#include "monitor.h" /* for monitor{Enter,Exit}() */ -#include "compiler.h" - - -/* - * Compile and invoke the method. - */ -bool_t compileAndInvokeMethod( - JHandle *o, struct methodblock *mb, int args_size, ExecEnv *ee) { - int key = obj_monitor(fieldclass(&mb->fb)); -#ifdef COMPILE_DEBUG - printf("\n"); - printf("compileAndInvokeMethod() is called:\n %s#%s %s\n key: %d\n", - cbName(mb->fb.clazz), mb->fb.name, mb->fb.signature, key); - fflush(stdout); -#endif - - monitorEnter(key); - - /* compile the called method */ - if (!(mb->CompiledCode) && - !(mb->fb.access & (ACC_ABSTRACT | ACC_NATIVE))) { -#ifdef COMPILE_DEBUG - printf(" now compiling.\n"); fflush(stdout); -#endif - if (compileMethod(mb)) { - /* fail to compile.. */ -#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); - } - } - -#ifdef COMPILE_DEBUG - printf("compileAndInvokeMethod(): now call invoker.\n"); - fflush(stdout); -#endif - monitorExit(key); - return mb->invoker(o, mb, args_size, ee); -} - - -/* - * Invoke the compiled method. - */ -bool_t invokeCompiledMethod( - JHandle *o, struct methodblock *mb, int args_size, ExecEnv *ee) { - JavaFrame *old_frame, *frame; - int access; - stack_item *native_vars; -#ifdef RUNTIME_DEBUG - int runtime_debug; -#endif - - /* caution: This code segment must be placed at code head. */ - { - /* allocate JavaFrame and local var. space */ - __asm__("subl %2,%%esp\n\t" /* %esp -= (8 + sizeof(JavaFrame)) */ - "movl %%esp,%0\n\t" /* frame = %esp */ - "leal -4(%%esp),%%edx\n\t" /* %edx = %esp - 4 */ - "subl %3,%%esp\n\t" /* %esp -= nlocals * 4 */ - "movl %%edx,%1" /* native_vars = %edx */ - : "=m" (frame), "=m" (native_vars) - : "i" (8/* for return value*/ + sizeof(JavaFrame)), - "r" (mb->nlocals * 4) - : "edx"); - /* native_vars = %esp - 4 */ - /* %esp -= (sizeof(JavaFrame) + nlocals * 4) */ - /* frame = %esp */ - } - -#ifdef RUNTIME_DEBUG -# if 1 - runtime_debug = 1; -# else - if ((!strcmp(cbName(mb->fb.clazz), "java/lang/FloatingDecimal")) - && (!strcmp(mb->fb.name, "toJavaFormatString"))) - runtime_debug = 1; - else if ((!strcmp(cbName(mb->fb.clazz), "java/util/Hashtable")) - && (!strcmp(mb->fb.name, "put"))) - runtime_debug = 1; - else if ((!strcmp(cbName(mb->fb.clazz), "E2.E2_Algorithm")) - && (!strcmp(mb->fb.name, "blockEncrypt"))) - runtime_debug = 1; - else - runtime_debug = 0; -# endif -#endif /* RUNTIME_DEBUG */ - -#ifdef RUNTIME_DEBUG - if (runtime_debug) { - printf("\n"); - printf("invokeCompiledMethod() is called:\n %s#%s %s\n", - cbName(mb->fb.clazz), mb->fb.name, mb->fb.signature); - if (exceptionOccurred(ee)) { - printf(" An exception not handled remains!\n"); - } - fflush(stdout); - - showStackFrames(ee); - } /* if (runtime_debug) */ -#endif /* RUNTIME_DEBUG */ - - old_frame = ee->current_frame; - access = mb->fb.access; - - /* creates a new frame */ -#define CALL_INVOKEJAVAMETHOD -#ifdef CALL_INVOKEJAVAMETHOD - if (access & ACC_SYNCHRONIZED) - invokeSynchronizedJavaMethod(o, mb, args_size, ee); - else - invokeJavaMethod(o, mb, args_size, ee); - - frame = ee->current_frame; -#else /* CALL_INVOKEJAVAMETHOD */ - { - JavaStack *stack = old_frame->javastack; - if (old_frame->optop + mb->nlocals >= stack->end_data) { - /* `mb->nlocals' don't have to be `mb->maxstack'. */ - /* create new JavaFrame on the chunk of JVM */ - invokeJavaMethod(o, mb, args_size, ee); - frame = ee->current_frame; - } - else { - /* employ the JavaFrame on the C stack */ - frame->javastack = stack; - frame->prev = old_frame; - - /* frame->vars = old_frame->optop; not needed */ - frame->optop = old_frame->optop + mb->nlocals; - - frame->current_method = mb; -#if 0 /* these members is not used. */ - frame->constant_pool = cbConstantPool(fieldclass(&mb->fb)); - frame->returnpc = mb->code; -#endif - if (java_monitor) { - frame->mon_starttime = now(); - } - ee->current_frame = frame; - } - - if (access & ACC_SYNCHRONIZED) { - frame->monitor = o; - monitorEnter(obj_monitor(o)); - } - else { - frame->monitor = 0; - } - } -#endif /* CALL_INVOKEJAVAMETHOD */ - - frame->lastpc = mb->code; - /* lastpc is not initialized in invoke*JavaMethod() */ - - /* call */ - - /* restack from JVM stack to native stack */ - { - struct methodblock *prev_method; - - prev_method = old_frame->current_method; - if (!prev_method) goto restack; - if (prev_method->CompiledCode) { - /* called by compiled method */ - frame->vars = (stack_item *)old_frame->returnpc; - goto restack_done; - } - - /* called by normal Java or native method */ - restack: - { - CodeInfo *info; - char *argsizes; - stack_item *args; - - info = (CodeInfo *)mb->CompiledCodeInfo; - if (!info) prepareCompiledCodeInfo(ee, mb); - /* make arg. size table for restack */ - - argsizes = info->argsizes; - args = old_frame->optop; /* points to JVM stack */ - - frame->vars = native_vars; - - while (*argsizes) { - if (*argsizes == 1) { - native_vars[0] = args[0]; - native_vars--; args++; - } - else { - native_vars[-1] = args[0]; - native_vars[0] = args[1]; - native_vars -= 2; args += 2; - } - argsizes++; - } /* while (*argsizes) */ - } /* restack: */ - - restack_done: - } - -#ifdef RUNTIME_DEBUG - if (runtime_debug) { - printf("call compiled method.\n"); - printf(" o:0x%08x, mb:0x%08x, args_size:%d, ee:0x%08x\n", - (int)o, (int)mb, args_size, (int)ee); - printf(" mb->CompiledCode: 0x%08x\n", (int)mb->CompiledCode); - fflush(stdout); - - { - stack_item *vars = ee->current_frame->vars; - char *sig; - int i; - - if (args_size > 0) { - printf(" args:\n"); - i = 0; - if (!(access & ACC_STATIC)) { - printf(" 0x%08x @ 0x%08x ", (int)vars[0].h, (int)vars); - showObjectBody("L;", vars[0].h); - printf("\n"); - i++; - } - sig = mb->fb.signature; - if (sig[0] == '(') sig++; - - for (; i < args_size; i++) { - JHandle *arg = vars[-i].h; - if ((sig[0] == 'D') || (sig[0] == 'J')) i++; - printf(" 0x%08x @ 0x%08x ", (int)arg, (int)(vars - i)); - sig = showObjectBody(sig, arg); - printf("\n"); - } - } - fflush(stdout); - } - } -#endif - -#ifdef RUNTIME_DEBUG - ((void (*) (JHandle *, struct methodblock *, int, ExecEnv *, int)) - mb->CompiledCode)(o, mb, args_size, ee, runtime_debug); -#else - ((void (*) (JHandle *, struct methodblock *, int, ExecEnv *)) - mb->CompiledCode)(o, mb, args_size, ee); -#endif - - if (frame->monitor) - monitorExit(obj_monitor(frame->monitor)); - ee->current_frame = frame->prev; - -#ifdef RUNTIME_DEBUG - if (runtime_debug) { - printf("compiled method finished: %s#%s %s\n", - cbName(mb->fb.clazz), mb->fb.name, mb->fb.signature); - fflush(stdout); - - printf(" free memory: handle %lld obj %lld\n", - FreeHandleMemory(), FreeObjectMemory()); - fflush(stdout); - - if (exceptionOccurred(ee)) { - JHandle *exc = ee->exception.exc; - printf(" exception occurred:\n"); - printf(" 0x%08x(%s)\n", - (int)exc, cbName(exc->methods->classdescriptor)); - showExcStackTrace(exc); - fflush(stdout); - } - printf("\n"); - fflush(stdout); - } /* if (runtime_debug) */ -#endif - - -#ifdef RUNTIME_DEBUG - runtime_debug = 0; -#endif - - return !(exceptionOccurred(ee)); -} diff -aruN shujit-0.2.3/develop/log-cm3 shujit-0.2.4/develop/log-cm3 --- shujit-0.2.3/develop/log-cm3 Mon Aug 24 13:33:50 1998 +++ shujit-0.2.4/develop/log-cm3 Thu Jan 1 09:00:00 1970 @@ -1,99 +0,0 @@ - shuJIT for JDK/IA32 Copyright (c) 1998 SHUDO Kazuyuki -Signal 11 is caught. -stack frames: - sun/awt/motif/MComponentPeer#dispose ()V pc: 16 (compiled) - sun/awt/motif/MFramePeer#dispose ()V pc: 9 (compiled) - java/awt/Component#removeNotify ()V pc: 128 (compiled) - java/awt/Container#removeNotify ()V pc: 42 (compiled) - java/awt/Window#dispose ()V pc: 33 (compiled) - java/awt/Frame#dispose ()V pc: 89 (compiled) - DialogAtom#cleanUp ()I pc: 11 (compiled) - BenchmarkUnit#loopsPerSecond ()I pc: 68 (compiled) - BenchmarkUnit#testScore ()I pc: 1 (compiled) - CaffeineMarkBenchmark#run ()V pc: 65 (compiled) - (null) lastpc: 0x4153ed74 -SIGSEGV 11* segmentation violation - stackbase=0x4153f000, stackpointer=0x4153e26c - -Full thread dump: - "Thread-6" (TID:0x4065d750, sys_thread_t:0x4153ef04, state:R) prio=5 *current thread* - sun.awt.motif.MComponentPeer.dispose(Compiled Code) - sun.awt.motif.MFramePeer.dispose(Compiled Code) - java.awt.Component.removeNotify(Compiled Code) - java.awt.Container.removeNotify(Compiled Code) - java.awt.Window.dispose(Compiled Code) - java.awt.Frame.dispose(Compiled Code) - DialogAtom.cleanUp(Compiled Code) - BenchmarkUnit.loopsPerSecond(Compiled Code) - BenchmarkUnit.testScore(Compiled Code) - CaffeineMarkBenchmark.run(Compiled Code) - "AWT-Finalizer" (TID:0x4065f498, sys_thread_t:0x4151df04, state:CW) prio=9 - java.lang.Object.wait(Compiled Code) - sun.awt.AWTFinalizer.run(Compiled Code) - "Screen Updater" (TID:0x4065c0e8, sys_thread_t:0x4148cf04, state:R) prio=4 - sun.awt.ScreenUpdater.nextEntry(Compiled Code) - sun.awt.ScreenUpdater.run(Compiled Code) - "AWT-Motif" (TID:0x4065a078, sys_thread_t:0x41432f04, state:CW) prio=5 - java.lang.Thread.run(Compiled Code) - "AWT-Input" (TID:0x4065a098, sys_thread_t:0x41411f04, state:CW) prio=5 - "AWT-EventQueue-0" (TID:0x4065a0a8, sys_thread_t:0x413f0f04, state:MW) prio=5 - sun.awt.motif.MComponentPeer.handleEvent(Compiled Code) - java.awt.Component.dispatchEventImpl(Compiled Code) - java.awt.Component.dispatchEvent(Compiled Code) - java.awt.EventDispatchThread.run(Compiled Code) - "thread applet-CaffeineMarkApplet" (TID:0x40659fd0, sys_thread_t:0x413cff04, state:CW) prio=4 - java.lang.Object.wait(Compiled Code) - sun.applet.AppletPanel.getNextEvent(Compiled Code) - sun.applet.AppletPanel.run(Compiled Code) - java.lang.Thread.run(Compiled Code) - "Finalizer thread" (TID:0x40647208, sys_thread_t:0x4138bf04, state:CW) prio=1 - "Async Garbage Collector" (TID:0x40647250, sys_thread_t:0x4136af04, state:CW) prio=1 - "Idle thread" (TID:0x40647298, sys_thread_t:0x41349f04, state:R) prio=0 - "Clock" (TID:0x40647088, sys_thread_t:0x41328f04, state:CW) prio=12 - "main" (TID:0x406470b0, sys_thread_t:0x81d9898, state:CW) prio=5 -Monitor Cache Dump: - java.lang.Object@1080340856/1080696176: owner "Thread-6" (0x4153ef04, 3 entries) - Waiting to enter: - "AWT-EventQueue-0" (0x413f0f04) - (0x0x4136af04): - Waiting to be notified: - "Async Garbage Collector" (0x4136af04) - sun.awt.AWTFinalizer@1080423576/1080745120: - Waiting to be notified: - "AWT-Finalizer" (0x4151df04) - sun.applet.AppletViewerPanel@1080400576/1080858664: - Waiting to be notified: - "thread applet-CaffeineMarkApplet" (0x413cff04) - sun.awt.motif.MToolkit@1080401552/1080865240: owner "Thread-6" (0x4153ef04, 1 entry) - Waiting to be notified: - "AWT-Motif" (0x41432f04) -Registered Monitor Dump: - Thread queue lock: - Waiting to be notified: - "main" (0x81d9898) - Name and type hash table lock: - String intern lock: - JNI pinning lock: - JNI global reference lock: - BinClass lock: - Class loading lock: - Java stack lock: - Code rewrite lock: - Heap lock: - Has finalization queue lock: - Finalize me queue lock: - Waiting to be notified: - "Finalizer thread" (0x4138bf04) - Monitor IO lock: - Child death monitor: - Event monitor: - I/O monitor: - Waiting to be notified: - "AWT-Input" (0x41411f04) - Alarm monitor: - Waiting to be notified: - "Clock" (0x41328f04) - Monitor registry: owner "Thread-6" (0x4153ef04, 1 entry) -Thread Alarm Q: - sys_thread_t 0x41432f04 [Timeout in 10 ms] - sys_thread_t 0x41411f04 [Timeout in 174 ms] diff -aruN shujit-0.2.3/gentable.rb shujit-0.2.4/gentable.rb --- shujit-0.2.3/gentable.rb Sun Oct 4 12:32:50 1998 +++ shujit-0.2.4/gentable.rb Mon Nov 30 01:01:39 1998 @@ -115,6 +115,7 @@ max_code_offset = -1 max_code_len = -1 max_constant_off = -1; +max_bytepc_off = -1; max_jumpexc_off = -1; func_arysize = 0 @@ -218,6 +219,7 @@ i += 1 while elems[i] != '62' off = elems[0].chop().hex() + i - 1 - code_addr #print "bytepcoff offset: #{off}\n" + max_bytepc_off = off if off > max_bytepc_off if init_state == STANY array = bytepc_table[opcode][0] else @@ -364,7 +366,7 @@ # constant_table[][NSTATE][] outTableToC(f, 'constant_table', constant_table, constant_arysize, max_constant_off) # bytepc_table[][NSTATE][] - outTableToC(f, 'bytepc_table', bytepc_table, bytepc_arysize, 255) + outTableToC(f, 'bytepc_table', bytepc_table, bytepc_arysize, max_bytepc_off) # jumpexc_table[][NSTATE][] outTableToC(f, 'jumpexc_table', jumpexc_table, jumpexc_arysize, max_jumpexc_off) # # jump_table[][NSTATE][] @@ -407,7 +409,7 @@ f.print "extern FuncTable func_table[][#{NSTATES}][#{func_arysize + 1}];\n\n" outTableToH(f, 'constant_table', constant_arysize, max_constant_off) - outTableToH(f, 'bytepc_table', bytepc_arysize, 255) + outTableToH(f, 'bytepc_table', bytepc_arysize, max_bytepc_off) outTableToH(f, 'jumpexc_table', jumpexc_arysize, max_jumpexc_off) # outTableToH(f, 'jump_table', jump_arysize, 255) outTableToH(f, 'jumpret_table', jumpret_arysize, 255) diff -aruN shujit-0.2.3/header shujit-0.2.4/header --- shujit-0.2.3/header Wed Jun 17 01:03:59 1998 +++ shujit-0.2.4/header Thu Jan 1 09:00:00 1970 @@ -1,10 +0,0 @@ -/* - * Copyright (C) 1998 - * SHUDO Kazuyuki - * - * Permission to use, copy, modify and distribute this software - * and its documentation for non-commercial purposes and without - * fee is hereby granted provided this copyright notice. - * - * $Id$ - */ diff -aruN shujit-0.2.3/invoker.c shujit-0.2.4/invoker.c --- shujit-0.2.3/invoker.c Sat Oct 10 19:39:09 1998 +++ shujit-0.2.4/invoker.c Thu Jan 7 14:33:56 1999 @@ -1,5 +1,5 @@ /* - * Copyright (C) 1998 + * Copyright (C) 1998,1999 * SHUDO Kazuyuki * * Permission to use, copy, modify and distribute this software @@ -20,11 +20,32 @@ */ bool_t compileAndInvokeMethod( JHandle *o, struct methodblock *mb, int args_size, ExecEnv *ee) { - int key = obj_monitor(fieldclass(&mb->fb)); + int key; + + int access; + bool_t (*norm_invoker)(JHandle*,struct methodblock *,int,ExecEnv*); + #ifdef COMPILE_DEBUG printf("\n"); - printf("compileAndInvokeMethod() is called:\n %s#%s %s\n key: %d\n", - cbName(mb->fb.clazz), mb->fb.name, mb->fb.signature, key); + printf("compileAndInvokeMethod() is called:\n %s#%s %s\n", + cbName(mb->fb.clazz), mb->fb.name, mb->fb.signature); + fflush(stdout); +#endif + + /* if compiler is disabled, call original invoker */ + if (!compiler_enabled) { +#ifdef RUNTIME_DEBUG + printf("Compiler is disabled, now call original invoker."); + fflush(stdout); +#endif + access = mb->fb.access; + norm_invoker = access2invoker(access); + goto candi_call_normal_method; + } + + key = obj_monitor(fieldclass(&mb->fb)); +#ifdef COMPILE_DEBUG + printf(" key: %d\n", key); fflush(stdout); #endif @@ -33,10 +54,11 @@ /* compile the called method */ #if 0 /* this check is not needed. */ if (!(mb->CompiledCode) && - !(mb->fb.access & (ACC_ABSTRACT | ACC_NATIVE))) { + !(mb->fb.access & (ACC_ABSTRACT | ACC_NATIVE))) #else + if (!(mb->CompiledCode)) +#endif /* if 0 */ { -#endif #ifdef COMPILE_DEBUG printf(" now compiling.\n"); fflush(stdout); #endif @@ -54,26 +76,86 @@ #ifdef COMPILE_DEBUG printf(" compilation failed...\n"); fflush(stdout); #endif - mb->invoker = (bool_t (*)(JHandle*,struct methodblock *,int,ExecEnv*)) - access2invoker(mb->fb.access); - goto candi_method_done; + access = mb->fb.access; + access &= ~ACC_MACHINE_COMPILED; + mb->fb.access = access; + +#if 0 /* can't restack if caller of this method is compiled method... */ + norm_invoker = mb->invoker = + (bool_t (*)(JHandle*,struct methodblock *,int,ExecEnv*)) + access2invoker(access); + + goto candi_call_normal_method; +#else + return FALSE; +#endif /* if 0 */ } } -candi_method_done: #ifdef COMPILE_DEBUG printf("compileAndInvokeMethod(): now call invoker.\n"); fflush(stdout); #endif monitorExit(key); return mb->invoker(o, mb, args_size, ee); + +candi_call_normal_method: + { + bool_t invoker_ret; + + invoker_ret = norm_invoker(o, mb, args_size, ee); + if (!invoker_ret) return FALSE; + + if (!(access & (ACC_ABSTRACT | ACC_NATIVE))) { + /* normal Java method */ + + /* restack is done in invokeMethod() (in runtime.c) + if this method is called by compiled method */ + + /* call ExecuteJava() */ + { + int exec_ret; + stack_item *optop, *old_optop; + int retsize; + JavaFrame *cur_frame;; + + cur_frame = ee->current_frame; + exec_ret = ExecuteJava(mb->code, ee); + old_optop = cur_frame->optop; +#ifdef EXECUTEJAVA_IN_ASM + if (cur_frame->monitor) monitorExit(obj_monitor(o)); +#endif /* EXECUTEJAVA_IN_ASM */ + cur_frame = cur_frame->prev; + ee->current_frame = cur_frame; + if (!exec_ret) return FALSE; + +#ifdef EXECUTEJAVA_IN_ASM + /* These operation is required + only with x86 assembly ver. of executeJava.c */ + retsize = ((CodeInfo *)mb->CompiledCodeInfo)->ret_size; + if (retsize != 0) { + optop = cur_frame->optop; + if (retsize == 1) { + optop[0] = old_optop[-1]; optop++; + } + else { /* retsize == 2 */ + optop[0] = old_optop[-2]; optop[1] = old_optop[-1]; optop += 2; + } + cur_frame->optop = optop; + } +#endif /* EXECUTEJAVA_IN_ASM */ + } /* call ExecuteJava() */ + } /* normal Java method */ + + return invoker_ret; + } } /* * Invoke the compiled method. */ -bool_t invokeCompiledMethod( +bool_t invokeJITCompiledMethod( JHandle *o, struct methodblock *mb, int args_size, ExecEnv *ee) { JavaFrame *old_frame, *frame; int access; @@ -93,17 +175,20 @@ /* %esp -= mb->nlocals * 4 */ #ifdef RUNTIME_DEBUG -# if 1 +# if 0 runtime_debug = 1; # else - if ((!strcmp(cbName(mb->fb.clazz), "com/sun/java/swing/text/PlainView")) - && (!strcmp(mb->fb.name, "paint"))) + if ((!strcmp(cbName(mb->fb.clazz), "sun/misc/Ref")) + && (!strcmp(mb->fb.name, ""))) + runtime_debug = 1; + else if ((!strcmp(cbName(mb->fb.clazz), "java/util/ResourceBundle")) + && (!strcmp(mb->fb.name, "findBundle"))) runtime_debug = 1; - else if ((!strcmp(cbName(mb->fb.clazz), "sun/io/CharToByteISO8859_1")) - && (!strcmp(mb->fb.name, "convert"))) + else if ((!strcmp(cbName(mb->fb.clazz), "javax/swing/UIManager")) + && (!strcmp(mb->fb.name, "maybeInitialize"))) runtime_debug = 1; - else if ((!strcmp(cbName(mb->fb.clazz), "java/lang/FloatingDecimal")) - && (!strcmp(mb->fb.name, "toJavaFormatString"))) + else if ((!strcmp(cbName(mb->fb.clazz), "java/io/PrintStream")) + && (!strcmp(mb->fb.name, "println"))) runtime_debug = 1; else runtime_debug = 0; @@ -113,14 +198,16 @@ #ifdef RUNTIME_DEBUG if (runtime_debug) { printf("\n"); - printf("invokeCompiledMethod() is called:\n %s#%s %s\n", + printf("invokeJITCompiledMethod() is called:\n %s#%s %s\n", cbName(mb->fb.clazz), mb->fb.name, mb->fb.signature); if (exceptionOccurred(ee)) { printf(" An exception not handled remains!\n"); } fflush(stdout); +#if 0 showStackFrames(ee); +#endif } /* if (runtime_debug) */ #endif /* RUNTIME_DEBUG */ @@ -143,53 +230,49 @@ { struct methodblock *prev_method = old_frame->current_method; if (prev_method) { - if (prev_method->fb.access & ACC_MACHINE_COMPILED) { - /* is expected to be equal to if (prev_method->CompiledCode) */ + if (prev_method->CompiledCode) { /* called by compiled method */ frame->vars = (stack_item *)old_frame->returnpc; goto restack_done; } } + } - /* called by normal Java or native method */ - restack: - { - CodeInfo *info; - char *argsizes; - stack_item *args; - - info = (CodeInfo *)mb->CompiledCodeInfo; - if (!info) prepareCompiledCodeInfo(ee, mb); - /* make arg. size table for restack */ - - argsizes = info->argsizes; - args = frame->vars; /* points to JVM stack */ - - frame->vars = native_vars; - - while (*argsizes) { - if (*argsizes == 1) { - native_vars[0] = args[0]; - native_vars--; args++; - } - else { - native_vars[-1] = args[0]; - native_vars[0] = args[1]; - native_vars -= 2; args += 2; - } - argsizes++; - } /* while (*argsizes) */ - } /* restack: */ + /* called by normal Java or native method */ + { /* restack */ + char *argsizes; + stack_item *args; + + argsizes = ((CodeInfo *)mb->CompiledCodeInfo)->argsizes; + args = frame->vars; /* points to JVM stack */ + + frame->vars = native_vars; + + while (*argsizes) { + if (*argsizes == 1) { + native_vars[0] = args[0]; + native_vars--; args++; + } + else { + native_vars[-1] = args[0]; + native_vars[0] = args[1]; + native_vars -= 2; args += 2; + } + argsizes++; + } /* while (*argsizes) */ + } /* restack */ - restack_done: - } +restack_done: #ifdef RUNTIME_DEBUG if (runtime_debug) { + CodeInfo *info = (CodeInfo *)mb->CompiledCodeInfo; + printf("call compiled method.\n"); printf(" o:0x%08x, mb:0x%08x, args_size:%d, ee:0x%08x\n", (int)o, (int)mb, args_size, (int)ee); printf(" mb->CompiledCode: 0x%08x\n", (int)mb->CompiledCode); + printf(" code size: 0x%08x\n", (info ? info->code_size : 0)); fflush(stdout); { diff -aruN shujit-0.2.3/memo shujit-0.2.4/memo --- shujit-0.2.3/memo Sun Oct 4 13:06:12 1998 +++ shujit-0.2.4/memo Thu Jan 1 09:00:00 1970 @@ -1,378 +0,0 @@ -最適化 - - スタック上の要素の性質 (例: 配列のサイズ) を trace し、 - 省ける各種チェック (例: 添字の範囲) を省く。仮想スタックライブラリを用意。 - - stack 上の倍精度浮動小数点数を 8バイト境界に align する。 - - VolanoMark を試す。 - - CM3 に対する compiled code を見る。 - - クロック数を計測。 - - invoke{,Synchronized}JavaMethod() の呼び出し回数を減らす。 - JavaFrame を C のスタック上に確保する。 - 障害: - JavaFrame のメンバ ostack と optop が同じ領域にあることを - 仮定したコードがある。 - JavaFrame の存在を仮定したコードが多い。 - - JavaFrame の作成を省く。 - - Object# の呼び出しを削除する。 - invokeignored_quick への recode 条件を調べる。 - - bytecode の静的最適化。 - invokeignored_quick への変換。 - [ifa]store{,_N}, [ifa]load{,_N} で、メモリからの読みだしを省く。 - - invoke(Synchronized)JavaMethod() の代替を用意、処理を軽減する。 - - CompilerContext をむやみに free(), malloc() しない。 - 排他制御が必要。-> thread library を使ってしまう。 - - native 命令列の書き換え。 - invoke -> invokevirtual*object* 相当など。 - obj_array_methodtable() ではなく obj_methodtable() が使える。 - - vars[0..] をレジスタにのせてキャッシュする。 - - lcmp, ifXX といった定番コード列について最適化。 - - 例外ハンドラを offset ではなく絶対アドレスで扱う。 - - lookupswitch 命令の検索アルゴリズムを改良する。 - - Address Generation Interlock(AGI) (MMX 本 pp.95,99) を避ける。 - - ジャンプ先を 8バイト境界に align。 - - invokeignored_quick にて、スタックのキャッシュ内容を無駄に push している。 - -Todo - - Win32 に移植。 - - よりハードなテスト。 - MC のコンパイルなど。 - - SignalError() の第 3引数として文字列を渡しているものをチェック。 - - JMP 命令の、E9 (引数 4 バイト) から EB (引数 1 バイト) への書き換え - - UseLosslessQuickOpcodes = TRUE でよいようにする。 - invokevirtual{,object}_quick で無理がある。 - インタプリタに実行させた場合に、optop が返り値の分増やされない - あらかじめ methodblock を取得する必要があるが、それができない。 - - exception handler でのスタックの扱い - クリア (frame->optop = frame->ostack) - 例外オブジェクトを push - -調査 - - invokeignored_quick への書き換え規則。 - -Idea - - JVM の挙動を変更する手段としての JIT compiler。 - javac の、フックをかけられる箇所を探す。 - -Done - - __{mul,div,mod}di3 を呼び出さないようにする。 - 64bit 整数の乗算、__muldi3 は自前のコードを用意した。 - 除、剰余算は inline で生成するとコードサイズが大きくなってしまう。 - - compiled code のサイズの表を作成、表示 - CODESIZE_DEBUG - - invokeignored_quick で pc[2] == 0 の場合、null check コードを省く。 - - x86 の CMOVcc (および FCMOVcc) の適用を検討する。 - w/ MMX でない Pentium 以前は {,F}CMOVcc を持たない。 - - restack を省く。native method の呼び出し時は省けない。 - - native 命令列の書き換え。 - new -> new_quick - - boudary check, null check などの諸チェックを省いた版も - コンパイルできるようにする。 - - ジャンプ前の state からジャンプ後の state へ移行コードが必要。 - tableswitch, lookupswitch はトランポリン方式で解決。 - -移植時の注意 - - 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() の定義に - 影響を受ける。 - - stack 上の要素が実行環境依存になる。 - jsr, ret 命令 - - JVM と X86 でスタックの成長方向が逆。 - 64bit (long,double) の値の 32bit x 2 への分割方法は - JVM の仕様としては未定義(!)。 - -JVM, JIT compiler のテスト - - JDK の regression test: javasrc/test/ - - Kaffe のもの - -known bugs - - 無限ループ実行中のスレッドが、 - 他スレッドから Thread#stop() しても実行停止しない。 - (genunix/java/green_threads/src/threads_md.c: - sysThreadPostException() も効かない。) - 他の JIT (Win32, Sol2) with Green Threads ではどうか調べる。 - TYA 1.0 でも同じ現象が起きる。 - -TYA 1.0 の bugs - - 上記 known bugs。:) - - 5 次元以上の配列を作成するコードをコンパイルできない。 - - NaN を integer に変換すると 0 にならない。 - - null を throw しようとすると、制御がおかしくなる。 - -JDK 1.1.6, Version 2 (by Steve Byrne) - - native method, sun.awt.motif.MChoicePeer#pReshape (IIII)V - at sun/awt/motif/MChoicePeer#pReshape (IIII)V - at sun/awt/motif/MComponentPeer#setBounds (IIII)V - (javasrc/src/genunix/sun/awt_Choice.c l.348) - にてエラーメッセージ - Tried to free bogus memory XXXXXXX, ignored - Motif or Xt のバグ。JDK/README.linux の Other issues に記述あり。 - JDK/demo/awt-1.1/symboltest/ にて、appletviewer index.html でテスト。 - -旧版の bugs - - exception_handler にて、スタックをクリアした後、 - 例外オブジェクトを push していない - - secondPass() にて goto_w で offset を 2バイトで解釈している。 - - compileOpcode in compile.c にて、 - invokevirtual{,object}_quick の定数解決が足りない。 - <- UseLosslessQuickOpcodes = FALSE なので、手をつけようがない。 - - showObjectBody() in runtime.c が、null object に対応していない。 - -各 (内部) 命令で行われている各種チェック - - iaload, laload, baload, caload, saload, iastore, bastore, castore, sastore - null, boundary - - aastore - null, boundary, instanceof - - getfield, getfield2, putfield, putfield2 - null - - invokevirtual, invokespecial, invokeinterface - null - - new - class access - - newarray, anewarray - negative array size - - arraylength - null - - athrow - null - - monitorenter, monitorexit - null - - nonnull_quick - null - -各種チェックに関係する内部命令およびマクロ in code.c - array_check, AASTORE_TEST(), FIELD_ACC(), - NEW_TEST(), NEWARRAY_TEST(), ARRAYLENGTH_TEST(), - NULL_TEST() - - -実行環境中立な実行コンテクストの取り出し - code.c - invoke* にて ee->current_frame->lastpc を設定。 - - -アーキテクチャ依存のコード - code.c - code.h - assembly code - self rewrite のためのオフセット (NEW_REWRITE_OFFSET_#) - gentable.rb - compiledCode() in code.c 中の定数抽出、オフセット計算 - compile.c - jump 命令の生成 (in writeForAnOpcode()) - invoker.c - スタックの積み直し (JVM -> native) - runtime.c - スタックの積み直し (native -> JVM) -非依存のコード - compiler.[hc] - computil.c - - -データ構造 - struct CatchFrame *cf = mb->exception_table; - cf->compiled_CatchFrame = (void *)オフセット in native code; - - -コンパイルに必要なもの - egcs or gcc2 - GNU binutils の objdump - ruby - constants.c, constants.h の生成 - - -コンパイルの手順 - makePCTable() - 命令の分解 - method head, exc. handler, method tail の付加 - processAnOpcode() - 代替 opcode を求める - opcode, state, bytecode PC を表に登録 - state, bytecode PC を update - writeCode() - writeForAnOpcode() - native code をバッファに書く - 定数を解決 - jump 命令 - 状態遷移コードを挿入 - 表に登録 - native PC を update - resolveJumpInstructions() - jump 表を解決 - makeExcTable() - 例外表に native PC (offset) を書き込む - resolveExcRetSw() - 以下を解決 - bytepcoff - exc. handler への jump - method tail への jump - tableswitch, lookupswitch の native PC 表を作成 - native code をコピー - 関数呼び出しを解決 - -定数 - bipush - value - ldc2_w - val[32:63], val[0:31] - iload - index * 4 - lload - index * 4, (index + 1) * 4 - istore - index * 4 - lstore - index * 4, (index + 1) * 4 - iinc - (signed char *pc)[2], pc[1] * 4 - jsr - native offset of a next instruction - ret - index * 4 - tableswitch - low, high, - lookupswitch - npairs,
- getstatic - address - getstatic2 - address, address + 4 - putstatic - address - putstatic2 - address, address + 4 - getfield - slot - getfield2 - slot - putfield - slot - putfield2 - slot - invokevirtual - invokevirtual_quick - invokevirtualobject_quick - args_size, methodIndex, retsize - invokespecial - args_size, method, local_var_space, retsize - invokestatic - args_size, method, local_var_space, retsize - invokeinterface - args_size, guessptr, imethod, retsize - new - cb - newarray - type - anewarray - elem_clazz - checkcast - cb - instanceof - cb - multianewarray - dimensions, arrayclazz - invokeignored_quick - args_size - new_quick - cb - -jump - ifeq, ne, lt, ge, gt, le - JP_ROP " " STR(ADDR_JP) - if_icmpeq, ne, lt, ge, gt, le - JP_ROP " " STR(ADDR_JP) - goto - jmp STR(ADDR_JP) - jsr - jmp STR(ADDR_JP) - ret - __asm__("addl %0,%%eax\n\t" /* eax += nativecode */ - "jmp %%eax" : - : "m" (nativecode)); - ifnull - jz STR(ADDR_JP) - ifnonnull - jnz STR(ADDR_JP) - -条件分岐 - ifeq, ne, lt, ge, gt, le - if_icmpeq, ne, lt, ge, gt, le - ifnull - ifnonnull - tableswitch - lookupswitch -ジャンプ - goto - jsr -? - ret - -x86 jump instructions -je - 74 XX - 0f 84 XX XX XX XX -jne - 75 - 0f 85 -jl - 7c - 0f 8c -jge - 7d - 0f 8d -jg - 7f - 0f 8f -jle - 7e - 0f 8e -jz == je -jnz == jne -jmp - eb - e9 - -ex) ifeq 4 -> 2 - code_ifeq - (cmpl 含む) - jne - state_to2(state:4) - jmp ジャンプ先 -ex) ifeq 4 -> 4 - code_ifeq - (cmpl 含む) - je ジャンプ先 - - -callee head: 8 byte - 55 pushl %ebp - 89 e5 movl %esp,%ebp - 83 ec XX subl $0xXX,%esp - 57 pushl %edi - 56 pushl %esi -( 53 pushl %ebx) - -callee tail: 7 byte - 8d 65 YY leal 0xffffffYY(%ebp),%esp -( 5b popl %ebx) - 5e popl %esi - 5f popl %edi - c9 leave - c3 ret - -0xYY = 0x100 - 0xXX - (4 * pushしたレジスタ数) diff -aruN shujit-0.2.3/postcmpl.rb shujit-0.2.4/postcmpl.rb --- shujit-0.2.3/postcmpl.rb Thu Jan 1 09:00:00 1970 +++ shujit-0.2.4/postcmpl.rb Sun Jan 3 17:48:48 1999 @@ -0,0 +1,10 @@ +#!/usr/local/bin/ruby + +while gets() + # translate "leal LC...,%esi" to "pushl LC..." + # Linux: .LC..., FreeBSD: LC... + gsub! /leal (\.?LC.*),.*/, 'pushl \1' + # skip PUSH ... + next if /PUSH/ + print +end diff -aruN shujit-0.2.3/runtime.c shujit-0.2.4/runtime.c --- shujit-0.2.3/runtime.c Sat Oct 3 10:58:25 1998 +++ shujit-0.2.4/runtime.c Thu Jan 7 14:19:54 1999 @@ -1,5 +1,5 @@ /* - * Copyright (C) 1998 + * Copyright (C) 1998,1999 * SHUDO Kazuyuki * * Permission to use, copy, modify and distribute this software @@ -12,6 +12,55 @@ #include "compiler.h" #include "monitor.h" /* for monitor{Enter,Exit}() and macro BINCLASS_*() */ +#ifdef JITDO +#include "jitdo/NET_shudo_jitdo_Proxy_old.h" +#endif /* JITDO */ + + +#ifdef EXC_BY_SIGNAL +/* + * show contents of structure sigcontext + */ +void showSigcontext(struct sigcontext *sc) { + printf("EAX: %08x, ECX: %08x, EDX: %08x, EBX: %08x\n", +#if defined(linux) + sc->eax, sc->ecx, sc->edx, sc->ebx +#elif defined(__FreeBSD__) + sc->sc_eax, sc->sc_ecx, sc->sc_edx, sc->sc_ebx +#endif + ); + + printf("ESI: %08x, EDI: %08x\n", +#if defined(linux) + sc->esi, sc->edi +#elif defined(__FreeBSD__) + sc->sc_esi, sc->sc_edi +#endif + ); + + printf("ESP: %08x, EBP: %08x EIP: %08x\n", +#if defined(linux) + sc->esp, sc->ebp, sc->eip +#elif defined(__FreeBSD__) + sc->sc_esp, sc->sc_ebp, sc->sc_eip +#endif + ); + +#if defined(linux) + printf("ESP at signal: %08x\n", sc->esp_at_signal); +#endif + +#if defined(linux) + printf("SS: %04x, CS: %04x, DS: %04x, ES: %04x, FS: %04x, GS: %04x\n", + sc->ss, sc->cs, sc->ds, sc->es, sc->fs, sc->gs +#elif defined(__FreeBSD__) + printf("SS: %04x, CS: %04x, DS: %04x, ES: %04x\n", + sc->sc_ss, sc->sc_cs, sc->sc_ds, sc->sc_es +#endif + ); +} +#endif /* EXC_BY_SIGNAL */ + /* * returns: return value size. -1 if an exception occurred. @@ -20,11 +69,17 @@ #ifdef RUNTIME_DEBUG int runtime_debug, #endif - ExecEnv *ee, int narg, int retsize, + ExecEnv *ee, int args_size, int retsize, JHandle *obj, struct methodblock *method, int bytepcoff, stack_item *stackpointer) { + JavaFrame *cur_frame; /* ee->current_frame */ int access; CodeInfo *info; + int dont_compile; + /* !compiler_enabled && (method->invoker == sym_compileAndInvokeMethod) */ +#ifdef RUNTIME_DEBUG + info = (CodeInfo *)method->CompiledCodeInfo; +#endif #ifdef RUNTIME_DEBUG if (runtime_debug) { @@ -35,15 +90,16 @@ /* set ee->current_frame->lastpc */ { - JavaFrame *cur_frame = ee->current_frame; - struct methodblock *cur_mb = cur_frame->current_method; - cur_frame->lastpc = cur_mb->code + bytepcoff; + cur_frame = ee->current_frame; + cur_frame->lastpc = cur_frame->current_method->code + bytepcoff; #ifdef RUNTIME_DEBUG if (runtime_debug) { + struct methodblock *cur_mb = cur_frame->current_method; + printf(" ee: 0x%08x\n", (int)ee); printf(" current_frame: 0x%08x\n", (int)cur_frame); - printf(" narg, retsize: %d, %d, %d\n", - narg, retsize, method->nlocals); + printf(" args_size, retsize, nlocals: %d, %d, %d\n", + args_size, retsize, method->nlocals); printf(" obj: 0x%08x\n", (int)obj); printf(" method: 0x%08x\n", (int)method); fflush(stdout); @@ -61,11 +117,6 @@ #endif } - access = method->fb.access; - - if (access & ACC_STATIC) - obj = (JHandle *)(cbHandle(method->fb.clazz)); - #ifdef RUNTIME_DEBUG /* let user know calling normal Java method */ if ((void *)method->invoker == sym_invokeJavaMethod) { @@ -81,23 +132,41 @@ #endif /* RUNTIME_DEBUG */ - info = (CodeInfo *)method->CompiledCodeInfo; - if (!info) info = prepareCompiledCodeInfo(ee, method); + access = method->fb.access; + stackpointer += (args_size - 1); + +#if 0 /* make CM3 worse, but Linpack better */ +if (access & ACC_STATIC) + obj = (JHandle *)(cbHandle(method->fb.clazz)); +#endif +#if 0 +if (access & ACC_STATIC) { + printf("invokeMethod:\n"); + printf("\torig: 0x%08x\n", (int)obj); + obj = (JHandle *)(cbHandle(method->fb.clazz)); + printf("\tnew : 0x%08x\n", (int)obj); +} +#endif - /* restack from native stack to JVM stack */ - stackpointer += (narg - 1); - if (method->fb.access & ACC_MACHINE_COMPILED) { + if ((access & ACC_MACHINE_COMPILED) && /* is expected to be equal to: - ((method->invoker == invokeCompiledMethod) || - (method->invoker == compileAndInvokeMethod)) + ((method->invoker == sym_invokeJITCompiledMethod) || + (method->invoker == sym_compileAndInvokeMethod)) */ - /* compiled method */ - ee->current_frame->returnpc = (unsigned char *)stackpointer; + (compiler_enabled || (method->invoker != sym_compileAndInvokeMethod)) + /* not (invoker is compiler, but the method is not to be compiled) */ + ) { + /* call compiled method */ + cur_frame->returnpc = (unsigned char *)stackpointer; } - else { /* normal Java or native method */ + else { + /* call normal Java or native method */ + /* restack from native stack to JVM stack */ stack_item *sp = stackpointer; - stack_item *optop = ee->current_frame->optop; - char *argsizes = info->argsizes; + stack_item *optop = cur_frame->optop; + char *argsizes; + + argsizes = ((CodeInfo *)method->CompiledCodeInfo)->argsizes; while (*argsizes) { if (*argsizes == 1) { @@ -112,6 +181,8 @@ argsizes++; } } + + #ifdef RUNTIME_DEBUG if (runtime_debug) { char *sig = method->fb.signature; @@ -140,7 +211,7 @@ if (access & ACC_SYNCHRONIZED) printf(" synchronized"); if (access & ACC_ABSTRACT) printf(" abstract"); printf("\n"); - printf(" args_size: %d\n", narg); + printf(" args_size: %d\n", args_size); fflush(stdout); i = 0; if (!(access & ACC_STATIC)) { @@ -151,7 +222,7 @@ i++; } if (sig[0] == '(') sig++; - for (; i < narg; i++) { + for (; i < args_size; i++) { JHandle *arg = optop[-i].h; if ((sig[0] == 'D') || (sig[0] == 'J')) i++; printf(" 0x%08x @ 0x%08x ", (int)arg, (int)(optop - i)); @@ -163,30 +234,28 @@ } #endif /* RUNTIME_DEBUG */ - if (!(method->invoker(obj, method, narg, ee))) + if (!(method->invoker(obj, method, args_size, ee))) return -1; + /* obj is required for enter/exit a monitor of the object. */ if (!(access & (ACC_ABSTRACT | ACC_NATIVE | ACC_MACHINE_COMPILED))) { /* normal Java method */ int exec_ret; - stack_item *optop; - stack_item *old_optop; - JavaFrame *cur_frame; - + stack_item *optop, *old_optop; + exec_ret = ExecuteJava(method->code, ee); - cur_frame = ee->current_frame; + cur_frame = ee->current_frame; /* reload */ old_optop = cur_frame->optop; #ifdef EXECUTEJAVA_IN_ASM - if (cur_frame->monitor) - monitorExit(obj_monitor(obj)); + if (cur_frame->monitor) monitorExit(obj_monitor(obj)); #endif cur_frame = cur_frame->prev; ee->current_frame = cur_frame; if (!exec_ret) return -1; - + #ifdef EXECUTEJAVA_IN_ASM /* These operation is required - with only x86 assembly ver. of executeJava.c */ + only with x86 assembly ver. of executeJava.c */ if (retsize != 0) { optop = cur_frame->optop; if (retsize == 1) { @@ -216,7 +285,11 @@ } #endif - return info->ret_size; +#if 0 + return ((CodeInfo *)method->CompiledCodeInfo)->ret_size; +#else + return retsize; +#endif } @@ -257,6 +330,13 @@ if (obj_flags(obj) == T_NORMAL_OBJECT) { mtable = obj_methodtable(obj); cb = mtable->classdescriptor; +#ifdef JITDO + if ((mtable == proxy_methodtable) && (REMOTE_FLAG(ee))) { + /* obj instanceof Proxy*/ + cb = unhand((HNET_shudo_jitdo_Proxy *)obj)->clazz; + mtable = cbMethodtable(cb); + } +#endif } else { cb = classJavaLangObject; mtable = cbMethodTable(cb); @@ -342,6 +422,12 @@ int found; int i; +#ifdef RUNTIME_DEBUG + if (runtime_debug) { + printf(" searchCatchFrame() called.\n"); fflush(stdout); + } +#endif + methodClazz = fieldclass(&mb->fb); constant_pool = cbConstantPool(methodClazz); type_table = constant_pool[CONSTANT_POOL_TYPE_TABLE_INDEX].type; @@ -475,7 +561,7 @@ sizearr[index++] = 1; if (*sig == 'L') while (*(sig++) != ';'); else if (*sig == '[') { - sig++; + do { sig++; } while (*sig == '['); if (*sig == 'L') while (*(sig++) != ';'); else sig++; } diff -aruN shujit-0.2.3/tsctest/x86tsc.c shujit-0.2.4/tsctest/x86tsc.c --- shujit-0.2.3/tsctest/x86tsc.c Wed Aug 26 18:21:33 1998 +++ shujit-0.2.4/tsctest/x86tsc.c Sun Jan 3 17:27:04 1999 @@ -1,5 +1,5 @@ /* - * Copyright (C) 1998 + * Copyright (C) 1998,1999 * SHUDO Kazuyuki * * Permission to use, copy, modify and distribute this software diff -aruN shujit-0.2.3/tsctest/x86tsc.h shujit-0.2.4/tsctest/x86tsc.h --- shujit-0.2.3/tsctest/x86tsc.h Sat Aug 15 19:29:12 1998 +++ shujit-0.2.4/tsctest/x86tsc.h Sun Jan 3 17:27:04 1999 @@ -1,5 +1,5 @@ /* - * Copyright (C) 1998 + * Copyright (C) 1998,1999 * SHUDO Kazuyuki * * Permission to use, copy, modify and distribute this software diff -aruN shujit-0.2.3/txt/acc_to_frame shujit-0.2.4/txt/acc_to_frame --- shujit-0.2.3/txt/acc_to_frame Thu Jan 1 09:00:00 1970 +++ shujit-0.2.4/txt/acc_to_frame Thu Aug 27 13:16:13 1998 @@ -0,0 +1,71 @@ +access to JavaFrame + +code.c + +l.235 methodhead + %esi = ee->current_frame->vars; +l.2902 ireturn + %edi = ee->current_frame->prev->optop; +l.2934 lretrun + %edi = ee->current_frame->prev->optop; +l.3267 invoke* + %edi = ee->current_frame->optop; +l.3438 new + %eax = ee->current_frame->current_method; + +invoker.c + +invokeCompiledMethod() +l.113 + showStackFrames(ee); +l.117 create new frame + invoke*JavaMethod(); +l.124 + frame = ee->current_frame; +l.135 restack + prev = frame->prev; +l.141 if called by compiled method + frame->vars = (stack_item *)prev->returnpc; +l.157 restack + args = frame->vars; /* points to JVM stack */ +l.159 restack + frame->vars = native_vars; +l.187 RUNTIME_DEBUG + ee->current_frame->vars; +l.224 monitor exit + if (frame->monitor) +l.226 + ee->current_frame = frame->prev; + +runtime.c + +invokeMethod() +l.35 + ee->current_frame->lastpc = + ee->current_frame->current_method->code + bytepcoff; +l.91 if call compiled method + ee->current_frame->returnpc = (unsigned char *)stackpointer; +l.95 if call normal Java method + optop = ee->current_frame->optop; +l.172 if call normal Java method + cur_frame = ee->current_frame; +l.175 + if (cur_frame->monitor) +l.178 + cur_frame = cur_frame->prev; + ee->current_frame = cur_frame; +l.185 + optop = cur_frame->optop; +l.192 + cur_frame->optop = optop; +l.199 + optop = ee->current_frame->optop; + +multianewarray() +l.300 + optop = ee->current_frame->optop; + +searchCatchFrame() +l.426 /* push exception object */ + ee->current_frame->optop = ee->current_frame->ostack; + (ee->current_frame->optop++)->h = ee->exception.exc; diff -aruN shujit-0.2.3/txt/benchmark-505EX shujit-0.2.4/txt/benchmark-505EX --- shujit-0.2.3/txt/benchmark-505EX Thu Jan 1 09:00:00 1970 +++ shujit-0.2.4/txt/benchmark-505EX Mon Jan 4 22:02:46 1999 @@ -0,0 +1,106 @@ +SONY PCG-505EX + Pentium/233MHz + libc5.4.44 + + +[TYA 付属のもの] + +* "Linux_JDK_1.1.7_v1a_green_threads" + plain TYA12 981212 981228 +Sieve 97 316 399 400 times +TestOpcodeField 4139 1307 1307 1308 msec +TestOpcodeStatic 3065 428 257 278 msec +TestFinalStatic 11942 2100 772 772 msec +Iview Valetta.jpg 438 463 507 514 msec + +* JDK 1.1.6v5 for Linux (ported by Steve Byrne) + plain TYA11v3 shuJIT023 +Sieve 97 317 400 times +TestOpcodeField 4138 1308 1308 msec +TestOpcodeStatic 3087 514 278 msec +TestFinalStatic 11878 5618 5235 msec +Iview Valetta.jpg 441 463 505 msec + FIELD_ACC() から NULL_TEST() を省いた shuJIT で TestOpcodeField は 1201 + + +[Linpack Benchmark -- Java Version] + +* 117v1a +plain TYA12 shuJIT981228 +1.918 5.049 5.323 + +* 116v5 +plain TYA11v4 shuJIT023 +1.918 5.086 5.323 + + +[E2 1MB 暗号化] +java EvalLargeData + +* 117v1a + plain TYA12 981212 981228 +128 806 326 359 383 +192 800 314 349 371 +256 800 314 346 370 + +* 116v5 + plain TYA11v3 shuJIT023 +128 792 304 350(280) msec +192 788 307 350(284) msec +256 797 303 346(279) msec + ()内は NO_CHECK 版 + + +[CaffeineMark 3.0] + +interpreter + 116v2 116v5 117v1a +Sieve 434 436 439 +Loop 499 484 484 +Logic 504 501 501 +String 821 773 780 +Float 444 443 444 +Method 464 466 467 +Graphics791 671 670 +Image 162 267 389 +Dialog 93 86 98 +CM3 392 399 423 + +TYA (1.2 から 117v1a) + 1.0 1.1 1.1v3 1.2 +Sieve 820 818 817 825 +Loop 1564 1562 1546 1547 +Logic 2990 2897 2921 2899 +String 1479 1456 1416 1382 +Float 1072 988 989 994 +Method 842 910 906 887 +Graphics729 712 677 703 +Image 560 281 241 393 +Dialog 95 87 88 93 +CM3 835 759 740 787 + +shuJIT (981227 から 117v1a) + 0.2.3 981227 981228 +Sieve 893 892 893 +Loop 1708 1706 1716 +Logic 2919 2888 2916 +String 1030 1014 1028 +Float 932 925 920 +Method 137 150 155 +Graphics515 503 471 +Image 74 304 448 +Dialog 85 89 84 +CM3 498 588 609 + + 8/18 NO_CHECK(8/19) +Sieve 895 960 *2 +Loop 1717 2048 *1 +Logic 2919 2902 +String 1034 1044 +Float 1038 1317 *1 +Method 120 138 +Graphics529 686 *2 +Image 503 226 ばらつく +Dialog 86 91 +CM3 618 628 + *1 効果大 *2 効果そこそこ diff -aruN shujit-0.2.3/txt/benchmark-SS3000 shujit-0.2.4/txt/benchmark-SS3000 --- shujit-0.2.3/txt/benchmark-SS3000 Thu Jan 1 09:00:00 1970 +++ shujit-0.2.4/txt/benchmark-SS3000 Wed Jan 6 23:55:55 1999 @@ -0,0 +1,69 @@ +TOSHIBA Dynabook SS 3000 + Pentium/233MHz + glibc2.0.7 + + +[TYA 付属のもの] + plain TYA12 990104 +Sieve 98 316 399 times +TestOpcodeField 4078 1309 1309 msec +TestOpcodeStatic 3094 429 279 msec +TestFinalStatic 12298 4833(*) 773(*) msec +Iview Valetta.jpg 456 482 647 msec + (*) 非常にばらつく TYA12: 4833-10668, 990104: 773-7469 + + +[Linpack Benchmark -- Java Version] +plain TYA12 990104 +1.973 5.086 4.213 + + +[E2 1MB 暗号化] +java EvalLargeData + + plain TYA12 990104 +128 845 363 458 +192 859 362 465 +256 855 384 481 + + +[CaffeineMark 3.0] +interpreter + 117v1a +Sieve 440 +Loop 498 +Logic 502 +String 764 +Float 446 +Method 461 +Graphics574 +Image 314 +Dialog 79 +CM3 391 + +TYA + 1.2 1.2(*) +Sieve 822 780 +Loop 1558 1404 +Logic 2887 2872 +String 1410 1372 +Float 993 915 +Method 888 877 +Graphics605 571 +Image 320 312 +Dialog 71 65 +CM3 735 699 + (*) EXCEPTIONS_BY_SIGNALS を #undef + +shuJIT + 990104 990106 +Sieve 890 891 +Loop 1712 1710 +Logic 2882 2891 +String 1015 1007 +Float 1038 1030 +Method 146 144 +Graphics472 481 +Image 303 304 +Dialog 63 63 +CM3 567 567 diff -aruN shujit-0.2.3/txt/code.o-each-cc shujit-0.2.4/txt/code.o-each-cc --- shujit-0.2.3/txt/code.o-each-cc Thu Jan 1 09:00:00 1970 +++ shujit-0.2.4/txt/code.o-each-cc Thu Jan 7 12:23:42 1999 @@ -0,0 +1,27 @@ +× gcc-2.7.2.3 + 5fc6: 8d b3 1c 01 00 leal 0x11c(%ebx),%esi + 5fcb: 00 + 5fc8: R_386_GOTOFF .rodata + 5fcc: ff 36 pushl (%esi) +○ egcs-1.0.3 (2.90.29 19980515) + 5f6e: ff b3 1c 01 00 pushl 0x11c(%ebx) + 5f73: 00 + 5f70: R_386_GOTOFF .rodata +○ egcs-1.1 (2.91.57 19980901) + 5e84: ff b3 20 01 00 pushl 0x120(%ebx) + 5e89: 00 + 5e86: R_386_GOTOFF .rodata +○ egcs-1.1-2 (2.91.57 19980901) + 5e84: ff b3 20 01 00 pushl 0x120(%ebx) + 5e89: 00 + 5e86: R_386_GOTOFF .rodata +× egcs-2.92.5-19981015 + 60e8: 8d b3 20 01 00 leal 0x120(%ebx),%esi + 60ed