diff -aruN shujit-0.6.5/ChangeLog shujit/ChangeLog --- shujit-0.6.5/ChangeLog Tue Sep 5 21:17:04 2000 +++ shujit/ChangeLog Wed Sep 13 19:35:22 2000 @@ -1,5 +1,53 @@ $Id$ +[20000913] + +末尾再帰を、メソッド先頭へのジャンプに変換する最適化を実装。 +マクロ ELIMINATE_TAIL_RECURSION (compiler.h) で有効になる。 +このために、内部命令 invoke_recursive{,_1,_2,_3} と start を用意。 +(code.c, compile.c, opcode_internal.h) + +0.6.6 リリース。 + +[20000912] + +(MetaVM) 遠隔操作を行わないプログラムがきちんと動作するようになった。 + +[20000911] + +static bind 可能なメソッドの呼び出しで、コンパイル済みかどうかの判定を省く +ために、あらかじめコンパイルしてしまうことで判定を省くオプション +EAGER_COMPILATION を用意。 +(compiler.h) + +[20000910] + +メソッドの末尾が return, [ifald]return 命令で +内部命令 methodtail へのジャンプを省ける場合には省くようにした。 +(compile.c) + +[20000909] + +compiled code 中で例外を発生させるために、これまでは +%eax に例外の名前 (char * 型) を、%edx にメッセージ (char * 型) を +入れて内部命令 exc_handler を実行していたところ、 +%eax には例外の ID (unsigned char 型) を入れるように変更した。 +生成コード量の削減のため。 +例えば、内部命令 array_check のサイズは 38 バイトから 30 バイトに減った。 +(code.c, code.h) + +配列の境界チェックの際に、これまでは + check index < 0, %edi = length, check index >= length +という順で処理してきたところ、length の取得を最初に行うようにした。 +Linpack benchmark: 13.205 -> 13.464 と微妙に向上 (Pentium II / 333 MHz)。 +(code.c) + +[20000906] + +(MetaVM) MetaVM がきちんと動作するように修整を始めた。 +ついでに、これまで JDK 1.1.X でしか動作しなかったので、 +JDK 1.2 以降をターゲットに作業開始。 + [20000905] JIT 用の例外表 (throwentry 型) の中でバイトコード上プログラムカウンタを diff -aruN shujit-0.6.5/NET/shudo/metavm/MetaVM.java shujit/NET/shudo/metavm/MetaVM.java --- shujit-0.6.5/NET/shudo/metavm/MetaVM.java Tue Mar 30 18:13:03 1999 +++ shujit/NET/shudo/metavm/MetaVM.java Tue Sep 12 21:00:28 2000 @@ -2,7 +2,7 @@ This file is part of shuJIT, Just In Time compiler for Sun Java Virtual Machine. - Copyright (C) 1998,1999 SHUDO Kazuyuki + Copyright (C) 1998,1999,2000 SHUDO Kazuyuki This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -38,6 +38,7 @@ /* enable/disable TCP_NODELAY (disable/enable Nagle's Algorithm) */ protected static boolean load_class_locally = false; /* always load classes locally */ + static { Properties props = System.getProperties(); diff -aruN shujit-0.6.5/NET/shudo/metavm/ObjectID.java shujit/NET/shudo/metavm/ObjectID.java --- shujit-0.6.5/NET/shudo/metavm/ObjectID.java Tue Mar 2 00:49:56 1999 +++ shujit/NET/shudo/metavm/ObjectID.java Tue Sep 12 19:49:26 2000 @@ -2,7 +2,7 @@ This file is part of shuJIT, Just In Time compiler for Sun Java Virtual Machine. - Copyright (C) 1998,1999 SHUDO Kazuyuki + Copyright (C) 1998,1999,2000 SHUDO Kazuyuki This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff -aruN shujit-0.6.5/NET/shudo/metavm/Proxy.java shujit/NET/shudo/metavm/Proxy.java --- shujit-0.6.5/NET/shudo/metavm/Proxy.java Sat Mar 20 22:59:47 1999 +++ shujit/NET/shudo/metavm/Proxy.java Tue Sep 12 19:49:32 2000 @@ -2,7 +2,7 @@ This file is part of shuJIT, Just In Time compiler for Sun Java Virtual Machine. - Copyright (C) 1998,1999 SHUDO Kazuyuki + Copyright (C) 1998,1999,2000 SHUDO Kazuyuki This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff -aruN shujit-0.6.5/NET/shudo/metavm/TypeUtil.java shujit/NET/shudo/metavm/TypeUtil.java --- shujit-0.6.5/NET/shudo/metavm/TypeUtil.java Sat Mar 20 23:17:59 1999 +++ shujit/NET/shudo/metavm/TypeUtil.java Tue Sep 12 19:49:39 2000 @@ -2,7 +2,7 @@ This file is part of shuJIT, Just In Time compiler for Sun Java Virtual Machine. - Copyright (C) 1998,1999 SHUDO Kazuyuki + Copyright (C) 1998,1999,2000 SHUDO Kazuyuki This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff -aruN shujit-0.6.5/NET/shudo/metavm/VMOperations.java shujit/NET/shudo/metavm/VMOperations.java --- shujit-0.6.5/NET/shudo/metavm/VMOperations.java Sat Mar 20 17:28:14 1999 +++ shujit/NET/shudo/metavm/VMOperations.java Tue Sep 12 19:49:45 2000 @@ -2,7 +2,7 @@ This file is part of shuJIT, Just In Time compiler for Sun Java Virtual Machine. - Copyright (C) 1998,1999 SHUDO Kazuyuki + Copyright (C) 1998,1999,2000 SHUDO Kazuyuki This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff -aruN shujit-0.6.5/README shujit/README --- shujit-0.6.5/README Tue Sep 5 20:16:28 2000 +++ shujit/README Wed Sep 13 19:40:35 2000 @@ -13,8 +13,8 @@ Working on the following platforms is confirmed. - Linux - - Blackdown JDK 1.2.2 FCS, pgcc 2.95.3, glibc2.1.3 and Linux 2.4.0-test8-pre4 - - JDK 1.1.8v1, pgcc 2.95.3, glibc2.1.3 and Linux 2.4.0-test8-pre4 + - Blackdown JDK 1.2.2 FCS, pgcc 2.95.3, glibc2.1.3 and Linux 2.4.0-test8-pre6 + - JDK 1.1.8v1, pgcc 2.95.3, glibc2.1.3 and Linux 2.4.0-test8-pre6 - JDK 1.1.7v1a, egcs 1.1.2, libc5.4.38 and Linux 2.0.35 - FreeBSD diff -aruN shujit-0.6.5/code.c shujit/code.c --- shujit-0.6.5/code.c Tue Sep 5 20:21:53 2000 +++ shujit/code.c Wed Sep 13 21:19:10 2000 @@ -35,6 +35,29 @@ // // Global Variables // + +// an array of signal names +char *signal_name[] = { // EXCID +#define EXCID_NullPointerException 0 + JAVAPKG "NullPointerException", +#define EXCID_OutOfMemoryError 1 + JAVAPKG "OutOfMemoryError", +#define EXCID_ClassCastException 2 + JAVAPKG "ClassCastException", +#define EXCID_IllegalAccessError 3 + JAVAPKG "IllegalAccessError", +#define EXCID_NoClassDefFoundError 4 + JAVAPKG "NoClassDefFoundError", +#define EXCID_ArithmeticException 5 + JAVAPKG "ArithmeticException", +#define EXCID_ArrayIndexOutOfBoundsException 6 + JAVAPKG "ArrayIndexOutOfBoundsException", +#define EXCID_NegativeArraySizeException 7 + JAVAPKG "NegativeArraySizeException", +#define EXCID_ArrayStoreException 8 + JAVAPKG "ArrayStoreException" +}; + // for strictfp #ifdef STRICT_USE_FSCALE # ifdef STRICT_FSCALE_USE_FLOAT @@ -366,11 +389,24 @@ "addl $12,%esp"); FFLUSH; asm("methodhead_name_done:"); + +# ifdef METAVM + // write remote addr + asm("movl %0,%%edi" : : "m" (ee)); + asm("pushl " EE_REMOTE_ADDR(%edi)); + asm("movsbl " EE_EXCEPTIONKIND(%edi) ",%edi\n\t" + "pushl %edi"); + PUSH_CONSTSTR(" excKind: %d\n remote addr: 0x%x\n"); + asm("call " SYMBOL(printf) "@PLT\n\t" + "addl $12,%esp"); + FFLUSH; +# endif DEBUG_OUT; } #endif // RUNTIME_DEBUG #ifdef RUNTIME_DEBUG + // write %esp if (runtime_debug) { asm("pushl %eax\n\t" "movl %esp,%eax"); @@ -418,8 +454,12 @@ } + // actual start point of a method + CODE(opc_start, start, STANY, STSTA, OPC_NONE) {} + + // epilogue - CODE(opc_epilogue, epilogue, STANY, STSTA, OPC_NONE) {} + CODE(opc_epilogue, epilogue, STANY, STATE_AFTER_RETURN, OPC_NONE) {} // method tail @@ -430,7 +470,7 @@ #if 0 // disuse // eax = !exceptionOccurred(ee) asm("movl %0,%%edi" : : "m" (ee)); // edi = ee - asm("movl " EE_EXCEPTIONKIND(%edi) ",%eax"); + asm("movsbl " EE_EXCEPTIONKIND(%edi) ",%eax"); #endif asm("popl %esi\n\t" @@ -506,22 +546,23 @@ METAVM_MONITOR(%eax, proxy_monitorenter, "sync_enter", 0); OBJ_MONITOR(%eax); CALL_MONITOR(%eax, monitorEnter); - asm("syncenter_done:"); + asm("sync_enter_done:"); } + // exit synchronized method -#define SYNC_EXIT() \ - FUNCCALL_IN(2);\ - \ - /* monitorExit(obj_monitor(o)) */\ - asm("movl %0,%%eax" : : "m" (o));\ - METAVM_MONITOR(%eax, proxy_monitorexit, "sync_exit", 0);\ - OBJ_MONITOR(%eax);\ - CALL_MONITOR(%eax, monitorExit);\ - \ - FUNCCALL_OUT(2) + CODE(opc_sync_exit, sync_exit, STANY, STSTA, OPC_NONE) { + FUNCCALL_IN(2); - CODE(opc_sync_exit, sync_exit, STANY, STSTA, OPC_NONE) { SYNC_EXIT(); } + // monitorExit(obj_monitor(o)) + asm("movl %0,%%eax" : : "m" (o)); + METAVM_MONITOR(%eax, proxy_monitorexit, "sync_exit", 0); + OBJ_MONITOR(%eax); + CALL_MONITOR(%eax, monitorExit); + asm("sync_exit_done:"); + + FUNCCALL_OUT(2); + } CODE(opc_strict_enter, strict_enter, STANY, STSTA, OPC_NONE) { @@ -585,13 +626,13 @@ // throw IllegalAccessError CODE(opc_throw_illegalaccess, throw_illegalaccess, STANY, ST0, OPC_THROW) { - SIGNAL_ERROR1(IllegalAccessError, "final or private field"); + SIGNAL_ERROR1(EXCID_IllegalAccessError, "final or private field"); } // throw NoClassDefFoundError CODE(opc_throw_noclassdef, throw_noclassdef, STANY, ST0, OPC_THROW) { - SIGNAL_ERROR0(NoClassDefFoundError); + SIGNAL_ERROR0(EXCID_NoClassDefFoundError); } @@ -1025,10 +1066,10 @@ // array_check #if 0 CODE(opc_array_check, array_check, ST[24], ST[24], OPC_SIGNAL) { - if (!h) { SIGNAL_ERROR0(NullPointerException); } + if (!h) { SIGNAL_ERROR0(EXCID_NullPointerException); } if ((index < 0) || (index >= obj_length(h))) { - SIGNAL_ERROR0(ArrayIndexOutOfBoundsException); + SIGNAL_ERROR0(EXCID_ArrayIndexOutOfBoundsException); } } #endif @@ -1061,33 +1102,42 @@ #if defined(METAVM) && !defined(METAVM_NO_ARRAY) # define METAVM_ARRAY_CHECK(HANDLE, LABEL) \ - asm("pushl %edi"); /* save HANDLE for opc_lastore */\ - JUMP_IF_NOT_PROXY(HANDLE, LABEL "_arychk_local");\ - asm("movl (%esp),%edi"); /* restore */\ + /* skip local check */\ + asm("pushl %edi\n\tpushl %eax"); /* save handle and index */\ + \ + asm("movl " #HANDLE ",%eax"); /* eax = handle */\ + JUMP_IF_NOT_PROXY(%eax, LABEL "_arychk_local");\ JUMP_IF_NOT_REMOTE(LABEL "_arychk_local");\ - asm("popl %edi\n\t" /* restore */\ + \ + asm("popl %eax\n\tpopl %edi\n\t" /* restore */\ "jmp " LABEL "_arychk_done\n\t"\ LABEL "_arychk_local:\n\t"\ - "popl %edi"); /* restore */ + "popl %eax\n\tpopl %edi"); /* restore */ #else # define METAVM_ARRAY_CHECK(HANDLE, LABEL) #endif // METAVM_NO_ARRAY #ifndef NO_CHECK # define ARRAY_CHECK(HANDLE, INDEX, LABEL) \ - NULL_TEST(HANDLE, LABEL "_1");\ - \ ARRAY_CHECK_DEBUG1(INDEX);\ - asm("testl " #INDEX "," #INDEX "\n\t"\ - "jl " LABEL "_arychk_exc");\ + \ + NULL_TEST(HANDLE, LABEL "_1");\ \ METAVM_ARRAY_CHECK(HANDLE, LABEL);\ + \ + /* edi = length */\ OBJ_LENGTH(HANDLE, %edi); /* edi = obj_length(handle) */\ ARRAY_CHECK_DEBUG2(%edi);\ + \ + /* check if index < 0 */\ + asm("testl " #INDEX "," #INDEX "\n\t"\ + "jl " LABEL "_arychk_exc");\ + /* check if index >= length */\ asm("cmpl %edi," #INDEX "\n\t"\ "jl " LABEL "_arychk_done");\ + \ asm(LABEL "_arychk_exc:");\ - SIGNAL_ERROR0(ArrayIndexOutOfBoundsException);\ + SIGNAL_ERROR0(EXCID_ArrayIndexOutOfBoundsException);\ asm(LABEL "_arychk_done:") /* label */ #else # define ARRAY_CHECK(HANDLE, INDEX, LABEL) \ @@ -1536,7 +1586,7 @@ asm("popl %eax");\ \ asm("jnz aastore_st" #STATE "_1");\ - SIGNAL_ERROR0(ArrayStoreException);\ + SIGNAL_ERROR0(EXCID_ArrayStoreException);\ asm("aastore_st" #STATE "_1:") #else # define AASTORE_TEST(OBJ, HANDLE, STATE) @@ -1610,8 +1660,8 @@ #define CODE_LASTORE(OPTOP1_REG, OPTOP2_REG, STATE) \ CODE(opc_lastore, [ld]astore, ST##STATE, ST0, OPC_SIGNAL) {\ - asm("popl %eax\n\t"\ - "movl (%esp),%edi");\ + asm("popl %eax\n\t" /* index */\ + "movl (%esp),%edi"); /* handle */\ METAVM_ASTORE2(%edi, %eax, OPTOP1_REG, OPTOP2_REG, "lastore_st" #STATE, STATE);\ ARRAY_CHECK(%edi, %eax, "lastore_st" #STATE);\ asm("popl %edi");\ @@ -1974,7 +2024,7 @@ # define INT_TEST(VOP, LABEL, DIVISOR) /* dividend is %eax */\ asm("testl " #DIVISOR "," #DIVISOR "\n\t"\ "jnz " LABEL "_1");\ - SIGNAL_ERROR0(ArithmeticException);\ + SIGNAL_ERROR0(EXCID_ArithmeticException);\ asm(LABEL "_1:");\ asm("cmpl $-1," #DIVISOR "\n\t"\ "jne " LABEL "_3\n\t"\ @@ -2219,7 +2269,7 @@ asm("movl %edx,%eax\n\t"\ "orl %ecx,%eax\n\t"\ "jnz " LABEL "_done");\ - SIGNAL_ERROR0(ArithmeticException);\ + SIGNAL_ERROR0(EXCID_ArithmeticException);\ asm(LABEL "_done:") // now state [24] #endif @@ -3651,7 +3701,7 @@ asm(LABEL "_initclass_success:");\ \ /* rewrite */\ - asm(".byte 0xe8\n\t.long 0\n\t"\ + asm(".byte 0xe8\n\t.long 0\n\t" /* call */\ "popl %edi");\ asm("subl $" GETSTATIC_REWRITE_OFFSET ",%edi\n\t"\ "movw $" GETSTATIC_REWRITE_DATA "eb,(%edi)"); /* jmp XX */\ @@ -3858,7 +3908,7 @@ asm(LABEL "_initclass_success:");\ \ /* rewrite */\ - asm(".byte 0xe8\n\t.long 0\n\t"\ + asm(".byte 0xe8\n\t.long 0\n\t" /* call */\ "popl %edi");\ asm("subl $" INVOKE_REWRITE_OFFSET ",%edi\n\t"\ "movw $" INVOKE_REWRITE_DATA "eb,(%edi)"); /* jmp XX */\ @@ -3874,29 +3924,25 @@ bytepcoff = BYTEPCOFF; #ifdef RUNTIME_DEBUG - DEBUG_IN; - asm("movl %0,%%eax" : : "m" (bytepcoff)); - asm("pushl %eax\n\tpushl %eax"); - PUSH_CONSTSTR(" pc: %d(0x%x)\n"); - asm("call " SYMBOL(printf) "@PLT\n\t" - "addl $12,%esp"); - FFLUSH; - DEBUG_OUT; + if (runtime_debug) { + DEBUG_IN; + asm("movl %0,%%eax" : : "m" (bytepcoff)); + asm("pushl %eax\n\tpushl %eax"); + PUSH_CONSTSTR(" pc: %d(0x%x)\n"); + asm("call " SYMBOL(printf) "@PLT\n\t" + "addl $12,%esp"); + FFLUSH; + DEBUG_OUT; + } #endif } #ifdef DIRECT_INVOCATION -# define INVOKE_CORE_DIRECT_JIT(LABEL) \ - /* assumption: edi is ee->current_frame, eax is method */\ - /* assumption: ACC_MACHINE_COMPILED is 0x4000 */\ +# define INVCORE_COMPILED \ asm("movl " METHOD_COMPILEDCODE(%eax) ",%ecx");\ /* ecx = method->CompiledCode */\ \ - asm("testb $0x40," METHOD_ACCESS_HIGH(%eax));\ - /*asm("testw $" STR(ACC_MACHINE_COMPILED) "," METHOD_ACCESS(%eax));*/\ - asm("jz " LABEL "_invoke_normal");\ - \ asm("movl %eax," FRAME_CURRENTMETHOD(%edi));\ /* current_frame->current_method = callee */\ \ @@ -3904,26 +3950,40 @@ /* must keep: return value (%eax)\ return value of Java method (%edx, %ecx) */\ \ + asm("movl 12(%ebp),%eax"); /* %eax = caller method */\ asm("movl %ebp," FRAME_VARS(%edi));\ /* current_frame->vars = %ebp */\ /* for CompiledFramePrev() */\ - asm("movl 12(%ebp),%eax"); /* %eax = caller method */\ - asm("movl %eax," FRAME_CURRENTMETHOD(%edi));\ - /* current_frame->current_method = caller */\ + asm("movl %eax," FRAME_CURRENTMETHOD(%edi)) + /* current_frame->current_method = caller */ /* filled registers: - %edx & %ecx: return value of Java method\ - %edi: current frame */\ + %edx & %ecx: return value of Java method + %edi: current frame */ +# define INVCORE_INVOKE \ + /* assumption: edi is ee->current_frame, eax is method */\ + /* assumption: ACC_MACHINE_COMPILED is 0x4000 */\ + asm("testb $0x40," METHOD_ACCESS_HIGH(%eax));\ + /*asm("testw $" STR(ACC_MACHINE_COMPILED) "," METHOD_ACCESS(%eax));*/\ + asm("jz inv_core_invoke_normal");\ \ - asm("jmp " LABEL "_invoke_done") + INVCORE_COMPILED;\ + \ + asm("jmp inv_core_invoke_done");\ + \ + asm("inv_core_invoke_normal:");\ + asm("call " SYMBOL(invocationHelper) "@PLT");\ + asm("inv_core_invoke_done:") #else -# define INVOKE_CORE_DIRECT_JIT(LABEL) \ +# define INVCORE_INVOKE \ /* cur_frame->returnpc = -1 */\ asm("movl $-1," FRAME_RETURNPC(%edi));\ /* cur_frame->lastpc = cur_frame->current_method->code + bytepcoff */\ asm("movl " FRAME_CURRENTMETHOD(%edi) ",%ecx\n\t"\ "movl " METHOD_CODE(%ecx) ",%ecx");\ asm("addl %0,%%ecx" : : "m" (bytepcoff));\ - asm("movl %ecx," FRAME_LASTPC(%edi)) + asm("movl %ecx," FRAME_LASTPC(%edi));\ + \ + asm("call " SYMBOL(invocationHelper) "@PLT") #endif // DIRECT_INVOCATION @@ -3945,69 +4005,65 @@ #ifdef RUNTIME_DEBUG #define INVOKE_CORE_PUSH_DEBUG_FLAG \ asm("pushl %0" : : "m" (runtime_debug)) -#define INVOKE_CORE_ARG_SIZE "28" +#define INVOKE_CORE_ARG_SIZE "24" #else #define INVOKE_CORE_PUSH_DEBUG_FLAG -#define INVOKE_CORE_ARG_SIZE "24" +#define INVOKE_CORE_ARG_SIZE "20" #endif // RUNTIME_DEBUG // const: retsize, args_size - CODE(opc_inv_core, inv_core, STANY, ST0, OPC_NONE) { - asm(".globl inv_core\n\t.type inv_core,@function"); - asm("inv_core:"); - - asm("subl %edi,%esp\n\t" - "pushl %edi\n\t" // save - "leal 4(%esp,%edi),%edi"); // edi = original esp - - asm("leal -4(%edi,%ecx,4),%edi"); // base of native stack - // edi = original esp + 4 * (args_size - 1) - - // save registers - //asm("pushl %esi"); - - // push args of invocationHelper() - INVOKE_CORE_PUSH_DEBUG_FLAG; // push runtime_debug - asm("pushl $" STR(CONST)); // push retsize - asm("pushl %edi"); // push var. base - asm("movl %0,%%edi" : : "m" (ee)); // edi = ee - asm("pushl %edi"); // push ee - asm("pushl %ecx\n\t" // push args_size - "pushl %eax\n\t" // push method - "pushl %edx"); // push obj - - asm("movl " EE_CURRENTFRAME(%edi) ",%edi"); - // edi = ee->current_frame - - INVOKE_CORE_DIRECT_JIT("inv_core"); - - asm("inv_core_invoke_normal:"); - asm("call " SYMBOL(invocationHelper) "@PLT"); - asm("inv_core_invoke_done:"); - - asm("addl $" INVOKE_CORE_ARG_SIZE ",%esp"); - // restore registers - //asm("popl %esi"); - - INVOKE_CORE_DEBUG1; - - asm("popl %eax"); // restore - asm("addl %eax,%esp"); // free local var space - - asm(".globl inv_core_done\n\t.type inv_core_done,@function"); - asm("inv_core_done:"); - - asm("movl %0,%%edi" : : "m" (ee)); // edi = ee +#define INVOKE_CORE(VOP, CORE_TYPE) \ + CODE(opc_##VOP, VOP, STANY, ST0, OPC_NONE) {\ + asm(".globl " #VOP "\n\t.type " #VOP ",@function");\ + asm(#VOP ":");\ + \ + asm("subl %edi,%esp\n\t"\ + "pushl %edi\n\t" /* save */\ + "leal 4(%esp,%edi),%edi"); /* edi = original esp */\ + \ + asm("leal -4(%edi,%ecx,4),%edi"); /* base of native stack */\ + /* edi = original esp + 4 * (args_size - 1) */\ + \ + /* push args of invocationHelper() */\ + INVOKE_CORE_PUSH_DEBUG_FLAG; /* push runtime_debug */\ + asm("pushl %edi"); /* push var. base */\ + asm("movl %0,%%edi" : : "m" (ee)); /* edi = ee */\ + asm("pushl %edi"); /* push ee */\ + asm("pushl %ecx\n\t" /* push args_size */\ + "pushl %eax\n\t" /* push method */\ + "pushl %edx"); /* push obj */\ + \ + asm("movl " EE_CURRENTFRAME(%edi) ",%edi");\ + /* edi = ee->current_frame */\ + \ + INVCORE_##CORE_TYPE;\ + \ + asm("addl $" INVOKE_CORE_ARG_SIZE ",%esp");\ + \ + INVOKE_CORE_DEBUG1;\ + \ + asm("popl %eax"); /* restore */\ + asm("addl %eax,%esp"); /* free local var space */\ + \ + asm(".globl " #VOP "_done\n\t.type " #VOP "_done,@function");\ + asm(#VOP "_done:");\ + \ + /* adjust optop */\ + asm("movl $" STR(CONST) ",%eax"); /* eax = args_size */\ + asm("leal (%esp,%eax,4),%esp"); /* esp += (args_size * 4) */\ + \ + /* eax = !exceptionOccurred(ee) */\ + asm("movl %0,%%edi" : : "m" (ee)); /* edi = ee */\ + EE_EXCEPTIONKIND_EAX(%edi);\ + asm("testl %eax,%eax\n\t"\ + "jnz " STR(ADDR_EXC));\ + } - // adjust optop - asm("movl $" STR(CONST) ",%eax\n\t" // eax = args_size - "leal (%esp,%eax,4),%esp"); // esp += (args_size * 4) + INVOKE_CORE(invoke_core, INVOKE); +#ifdef EAGER_COMPILATION + INVOKE_CORE(invoke_core_compiled, COMPILED); +#endif - // eax = !exceptionOccurred(ee) - asm("movl " EE_EXCEPTIONKIND(%edi) ",%eax\n\t" - "testl %eax,%eax\n\t" - "jnz " STR(ADDR_EXC)); - } CODE(opc_inv_vir_obj, inv_vir_obj, STANY, STSTA, OPC_NONE) { asm("movl -4(%esp,%ecx,4),%edx"); // ecx must be args_size @@ -4016,25 +4072,25 @@ } #ifdef METAVM -# define METAVM_INVOKEVIRTUAL \ - JUMP_IF_NOT_REMOTE("invokevir_not_proxy"); /* break edi */\ +# define METAVM_INVOKEVIRTUAL(LABEL) \ + JUMP_IF_NOT_REMOTE(LABEL "_not_proxy"); /* break edi */\ \ METHODTABLE_OF_PROXY(%edi);\ asm("cmpl %eax,%edi\n\t"\ - "jnz invokevir_not_proxy");\ + "jnz " LABEL "_not_proxy");\ PROXY_CLAZZ(%edx, %eax); /* eax = Proxy.clazz */\ CB_METHODTABLE(%eax, %eax); /* eax = methodtable of Proxy.clazz */\ \ - asm("invokevir_not_proxy:") + asm(LABEL "_not_proxy:") #else -# define METAVM_INVOKEVIRTUAL +# define METAVM_INVOKEVIRTUAL(LABEL) #endif // const: slot CODE(opc_invokevirtual, invokevirtual, STANY, STSTA, OPC_SIGNAL) { OBJ_ARRAY_METHODTABLE_TO_EAX(%edx, "invokevir"); // may cause SIGSEGV - METAVM_INVOKEVIRTUAL; + METAVM_INVOKEVIRTUAL("invvir"); asm("movl $" STR(CONST) ",%edi"); // edi = slot MT_SLOT(%eax, %edi, %eax); // eax = method METHOD_DEBUG(%eax, "invokevirtual"); @@ -4043,7 +4099,7 @@ CODE(opc_invokevirtual_obj, invokevirtual_obj, STANY, STSTA, OPC_SIGNAL) { OBJ_METHODTABLE(%edx, %eax); // may cause SIGSEGV - METAVM_INVOKEVIRTUAL; + METAVM_INVOKEVIRTUAL("invvir_obj"); asm("movl $" STR(CONST) ",%edi"); // edi = slot MT_SLOT(%eax, %edi, %eax); // eax = method METHOD_DEBUG(%eax, "invokevirtual_obj"); @@ -4097,7 +4153,7 @@ "addl $24,%esp"); asm("popl %ecx"); // restore - asm("jmp " STR(CONST)); // jump to inv_core_done + asm(".byte 0xe9\n\t.long " STR(CONST)); // jump to invoke_core_done asm("inv_metavm_inv_local:"); } @@ -4174,7 +4230,7 @@ asm(".short 0x9090") #define INVINTF_REWRITE2() \ - asm(".byte 0xe8\n\t.long 0\n\t"\ + asm(".byte 0xe8\n\t.long 0\n\t" /* call */\ "popl %edi"); /* here, can break edi */\ asm("subl $" INVINTF_REWRITE_OFFSET ",%edi\n\t"\ "movw $" INVINTF_REWRITE_DATA "eb,(%edi)") /* jmp XX */ @@ -4210,14 +4266,49 @@ // inv_int_varspace is same as inv_vir_varspace -#if 0 // how to get methodblock -# if 0 - if (opcode == opc_invokevirtual_quick) // obj isn't an array - method = mt_slot(obj_methodtable(obj), slot); - else -# endif - method = mt_slot(obj_array_methodtable(obj), slot); -#endif +#ifdef ELIMINATE_TAIL_RECURSION + // const: args_size + CODE(opc_invoke_recursive, invoke_recursive, ST0, ST0, OPC_NONE) { + asm("movl $" STR(CONST) ",%ecx"); // ecx = args_size + + asm("movl %esi,%edx\n\t" // save esi + "movl %esi,%edi\n\t" // target addr. + "movl %ecx,%eax\n\t" // save args_size + "leal -4(%esp,%ecx,4),%esi\n\t"// source addr. + "std\n\t" // set direction flag + ".short 0xa5f3\n\t" // "rep movsl (%esi),(%edi)\n\t" + "leal (%esp,%eax,4),%esp\n\t" // esp += 4 * args_size + "movl %edx,%esi"); // restore esi + asm(".byte 0xe9\n\t.long " STR(CONST)); + } + + CODE(opc_invoke_recursive_1, invoke_recursive_1, ST0, ST0, OPC_NONE) { + asm("movl (%esp),%eax\n\t" + "addl $4,%esp\n\t" + "movl %eax,(%esi)\n\t" + ".byte 0xe9\n\t.long " STR(CONST)); + } + + CODE(opc_invoke_recursive_2, invoke_recursive_2, ST0, ST0, OPC_NONE) { + asm("movl (%esp),%eax\n\t" + "movl 4(%esp),%edi\n\t" + "addl $8,%esp\n\t" + "movl %eax,-4(%esi)\n\t" + "movl %edi,(%esi)\n\t" + ".byte 0xe9\n\t.long " STR(CONST)); + } + + CODE(opc_invoke_recursive_3, invoke_recursive_3, ST0, ST0, OPC_NONE) { + asm("movl (%esp),%eax\n\t" + "movl 4(%esp),%edi\n\t" + "movl 8(%esp),%ecx\n\t" + "addl $12,%esp\n\t" + "movl %eax,-8(%esi)\n\t" + "movl %edi,-4(%esi)\n\t" + "movl %ecx,(%esi)\n\t" + ".byte 0xe9\n\t.long " STR(CONST)); + } +#endif // ELIMINATE_TAIL_RECURSION // xxxunusedxxx @@ -4303,7 +4394,7 @@ asm(LABEL "_once_success:");\ \ /* rewrite */\ - asm(".byte 0xe8\n\t.long 0\n\t"\ + asm(".byte 0xe8\n\t.long 0\n\t" /* call */\ "popl %edi");\ asm("subl $" NEW_REWRITE_OFFSET ",%edi\n\t"\ "movw $" NEW_REWRITE_DATA "eb,(%edi)"); /* jmp XX */\ @@ -4360,7 +4451,7 @@ # define NEWARRAY_TEST(OPTOP1_REG, LABEL) \ asm("testl " #OPTOP1_REG "," #OPTOP1_REG "\n\t"\ "jge " LABEL "_test_done");\ - SIGNAL_ERROR0(NegativeArraySizeException);\ + SIGNAL_ERROR0(EXCID_NegativeArraySizeException);\ asm(LABEL "_test_done:") #else # define NEWARRAY_TEST(OPTOP1_REG, LABEL) @@ -4392,6 +4483,13 @@ asm("movl %0,%%edi" : : "m" (ee)); /* edi = ee*/\ /* local operation if remote VM addr is null */\ asm("movl " EE_REMOTE_ADDR(%edi) ",%eax");\ +DEBUG_IN;\ +asm("pushl %eax");\ +PUSH_CONSTSTR("remote addr: %x\n");\ +asm("call " SYMBOL(printf) "@PLT\n\t"\ + "addl $8,%esp");\ +FFLUSH;\ +DEBUG_OUT;\ asm("testl %eax,%eax\n\t"\ "jz " LABEL "_addr_null");\ \ @@ -4442,7 +4540,7 @@ FUNCCALL_OUT(STATE);\ asm("testl %eax,%eax\n\t"\ "jnz " LABEL "_done");\ - SIGNAL_ERROR0(OutOfMemoryError);\ + SIGNAL_ERROR0(EXCID_OutOfMemoryError);\ asm(LABEL "_done:\n\t"\ "movl %eax," #OPTOP1_REG) // store to dst. @@ -4519,7 +4617,7 @@ FUNCCALL_OUT(STATE);\ asm("testl %eax,%eax\n\t"\ "jnz " LABEL "_2");\ - SIGNAL_ERROR0(OutOfMemoryError);\ + SIGNAL_ERROR0(EXCID_OutOfMemoryError);\ asm(LABEL "_2:");\ \ UNHAND(%eax, %edi);\ @@ -4648,7 +4746,7 @@ "testl %eax,%eax\n\t"\ "popl %eax");\ FUNCCALL_OUT(STATE);\ - asm("jnz " LABEL "_true");\ + asm("jnz " LABEL "_done");\ \ /* compare handle->methods with cb_of_Proxy->methodtable */\ JUMP_IF_NOT_PROXY(OPTOP1_REG, LABEL "_local");\ @@ -4716,8 +4814,9 @@ FUNCCALL_OUT(STATE);\ \ asm("testl %eax,%eax\n\t"\ - "jnz " LABEL "_done");\ - SIGNAL_ERROR0(ClassCastException);\ + "jnz " LABEL "_done\n\t"\ + LABEL "_fail:");\ + SIGNAL_ERROR0(EXCID_ClassCastException);\ asm(LABEL "_done:") CODE(opc_checkcast, checkcast, ST0, ST1, OPC_THROW) { @@ -4870,11 +4969,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(EXCID_NegativeArraySizeException);\ asm("mulary_st" #STATE "_1:");\ asm("testl %eax,%eax\n\t"\ "jnz mulary_st" #STATE "_2");\ - SIGNAL_ERROR0(OutOfMemoryError);\ + SIGNAL_ERROR0(EXCID_OutOfMemoryError);\ asm("mulary_st" #STATE "_2:") #ifdef RUNTIME_DEBUG @@ -5160,91 +5259,6 @@ #endif // SPECIAL_INLINING -#if defined(DIRECT_INVOCATION) && defined(REWRITE_CALLER) - CODE(opc_direct_invoke, direct_invoke, STANY, STSTA, OPC_NONE) { - asm("movl 4(%ebp),%edi"); // edi = return address - asm("cmpw $0xd1ff,-2(%edi)\n\t" // FF D1: call *%ecx - "jne dinv_done"); - -#ifdef RUNTIME_DEBUG - if (runtime_debug) { - DEBUG_IN; - printf(" rewriting.\n"); - fflush(stdout); - DEBUG_OUT; - } -#endif // RUNTIME_DEBUG - - // this code assumes INVOKE_CORE_DIRECT_JIT as the following: - // 2e1d: f6 40 11 40 testb $0x40,0x11(%eax) - // 2e21: 74 10 je 2e33 - // 2e23: 89 47 1c mov %eax,0x1c(%edi) - // 2e26: ff d1 call *%ecx - -#if 1 - // rewrite - // from: XX XX XX XX XX XX XX XX XX XX XX - // to: EB 04 XX XX XX XX E8 - - asm("movl %0,%%eax" : : "m" (mb)); // eax = mb - asm("movl " METHOD_COMPILEDCODE(%eax) ",%eax"); - // eax = mb->CompiledCode - asm("movb $0xe8,-5(%edi)\n\t" - "subl %edi,%eax"); - asm("movw $0xfeeb,-11(%edi)"); - // 11: depends on INVOKE_CORE_DIRECT_JIT macro. - asm("movl %eax,-4(%edi)"); - asm("movb $0x04,-10(%edi)"); -#endif -#if 0 - // rewrite - // from: XX XX XX XX XX ... - // to: E8 - - asm("subl $11,%edi\n\t" - // 11: depends on INVOKE_CORE_DIRECT_JIT macro. - "movw $0xfeeb,(%edi)"); // EB FE: jump to self - asm("movl %0,%%eax" : : "m" (mb)); // eax = mb - asm("addl $5,%edi"); // edi += 5 - asm("movl " METHOD_COMPILEDCODE(%eax) ",%eax"); - // eax = mb->CompiledCode - asm("subl %edi,%eax\n\t" - "pushl %eax\n\t" // save the argument - "movb $0xfe,%al\n\t" - "movl %eax,-4(%edi)"); - - asm("movw $0x04eb,(%edi)"); - - asm("popl %eax\n\t" // restore the argument - "movb %al,%ah\n\t" - "movb $0xe8,%al\n\t" - "movw %ax,-5(%edi)"); -#endif -#if 0 - // rewrite - // from: XX XX XX XX XX XX ... - // to: 90 E8 - - asm("subl $11,%edi\n\t" - // 11: depends on INVOKE_CORE_DIRECT_JIT macro. - "movw $0xfeeb,(%edi)"); // EB FE: jmp to self - asm("movl %0,%%eax" : : "m" (mb)); // eax = mb - asm("addl $6,%edi"); // edi += 6 - asm("movl " METHOD_COMPILEDCODE(%eax) ",%eax"); - // eax = mb->CompiledCode - asm("subl %edi,%eax\n\t" - "movl %eax,-4(%edi)"); - - asm("movw $0x03eb,(%edi)"); - - asm("movw $0xe890,-6(%edi)"); -#endif - - asm("dinv_done:"); - } -#endif // DIRECT_INVOCATION && REWRITE_CALLER - - CODEEND; } @@ -5275,8 +5289,14 @@ asm("cmpb $0," EE_EXCEPTIONKIND(%edi) "\n\t" "jnz exc_new_done"); // if (exceptionOccurred(ee)) - asm("pushl %%edx\n\t" // edx should be (char *) DetailMessage - "pushl %%eax\n\t" // eax should be (char *) ename + + asm("pushl %edx"); // edx should be (char *) DetailMessage + asm("movl %0,%%edi\n\t" + "andl $0xff,%%eax\n\t" // al contains EXCID + "movl (%%edi,%%eax,4),%%eax" + : : "m" (signal_name) : "eax","esi"); + // eax = signal_name[eax] + asm("pushl %%eax\n\t" // eax should be (char *) ename "pushl %0\n\t" "call " SYMBOL(SignalError) "@PLT\n\t" "addl $12,%%esp" : : "m" (ee)); diff -aruN shujit-0.6.5/code.h shujit/code.h --- shujit-0.6.5/code.h Tue Sep 5 17:28:34 2000 +++ shujit/code.h Tue Sep 12 14:13:28 2000 @@ -167,17 +167,17 @@ bytepcoff = BYTEPCOFF;\ asm("jmp " STR(ADDR_EXC)) -#define SIGNAL_ERROR_CORE(KIND) \ - asm("movl %0,%%eax" : : "m" (JAVAPKG #KIND)); /* char *ename */\ +#define SIGNAL_ERROR_CORE(EXCID) \ + asm("movb $" #EXCID ",%al");\ SIGNAL_ERROR_JUMP() -#define SIGNAL_ERROR0(KIND) \ +#define SIGNAL_ERROR0(EXCID) \ asm("xorl %edx,%edx"); /* char *DetailMessage */\ - SIGNAL_ERROR_CORE(KIND) + SIGNAL_ERROR_CORE(EXCID) -#define SIGNAL_ERROR1(KIND, MSG) \ +#define SIGNAL_ERROR1(EXCID, MSG) \ asm("movl %0,%%edx" : : "m" (MSG)); /* char *DetailMessage */\ - SIGNAL_ERROR_CORE(KIND) + SIGNAL_ERROR_CORE(EXCID) #if !defined(NO_CHECK) && !defined(NULLEXC_BY_SIGNAL) @@ -335,6 +335,15 @@ #define EE_EXCEPTION(EE) "16(" #EE ")" #endif // JDK_VER +#ifdef METAVM +# define EE_EXCEPTIONKIND_EAX(EE) \ + asm("movsbl " EE_EXCEPTIONKIND(EE) ",%eax") +#else +# define EE_EXCEPTIONKIND_EAX(EE) \ + asm("movl " EE_EXCEPTIONKIND(EE) ",%eax") + // This is rather desirable, but not compatible with MetaVM. +#endif // METAVM + #define FRAME_RETURNPC(FRAME) "4(" #FRAME ")" #define FRAME_OPTOP(FRAME) "8(" #FRAME ")" #define FRAME_VARS(FRAME) "12(" #FRAME ")" @@ -376,10 +385,15 @@ // MetaVM related stuff // #if JDK_VER >= 12 -#define EE_REMOTE_FLAG(EE) "72(" #EE ")" - // ee->RESERVED1 -#define EE_REMOTE_ADDR(EE) "20(" #EE ")" +#define EE_REMOTE_FLAG(EE) "17(" #EE ")" + // ((char *)ee->exceptionKind) + 1 +#if 1 +# define EE_REMOTE_ADDR(EE) "120(" #EE ")" + // ee->RESERVED3 +#else +# define EE_REMOTE_ADDR(EE) "20(" #EE ")" // ee->exception.exc +#endif #else #define EE_REMOTE_FLAG(EE) "61(" #EE ")" // ee->alloc_cache.cache_pad[0] @@ -388,10 +402,7 @@ #endif // JDK_VER #define JUMP_IF_NOT_REMOTE(LABEL) \ - { /* %edi = ee */\ - register ExecEnv *cur_ee asm("edi");\ - cur_ee = ee;\ - }\ + asm("movl %0,%%edi" : : "m" (ee));\ asm("movsbl " EE_REMOTE_FLAG(%edi) ",%edi");\ asm("testl %edi,%edi\n\t"\ "jz " LABEL) @@ -413,7 +424,7 @@ asm("movl 4(" #DST ")," #DST); #define JUMP_IF_EXC_HASNT_OCCURRED(EE, LABEL) \ - asm("movl " EE_EXCEPTIONKIND(EE) ",%edi");\ + asm("movsbl " EE_EXCEPTIONKIND(EE) ",%edi");\ asm("testl %edi,%edi\n\t"\ "jz " LABEL) #else diff -aruN shujit-0.6.5/compile.c shujit/compile.c --- shujit-0.6.5/compile.c Tue Sep 5 16:04:57 2000 +++ shujit/compile.c Wed Sep 13 20:43:06 2000 @@ -84,8 +84,12 @@ #endif if (!info) { - printf("WARNING: method->CompiledCodeInfo is NULL. (compileMethod())\n"); +#ifdef COMPILE_DEBUG + printf("cmplMtd(): method->CompiledCodeInfo is NULL.\n"); fflush(stdout); +#endif + if (!(info = prepareCompiledCodeInfo(EE(), mb))) + return 1; // failure } if (!mb->code) { /* mb->code is NULL */ @@ -94,13 +98,13 @@ cbName(fieldclass(&mb->fb)), mb->fb.name, mb->fb.signature); fflush(stdout); #endif - return 1; /* failure */ + return 1; // failure } if ((mb->fb.access & (ACC_ABSTRACT | ACC_NATIVE)) || (mb->invoker == sym_invokeJITCompiledMethod)) { - /* needless to compile */ + // needless to compile #ifdef COMPILE_DEBUG printf(" needless to compile: %s#%s\n", cbName(fieldclass(&mb->fb)), mb->fb.name, mb->fb.signature); @@ -110,34 +114,44 @@ } + mb->invoker = access2invoker(mb->fb.access); + + + + cc = getCompilerContext(mb); #ifdef COMPILE_DEBUG + compile_debug = cc->compile_debug; if (compile_debug) { printf("\n"); - printf("cmlMtd() called.\n %s#%s %s\n", + printf("cmplMtd() called.\n %s#%s %s\n", cbName(fieldclass(&mb->fb)), mb->fb.name, mb->fb.signature); - { - int acc = mb->fb.access; - printf(" access: 0x%x", acc); - if (acc & ACC_NATIVE) printf(" native"); -/* if (acc & ACC_MACHINE_COMPILED) printf(" machine_compiled");*/ - if (acc & ACC_PUBLIC) printf(" public"); - if (acc & ACC_PRIVATE) printf(" private"); - if (acc & ACC_PROTECTED) printf(" protected"); - if (acc & ACC_STATIC) printf(" static"); - if (acc & ACC_FINAL) printf(" final"); - if (acc & ACC_SYNCHRONIZED) printf(" synchronized"); - if (acc & ACC_ABSTRACT) printf(" abstract"); - printf("\n"); - } - fflush(stdout); + + showCompilerContext(cc, " "); } #endif - cc = getCompilerContext(mb); + #ifdef COMPILE_DEBUG - compile_debug = cc->compile_debug; if (compile_debug) { - showCompilerContext(cc); + int acc = mb->fb.access; + printf(" access: 0x%x", acc); + if (acc & ACC_NATIVE) printf(" native"); +// if (acc & ACC_MACHINE_COMPILED) printf(" machine_compiled"); + if (acc & ACC_PUBLIC) printf(" public"); + if (acc & ACC_PRIVATE) printf(" private"); + if (acc & ACC_PROTECTED) printf(" protected"); + if (acc & ACC_STATIC) printf(" static"); + if (acc & ACC_FINAL) printf(" final"); + if (acc & ACC_SYNCHRONIZED) printf(" synchronized"); + if (acc & ACC_ABSTRACT) printf(" abstract"); + printf("\n"); + +# ifdef METAVM + printf(" excKind: %d\n", cc->ee->exceptionKind); + printf(" remote addr: 0x%x\n", REMOTE_ADDR(cc->ee)); +# endif + + fflush(stdout); } #endif @@ -424,14 +438,11 @@ processAnOpcode(cc, opc_strict_enter, -1); } -#if defined(DIRECT_INVOCATION) && defined(REWRITE_CALLER) - if (mb->fb.access & (ACC_STATIC | ACC_PRIVATE)) - processAnOpcode(cc, opc_direct_invoke, -1); -#endif - if ((mb->fb.access & ACC_SYNCHRONIZED) && !OPT_SETQ(OPT_IGNLOCK)) processAnOpcode(cc, opc_sync_enter, -1); + processAnOpcode(cc, opc_start, -1); + while (byteoff < endoff) { cc->ninsn++; opcode = *(methodcode + byteoff); @@ -742,7 +753,7 @@ processAnOpcode(cc, opc_inv_metavm, byteoff); #endif processAnOpcode(cc, opc_inv_vir_varspace, byteoff); - processAnOpcode(cc, opc_inv_core, byteoff); + processAnOpcode(cc, opc_invoke_core, byteoff); } break; @@ -793,6 +804,43 @@ } } +#ifdef ELIMINATE_TAIL_RECURSION + { + struct methodblock *method = constant_pool[operand].mb; + if (mb == method) { + // recursive call + int next_opcode = *(methodcode + byteoff + byteinc); + if ((opc_ireturn <= next_opcode) && (next_opcode <= opc_return)) { + // next insn. is return + // tail recursion + int reccall_opcode; +# ifdef COMPILE_DEBUG + if (compile_debug) { + printf("tail recursion.\n"); + printf(" args_size: %d\n", method->args_size); + fflush(stdout); + } +# endif + switch (method->args_size) { + case 1: + reccall_opcode = opc_invoke_recursive_1; break; + case 2: + reccall_opcode = opc_invoke_recursive_2; break; + case 3: + reccall_opcode = opc_invoke_recursive_3; break; + default: + reccall_opcode = opc_invoke_recursive; break; + } + + processAnOpcode(cc, opc_stateto0, byteoff); + processAnOpcode(cc, reccall_opcode, byteoff); + + goto makepc_invoke_done; + } + } + } +#endif // ELIMINATE_TAIL_RECURSION + switch (opcode) { case opc_invokespecial: processAnOpcode(cc, opc_stateto0, byteoff); @@ -803,7 +851,35 @@ processAnOpcode(cc, opc_inv_metavm, byteoff); #endif processAnOpcode(cc, opc_inv_spe_varspace, byteoff); - processAnOpcode(cc, opc_inv_core, byteoff); + { +#ifdef EAGER_COMPILATION + bool_t processed = FALSE; + struct methodblock *method = constant_pool[operand].mb; + if (!(method->fb.access & (ACC_ABSTRACT | ACC_NATIVE))) { + if (method->invoker == sym_compileAndInvokeMethod) { +# ifdef COMPILE_DEBUG + if (cc->compile_debug) { + printf(" call compileMethod()\n"); fflush(stdout); } +# endif + compileMethod(method); + } + if (method->invoker == sym_invokeJITCompiledMethod) { +# ifdef COMPILE_DEBUG + if (cc->compile_debug) { + printf("compiled(special): %s#%s %s.\n", + cbName(fieldclass(&method->fb)), + method->fb.name, method->fb.signature); + fflush(stdout); + } +# endif + processAnOpcode(cc, opc_invoke_core_compiled, byteoff); + processed = TRUE; + } + } + if (!processed) +#endif // EAGER_COMPILATION + processAnOpcode(cc, opc_invoke_core, byteoff); + } break; case opc_invokestatic: @@ -867,7 +943,35 @@ else processAnOpcode(cc, opc_invokestatic_quick, byteoff); processAnOpcode(cc, opc_inv_stq_varspace, byteoff); - processAnOpcode(cc, opc_inv_core, byteoff); + { +#ifdef EAGER_COMPILATION + bool_t processed = FALSE; + struct methodblock *method = constant_pool[operand].mb; + if (!(method->fb.access & (ACC_ABSTRACT | ACC_NATIVE))) { + if (method->invoker == sym_compileAndInvokeMethod) { +# ifdef COMPILE_DEBUG + if (cc->compile_debug) { + printf(" call compileMethod()\n"); fflush(stdout); } +# endif + compileMethod(method); + } + if (method->invoker == sym_invokeJITCompiledMethod) { +# ifdef COMPILE_DEBUG + if (cc->compile_debug) { + printf("compiled(static): %s#%s %s.\n", + cbName(fieldclass(&method->fb)), + method->fb.name, method->fb.signature); + fflush(stdout); + } +# endif + processAnOpcode(cc, opc_invoke_core_compiled, byteoff); + processed = TRUE; + } + } + if (!processed) +#endif // EAGER_COMPILATION + processAnOpcode(cc, opc_invoke_core, byteoff); + } } } } @@ -882,7 +986,7 @@ processAnOpcode(cc, opc_inv_metavm, byteoff); #endif processAnOpcode(cc, opc_inv_vir_varspace, byteoff); - processAnOpcode(cc, opc_inv_core, byteoff); + processAnOpcode(cc, opc_invoke_core, byteoff); break; } // switch (opcode) @@ -1289,7 +1393,8 @@ break; case opc_inv_head: - case opc_inv_core: + case opc_invoke_core: + case opc_invoke_core_compiled: case opc_invokevirtual: case opc_invokevirtual_obj: case opc_invokespecial: @@ -1300,6 +1405,9 @@ case opc_invokeinterface: case opc_invokeignored_static: case opc_invokeignored_static_quick: +#ifdef ELIMINATE_TAIL_RECURSION + case opc_invoke_recursive: +#endif // ELIMINATE_TAIL_RECURSION operand = GET_UINT16(bytepc + 1); break; @@ -1356,6 +1464,21 @@ operand = GET_UINT16(bytepc + 1); break; + case opc_methodtail: + { + int last_index = pctableLen(cc) - 2; // -1: opc_epilogue + pcentry *entry = pctableGet(cc, last_index); + + if (entry->opcode == opc_return) { + // copy byteoff to opc_epilogue + pcentry *epilogue_entry = pctableGet(cc, last_index + 1); + epilogue_entry->byteoff = entry->byteoff; + + pctableDelete(cc, last_index); + } + } + break; + case opc_wide: code_opcode = *(bytepc + 1); goto proc_opc_switch; // translate again @@ -1542,7 +1665,7 @@ } #endif - tgtentry = pctableGet(cc, tgtpc); + tgtentry = pctableGetByPC(cc, tgtpc); sysAssert(tgtentry != NULL); pcentrySetBlockTop(tgtentry); if (loopp) pcentrySetLoopTop(tgtentry); @@ -1572,7 +1695,7 @@ loopp = (defoff < 0) ? TRUE : FALSE; defoff += entry->byteoff; - tgtentry = pctableGet(cc, defoff); + tgtentry = pctableGetByPC(cc, defoff); sysAssert(tgtentry != NULL); pcentrySetBlockTop(tgtentry); if (loopp) pcentrySetLoopTop(tgtentry); @@ -1589,7 +1712,7 @@ fflush(stdout); } #endif - tgtentry = pctableGet(cc, off); + tgtentry = pctableGetByPC(cc, off); sysAssert(tgtentry != NULL); pcentrySetBlockTop(tgtentry); if (loopp) pcentrySetLoopTop(tgtentry); @@ -1608,7 +1731,7 @@ loopp = (defoff < 0) ? TRUE : FALSE; defoff += entry->byteoff; - tgtentry = pctableGet(cc, defoff); + tgtentry = pctableGetByPC(cc, defoff); sysAssert(tgtentry != NULL); pcentrySetBlockTop(tgtentry); if (loopp) pcentrySetLoopTop(tgtentry); @@ -1625,7 +1748,7 @@ fflush(stdout); } #endif - tgtentry = pctableGet(cc, off); + tgtentry = pctableGetByPC(cc, off); sysAssert(tgtentry != NULL); pcentrySetBlockTop(tgtentry); if (loopp) pcentrySetLoopTop(tgtentry); @@ -1658,6 +1781,15 @@ opcode = pctable->opcode; codep = &code_table[opcode][state]; + // set current state + switch (opcode) { + case opc_return: + case opc_epilogue: + // for a statement which jump to return insn. + state = 0; + break; + } + pcentrySetState(pctable, state); #ifdef COMPILE_DEBUG if (compile_debug) { @@ -1667,6 +1799,7 @@ } #endif + // set next state switch (opcode) { // jump instructions case opc_goto: @@ -1680,7 +1813,8 @@ break; // invocation instructions - case opc_inv_core: + case opc_invoke_core: + case opc_invoke_core_compiled: { cp_item_type *constant_pool = cbConstantPool(fieldclass(&cc->mb->fb)); @@ -1750,7 +1884,7 @@ 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); + pcentry *table = pctableGetByPC(cc, cf->handler_pc); int nativeoff = table->nativeoff; // offset in byte code -> offset in native code cf->compiled_CatchFrame = (void *)nativeoff; @@ -1796,6 +1930,8 @@ } #endif + sysAssert(info != NULL); + for (i = 0; i < pctableLen(cc); i++) { pctable = cc->pctable + i; opcode = pctable->opcode; @@ -1940,7 +2076,7 @@ else jumpoff = GET_INT16(bytepc + 1); tgtoff = pctable->byteoff + jumpoff; - tgttable = pctableGet(cc, tgtoff); + tgttable = pctableGetByPC(cc, tgtoff); sysAssert(tgttable != NULL); tgtstate = pcentryState(tgttable); #ifdef COMPILE_DEBUG @@ -2128,6 +2264,7 @@ #endif index = operand * -4; + sysAssert(constant_table[opcode][state][0] != 0); memcpy(bufp + constant_table[opcode][state][0], &index, 4); #ifdef RUNTIME_DEBUG if ((opcode != opc_fload_fld) && (opcode != opc_fst_fstore)) { @@ -2371,29 +2508,20 @@ } break; - case opc_inv_core: + case opc_invoke_core: + case opc_invoke_core_compiled: { struct methodblock *method = constant_pool[operand].mb; - char *sig; - int32_t args_size, ret_size; - - sig = method->fb.signature; - while (*(sig++) != ')'); - if (*sig == 'V') ret_size = 0; - else if ((*sig == 'D') || (*sig == 'J')) ret_size = 2; - else ret_size = 1; - - args_size = method->args_size; + int32_t args_size = method->args_size; #ifdef COMPILE_DEBUG if (compile_debug) { - printf(" args_size, ret_size: %d, %d\n", args_size, ret_size); + printf(" args_size: %d\n", args_size); fflush(stdout); } #endif - memcpy(bufp + constant_table[opcode][state][0], &ret_size, 4); - memcpy(bufp + constant_table[opcode][state][1], &args_size, 4); + memcpy(bufp + constant_table[opcode][state][0], &args_size, 4); } break; @@ -2430,6 +2558,46 @@ } break; +#ifdef ELIMINATE_TAIL_RECURSION + case opc_invoke_recursive: + case opc_invoke_recursive_1: + case opc_invoke_recursive_2: + case opc_invoke_recursive_3: + { + int const_off; + pcentry *entry_start; + int j; + uint32_t arg_off, tgt_off; + + if (opcode == opc_invoke_recursive) { + struct methodblock *method = constant_pool[operand].mb; + int32_t args_size = method->args_size; + + memcpy(bufp + constant_table[opcode][state][0], &args_size, 4); + const_off = 1; + } + else + const_off = 0; + + // search opc_start + for (j = 0; j < pctableLen(cc); j++) { + entry_start = pctable = cc->pctable + j; + if (entry_start->opcode == opc_start) + break; + } + sysAssert(j < pctableLen(cc)); + + arg_off = insn_head_off + constant_table[opcode][state][const_off]; + tgt_off = entry_start->nativeoff; + + tgt_off -= arg_off; + tgt_off -= 4; + + memcpy(bufp + constant_table[opcode][state][const_off], &tgt_off, 4); + } + break; +#endif + case opc_newarray: { sysAssert(operand != -1); @@ -2492,31 +2660,47 @@ else // invokeignroed_static_quick memcpy(bufp + constant_table[opcode][state][0], &args_size, 4); #endif + } + break; #ifdef METAVM - case: opc_inv_metavm: - { - pcentry *succ_pctable; - int succ_opcode; - CodeTable *succ_codep; - int j = i, jump_arg = 0; - while (TRUE) { - succ_pctable = cc->pctable + j; - succ_opcode = succ_pctable->opcode; - if (succ_opcode == opc_inv_core) break; - succ_codep = - &code_table[succ_opcode][pcentryState(succ_pctable)]; - jump_arg += succ_codep->length; - j++; - } - jump_arg += (((char *)inv_core_done) - ((char *)inv_core)); + case opc_inv_metavm: + { + pcentry *succ_pctable; + int succ_opcode; + CodeTable *succ_codep; + + extern void invoke_core(), invoke_core_done(); +# ifdef EAGER_COMPILATION + extern void invoke_core_compiled(), invoke_core_compiled_done(); +# endif - memcpy(bufp + constant_table[opcode][state][0], &jump_arg, 4); + // search opc_invoke_core + int j = i, jump_arg = 0; + while (TRUE) { + succ_pctable = cc->pctable + j; + succ_opcode = succ_pctable->opcode; + if (succ_opcode == opc_invoke_core) { + jump_arg += (((char *)invoke_core_done) - ((char *)invoke_core)); + break; + } +# ifdef EAGER_COMPILATION + if (succ_opcode == opc_invoke_core_compiled) { + jump_arg += (((char *)invoke_core_compiled_done) - + ((char *)invoke_core_compiled)); + break; + } +# endif + succ_codep = + &code_table[succ_opcode][pcentryState(succ_pctable)]; + jump_arg += succ_codep->length; + j++; } - break; -#endif // METAVM + + memcpy(bufp + constant_table[opcode][state][0], &jump_arg, 4); } break; +#endif // METAVM } // resolve constants: switch (opcode) // update native offset @@ -2989,7 +3173,7 @@ while (jptable < jptable_end) { unsigned int argoff = jptable->argoff; - pcentry *tgttable = pctableGet(cc, jptable->tgtoff); + pcentry *tgttable = pctableGetByPC(cc, jptable->tgtoff); unsigned int tgtoff = tgttable->nativeoff; int32_t arg = tgtoff - (argoff + 4); @@ -3209,7 +3393,7 @@ } // default - tgttable = pctableGet(cc, byteoff + defoff); + tgttable = pctableGetByPC(cc, byteoff + defoff); sysAssert(tgttable != NULL); tblp[0] = tgttable->nativeoff; codep = &code_table[opc_goto_st0 + pcentryState(tgttable)][last_state]; @@ -3227,7 +3411,7 @@ for (i = 0; i < (h - l + 1); i++) { int32_t off = (int32_t)ntohl((unsigned long)argp[i]); - tgttable = pctableGet(cc, byteoff + off); + tgttable = pctableGetByPC(cc, byteoff + off); sysAssert(tgttable != NULL); tblp[0] = tgttable->nativeoff; codep = @@ -3290,7 +3474,7 @@ int32_t off = (int32_t)ntohl((unsigned long)argp[1]); tblp[0] = match; - tgttable = pctableGet(cc, byteoff + off); + tgttable = pctableGetByPC(cc, byteoff + off); sysAssert(tgttable != NULL); tblp[1] = tgttable->nativeoff; codep = @@ -3309,7 +3493,7 @@ } // (int32_t)dummy_match and (int32_t)default - tgttable = pctableGet(cc, byteoff + defoff); + tgttable = pctableGetByPC(cc, byteoff + defoff); sysAssert(tgttable != NULL); tblp[0] = 0; tblp[1] = tgttable->nativeoff; diff -aruN shujit-0.6.5/compiler.c shujit/compiler.c --- shujit-0.6.5/compiler.c Sun Aug 20 19:40:35 2000 +++ shujit/compiler.c Wed Sep 13 19:46:47 2000 @@ -152,17 +152,52 @@ fflush(stdout); #endif + // prevent unloading of java.lang.Compiler class { ClassClass *compiler_cb = FindClass(ee, "java/lang/Compiler", TRUE); - if (!compiler_cb) { - printf("FATAL: cannot find the java.lang.Compiler class.\n"); + if (compiler_cb == NULL) { + printf("FATAL: cannot find java.lang.Compiler class.\n"); + if (exceptionOccurred(ee)) { + JHandle *exc = ee->exception.exc; + if (exc != NULL) + fprintf(stderr, "%s\n", cbName(exc->methods->classdescriptor)); +#if JDK_VER >= 12 + printStackTrace(ee, 100, NULL); +#endif + fflush(stderr); + } JVM_Exit(1); } CCSet(compiler_cb, Sticky); } +#ifdef METAVM + // force JVM to load Proxy class + { + ClassClass *proxy_cb; + +#if 1 + proxy_cb = FindClass(ee, METAVM_PKG "Proxy", TRUE); +#else + proxy_cb = LoadClassLocally(METAVM_PKG "Proxy"); +#endif + if (proxy_cb == NULL) { + printf("FATAL: cannot find " METAVM_PKG "Proxy class.\n"); +#if JDK_VER >= 12 + printf("You have to place MetaVM classes in JDK_DIR/jre/classes.\n"); +#endif + fflush(stdout); + JVM_Exit(1); + } + + // prevent unloading + CCSet(proxy_cb, Sticky); + } +#endif // METAVM + + // version check #if JDK_VER < 12 @@ -476,18 +511,6 @@ #endif // CODE_DB -#ifdef METAVM - { - ExecEnv *ee = EE(); - // force JVM to load Proxy class - FindClass(ee, METAVM_PKG "Proxy", TRUE); - - // set remote flag on - REMOTE_FLAG_ON(ee); - } -#endif - - // for strictfp // check the FPU roundig precision { @@ -499,6 +522,12 @@ (is_fpupc_double?"":"not ")); #endif } + + +#ifdef METAVM + // set remote flag on + REMOTE_FLAG_ON(ee); +#endif // METAVM #ifdef COMPILE_DEBUG diff -aruN shujit-0.6.5/compiler.h shujit/compiler.h --- shujit-0.6.5/compiler.h Tue Sep 5 17:00:05 2000 +++ shujit/compiler.h Wed Sep 13 18:03:09 2000 @@ -30,6 +30,11 @@ #include "opcodes.h" #include "opcodes_internal.h" +#ifdef METAVM +# include "metavm/metavm.h" + // constants.c requires prototype declarations +#endif // METAVM + // offerred by Sun #include "native.h" @@ -76,7 +81,8 @@ #undef COUNT_TSC #define DIRECT_INVOCATION -#undef REWRITE_CALLER +#define EAGER_COMPILATION +#define ELIMINATE_TAIL_RECURSION #define GET_SIGCONTEXT #define NULLEXC_BY_SIGNAL #define ARITHEXC_BY_SIGNAL @@ -91,7 +97,11 @@ #undef NO_CHECK #if defined(NULLEXC_BY_SIGNAL) || defined(ARITHEXC_BY_SIGNAL) -#define EXC_BY_SIGNAL +# define EXC_BY_SIGNAL +#endif + +#ifndef DIRECT_INVOCATION +# undef EAGER_COMPILATION #endif #if 0 @@ -272,11 +282,12 @@ #endif -#define JIT_LIB_NAME "shujit" #ifdef METAVM +# define JIT_LIB_NAME "metavm" # define SYS_NAME "MetaVM" #else +# define JIT_LIB_NAME "shujit" # define SYS_NAME "shuJIT" #endif # define CREDIT " " SYS_NAME " for Sun JVM/IA-32 Copyright 1998,1999,2000 by SHUDO Kazuyuki\n" @@ -565,7 +576,7 @@ extern void *access2invoker(int access); extern char *nameOfInvoker(void *inv); -extern void showCompilerContext(CompilerContext *cc); +extern void showCompilerContext(CompilerContext *cc, char *prefix); extern CompilerContext *getCompilerContext(struct methodblock *mb); extern void releaseCompilerContext(CompilerContext *cc); extern void cancelOnBuffer(CompilerContext *cc, size_t); @@ -586,7 +597,8 @@ extern void pctableNDelete(CompilerContext *cc, int index, int len); extern void pctableDelete(CompilerContext *cc, int index); extern pcentry *pctableNext(CompilerContext *cc, pcentry *entry); -extern pcentry *pctableGet(CompilerContext *cc, int byteoff); +extern pcentry *pctableGet(CompilerContext *cc, int index); +extern pcentry *pctableGetByPC(CompilerContext *cc, int byteoff); extern void pcentryClear(pcentry *entry); #define pcentryState(PCENTRY) (((PCENTRY)->flag) & 0xf) #define pcentrySetState(PCENTRY, ST) \ @@ -649,7 +661,7 @@ // in runtime.c extern int invocationHelper( JHandle *obj, struct methodblock *method, int args_size, ExecEnv *ee, - stack_item *var_base, int retsize + stack_item *var_base #ifdef RUNTIME_DEBUG , int runtime_debug #endif diff -aruN shujit-0.6.5/computil.c shujit/computil.c --- shujit-0.6.5/computil.c Tue Sep 5 16:03:52 2000 +++ shujit/computil.c Tue Sep 12 13:55:23 2000 @@ -77,23 +77,23 @@ } -void showCompilerContext(CompilerContext *cc) { - printf("compiler context: 0x%x\n", (int)cc); +void showCompilerContext(CompilerContext *cc, char *prefix) { + printf("%scompiler context: 0x%x\n", prefix, (int)cc); fflush(stdout); if (cc) { struct methodblock *mb = cc->mb; - printf(" ExecEnv: 0x%08x\n", (int)cc->ee); - printf(" method: %s#%s %s (0x%08x)\n", + printf("%s ExecEnv: 0x%08x\n", prefix, (int)cc->ee); + printf("%s method: %s#%s %s (0x%08x)\n", prefix, (mb ? cbName(fieldclass(&mb->fb)) : "(null)"), (mb ? mb->fb.name : "(null)"), (mb ? mb->fb.signature : "(null)"), (int)mb); - printf(" buffer: 0x%08x\n", (int)cc->buffer); - printf(" bufp : 0x%08x offset:0x%x(%d)\n", + printf("%s buffer: 0x%08x\n", prefix, (int)cc->buffer); + printf("%s bufp : 0x%08x offset:0x%x(%d)\n", prefix, (int)cc->bufp, cc->bufp - cc->buffer, cc->bufp - cc->buffer); - printf(" pctable: 0x%08x\n", cc->pctable); - printf(" jptable: 0x%08x\n", cc->jptable); + printf("%s pctable: 0x%08x\n", prefix, cc->pctable); + printf("%s jptable: 0x%08x\n", prefix, cc->jptable); } fflush(stdout); } @@ -192,11 +192,7 @@ static void resetCompilerContext(CompilerContext *cc, struct methodblock *mb) { #ifdef COMPILE_DEBUG -# if 1 cc->compile_debug = debugp(mb); -# else - cc->compile_debug = 1; -# endif #endif #ifdef COMPILE_DEBUG @@ -380,7 +376,15 @@ } -pcentry *pctableGet(CompilerContext *cc, int byteoff) { +pcentry *pctableGet(CompilerContext *cc, int index) { + if ((index < 0) || (index >= cc->pctablelen)) + return NULL; + else + return cc->pctable + index; +} + + +pcentry *pctableGetByPC(CompilerContext *cc, int byteoff) { int l = 0; int h = cc->pctablelen; int index; @@ -402,7 +406,7 @@ if (l == h) { // not found #ifdef COMPILE_DEBUG struct methodblock *mb = cc->mb; - printf("FATAL: pctableGet(%s#%s %s)\n", + printf("FATAL: pctableGetByPC(%s#%s %s)\n", cbName(fieldclass(&mb->fb)), mb->fb.name, mb->fb.signature); printf(" not found: %x(%d)\n", byteoff, byteoff); fflush(stdout); @@ -596,6 +600,8 @@ void throwtableAdd(CodeInfo *info, uint32_t start, uint16_t len, uint16_t byteoff) { throwentry *entryp; + + sysAssert(info != NULL); if (info->throwtablelen >= info->throwtablesize) { // extend table size do diff -aruN shujit-0.6.5/gentable.rb shujit/gentable.rb --- shujit-0.6.5/gentable.rb Sun Sep 3 13:29:45 2000 +++ shujit/gentable.rb Wed Sep 13 20:42:09 2000 @@ -4,7 +4,7 @@ CONST_C_FNAME = 'constants.c' CONST_H_FNAME = 'constants.h' -NOPCODES = 313 +NOPCODES = 318 NSTATES = 5 STANY = 5 STSTA = 5 @@ -201,7 +201,9 @@ else func_table[opcode][init_state] = array end - elsif /0x606060/ # constant + elsif /(0x606060|60 60 60 00)/ # constant + # must match with `e9 60 60 60 00' (jmp) + # and `... 60 60 6000 ... 0x606060 ...'. i = 1 i += 1 while elems[i] != '60' off = elems[0].chop().hex() + i - 1 - code_addr diff -aruN shujit-0.6.5/invoker.c shujit/invoker.c --- shujit-0.6.5/invoker.c Tue Sep 5 19:45:07 2000 +++ shujit/invoker.c Wed Sep 13 22:03:28 2000 @@ -603,14 +603,8 @@ else if ((!strcmp(cbName(fieldclass(&mb->fb)), "java/security/Security")) && (!strcmp(mb->fb.name, "initialize"))) runtime_debug = 1; - else if ((!strcmp(cbName(fieldclass(&mb->fb)), "Linpack")) - && (!strcmp(mb->fb.name, "daxpy"))) - runtime_debug = 1; - else if ((!strcmp(cbName(fieldclass(&mb->fb)), "Linpack")) - && (!strcmp(mb->fb.name, "dgesl"))) - runtime_debug = 1; - else if ((!strcmp(cbName(fieldclass(&mb->fb)), "SinBenchmark")) - && (!strcmp(mb->fb.name, "main"))) + else if ((!strcmp(cbName(fieldclass(&mb->fb)), "java/lang/ClassLoader")) + && (!strcmp(mb->fb.name, "getSystemClassLoader"))) runtime_debug = 1; else if (!strcmp(mb->fb.name, "dtoa")) runtime_debug = 1; diff -aruN shujit-0.6.5/metavm/byvalue.c shujit/metavm/byvalue.c --- shujit-0.6.5/metavm/byvalue.c Tue Mar 16 00:08:43 1999 +++ shujit/metavm/byvalue.c Wed Sep 6 12:07:55 2000 @@ -49,7 +49,7 @@ clz_ByValueUtil = (*env)->FindClass(env, BYVALUEUTIL_CLASSNAME); #if 0 if (!clz_ByValueUtil) { - /* not reached */ + /* NOTREACHED */ printf("FATAL: class \"" BYVALUEUTIL_CLASSNAME "\" is not found.\n"); } #endif @@ -58,7 +58,7 @@ "isByValue", "(Ljava/lang/Class;)Z"); #if 0 if (!clz_ByValueUtil) { - /* not reached */ + /* NOTREACHED */ printf("FATAL: class \"" BYVALUEUTIL_CLASSNAME "\" is not found.\n"); } #endif @@ -66,7 +66,7 @@ result = (*env)->CallStaticBooleanMethod(env, clz_ByValueUtil, mid_isByValue, - MkRefLocal(env, (void *)clazz, JNI_REF_HANDLE_TAG)); + MK_REF_LOCAL(env, (void *)clazz)); #ifdef RUNTIME_DEBUG printf("isByValue() returns: %s\n", (result?"true":"false")); diff -aruN shujit-0.6.5/metavm/controller.c shujit/metavm/controller.c --- shujit-0.6.5/metavm/controller.c Mon Mar 15 21:15:45 1999 +++ shujit/metavm/controller.c Thu Sep 7 22:46:47 2000 @@ -21,13 +21,17 @@ $Id$ */ -#include "NET_shudo_metavm_MetaVM.h" +#include "metavm.h" -#include "native.h" /* for type ExecEnv */ -#include "sys_api.h" /* for sys*() */ -#include "java_lang_Thread.h" /* for ->eetop */ +#include "native.h" // for type ExecEnv +#include "sys_api.h" // for sys*() +#include "java_lang_Thread.h" // for ->eetop -#include "metavm.h" +#include "NET_shudo_metavm_MetaVM.h" + +#if JDK_VER >= 12 +# include "typedefs_md.h" // for ll2ptr() +#endif JNIEXPORT jboolean JNICALL Java_NET_shudo_metavm_MetaVM_remoteTransparency__ @@ -50,7 +54,7 @@ if (!ee) return JNI_FALSE; orig = (jboolean)GET_REMOTE_FLAG(ee); - SET_REMOTE_FLAG(ee, flag); /* JNI_TRUE or JNI_FALSE */ + SET_REMOTE_FLAG(ee, flag); // JNI_TRUE or JNI_FALSE return orig; } @@ -73,7 +77,12 @@ fflush(stdout); #endif - ee = (ExecEnv *)unhand((Hjava_lang_Thread *)DeRef(env, thr))->eetop; + ee = (ExecEnv *) +#if JDK_VER >=12 + ll2ptr(unhand((Hjava_lang_Thread *)DeRef(env, thr))->eetop); +#else + *(ExecEnv **)&(unhand((Hjava_lang_Thread *)DeRef(env, thr))->eetop); +#endif if (!ee) return JNI_FALSE; orig = (jboolean)GET_REMOTE_FLAG(ee); SET_REMOTE_FLAG(ee, flag); @@ -100,7 +109,7 @@ REMOTE_ADDR(ee) = NULL; if (h) - return MkRefLocal(env, (void *)h, JNI_REF_HANDLE_TAG); + return MK_REF_LOCAL(env, (void *)h); else return NULL; } diff -aruN shujit-0.6.5/metavm/metavm.h shujit/metavm/metavm.h --- shujit-0.6.5/metavm/metavm.h Wed Jul 21 12:22:40 1999 +++ shujit/metavm/metavm.h Tue Sep 12 14:35:13 2000 @@ -2,7 +2,7 @@ This file is part of shuJIT, Just In Time compiler for Sun Java Virtual Machine. - Copyright (C) 1998,1999 SHUDO Kazuyuki + Copyright (C) 1998,1999,2000 SHUDO Kazuyuki This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -26,34 +26,54 @@ #include "../config.h" -#include "NET_shudo_metavm_VMAddress_old.h" /* for proxy_new() */ +#include "NET_shudo_metavm_VMAddress_old.h" // for proxy_new() #include "native.h" +// +// MetaVM specific macro definitions +// + #define METAVM_PKG "NET/shudo/metavm/" -#define REMOTE_ADDR(EE) ((EE)->exception.exc) -#if JDK_VER == 11 -# define GET_REMOTE_FLAG(EE) ((EE)->alloc_cache.cache_pad[0]) +#if JDK_VER >= 12 +# define GET_REMOTE_FLAG(EE) \ + (*(((char *)&(EE)) + 17)) # define SET_REMOTE_FLAG(EE, FLAG) \ - ((EE)->alloc_cache.cache_pad[0] = (char)(FLAG)) + (*(((char *)&(EE)) + 17) = (char)(FLAG)) +# define REMOTE_ADDR(EE) ((JHandle *)(EE)->RESERVED3) #else -# define GET_REMOTE_FLAG(EE) ((int)((EE)->RESERVED1)) +# define GET_REMOTE_FLAG(EE) \ + ((EE)->alloc_cache.cache_pad[0]) # define SET_REMOTE_FLAG(EE, FLAG) \ - ((EE)->RESERVED1 = (void *)(FLAG)) -#endif /* JDK_VER */ + ((EE)->alloc_cache.cache_pad[0] = (char)(FLAG)) +# define REMOTE_ADDR(EE) ((JHandle *)(EE)->exception.exc) +#endif // JDK_VER #define REMOTE_FLAG_OFF(EE) SET_REMOTE_FLAG(EE, 0) #define REMOTE_FLAG_ON(EE) SET_REMOTE_FLAG(EE, 1) -/* - * Global functions - */ -/* type.c */ + +#if JDK_VER >= 12 +# define MK_REF_LOCAL(env, jobj) \ + MkRefLocal(env, jobj) +#else +# define MK_REF_LOCAL(env, jobj) \ + ((jobject)MkRefLocal(env, jobj, JNI_REF_HANDLE_TAG)) +#endif + + +// +// Global functions +// +// type.c extern int isCheckPassType(ClassClass *cb); extern void forceToImplement(ExecEnv *ee, ClassClass *clazz, ClassClass *intf); -/* proxy.c */ +// byvalue.c +extern bool_t isByValue(ExecEnv *ee, ClassClass *clazz); + +// proxy.c extern JHandle *proxy_new(ExecEnv *, ClassClass *, HNET_shudo_metavm_VMAddress *, ClassClass *); extern JHandle *proxy_newarray(ExecEnv *, ClassClass *, @@ -65,22 +85,27 @@ int dim, stack_item *stackpointer); #define DECL_GET_FIELD(NAME, CTYPE) \ - extern CTYPE proxy_##NAME(ExecEnv *, JHandle *proxy, int32_t slot); -DECL_GET_FIELD(get32field, int32_t) -DECL_GET_FIELD(get64field, int64_t) -DECL_GET_FIELD(getobjfield, JHandle *) + extern CTYPE proxy_##NAME(ExecEnv *, JHandle *proxy, int32_t slot) +DECL_GET_FIELD(get32field, jint); +DECL_GET_FIELD(get64field, jlong); +DECL_GET_FIELD(getobjfield, JHandle *); +DECL_GET_FIELD(aload32, jint); +DECL_GET_FIELD(aload64, jlong); +DECL_GET_FIELD(aloadobj, JHandle *); #define DECL_PUT_FIELD(NAME, CTYPE) \ - extern void proxy_##NAME(ExecEnv *, JHandle *proxy, int32_t, CTYPE); -DECL_PUT_FIELD(put32field, int32_t) -DECL_PUT_FIELD(put64field, int64_t) -DECL_PUT_FIELD(putobjfield, JHandle *) -#define DECL_ARRAY_LOAD(NAME, CTYPE) \ - extern CTYPE proxy_##NAME(ExecEnv *, JHandle *proxy, int32_t slot); + extern void proxy_##NAME(ExecEnv *, JHandle *proxy, int32_t, CTYPE) +DECL_PUT_FIELD(put32field, int32_t); +DECL_PUT_FIELD(put64field, int64_t); +DECL_PUT_FIELD(putobjfield, JHandle *); +DECL_PUT_FIELD(astore32, int32_t); +DECL_PUT_FIELD(astore64, int64_t); +DECL_PUT_FIELD(astoreobj, JHandle *); +extern int32_t proxy_arraylength(ExecEnv *ee, JHandle *proxy); extern int proxy_invoke(ExecEnv *, JHandle *proxy, struct methodblock *mb, int32_t slot, char *sig, stack_item *stackpointer); extern int proxy_monitorenter(ExecEnv *, JHandle *proxy); extern int proxy_monitorexit(ExecEnv *, JHandle *proxy); -#endif /* _METAVM_H_ */ +#endif // _METAVM_H_ diff -aruN shujit-0.6.5/metavm/objectid.c shujit/metavm/objectid.c --- shujit-0.6.5/metavm/objectid.c Tue Mar 2 00:46:56 1999 +++ shujit/metavm/objectid.c Thu Sep 7 22:48:12 2000 @@ -2,7 +2,7 @@ This file is part of shuJIT, Just In Time compiler for Sun Java Virtual Machine. - Copyright (C) 1998,1999 SHUDO Kazuyuki + Copyright (C) 1998,1999,2000 SHUDO Kazuyuki This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -21,8 +21,10 @@ $Id$ */ +#include "metavm.h" // for MK_REF_LOCAL() + #include "NET_shudo_metavm_ObjectID.h" -#include "native.h" /* for MkRefLocal() */ +#include "native.h" // for MkRefLocal() JNIEXPORT jint JNICALL Java_NET_shudo_metavm_ObjectID_idByObject @@ -41,5 +43,5 @@ printf("objectById() called.\n"); fflush(stdout); #endif - return (jobject)MkRefLocal(env, id, JNI_REF_HANDLE_TAG); + return (jobject)MK_REF_LOCAL(env, id); } diff -aruN shujit-0.6.5/metavm/proxy.c shujit/metavm/proxy.c --- shujit-0.6.5/metavm/proxy.c Tue Mar 30 17:43:13 1999 +++ shujit/metavm/proxy.c Tue Sep 12 21:26:27 2000 @@ -21,7 +21,7 @@ $Id$ */ -#include /* for strlen(), memcpy() */ +#include // for strlen(), memcpy() #include "metavm.h" #include "native.h" @@ -43,7 +43,7 @@ #define PROXY_CLASSNAME METAVM_PKG "Proxy" -/* Global Varialbe */ +// Global Varialbe struct methodtable *proxy_methodtable; @@ -83,20 +83,20 @@ (JNIEnv *env, jclass clazz) { ExecEnv *ee = JNIEnv2EE(env); ClassClass *cb = (ClassClass *)DeRef(env, clazz); -/* +#if 0 printf("cb of Proxy: 0x%08x\n", (int)cb); -*/ +#endif proxy_methodtable = unhand(cb)->methodtable; -/* +#if 0 printf("proxy_methodtable: 0x%08x\n", (int)proxy_methodtable); fflush(stdout); -*/ +#endif #define CLAZZ_INIT(JCLASS, CLASSNAME) \ jclz_##JCLASS = (*env)->FindClass(env, CLASSNAME);\ jclz_##JCLASS = (*env)->NewGlobalRef(env, jclz_##JCLASS);\ - clz_##JCLASS = DeRef(env, jclz_##JCLASS) + clz_##JCLASS = (ClassClass *)DeRef(env, jclz_##JCLASS) #define LANG_CLAZZ_INIT(JCLASS) \ CLAZZ_INIT(JCLASS, "java/lang/" #JCLASS) @@ -138,11 +138,13 @@ fflush(stdout); #endif + sysAssert(clz_Proxy != NULL); + obj = (JHandle *)do_execute_java_method(ee, clz_Proxy, "get", "(Ljava/lang/Class;L" METAVM_PKG "VMAddress;Ljava/lang/Class;)L" METAVM_PKG "Proxy;", - NULL, /* struct methodblock */ - TRUE, /* isStaticCall */ + NULL, // struct methodblock + TRUE, // isStaticCall fromClazz, addr, cb); #ifdef RUNTIME_DEBUG if (exceptionOccurred(ee)) { @@ -172,11 +174,13 @@ fflush(stdout); #endif + sysAssert(clz_Proxy != NULL); + obj = (JHandle *)do_execute_java_method(ee, clz_Proxy, "get", "(Ljava/lang/Class;L" METAVM_PKG "VMAddress;II)L" METAVM_PKG "Proxy;", - NULL, /* struct methodblock */ - TRUE, /* isStaticCall */ + NULL, // struct methodblock + TRUE, // isStaticCall fromClazz, addr, type, count); #ifdef RUNTIME_DEBUG if (exceptionOccurred(ee)) { @@ -202,11 +206,13 @@ char orig = GET_REMOTE_FLAG(ee); REMOTE_FLAG_OFF(ee); + sysAssert(clz_Proxy != NULL); + obj = (JHandle *)do_execute_java_method(ee, clz_Proxy, "get", "(Ljava/lang/Class;L" METAVM_PKG "VMAddress;Ljava/lang/Class;I)L" METAVM_PKG "Proxy;", - NULL, /* struct methodblock */ - TRUE, /* isStaticCall */ + NULL, // struct methodblock + TRUE, // isStaticCall fromClazz, addr, cb, count); #ifdef RUNTIME_DEBUG if (exceptionOccurred(ee)) { @@ -251,7 +257,7 @@ printf(" %d: %d\n", i, size); fflush(stdout); #endif #ifndef NO_CHECK - if (size < 0) /* NegativeArraySizeException */ + if (size < 0) // NegativeArraySizeException return (JHandle *)-1; #endif csizes[i] = size; @@ -261,11 +267,13 @@ (*env)->ReleaseIntArrayElements(env, sizes, csizes, JNI_COMMIT); + sysAssert(clz_Proxy != NULL); + obj = (JHandle *)do_execute_java_method(ee, clz_Proxy, "get", "(Ljava/lang/Class;L" METAVM_PKG "VMAddress;Ljava/lang/Class;[I)L" METAVM_PKG "Proxy;", - NULL, /* struct methodblock */ - TRUE, /* isStaticCall */ + NULL, // struct methodblock + TRUE, // isStaticCall fromClazz, addr, cb, DeRef(env, sizes)); #ifdef RUNTIME_DEBUG if (exceptionOccurred(ee)) { @@ -284,11 +292,11 @@ } -/* definitions of proxy_get*field() */ +// definitions of proxy_get*field() #define GET_FIELD(METHOD_NAME, JTYPE, SIG, CTYPE, JNITYPE, POSTPROC) \ CTYPE proxy_##METHOD_NAME(ExecEnv *ee, JHandle *proxy, int32_t slot) {\ JNIEnv *env = EE2JNIEnv(ee);\ - jobject obj = (jobject)MkRefLocal(env, proxy, JNI_REF_HANDLE_TAG);\ + jobject obj = (jobject)MK_REF_LOCAL(env, proxy);\ jvalue args[1];\ JNITYPE val;\ \ @@ -310,7 +318,7 @@ GET_FIELD(getobjfield, Object, Ljava/lang/Object;, JHandle *, jobject, DeRef(env, val)); -/* definitions of proxy_put*field() */ +// definitions of proxy_put*field() #define PUT_FIELD(METHOD_NAME, SIG, CTYPE) \ void proxy_##METHOD_NAME(ExecEnv *ee,\ JHandle *proxy, int32_t slot, CTYPE val) {\ @@ -331,13 +339,13 @@ PUT_FIELD(putobjfield, Ljava/lang/Object;, JHandle *); -/* definitions of proxy_aload*() */ +// definitions of proxy_aload*() GET_FIELD(aload32, Int, I, int32_t, jint, (int32_t)val); GET_FIELD(aload64, Long, J, int64_t, jlong, (int64_t)val); GET_FIELD(aloadobj, Object, Ljava/lang/Object;, JHandle *, jobject, DeRef(env, val)); -/* definitions of proxy_astore*() */ +// definitions of proxy_astore*() PUT_FIELD(astore32, I, int32_t); PUT_FIELD(astore64, J, int64_t); PUT_FIELD(astoreobj, Ljava/lang/Object;, JHandle *); @@ -352,7 +360,7 @@ len = (int32_t)do_execute_java_method(ee, proxy, "arraylength", "()I", NULL, - FALSE); /* isStaticCall */ + FALSE); // isStaticCall #ifdef RUNTIME_DEBUG if (exceptionOccurred(ee)) { printf("exc. occurred.\n"); @@ -370,9 +378,9 @@ struct methodblock *mb, int32_t slot, char *sig, stack_item *stackpointer) { JNIEnv *env = EE2JNIEnv(ee); - int args_size; /* in 4byte, mb->args_size */ + int args_size; // in 4byte, mb->args_size stack_item *var_base, *spptr; - int args_len; /* number of elements, NOT size */ + int args_len; // number of elements, NOT size char *p; HArrayOfObject *args = NULL; JHandle **args_body; JHandle *args_elem; JHandle *ret; @@ -392,7 +400,7 @@ #endif - /* args_size and var_base */ + // args_size and var_base args_size = mb->args_size; var_base = stackpointer + args_size - 1; #ifdef RUNTIME_DEBUG @@ -408,7 +416,7 @@ #endif - /* number of arguments */ + // number of arguments args_len = 0; for (p = sig + 1; *p != ')'; p++) { args_len++; @@ -434,7 +442,7 @@ args = (HArrayOfObject *)ArrayAlloc(T_CLASS, args_len); unhand(args)->body[args_len] = (HObject *)classJavaLangObject; - MkRefLocal(env, args, JNI_REF_HANDLE_TAG); /* register as local ref */ + MK_REF_LOCAL(env, args); // register as local ref #ifdef RUNTIME_DEBUG printf("classJavaLangObject: 0x%08x\n", (int)classJavaLangObject); fflush(stdout); @@ -486,10 +494,10 @@ p++; } - } /* if (args_len > 0) */ + } // if (args_len > 0) while (*p != ')') p++; p++; - /* Now, p points sig. of return value */ + // Now, p points sig. of return value #ifdef RUNTIME_DEBUG { int i; @@ -500,7 +508,7 @@ #endif - /* calculate size of return value */ + // calculate size of return value switch (*p) { case 'V': ret_size = 0; @@ -518,7 +526,7 @@ break; } - /* invoke */ + // invoke { JavaFrame *cur_frame = ee->current_frame; stack_item *optop = cur_frame->optop; @@ -531,8 +539,8 @@ ret = (JHandle *)do_execute_java_method(ee, proxy, "invoke", "(ILjava/lang/String;[Ljava/lang/Object;)Ljava/lang/Object;", - NULL, /* struct methodblock */ - FALSE, /* isStaticCall */ + NULL, // struct methodblock + FALSE, // isStaticCall slot, makeJavaStringUTF(sig), args); if (exceptionOccurred(ee)) return -1; @@ -596,8 +604,8 @@ int proxy_monitorenter(ExecEnv *ee, JHandle *proxy) { do_execute_java_method(ee, proxy, "monitorEnter", "()V", - NULL, /* struct methodblock */ - FALSE); /* isStaticCall */ + NULL, // struct methodblock + FALSE); // isStaticCall if (exceptionOccurred(ee)) return -1; @@ -609,8 +617,8 @@ int proxy_monitorexit(ExecEnv *ee, JHandle *proxy) { do_execute_java_method(ee, proxy, "monitorExit", "()V", - NULL, /* struct methodblock */ - FALSE); /* isStaticCall */ + NULL, // struct methodblock + FALSE); // isStaticCall if (exceptionOccurred(ee)) return -1; diff -aruN shujit-0.6.5/metavm/type.c shujit/metavm/type.c --- shujit-0.6.5/metavm/type.c Tue Mar 2 00:49:00 1999 +++ shujit/metavm/type.c Mon Sep 11 18:38:07 2000 @@ -23,7 +23,7 @@ #include "NET_shudo_metavm_TypeUtil.h" -#include "sys_api.h" /* for sys*() */ +#include "sys_api.h" // for sys*() #include "metavm.h" @@ -78,7 +78,8 @@ JNIEXPORT void JNICALL Java_NET_shudo_metavm_TypeUtil_forceToImplement0 (JNIEnv *env, jclass clz, jclass jclazz, jclass jintf) { - forceToImplement(JNIEnv2EE(env), DeRef(env, jclazz), DeRef(env, jintf)); + forceToImplement(JNIEnv2EE(env), + (ClassClass *)DeRef(env, jclazz), (ClassClass *)DeRef(env, jintf)); } @@ -108,10 +109,19 @@ return; } -#if 0 /* can't touch implements and implements_count */ +#if 0 // can't touch implements and implements_count cbImplementsCount(clazz)++; #endif +#if JDK_VER >= 12 + if (!CCIs(clazz, InterfacePrepared)) { +# ifdef FORCE_IMPL_DEBUG + printf(" InterfacePrepared is false.\n"); fflush(stdout); +# endif + LinkClass(clazz); + } +#endif // JDK_VER + clazz_imtable = cbIntfMethodTable(clazz); clazz_icount = clazz_imtable->icount; intf_imtable = cbIntfMethodTable(intf); @@ -157,11 +167,11 @@ imtable->icount = icount; memcpy(&imtable->itable[0], &clazz_imtable->itable[0], - clazz_icount * ITEM_SIZE); /* copy original itable */ + clazz_icount * ITEM_SIZE); // copy original itable memcpy(&imtable->itable[clazz_icount], &intf_imtable->itable[0], - intf_icount * ITEM_SIZE); /* copy intf's itable */ + intf_icount * ITEM_SIZE); // copy intf's itable - /* copy offsets */ + // copy offsets for (i = 0; i < clazz_icount; i++) { int nmethod = cbMethodsCount(clazz_imtable->itable[i].classdescriptor); unsigned long *clazz_offs = clazz_imtable->itable[i].offsets; @@ -172,7 +182,7 @@ for (j = 0; j < nmethod; j++) offs[j] = clazz_offs[j]; } - /* make offsets of implemented interface */ + // make offsets of implemented interface for (i = 0; i < intf_icount; i++) { int nmethod = cbMethodsCount(intf_imtable->itable[i].classdescriptor); unsigned long *intf_offs = intf_imtable->itable[i].offsets; @@ -184,7 +194,7 @@ for (j = 0; j < nmethod; j++) offs[j] = intf_offs[j]; } -#if 0 /* leak clazz_imtable !!! */ +#if 0 // leak clazz_imtable !!! if (clazz_icount) { sysFree(clazz_imtable); } diff -aruN shujit-0.6.5/metavm/vmop.c shujit/metavm/vmop.c --- shujit-0.6.5/metavm/vmop.c Sat Mar 20 17:36:32 1999 +++ shujit/metavm/vmop.c Tue Sep 12 02:24:17 2000 @@ -21,8 +21,10 @@ $Id$ */ -#include "native.h" /* for old style native methods */ -#include "sys_api.h" /* sys*() */ +#include "metavm.h" + +#include "native.h" // for old style native methods +#include "sys_api.h" // sys*() #include "NET_shudo_metavm_VMOperations.h" @@ -45,9 +47,9 @@ } -/* - * Local Functions - */ +// +// Local Functions +// static jobject invokeMethod(JNIEnv *env, jobject, jmethodID, const char *csig, jobjectArray); @@ -60,7 +62,7 @@ printf("vmop#instantiate called.\n"); fflush(stdout); { - ClassClass *clz = DeRef(env, tgtclz); + ClassClass *clz = (ClassClass *)DeRef(env, tgtclz); printf(" class: %s\n", (clz?cbName(clz):"null")); } fflush(stdout); @@ -128,13 +130,13 @@ fflush(stdout); (*env)->ReleaseIntArrayElements(env, sizes, csizes, JNI_ABORT); - /* JNI_ABORT: copy back isn't required */ + // JNI_ABORT: copy back isn't required - array = MultiArrayAlloc((int)dim, DeRef(env, aryclz), s); + array = MultiArrayAlloc((int)dim, (ClassClass *)DeRef(env, aryclz), s); free(s); - return MkRefLocal(env, array, JNI_REF_HANDLE_TAG); + return MK_REF_LOCAL(env, array); } @@ -158,9 +160,7 @@ JNIEXPORT jobject JNICALL Java_NET_shudo_metavm_VMOperations_getObjectField (JNIEnv *env, jclass clazz, jobject obj, jint slot) { - return (jobject)MkRefLocal(env, - obj_getslot((JHandle *)DeRef(env, obj), slot), - JNI_REF_HANDLE_TAG); + return MK_REF_LOCAL(env, obj_getslot((JHandle *)DeRef(env, obj), slot)); } JNIEXPORT void JNICALL Java_NET_shudo_metavm_VMOperations_put32Field @@ -232,7 +232,7 @@ fflush(stdout); #endif - /* get method ID */ + // get method ID mid = (*env)->GetMethodID(env, objClazz, cname, csig); if (!mid) { if (!jclz_NoSuchMethodException) { @@ -240,12 +240,12 @@ (*env)->FindClass(env, "java/lang/NoSuchMethodException"); jclz_NoSuchMethodException = (*env)->NewGlobalRef(env, jclz_NoSuchMethodException); - /* register as global ref. */ + // register as global ref. } (*env)->ThrowNew(env, jclz_NoSuchMethodException, NULL); } - /* invoke the method */ + // invoke the method result = invokeMethod(env, obj, mid, csig, args); (*env)->ReleaseStringUTFChars(env, name, cname); @@ -284,8 +284,8 @@ #endif cb = (Hjava_lang_Class *)DeRef(env, objClazz); - /* get method ID */ - if (slot == 0) { /* caller is a constructor */ + // get method ID + if (slot == 0) { // caller is a constructor csig = (*env)->GetStringUTFChars(env, sig, NULL); mid = (*env)->GetMethodID(env, objClazz, "", csig); } @@ -305,7 +305,7 @@ fflush(stdout); #endif #endif - if (!mid) return NULL; /* haven't to be called */ + if (!mid) return NULL; // haven't to be called csig = ((struct methodblock *)mid)->fb.signature; } #ifdef RUNTIME_DEBUG @@ -318,7 +318,7 @@ fflush(stdout); #endif - /* invoke the method */ + // invoke the method result = invokeMethod(env, obj, mid, csig, args); if (slot == 0) { @@ -343,7 +343,7 @@ jobject result; int i; - /* prepare arguments */ + // prepare arguments if (args) { arrayLength = (*env)->GetArrayLength(env, args); #ifdef RUNTIME_DEBUG @@ -357,7 +357,7 @@ { jobject elem; - char *p; + const char *p; #define COPY_ARG(JCLASS, JTYPE, SIG, sig) \ if (!fid_##JCLASS##Value) {\ @@ -403,14 +403,14 @@ p++; } } - } /* if (args) */ + } // if (args) else { cargs = NULL; } - /* invoke */ + // invoke { - char *p = csig; + const char *p = csig; while (*p != ')') p++; p++; @@ -469,5 +469,5 @@ JNIEXPORT void JNICALL Java_NET_shudo_metavm_VMOperations_printStackTrace (JNIEnv *env, jclass clazz) { - showStackFrames(JNIEnv2EE(env)); /* in runtime.c */ + showStackFrames(JNIEnv2EE(env)); // in runtime.c } diff -aruN shujit-0.6.5/opcodes_internal.h shujit/opcodes_internal.h --- shujit-0.6.5/opcodes_internal.h Sun Sep 3 13:29:41 2000 +++ shujit/opcodes_internal.h Wed Sep 13 19:07:30 2000 @@ -29,107 +29,112 @@ #define opc_methodhead 230 // 0xe6 -#define opc_epilogue 231 -#define opc_exc_handler 232 -#define opc_methodtail 233 -#define opc_sync_enter 234 -#define opc_sync_exit 235 - -#define opc_inv_head 236 // 0xec -#define opc_inv_core 237 -#define opc_inv_metavm 238 - -#define opc_inv_vir_obj 239 // 0xef -#define opc_inv_vir_varspace 240 -#define opc_invokevirtual_obj 241 - -#define opc_inv_spe_obj 242 -#define opc_inv_spe_varspace 243 - -#define opc_inv_stq_obj 244 -#define opc_inv_stq_varspace 245 - -#define opc_direct_invoke 246 // 0xf6 - -#define opc_invokeignored_static 247 // 0xf7 -#define opc_invokeignored_static_quick 248 - -#define opc_throw_illegalaccess 249 // 0xf9 -#define opc_throw_noclassdef 250 - -#define opc_fill_cache 251 -#define opc_flush_cache 252 -#define opc_array_check 253 - - -#define opc_strict_enter 256 // 0x100 -#define opc_strict_exit 257 - -#define opc_fld4 258 // 0x102 -#define opc_fld 259 -#define opc_fst 260 -#define opc_dld8 261 -#define opc_dld 262 -#define opc_dst 263 - -#define opc_fppc_save 264 // 0x108 -#define opc_fppc_restore 265 -#define opc_fppc_single 266 -#define opc_fppc_double 267 -#define opc_fppc_extended 268 - -#define opc_strict_fprep 269 // 0x10d -#define opc_strict_fscdown 270 -#define opc_strict_fscup 271 -#define opc_strict_fsettle 272 -#define opc_strict_dprep 273 -#define opc_strict_dscdown 274 -#define opc_strict_dscup 275 -#define opc_strict_dsettle 276 - -#define opc_getstatic2 277 // 0x115 -#define opc_putstatic2 278 -#define opc_getfield2 279 -#define opc_putfield2 280 - -#define opc_iastore1 281 // 0x119 -#define opc_lastore1 282 - -#define opc_stateto0 283 // 0x11b -#define opc_stateto1 284 -#define opc_stateto2 285 -#define opc_stateto3 286 -#define opc_stateto4 287 - -#define opc_goto_st0 288 // 0x120 -#define opc_goto_st1 289 -#define opc_goto_st2 290 -#define opc_goto_st3 291 -#define opc_goto_st4 292 - -#define opc_sqrt 293 // 0x125 -#define opc_sin 294 -#define opc_cos 295 -#define opc_tan 296 -#define opc_atan2 297 -#define opc_atan 298 // 0x12a -#define opc_exp 299 -#define opc_log 300 -#define opc_floor 301 -#define opc_ceil 302 +#define opc_start 231 +#define opc_epilogue 232 +#define opc_exc_handler 233 +#define opc_methodtail 234 +#define opc_sync_enter 235 +#define opc_sync_exit 236 + +#define opc_inv_head 237 // 0xed +#define opc_invoke_core 238 +#define opc_invoke_core_compiled 239 +#define opc_inv_metavm 240 + +#define opc_inv_vir_obj 241 // 0xf1 +#define opc_inv_vir_varspace 242 +#define opc_invokevirtual_obj 243 + +#define opc_inv_spe_obj 244 +#define opc_inv_spe_varspace 245 + +#define opc_inv_stq_obj 246 +#define opc_inv_stq_varspace 247 + +#define opc_invokeignored_static 248 // 0xf8 +#define opc_invokeignored_static_quick 249 + +#define opc_invoke_recursive 250 +#define opc_invoke_recursive_1 251 +#define opc_invoke_recursive_2 252 +#define opc_invoke_recursive_3 253 + + +#define opc_fill_cache 256 +#define opc_flush_cache 257 +#define opc_array_check 258 + +#define opc_throw_illegalaccess 259 +#define opc_throw_noclassdef 260 + +#define opc_strict_enter 261 +#define opc_strict_exit 262 + +#define opc_fld4 263 // 0x107 +#define opc_fld 264 +#define opc_fst 265 +#define opc_dld8 266 +#define opc_dld 267 +#define opc_dst 268 + +#define opc_fppc_save 269 // 0x10d +#define opc_fppc_restore 270 +#define opc_fppc_single 271 +#define opc_fppc_double 272 +#define opc_fppc_extended 273 + +#define opc_strict_fprep 274 // 0x112 +#define opc_strict_fscdown 275 +#define opc_strict_fscup 276 +#define opc_strict_fsettle 277 +#define opc_strict_dprep 278 +#define opc_strict_dscdown 279 +#define opc_strict_dscup 280 +#define opc_strict_dsettle 281 + +#define opc_getstatic2 282 // 0x11a +#define opc_putstatic2 283 +#define opc_getfield2 284 +#define opc_putfield2 285 + +#define opc_iastore1 286 // 0x11e +#define opc_lastore1 287 + +#define opc_stateto0 288 // 0x120 +#define opc_stateto1 289 +#define opc_stateto2 290 +#define opc_stateto3 291 +#define opc_stateto4 292 + +#define opc_goto_st0 293 // 0x125 +#define opc_goto_st1 294 +#define opc_goto_st2 295 +#define opc_goto_st3 296 +#define opc_goto_st4 297 + +#define opc_sqrt 298 // 0x12a +#define opc_sin 299 +#define opc_cos 300 +#define opc_tan 301 +#define opc_atan2 302 +#define opc_atan 303 // 0x12f +#define opc_exp 304 +#define opc_log 305 +#define opc_floor 306 +#define opc_ceil 307 // for OPTIMIZE_INTERNAL_CODE -#define opc_fload_fld 303 // 0x12f -#define opc_dload_dld 304 -#define opc_faload_fld 305 -#define opc_daload_dld 306 - -#define opc_fst_fstore 307 -#define opc_dst_dstore 308 -#define opc_fst_fastore 309 -#define opc_dst_dastore 310 +#define opc_fload_fld 308 // 0x134 +#define opc_dload_dld 309 +#define opc_faload_fld 310 +#define opc_daload_dld 311 + +#define opc_fst_fstore 312 +#define opc_dst_dstore 313 +#define opc_fst_fastore 314 +#define opc_dst_dastore 315 -#define opc_istld 311 // 0x137 -#define opc_lstld 312 +#define opc_istld 316 // 0x13c +#define opc_lstld 317 -#define NOPCODES 313 +#define NOPCODES 318 diff -aruN shujit-0.6.5/runtime.c shujit/runtime.c --- shujit-0.6.5/runtime.c Tue Sep 5 15:43:58 2000 +++ shujit/runtime.c Sun Sep 10 23:38:17 2000 @@ -36,7 +36,7 @@ */ int invocationHelper( JHandle *obj, struct methodblock *method, int args_size, ExecEnv *ee, - stack_item *var_base, int retsize + stack_item *var_base #ifdef RUNTIME_DEBUG , int runtime_debug #endif @@ -44,6 +44,7 @@ void *invoker; CodeInfo *info; JavaFrame *cur_frame; // ee->current_frame + int retsize; int access; #ifdef RUNTIME_DEBUG @@ -70,6 +71,7 @@ struct methodblock *cur_mb; char *sig; int i; + retsize = info->ret_size; access = method->fb.access; cur_frame = ee->current_frame; @@ -179,6 +181,7 @@ #endif // DIRECT_INVOCATION info = (CodeInfo *)method->CompiledCodeInfo; + retsize = info->ret_size; #ifdef DIRECT_INV_NATIVE if ((invoker == sym_invokeJNINativeMethod) || diff -aruN shujit-0.6.5/txt/SPECjvm98 shujit/txt/SPECjvm98 --- shujit-0.6.5/txt/SPECjvm98 Tue Sep 5 21:11:46 2000 +++ shujit/txt/SPECjvm98 Wed Sep 13 21:56:03 2000 @@ -10,23 +10,23 @@ * TYA 1.7v2 * interpreter - 0.6.5 0.6.4 0.6.3 -_201_compress 143.152 146.926 147.786 -_202_jess 57.459 57.876 58.563 -_209_db 129.824 137.821 129.598 -_213_javac 124.729 126.728 126.206 -_222_mpegaudio 110.923 116.418 125.457 -_227_mtrt 85.534 87.007 89.999 -_228_jack 69.653 68.524 72.625 + 0.6.6 0.6.5 0.6.4 0.6.3 +_201_compress 140.161 143.152 146.926 147.786 +_202_jess 56.649 57.459 57.876 58.563 +_209_db 125.032 129.824 137.821 129.598 +_213_javac 121.552 124.729 126.728 126.206 +_222_mpegaudio 107.761 110.923 116.418 125.457 +_227_mtrt 84.81 85.534 87.007 89.999 +_228_jack 66.717 69.653 68.524 72.625 -_227_mtrt 5.38 5.29 5.11 -_202_jess 6.61 6.57 6.49 -_201_compress 8.21 8.00 7.95 -_209_db 3.89 3.66 3.90 -_222_mpegaudio 9.92 9.45 8.77 -_228_jack 6.53 6.64 6.27 -_213_javac 3.41 3.35 3.37 -Geometric Mean 5.91 5.77 5.68 +_227_mtrt 5.42 5.38 5.29 5.11 +_202_jess 6.71 6.61 6.57 6.49 +_201_compress 8.38 8.21 8.00 7.95 +_209_db 4.04 3.89 3.66 3.90 +_222_mpegaudio 10.2 9.92 9.45 8.77 +_228_jack 6.82 6.53 6.64 6.27 +_213_javac 3.50 3.41 3.35 3.37 +Geometric Mean 6.06 5.91 5.77 5.68 TYA JBui OpenJIT int:FCS int:RC4 _201_compress 153.195 112.659 114.529 596.893 615.064 diff -aruN shujit-0.6.5/txt/acc_to_frame shujit/txt/acc_to_frame --- shujit-0.6.5/txt/acc_to_frame Thu Aug 27 13:16:13 1998 +++ shujit/txt/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.6.5/txt/benchmark-PJ2X3 shujit/txt/benchmark-PJ2X3 --- shujit-0.6.5/txt/benchmark-PJ2X3 Tue Sep 5 22:15:46 2000 +++ shujit/txt/benchmark-PJ2X3 Wed Sep 13 19:53:08 2000 @@ -3,8 +3,8 @@ [TYA 付属のもの] - interp. TYA17v2 Inp1215 000423 000429 0.6.4 0.6.5 -Sieve 125 586 1096 622 634 629 618 + interp. TYA17v2 Inp1215 000423 000429 0.6.4 0.6.5 0.6.6 +Sieve 125 586 1096 622 634 629 618 632 [Linpack Benchmark -- Java Version] @@ -17,6 +17,8 @@ shuJIT-000822 9.035 0.08 shuJIT-000901 11.257 0.06 shuJIT-0.6.4 13.205 0.05 +shuJIT-000909 13.464 0.05 +shuJIT-0.6.6 13.733 0.05 TYA-1.7 11.444 0.06 OpenJIT-1.1.10 12.956 0.05 OpenJIT-1.1.13 13.464 0.05 @@ -43,29 +45,17 @@ CM3 439 * shuJIT - 000712 000717 000723 000731 000814 -Sieve 2000 2008 2002→ 2003 2006 1994 2001 -Loop 3344 3343 3307↓ 3310 3343 3194 3334 -Logic 4364 4364 4400↑ 4394 4362 4388 4341 -String 1813 1701 1774↑ 2377 1846 2351 1840 -Float 1760 1964 2052↑ 1897 1904 1899 1888 -Method 621 434 433→ 446 449 446 444 -Graphics 336 358 425↑ 300 345 355 305 -Image 511 518 524 514 512 515 501 -Dialog 84 82 83 96 85 150 119 -CM3 980 952 981 984 960 1048 979 - - 000816 000822 000827 0.6.3 000829 000901 0.6.4 0.6.5 -Sieve 2007 1996 1997 1994 1990 1999 1992 1975↓ -Loop 3348 3346 3348 3337 3350 3351 3347 3323 -Logic 4401 4912↑ 4818 5935↑ 5950 6879(?) 5950(?) 6864(?) -String 1844 1867 1879 1855 1943↑ 2487(?) 2450(?) 2521 -Float 2024 1920 1822 1829 1831 2079↑ 2448↑ 2505↑ -Method 1508 1672↑ 1737 1752 1732 1736 1827↑ 1826 -Graphics 346 343 392 323 324 312 319 343 -Image 513 518 506 526 517 524 529 526 -Dialog 126 121 127 114 120 129 127 107 -CM3 1157 1173 1191 1183 1193 1272 1281 1291 + 000816 000822 000827 0.6.3 000829 000901 0.6.4 0.6.5 0.6.6 +Sieve 2007 1996 1997 1994 1990 1999 1992 1975↓ 1989 +Loop 3348 3346 3348 3337 3350 3351 3347 3323 3370 +Logic 4401 4912↑ 4818 5935↑ 5950 6879(?) 5950(?) 6864(?) 6864(?) +String 1844 1867 1879 1855 1943↑ 2487(?) 2450(?) 2521 2445 +Float 2024 1920 1822 1829 1831 2079↑ 2448↑ 2505↑ 2501 +Method 1508 1672↑ 1737 1752 1732 1736 1827↑ 1826 1864 +Graphics 346 343 392 323 324 312 319 343 312 +Image 513 518 506 526 517 524 529 526 518 +Dialog 126 121 127 114 120 129 127 107 118 +CM3 1157 1173 1191 1183 1193 1272 1281 1291 1291 TYA 1.7v2 OpenJIT 1.1.13 OpenJIT 1.1.14 Sieve 1911 3231 3224 diff -aruN shujit-0.6.5/txt/codesize shujit/txt/codesize --- shujit-0.6.5/txt/codesize Sun Feb 7 01:48:52 1999 +++ shujit/txt/codesize Wed Sep 6 22:25:55 2000 @@ -1,5 +1,4 @@ 生成コードのサイズ - 1998年 9月 21日 methodhead (eb, 235) 1f (31) @@ -14,25 +13,41 @@ } } -* javac - % javac -g -O DoNothing.java +[1998年 9月 21日] 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 -* 実行 +[2000年 9月 6日 (0.6.5 + 1.1.8v1)] +num of compiled method: 537 +num of byte code inst: 26215 +byte code size (byte): 57146 +native code size (byte): 640519 +native code size / num of inst: 24.43330154 +native code size / byte code size: 11.20846603 + % java DoNothing +[1998年 9月 21日] 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 + +[2000年 9月 6日 (0.6.5 + 1.1.8v1)] +num of compiled method: 14 +num of byte code inst: 329 +byte code size (byte): 590 +native code size (byte): 7143 +native code size / num of inst: 21.7112462 +native code size / byte code size: 12.10677966 + 2. E2 暗号化 diff -aruN shujit-0.6.5/txt/memo shujit/txt/memo --- shujit-0.6.5/txt/memo Sun Sep 3 17:37:19 2000 +++ shujit/txt/memo Wed Sep 13 21:37:24 2000 @@ -1,4 +1,5 @@ Todo + - きちんと StackOverflowError を起こす。 - private メンバへのアクセス時に NoClassDefFoundError を発生させてしまうのを きちんと IllegalAccessError にする。 - 特定メソッドの inlining。 @@ -38,6 +39,7 @@ コンパイル中に、そのメソッドが呼ぶメソッドを途中までコンパイル、 PEI の有無やコード長などを調べておく。 - peephole 最適化。 + - ldc2_w, flush_cache, dld -> ... - invokeignored_quick への変換を進める。 - [ifa]store{,_N}, [ifa]load{,_N} で、メモリからの読みだしを省く。 - lcmp, ifXX といった定番コード列について最適化。 @@ -71,6 +73,7 @@ javac の、フックをかけられる箇所を探す。-> Jikes を改造? Done + - 末尾再帰をメソッド先頭へのジャンプに変換。 - JMP 命令の、E9 (引数 4 バイト) から EB (引数 1 バイト) への書き換え - JavaFrame の作成を省く。 - メソッド呼び出しの overhead 削減。 diff -aruN shujit-0.6.5/txt/metavm shujit/txt/metavm --- shujit-0.6.5/txt/metavm Tue Mar 30 17:25:10 1999 +++ shujit/txt/metavm Wed Sep 6 22:13:59 2000 @@ -51,7 +51,7 @@ コンパイル方法 - - def.mk 中の `METAVM = 1' を有効にする。 + - configure 時に --enable-metavm オプションを付ける。 - CLASSPATH に MetaVM.jar か shujit/ を追加する。 - libshujit.so ではなく libmetavm.so が得られる。 @@ -71,15 +71,20 @@ スレッドごとに持たせる情報 - - Proxy 型オブジェクトがどう見えるかのフラグ: 1 bit + - Proxy 型オブジェクトがどう見えるかのフラグ: 1 bit (最低) - インスタンス生成場所 (host, port): sizeof(ptr) 4 byte ExecEnv 中の利用可能スペース。 - alloc_cache.cache_pad <- (char[3]) pad なので完全にすき間。 - - exception.exc <- (JHandle *) - - exception.addr <- (unsigned char *) + - union { + exception.exc JHandle * 型 + exception.addr unsigned char * 型 + } 例外が throw されると壊れる。 + - JDK 1.2 の場合: + void *RESERVED1; + void *RESERVED2; 注意