diff -aruN shujit-0.2.7/ChangeLog shujit/ChangeLog --- shujit-0.2.7/ChangeLog Sat Jan 30 20:34:58 1999 +++ shujit/ChangeLog Mon Feb 8 21:36:25 1999 @@ -1,5 +1,74 @@ $Id$ +[19990208] + +0.2.8 リリース。 + +[19990207] + +gdbm_*(), dbm_*() のアドレス解決をリンカに頼らずに、 +dlopen(), dlsym() で行うようにした。 +libgdbm.so, libndbm.so がなくとも動作するように。 +(compiler.c, codedb.c, compiler.h) + +code DB 内を閲覧するツール codedbinfo を用意。 +(codedbinfo.c, GNUmakefile) + +[19990206] + +writeCode() (compile.c) 中ですべて行っていた定数の解決のうち、 +実行のたびに変わり得るものの解決を resolveDynamicConstants() に分離した。 +(compile.c) + +マクロ GET_SIGCONTEXT を定義した場合、EXC_BY_SIGNAL にかかわらず、 +signal handler で struct sigcontext の中身を表示するようにした。 +デバッグのため。 +(compiler.c, runtime.c, compiler.h) + +getstatic, putstatic が constant pool から参照する フィールドを +解決 (ResolveClassConstant*()) し忘れていたのを修整。 +(compile.c) + +構造体 throwentry の各メンバのサイズを変更。 +throwentry の表も code DB に記録する必要があるため、サイズを小さくした。 +(compiler.h) + +生成した native code をファイルに保存、再利用する機能を実装。 +def.mk 中の CODE_DB を有効にしてコンパイルし、 +オプション codedb で利用できる。 +(def.mk, GNUmakefile, codedb.c, compile.c, compiler.c, compiler.h, computil.c) + +gcc 2.7 用のアセンブリコード修整スクリプト postcmpl.rb を、 +コンパイラが生成した部分は変更しないようにした。 +`leal \.?LC' にマッチして、かつ次の行が `#APP' だった場合のみ、 +leal を pushl に置換する。 +(postcmpl.rb) + +[19990205] + +native code から invokeMethod() (runtime.c) を呼ぶ際に、 +%edi, %esi をスタックに退避するのをやめた。メソッド呼び出し高速化。 +(code.c) + +invokeMethod() (runtime.c) の引数の順を変えた。 +method->invoker() を呼び出す際に引数 4つの push を省こうという計画への布石。 +計画は噸座… +(runtime.c, compiler.h, code.c) + +オプション igndisable だけでなく、マクロ IGNORE_DISABLE で、 +java.lang.Compiler#disable(),enable() を無効化できるようにした。 +(compiler.c, runtime.c, invoker.c, compiler.h) + +invokeMethod() 中で、生成された native code を呼ぶ際の +条件判断をひとつ減らした。メソッド呼び出し高速化。 +(runtime.c) + +[19990201] + +struct sigcontext を探す起点の表現方法を変えた。 +ひとつ目の局所変数のアドレス + 16 -> &uc +(compiler.c) + [19990130] signal を利用して null check を削減した。 diff -aruN shujit-0.2.7/GNUmakefile shujit/GNUmakefile --- shujit-0.2.7/GNUmakefile Sat Jan 30 20:31:17 1999 +++ shujit/GNUmakefile Sun Feb 7 19:29:41 1999 @@ -11,14 +11,28 @@ CDEBUGFLAGS =# -g -DRUNTIME_DEBUG# -DCOMPILE_DEBUG# -DNO_CHECK NOOPTCFLAGS = -pipe -fPIC ${CDEBUGFLAGS} ${INCDIR} CFLAGS = ${OPTFLAGS} ${NOOPTCFLAGS} +LIBS = TARGET = libshujit.so GENEDHDR = constants.h GENEDOBJ = constants.o +TOOLS = codedbinfo +TOOLSOBJ = codedbinfo.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 +ifdef CODE_DB + OBJ += codedb.o + CFLAGS += -DCODE_DB -I/usr/local/include +# LIBS += -L/usr/local/lib +ifdef GDBM + CFLAGS += -DGDBM +# LIBS += -lgdbm +else +# LIBS += -lndbm +endif +endif # subdirectories SUBDIR = @@ -33,9 +47,10 @@ all: $(TARGET) +tool: codedbinfo ${TARGET}: subdir ${OBJ} ${GENEDOBJ} - ${LD_DYNAMIC} -o $@ ${OBJ} ${GENEDOBJ} + ${LD_DYNAMIC} -o $@ ${OBJ} ${GENEDOBJ} ${LIBS} subdir: ifdef SUBDIR @@ -47,10 +62,11 @@ # generate code.o ifeq (${CC_VER},gcc27) -code.s: code.c ${POSTPROC} +tmp.s: code.c ${POSTPROC} ${CC} -S -DGCC27 ${NOOPTCFLAGS} -o tmp.s $< - ${POSTPROC} < tmp.s > $@ - ${RM} tmp.s +code.s: tmp.s + ${POSTPROC} < $< > $@ + ${RM} $< code.o: code.s ifeq (${OSTYPE},FreeBSD) /usr/bin/as -k -o $@ $< @@ -71,14 +87,18 @@ ${OBJDUMP} -dx $< | ${GENCONST} compile.o: compiler.h ${GENEDHDR} ${GENEDOBJ:.o=.c} - compiler.o: compiler.c compiler.h - runtime.o: runtime.c compiler.h +computil.o: compiler.h +codedb.o: compiler.h + +codedbinfo.o: compiler.h +codedbinfo: codedbinfo.o + ${CC} -o $@ $< -lgdbm clean: subdirclean - ${RM} TAGS *~ ${TARGET} ${OBJ} ${GENEDHDR} ${GENEDOBJ} ${GENEDOBJ:.o=.c} *.s + ${RM} TAGS *~ ${TARGET} ${OBJ} ${GENEDHDR} ${GENEDOBJ} ${GENEDOBJ:.o=.c} *.s ${TOOLS} ${TOOLSOBJ} subdirclean: ifdef SUBDIR @@ -91,4 +111,4 @@ ${ETAGS} *.[hc] wc: - ${WC} ${OBJ:.o=.c} ${HDR} ${GENCONST} + ${WC} ${OBJ:.o=.c} ${HDR} ${GENCONST} ${TOOLSOBJ:.o=.c} diff -aruN shujit-0.2.7/code.c shujit/code.c --- shujit-0.2.7/code.c Sat Jan 30 17:11:22 1999 +++ shujit/code.c Sat Feb 6 19:54:11 1999 @@ -425,8 +425,8 @@ } CODE(opc_lconst_0, [ld]const_0, ST1, ST2, 0) { __asm__("pushl %edx\n\t" - "xorl %edx,%edx\n\t" - "xorl %ecx,%ecx"); + "xorl %ecx,%ecx\n\t" + "xorl %edx,%edx"); } CODE(opc_lconst_0, [ld]const_0, ST2, ST2, 0) { __asm__("pushl %edx\n\t" @@ -660,7 +660,7 @@ "sarl $2,%eax\n\t"\ "negl %eax\n\t"\ "pushl %eax");\ - PUSH_CONSTSTR(" var[%d]: 0x%08x %d %g\n");\ + PUSH_CONSTSTR(" [%d] 0x%08x %d %g\n");\ __asm__("call " SYMBOL(printf) "@PLT\n\t"\ "addl $24,%esp");\ FFLUSH;\ @@ -3477,27 +3477,24 @@ #ifdef RUNTIME_DEBUG # define CALL_INVOKEMETHOD_FUNC \ __asm__("pushl %0" : : "m" (runtime_debug));\ - __asm__("call " SYMBOL(invokeMethod) "@PLT\n\t"\ - "addl $32,%esp") + __asm__("call " SYMBOL(invokeMethod) "@PLT");\ + __asm__("addl $32,%esp") #else # define CALL_INVOKEMETHOD_FUNC \ - __asm__("call " SYMBOL(invokeMethod) "@PLT\n\t"\ - "addl $28,%esp") + __asm__("call " SYMBOL(invokeMethod) "@PLT");\ + __asm__("addl $28,%esp") #endif #define CALL_INVOKEMETHOD(LABEL) \ - __asm__("pushl $" STR(CONST) "\n\t" /* retsize */\ - "pushl %edi"); /* args_size */\ - __asm__("pushl %0" : : "m" (ee)); /* ee */\ + __asm__("pushl %ecx"); /* origianl esp */\ + __asm__("pushl %0" : : "m" (bytepcoff)); /* bytepcoff */\ + __asm__("pushl $" STR(CONST)); /* retsize */\ + __asm__("pushl %0" : : "m" (ee)); /* ee */\ + __asm__("pushl %edi\n\t" /* args_size */\ + "pushl %eax\n\t" /* method */\ + "pushl %edx"); /* obj */\ CALL_INVOKEMETHOD_FUNC;\ - CALL_INVOKEMETHOD_DEBUG1;\ - \ - __asm__("popl %edi\n\tpopl %esi"); /* restore */\ - \ - __asm__("popl %ecx"); /* free local var space */\ - __asm__("addl %ecx,%esp");\ - \ - INVOKE_RESTACK(LABEL) + CALL_INVOKEMETHOD_DEBUG1 #define INVOKE_RESTACK(LABEL) \ /* restack\ @@ -3598,17 +3595,17 @@ "pushl %ecx\n\t"\ "leal 4(%esp,%ecx),%ecx"); /* ecx = original 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 */\ - CALL_INVOKEMETHOD(LABEL) + CALL_INVOKEMETHOD(LABEL);\ + \ + __asm__("popl %ecx"); /* free local var space */\ + __asm__("addl %ecx,%esp");\ + \ + INVOKE_RESTACK(LABEL) + #define CODE_INVOKE(vop, VOP, THROW_EXC) \ CODE(opc_invoke##vop, invoke##vop, ST0, ST0, THROW_EXC) {\ diff -aruN shujit-0.2.7/code.h shujit/code.h --- shujit-0.2.7/code.h Sat Jan 30 19:13:26 1999 +++ shujit/code.h Sat Feb 6 19:05:06 1999 @@ -189,19 +189,15 @@ #ifdef RUNTIME_DEBUG # define CODE_DEBUG(LABEL) \ - __asm__("pushl %eax\n\t"\ - "movl %esp,%eax");\ DEBUG_IN;\ if (runtime_debug) {\ - __asm__("addl $4,%eax\n\t"\ - "pushl %eax"); /* %esp */\ + __asm__("pushl %ebp");\ PUSH_CONSTSTR(">" LABEL " %x\n");\ __asm__("call " SYMBOL(printf) "@PLT\n\t"\ "addl $8,%esp");\ FFLUSH;\ }\ - DEBUG_OUT;\ - __asm__("popl %eax"); + DEBUG_OUT; #else # define CODE_DEBUG(LABEL) #endif diff -aruN shujit-0.2.7/codedb.c shujit/codedb.c --- shujit-0.2.7/codedb.c Thu Jan 1 00:00:00 1970 +++ shujit/codedb.c Sun Feb 7 17:46:35 1999 @@ -0,0 +1,236 @@ +/* + * Copyright (C) 1998,1999 + * 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$ + */ + +#ifdef CODE_DB + +#include +#include /* for lseek() */ +#include /* for lseek() */ + +#include "compiler.h" + +#ifdef GDBM +# include +#else +# include +#endif + + +#define MAX_SIG_LEN 256 + + +/* in codedb.c */ +void writeCompiledCode( +# ifdef GDBM +GDBM_FILE db +# else +DBM *db +# endif +, int fd, CompilerContext *cc) { + struct methodblock *mb = cc->mb; + datum key, dbdata; + off_t position; + char sig[MAX_SIG_LEN]; +#ifdef CODE_DB_DEBUG + printf("writeCompiledCode() called.\n"); fflush(stdout); +#endif + + position = lseek(fd, (off_t)0, SEEK_END); +#ifdef CODE_DB_DEBUG + printf(" position: %d\n", position); fflush(stdout); +#endif + + /* write to DB */ + { + CodeInfo *info = (CodeInfo *)mb->CompiledCodeInfo; + pcentry *pcentry = cc->pctable; +#ifdef EXC_BY_SIGNAL + throwentry *tentry = info->throwtable; +#endif /* EXC_BY_SIGNAL */ + uint32_t len; + int i = 0; + +#ifdef CODE_DB_DEBUG + printf(" code_size:4: 0x%x\n", info->code_size); fflush(stdout); +#endif + write(fd, &info->code_size, 4); +#ifdef CODE_DB_DEBUG + printf(" pctablelen:4: 0x%x\n", cc->pctablelen); fflush(stdout); +#endif + write(fd, &cc->pctablelen, 4); +#ifdef EXC_BY_SIGNAL +#ifdef CODE_DB_DEBUG + printf(" throwtablelen:4: 0x%x\n", info->throwtablelen); fflush(stdout); +#endif + write(fd, &info->throwtablelen, 4); +#endif /* EXC_BY_SIGNAL */ + +#ifdef CODE_DB_DEBUG + printf(" ret_size:4: 0x%x\n", info->ret_size); + printf(" exc_handler_nativeoff:4: 0x%x\n", info->exc_handler_nativeoff); + printf(" finish_return_nativeoff:4: 0x%x\n", + info->finish_return_nativeoff); + fflush(stdout); +#endif + write(fd, &info->ret_size, 4); + write(fd, &info->exc_handler_nativeoff, 4); + write(fd, &info->finish_return_nativeoff, 4); + + len = cc->pctablelen; + for (i = 0; i < len; i++) { + write(fd, &pcentry->opcode, 2); + write(fd, &pcentry->state, 2); + write(fd, &pcentry->byteoff, 4); + write(fd, &pcentry->nativeoff, 4); + pcentry++; + } + +#ifdef EXC_BY_SIGNAL + len = info->throwtablelen; + for (i = 0; i < len; i++) { + write(fd, &tentry->start, 4); + write(fd, &tentry->len, 2); + write(fd, &tentry->byteoff, 2); + tentry++; + } +#endif /* EXC_BY_SIGNAL */ + + write(fd, mb->CompiledCode, info->code_size); + } + + /* store */ + snprintf(sig, MAX_SIG_LEN, "%s#%s%s", + cbName(mb->fb.clazz), mb->fb.name, mb->fb.signature); +#ifdef CODE_DB_DEBUG + printf(" key: %s\n", sig); fflush(stdout); +#endif + + key.dptr = sig; + key.dsize = strlen(sig); + dbdata.dptr = (char *)&position; + dbdata.dsize = sizeof(off_t); +#ifdef GDBM + sym_dbm_store(db, key, dbdata, GDBM_REPLACE); + /*sym_dbm_sync(db);*/ +#else + sym_dbm_store(db, key, dbdata, DBM_REPLACE); +#endif +} + + +int readCompiledCode( +# ifdef GDBM +GDBM_FILE db +# else +DBM *db +# endif +, int fd, CompilerContext *cc) { + struct methodblock *mb = cc->mb; + datum key, dbdata; + off_t offset; + char sig[MAX_SIG_LEN]; +#ifdef CODE_DB_DEBUG + printf("readCompiledCode() called.\n"); fflush(stdout); +#endif + + /* fetch */ + snprintf(sig, MAX_SIG_LEN, "%s#%s%s", + cbName(mb->fb.clazz), mb->fb.name, mb->fb.signature); +#ifdef CODE_DB_DEBUG + printf(" key: %s\n", sig); fflush(stdout); +#endif + + key.dptr = sig; + key.dsize = strlen(sig); + dbdata = sym_dbm_fetch(db, key); + + if (!dbdata.dptr) { /* compiled code is not found */ +#ifdef CODE_DB_DEBUG + printf(" code isn't found.\n"); fflush(stdout); +#endif + return 0; + } + + offset = *((off_t *)dbdata.dptr); +#ifdef CODE_DB_DEBUG + printf(" offset: %d\n", offset); fflush(stdout); +#endif + + if ((lseek(fd, offset, SEEK_SET)) < 0) { + perror("lseek"); exit(1); + } + + /* read from DB */ + { + CodeInfo *info = (CodeInfo *)mb->CompiledCodeInfo; + uint32_t len; + pcentry *pcentry; +#ifdef EXC_BY_SIGNAL + throwentry *tentry; +#endif /* EXC_BY_SIGNAL */ + int i; + + read(fd, &info->code_size, 4); +#ifdef CODE_DB_DEBUG + printf(" code_size:4: 0x%x\n", info->code_size); fflush(stdout); +#endif + read(fd, &cc->pctablelen, 4); +#ifdef CODE_DB_DEBUG + printf(" pctablelen:4: 0x%x\n", cc->pctablelen); fflush(stdout); +#endif +#ifdef EXC_BY_SIGNAL + read(fd, &info->throwtablelen, 4); +#ifdef CODE_DB_DEBUG + printf(" throwtablelen:4: 0x%x\n", info->throwtablelen); fflush(stdout); +#endif +#endif /* EXC_BY_SIGNAL */ + + read(fd, &info->ret_size, 4); + read(fd, &info->exc_handler_nativeoff, 4); + read(fd, &info->finish_return_nativeoff, 4); +#ifdef CODE_DB_DEBUG + printf(" ret_size:4: 0x%x\n", info->ret_size); + printf(" exc_handler_nativeoff:4: 0x%x\n", info->exc_handler_nativeoff); + printf(" finish_return_nativeoff:4: 0x%x\n", + info->finish_return_nativeoff); + fflush(stdout); +#endif + + pctableExtend(cc, cc->pctablelen); + pcentry = cc->pctable; + len = cc->pctablelen; + for (i = 0; i < len; i++) { + read(fd, &pcentry->opcode, 2); + read(fd, &pcentry->state, 2); + read(fd, &pcentry->byteoff, 4); + read(fd, &pcentry->nativeoff, 4); + pcentry++; + } + +#ifdef EXC_BY_SIGNAL + throwtableExtend(info, info->throwtablelen); + tentry = info->throwtable; + len = info->throwtablelen; + for (i = 0; i < len; i++) { + read(fd, &tentry->start, 4); + read(fd, &tentry->len, 2); + read(fd, &tentry->byteoff, 2); + tentry++; + } +#endif /* EXC_BY_SIGNAL */ + + mb->CompiledCode = (void *)sysMalloc(info->code_size); + read(fd, mb->CompiledCode, info->code_size); + } + + return 1; +} +#endif /* CODE_DB */ diff -aruN shujit-0.2.7/codedbinfo.c shujit/codedbinfo.c --- shujit-0.2.7/codedbinfo.c Thu Jan 1 00:00:00 1970 +++ shujit/codedbinfo.c Sun Feb 7 19:08:44 1999 @@ -0,0 +1,195 @@ +/* + * Copyright (C) 1998,1999 + * 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 +#include /* for lseek(), getopt() */ +#include /* for open(), lseek() */ +#include /* for open(), gdbm_open() */ +#include /* for open() */ + +#include "compiler.h" + +#ifdef GDBM +# include +#else +# include +#endif + +#ifndef FILENAME_MAX +# defne FILENAME_MAX 1023 +#endif + +#define MIN(a,b) ((a)<(b)?(a):(b)) +#define MAX(a,b) ((a)>(b)?(a):(b)) + + +#define COMMAND "codedbinfo" + + +void usage(const char *command) { + printf("usage: %s [-h] [db_file_name]\n", command); +} + + +int main(int argc, char **argv) { + int ch; /* for getopt() */ + char *fname_db, *fname_page; +#ifdef GDBM + GDBM_FILE db; +#else + DBM *db; +#endif + int db_page = -1; + + datum key, dbdata; + + + while ((ch = getopt(argc, argv, "h")) >= 0) { + switch (ch) { + case 'h': + usage(COMMAND); + exit(0); + break; + default: + break; + } + } + argc -= optind; + + if (argc <= 0) { + fname_db = CODEDB_DB; + fname_page = CODEDB_PAGE; + } + else { /* file name is specified */ + int suf_len = MAX(strlen(CODEDB_DB_SUFFIX), strlen(CODEDB_PAGE_SUFFIX)); + int index; + + fname_db = (char *)malloc(FILENAME_MAX + 1); + fname_page = (char *)malloc(FILENAME_MAX + 1); + + strncpy(fname_db, argv[1], FILENAME_MAX + 1); + strncpy(fname_page, argv[1], FILENAME_MAX + 1); + + index = strlen(fname_db) - 1; + if (fname_db[index] == '.') { + fname_db[index] = fname_page[index] = '\0'; + index = -1; + } + while (index >= 0) { + if (fname_db[index] == '.') break; + index--; + } + if (index >= 0) { + index = MIN(index, FILENAME_MAX + 1 - suf_len); + fname_page[index] = '\0'; + strcat(fname_page, CODEDB_PAGE_SUFFIX); + } + else { + index = MIN(strlen(fname_db), FILENAME_MAX + 1 - suf_len); + fname_db[index] = fname_page[index] = '\0'; + strcat(fname_db, CODEDB_DB_SUFFIX); + strcat(fname_page, CODEDB_PAGE_SUFFIX); + } + } + + printf("db file: %s\npage file: %s\n\n", fname_db, fname_page); + + + if ((db_page = open(fname_page, O_RDONLY)) < 0) { + perror("open"); exit(1); + } + +#ifdef GDBM + if (!(db = gdbm_open(fname_db, 512, GDBM_READER, 0, NULL))) { +#else + if (!(db = dbm_open(fname_db, O_RDONLY, 0))) { +#endif + perror("dbm_open"); + if (db_page >= 0) close(db_page); + exit(1); + } + + free(fname_db); fname_db = NULL; + free(fname_page); fname_page = NULL; + + + printf("code_size #pc_entry"); +#ifdef EXC_BY_SIGNAL + printf(" #throw_entry"); +#endif + printf("\n\n"); + +#ifdef GDBM + key = gdbm_firstkey(db); +#else + key = dbm_firstkey(db); +#endif + while (key.dptr) { + off_t offset; + +#ifdef GDBM + dbdata = gdbm_fetch(db, key); +#else + dbdata = dbm_fetch(db, key); +#endif + + offset = *((off_t *)dbdata.dptr); + + if ((lseek(db_page, offset, SEEK_SET)) < 0) { + perror("lseek"); exit(1); + } + + { + int32_t code_size; + uint32_t pctablelen; +#ifdef EXC_BY_SIGNAL + uint32_t throwtablelen; +#endif + +#define BUF_LEN 256 + char buf[BUF_LEN]; + int len; + + read(db_page, &code_size, 4); + read(db_page, &pctablelen, 4); +#ifdef EXC_BY_SIGNAL + read(db_page, &throwtablelen, 4); +#endif + + len = MIN(key.dsize, BUF_LEN - 1); + strncpy(buf, key.dptr, len); + buf[len] = '\0'; + +#ifdef EXC_BY_SIGNAL + printf("%6d %5d %5d %s\n", code_size, pctablelen, throwtablelen, buf); +#else + printf("%6d %5d %s\n", code_size, pctablelen, buf); +#endif + } + +#ifdef GDBM + key = gdbm_nextkey(db, key); +#else + key = dbm_nextkey(db, key); +#endif + } + + + close(db_page); +#ifdef GDBM + gdbm_close(db); +#else + dbm_close(db); +#endif + + + return 0; +} diff -aruN shujit-0.2.7/compile.c shujit/compile.c --- shujit-0.2.7/compile.c Sat Jan 30 16:53:06 1999 +++ shujit/compile.c Sun Feb 7 12:41:58 1999 @@ -9,7 +9,7 @@ * $Id$ */ -#include /* for memcpy() */ +#include /* for memcpy(), strlen() */ #include /* for malloc() */ #ifdef __FreeBSD__ # include /* for a type u_long */ @@ -33,12 +33,15 @@ * Local Functions */ static int makePCTable(CompilerContext *cc); + static int processAnOpcode(CompilerContext *cc, int opcode, int *statep, int32_t *byteoffp); static int writeCode(CompilerContext *cc); static void resolveJumpInstructions(CompilerContext *cc); -static void makeExcTable(CompilerContext *cc); static void resolveExcRetSw(CompilerContext *cc); + +static int resolveDynamicConstants(CompilerContext *cc); +static void makeExcTable(CompilerContext *cc); static void resolveFunctionSymbols(CompilerContext *cc); @@ -79,6 +82,7 @@ } +#ifndef IGNORE_DISABLE if (!compiler_enabled) { #ifdef COMPILE_DEBUG printf(" compiler has been disabled.\n return.\n"); @@ -86,17 +90,24 @@ #endif return 0; } +#endif /* IGNORE_DISABLE */ cc = newCompilerContext(mb); #ifdef COMPILE_DEBUG showCompilerContext(cc); #endif +#ifdef CODE_DB + if (opt_codedb) { + if (readCompiledCode(db, db_page, cc)) + goto compilation_done; + } /* if (opt_codedb) */ +#endif /* CODE_DB */ + /* compile */ if (makePCTable(cc)) goto compile_failed; /* an exception occurred. */ if (writeCode(cc)) goto compile_failed; /* an exception occurred. */ resolveJumpInstructions(cc); - makeExcTable(cc); resolveExcRetSw(cc); /* set generated code to methodblock */ @@ -116,6 +127,16 @@ memcpy(mb->CompiledCode, cc->buffer, code_size); } +#ifdef CODE_DB + if (opt_codedb) + writeCompiledCode(db, db_page, cc); +#endif /* CODE_DB */ + +compilation_done: + + + resolveDynamicConstants(cc); + makeExcTable(cc); resolveFunctionSymbols(cc); @@ -170,16 +191,20 @@ unsigned char *p; int i; - snprintf(funcname, 256, "code_%s#%s%s", + snprintf(funcname, 256, "code-%s#%s%s", cbName(fieldclass(&mb->fb)), mb->fb.name, mb->fb.signature); for (p = funcname; *p != '\0'; p++) { switch (*p) { - case '/': *p = '_'; break; + case '(': + case ')': + *p = '-'; break; + case '/': + case ';': case '<': case '>': + *p = '_'; break; +#if 0 case '#': *p = 'q'; break; case '[': *p = 'a'; break; - case '(': *p = 'l'; break; - case ')': *p = 'r'; break; - case ';': case '<': case '>': *p = '_'; break; +#endif } } @@ -189,7 +214,9 @@ } fprintf(codefp, ".globl %s\n", funcname); +#ifdef linux fprintf(codefp, ".align 16,0x90\n"); +#endif fprintf(codefp, "%s:", funcname); fprintf(codefp, ".byte "); p = (unsigned char *)mb->CompiledCode; @@ -455,13 +482,13 @@ #define ADJUST_GETMEMBER(vop) \ case opc_##vop##:\ {\ - int index = GET_UINT16(bytepc + 1);\ + unsigned index = GET_UINT16(bytepc + 1);\ struct fieldblock *fb;\ char *sig;\ \ if (!(type_table[index] & CONSTANT_POOL_ENTRY_RESOLVED)) {\ if (!ResolveClassConstantFromClass(\ - fieldclass(&mb->fb), (unsigned)index,\ + fieldclass(&mb->fb), index,\ cc->ee, 1 << CONSTANT_Fieldref))\ return 1;\ }\ @@ -528,11 +555,11 @@ /* adjust to invokespecial if invokevirtual private method */ if (opcode == opc_invokevirtual) { - int index = GET_UINT16(bytepc + 1); + unsigned index = GET_UINT16(bytepc + 1); struct methodblock *method; if (!(type_table[index] & CONSTANT_POOL_ENTRY_RESOLVED)) { if (!ResolveClassConstantFromClass( - fieldclass(&mb->fb), (unsigned)index, + fieldclass(&mb->fb), index, cc->ee, 1 << CONSTANT_Methodref)) return 1; } @@ -682,7 +709,7 @@ pcentry *pctable; int opcode, state; - int32_t nativeoff = 0; + int32_t nativeoff = 0, nextoff = 0; unsigned char *bytepc; int i; @@ -732,8 +759,8 @@ if (nativecode[-1]) { /* these native code may throw NullPointerException */ throwtableAdd(info, - nativeoff, nativeoff + codep->length, pctable->byteoff); -#ifdef RUNTIME_DEBUG + nativeoff, (uint16_t)codep->length, (uint16_t)pctable->byteoff); +#ifdef COMPILE_DEBUG printf("throwtableAdd(): opc %x, byte 0x%x, native 0x%x - 0x%x\n", opcode, pctable->byteoff, nativeoff, nativeoff + codep->length); fflush(stdout); @@ -742,11 +769,11 @@ #endif /* EXC_BY_SIGNAL */ } - nativeoff += codep->length; + nextoff = nativeoff + codep->length; /* register jump instructions to table - and update nativeoff. */ + and update nextoff. */ if ((opc_ifeq <= opcode) && (opcode <= opc_ret)) /* || ((opc_ifnull <= opcode) && (opcode <= opc_ifnonnull)) */ /* || (opcode == opc_goto_w) || (opcode == opc_jsr_w)) */ { @@ -814,65 +841,64 @@ unsigned char code_jp[] = { 0x0f, rop, 0, 0, 0, 0 }; /* jxx X(4byte) */ writeToBuffer(cc, code_jp, 6); - nativeoff += 6; + nextoff += 6; } else { /* jXX 5 */ { unsigned char code_jp[] = { rop_rev, transcodep->length + 5 }; writeToBuffer(cc, code_jp, 2); + nextoff += 2; } - nativeoff += 2; /* code_statetoX */ pctableInsert(cc, i + 1, opc_stateto0 + tgtstate, laststate, - pctable->byteoff, nativeoff); + pctable->byteoff, nextoff); i++; writeToBuffer(cc, (unsigned char *)assembledCode + transcodep->offset, transcodep->length); - nativeoff += transcodep->length; + nextoff += transcodep->length; /* jmp X(4byte) */ { unsigned char code_jp[] = { 0xe9, 0, 0, 0, 0 }; writeToBuffer(cc, code_jp, 5); } - nativeoff += 5; + nextoff += 5; } - jptableAdd(cc, tgtoff, nativeoff - 4); + jptableAdd(cc, tgtoff, nextoff - 4); } else /* ((opc_goto <= opcode) || (opcode <= opc_ret)) */ /* || ((opcode == opc_goto_w) && (opcode == opc_jsr_w)) */ { /* code_sattetoX */ pctableInsert(cc, i + 1, opc_stateto0 + tgtstate, laststate, - pctable->byteoff, nativeoff); + pctable->byteoff, nextoff); i++; writeToBuffer(cc, (unsigned char *)assembledCode + transcodep->offset, transcodep->length); - nativeoff += transcodep->length; + nextoff += transcodep->length; if (opcode != opc_ret) { /* goto, jsr */ /* jmp X(4byte) */ unsigned char code_jp[] = { 0xe9, 0, 0, 0, 0 }; writeToBuffer(cc, code_jp, 5); - nativeoff += 5; + nextoff += 5; - jptableAdd(cc, tgtoff, nativeoff - 4); + jptableAdd(cc, tgtoff, nextoff - 4); } else { /* ret */ /* jmp *%eax */ unsigned char code_jp[] = { 0xff, 0xe0 }; writeToBuffer(cc, code_jp, 2); - nativeoff += 2; + nextoff += 2; } } } /* if jump instruction */ /* resolve constants */ - /* attention: var. nativeoff is already updated. */ bufp = cc->buffer + insn_head_off; switch (opcode) { @@ -897,12 +923,14 @@ #ifdef COMPILE_DEBUG printf(" index: %d\n", v); fflush(stdout); #endif - if (!(type_table[v] & CONSTANT_POOL_ENTRY_RESOLVED)) { + if (!(type_table[v] & CONSTANT_POOL_ENTRY_RESOLVED)) if (!ResolveClassConstantFromClass(fieldclass(&mb->fb), v, cc->ee, (1 << CONSTANT_Integer) | (1 << CONSTANT_Float) | (1 << CONSTANT_String))) return 1; - } + if (CONSTANT_POOL_TYPE_TABLE_GET_TYPE(type_table, v) == + CONSTANT_String) + goto wc_ldc_break; v = constant_pool[v].i; break; case opc_ldc_w: @@ -910,12 +938,14 @@ #ifdef COMPILE_DEBUG printf(" index: %d\n", v); fflush(stdout); #endif - if (!(type_table[v] & CONSTANT_POOL_ENTRY_RESOLVED)) { + if (!(type_table[v] & CONSTANT_POOL_ENTRY_RESOLVED)) if (!ResolveClassConstantFromClass(fieldclass(&mb->fb), v, cc->ee, (1 << CONSTANT_Integer) | (1 << CONSTANT_Float) | (1 << CONSTANT_String))) return 1; - } + if (CONSTANT_POOL_TYPE_TABLE_GET_TYPE(type_table, v) == + CONSTANT_String) + goto wc_ldc_break; v = constant_pool[v].i; break; case opc_ldc_quick: @@ -923,6 +953,9 @@ #ifdef COMPILE_DEBUG printf(" index: %d\n", v); fflush(stdout); #endif + if (CONSTANT_POOL_TYPE_TABLE_GET_TYPE(type_table, v) == + CONSTANT_String) + goto wc_ldc_break; v = constant_pool[v].i; break; case opc_ldc_w_quick: @@ -930,12 +963,18 @@ #ifdef COMPILE_DEBUG printf(" index: %d\n", v); fflush(stdout); #endif + if (CONSTANT_POOL_TYPE_TABLE_GET_TYPE(type_table, v) == + CONSTANT_String) + goto wc_ldc_break; v = constant_pool[v].i; break; + default: + goto wc_ldc_break; } memcpy(bufp + constant_table[opcode][state][0], &v, 4); } + wc_ldc_break: break; case opc_ldc2_w: @@ -1030,10 +1069,10 @@ case opc_jsr: #ifdef COMPILE_DEBUG - printf(" native offset: 0x%x(%d)\n", nativeoff, nativeoff); + printf(" next native offset: 0x%x(%d)\n", nextoff, nextoff); fflush(stdout); #endif - memcpy(bufp + constant_table[opcode][state][0], &nativeoff, 4); + memcpy(bufp + constant_table[opcode][state][0], &nextoff, 4); break; case opc_tableswitch: @@ -1060,44 +1099,6 @@ } break; - case opc_getstatic: - case opc_putstatic: - { - int32_t index = GET_UINT16(bytepc + 1); - struct fieldblock *fb; - OBJECT *addr; -#ifdef COMPILE_DEBUG - printf(" index: %d\n", index); fflush(stdout); -#endif - fb = constant_pool[index].fb; -#ifdef COMPILE_DEBUG - printf(" %s#%s\n", cbName(fb->clazz), fb->name); fflush(stdout); -#endif - addr = (OBJECT *)normal_static_address(fb); - memcpy(bufp + constant_table[opcode][state][0], &addr, 4); - } - break; - - case opc_getstatic2: - case opc_putstatic2: - { - int32_t index = GET_UINT16(bytepc + 1); - struct fieldblock *fb; - stack_item *addr; -#ifdef COMPILE_DEBUG - printf(" index: %d\n", index); fflush(stdout); -#endif - fb = constant_pool[index].fb; -#ifdef COMPILE_DEBUG - printf(" %s#%s\n", cbName(fb->clazz), fb->name); fflush(stdout); -#endif - addr = (stack_item *)twoword_static_address(fb); - memcpy(bufp + constant_table[opcode][state][0], &addr, 4); - addr++; - memcpy(bufp + constant_table[opcode][state][1], &addr, 4); - } - break; - #ifdef COMPILE_DEBUG # define CONST_GETMEMBER_DEBUG1 \ printf(" %s#%s\n", cbName(fb->clazz), fb->name);\ @@ -1159,7 +1160,7 @@ CONST_GETMEMBER(putfield); #ifdef COMPILE_DEBUG -# define CONST_INVOKE_DEBUG1(VIRTUALP) \ +# define WC_CONST_INVOKE_DEBUG1(VIRTUALP) \ printf(" %s#%s %s\n", cbName(method->fb.clazz), method->fb.name,\ method->fb.signature);\ printf(" args_size, ret_size, localvar_space: %d, %d, %d\n",\ @@ -1168,10 +1169,10 @@ printf(" offset in table: %d\n", method->fb.u.offset);\ fflush(stdout) #else -# define CONST_INVOKE_DEBUG1 +# define WC_CONST_INVOKE_DEBUG1 #endif -#define CONST_INVOKE(vop, VIRTUALP, INTERFACEP) \ +#define WC_CONST_INVOKE(vop, VIRTUALP, INTERFACEP) \ {\ int32_t index;\ struct methodblock *method;\ @@ -1202,7 +1203,7 @@ else if ((*sig == 'D') || (*sig == 'J')) ret_size = 2;\ else ret_size = 1;\ \ - CONST_INVOKE_DEBUG1(VIRTUALP);\ + WC_CONST_INVOKE_DEBUG1(VIRTUALP);\ \ memcpy(bufp + constant_table[opcode][state][0], &args_size, 4);\ if (VIRTUALP) { /* invokevirtual */\ @@ -1211,13 +1212,9 @@ memcpy(bufp + constant_table[opcode][state][2], &ret_size, 4);\ }\ else if (INTERFACEP) { /* invokeinterface */\ - unsigned char *guessptr = bytepc + 4;\ - memcpy(bufp + constant_table[opcode][state][1], &guessptr, 4);\ - memcpy(bufp + constant_table[opcode][state][2], &method, 4);\ memcpy(bufp + constant_table[opcode][state][3], &ret_size, 4);\ }\ else { /* invokespecial, invokestatic */\ - memcpy(bufp + constant_table[opcode][state][1], &method, 4);\ memcpy(bufp + constant_table[opcode][state][2], &localvar_space, 4);\ memcpy(bufp + constant_table[opcode][state][3], &ret_size, 4);\ }\ @@ -1225,16 +1222,16 @@ break case opc_invokevirtual: - CONST_INVOKE(virtual, 1, 0); + WC_CONST_INVOKE(virtual, 1, 0); case opc_invokespecial: - CONST_INVOKE(special, 0, 0); + WC_CONST_INVOKE(special, 0, 0); case opc_invokestatic: - CONST_INVOKE(static, 0, 0); + WC_CONST_INVOKE(static, 0, 0); case opc_invokeinterface: - CONST_INVOKE(interface, 0, 1); + WC_CONST_INVOKE(interface, 0, 1); case opc_invokevirtualobject_quick: case opc_invokevirtual_quick: @@ -1251,6 +1248,265 @@ } break; + case opc_new: +#ifndef NO_REWRITE_NEW + /* to rewrite self */ + memcpy(bufp + constant_table[opcode][state][1], &nativeoff, 4); +#endif + break; + + case opc_newarray: + { + int32_t type = bytepc[1]; +#ifdef COMPILE_DEBUG + printf(" type: %d\n", type); fflush(stdout); +#endif + memcpy(bufp + constant_table[opcode][state][0], &type, 4); + } + break; + + case opc_multianewarray: + { + int32_t dimensions = bytepc[3]; +#ifdef COMPILE_DEBUG + printf(" index: %d\n dimensions: %d\n", index, dimensions); + fflush(stdout); +#endif + memcpy(bufp + constant_table[opcode][state][0], &dimensions, 4); + } + break; + + case opc_invokeignored_quick: + case opc_invokeignored_nocheck: + { + int32_t args_size = bytepc[1]; +#ifdef COMPILE_DEBUG + printf(" args_size: %d\n", args_size); fflush(stdout); +#endif + memcpy(bufp + constant_table[opcode][state][0], &args_size, 4); + } + break; + } /* resolve constants: switch (opcode) */ + + /* update native offset */ + nativeoff = nextoff; + } /* for (i = 0; i < cc->pctablelen; i++) */ + + return 0; +} + + +static int resolveDynamicConstants(CompilerContext *cc) { + struct methodblock *mb = cc->mb; + CodeInfo *info = (CodeInfo *)(mb->CompiledCodeInfo); + cp_item_type *constant_pool = cbConstantPool(fieldclass(&mb->fb)); + unsigned char *type_table = + constant_pool[CONSTANT_POOL_TYPE_TABLE_INDEX].type; + + pcentry *pctable; + int opcode, state; + int32_t nativeoff = 0; + unsigned char *bytepc; + int i; + + CodeTable *codep; + unsigned char *bufp; + + for (i = 0; i < cc->pctablelen; i++) { + pctable = cc->pctable + i; + opcode = pctable->opcode; + state = pctable->state; + bytepc = mb->code + pctable->byteoff; + nativeoff = pctable->nativeoff; + +#ifdef COMPILE_DEBUG + printf("resolveDynConst(): %s(0x%02x,%d), st: %d\n", + ((opcode > opc_nonnull_quick) ? "(null)" : opcode_symbol[opcode]), + opcode, opcode, state); + printf(" off: b 0x%x(%d) n 0x%x(%d)\n", + pctable->byteoff, pctable->byteoff, + nativeoff, nativeoff); + fflush(stdout); +#endif + + codep = &code_table[opcode][state]; +#ifdef COMPILE_DEBUG + printf(" len native: 0x%x(%d)\n", codep->length, codep->length); + fflush(stdout); +#endif + + /* resolve constants */ + /* attention: var. nativeoff is already updated. */ +#if 1 + bufp = mb->CompiledCode + nativeoff; +#else + bufp = cc->buffer + nativeoff; +#endif + + switch (opcode) { + case opc_bipush: + { + int32_t v; + switch (*bytepc) { + case opc_ldc: + v = bytepc[1]; +#ifdef COMPILE_DEBUG + printf(" index: %d\n", v); fflush(stdout); +#endif + if (!(type_table[v] & CONSTANT_POOL_ENTRY_RESOLVED)) + if (!ResolveClassConstantFromClass(fieldclass(&mb->fb), v, cc->ee, + (1 << CONSTANT_Integer) | (1 << CONSTANT_Float) | + (1 << CONSTANT_String))) + return 1; + if (CONSTANT_POOL_TYPE_TABLE_GET_TYPE(type_table, v) != + CONSTANT_String) + goto rc_ldc_break; + v = constant_pool[v].i; + break; + case opc_ldc_w: + v = GET_UINT16(bytepc + 1); +#ifdef COMPILE_DEBUG + printf(" index: %d\n", v); fflush(stdout); +#endif + if (!(type_table[v] & CONSTANT_POOL_ENTRY_RESOLVED)) + if (!ResolveClassConstantFromClass(fieldclass(&mb->fb), v, cc->ee, + (1 << CONSTANT_Integer) | (1 << CONSTANT_Float) | + (1 << CONSTANT_String))) + return 1; + if (CONSTANT_POOL_TYPE_TABLE_GET_TYPE(type_table, v) != + CONSTANT_String) + goto rc_ldc_break; + v = constant_pool[v].i; + break; + case opc_ldc_quick: + v = bytepc[1]; +#ifdef COMPILE_DEBUG + printf(" index: %d\n", v); fflush(stdout); +#endif + if (CONSTANT_POOL_TYPE_TABLE_GET_TYPE(type_table, v) != + CONSTANT_String) + goto rc_ldc_break; + v = constant_pool[v].i; + break; + case opc_ldc_w_quick: + v = GET_UINT16(bytepc + 1); +#ifdef COMPILE_DEBUG + printf(" index: %d\n", v); fflush(stdout); +#endif + if (CONSTANT_POOL_TYPE_TABLE_GET_TYPE(type_table, v) != + CONSTANT_String) + goto rc_ldc_break; + v = constant_pool[v].i; + break; + default: + goto rc_ldc_break; + } + + memcpy(bufp + constant_table[opcode][state][0], &v, 4); + } + rc_ldc_break: + break; + + case opc_getstatic: + case opc_putstatic: + { + unsigned index = GET_UINT16(bytepc + 1); + struct fieldblock *fb; + OBJECT *addr; +#ifdef COMPILE_DEBUG + printf(" index: %d\n", index); fflush(stdout); +#endif + if (!(type_table[index] & CONSTANT_POOL_ENTRY_RESOLVED)) { + if (!ResolveClassConstantFromClass( + fieldclass(&mb->fb), index, cc->ee, + 1 << CONSTANT_Fieldref)) + return 1; + } + fb = constant_pool[index].fb; +#ifdef COMPILE_DEBUG + printf(" %s#%s\n", cbName(fb->clazz), fb->name); fflush(stdout); +#endif + addr = (OBJECT *)normal_static_address(fb); + memcpy(bufp + constant_table[opcode][state][0], &addr, 4); + } + break; + + case opc_getstatic2: + case opc_putstatic2: + { + int32_t index = GET_UINT16(bytepc + 1); + struct fieldblock *fb; + stack_item *addr; +#ifdef COMPILE_DEBUG + printf(" index: %d\n", index); fflush(stdout); +#endif + if (!(type_table[index] & CONSTANT_POOL_ENTRY_RESOLVED)) { + if (!ResolveClassConstantFromClass( + fieldclass(&mb->fb), index, cc->ee, + 1 << CONSTANT_Fieldref)) + return 1; + } + fb = constant_pool[index].fb; +#ifdef COMPILE_DEBUG + printf(" %s#%s\n", cbName(fb->clazz), fb->name); fflush(stdout); +#endif + addr = (stack_item *)twoword_static_address(fb); + memcpy(bufp + constant_table[opcode][state][0], &addr, 4); + addr++; + memcpy(bufp + constant_table[opcode][state][1], &addr, 4); + } + break; + +#ifdef COMPILE_DEBUG +# define RC_CONST_INVOKE_DEBUG1 \ + printf(" %s#%s %s\n", cbName(method->fb.clazz), method->fb.name,\ + method->fb.signature);\ + fflush(stdout) +#else +# define RC_CONST_INVOKE_DEBUG1 +#endif + +#define RC_CONST_INVOKE(vop, VIRTUALP, INTERFACEP) \ + {\ + unsigned index;\ + struct methodblock *method;\ + \ + index = GET_UINT16(bytepc + 1);\ + if (*bytepc == opc_invoke##vop) {\ + if (!(type_table[index] & CONSTANT_POOL_ENTRY_RESOLVED)) {\ + if (!ResolveClassConstantFromClass(\ + fieldclass(&mb->fb), index, cc->ee,\ + 1 << (INTERFACEP ?\ + CONSTANT_InterfaceMethodref : CONSTANT_Methodref)))\ + return 1;\ + }\ + }\ + method = constant_pool[index].mb;\ + \ + RC_CONST_INVOKE_DEBUG1;\ + \ + if (VIRTUALP) { /* invokevirtual */\ + }\ + else if (INTERFACEP) { /* invokeinterface */\ + unsigned char *guessptr = bytepc + 4;\ + memcpy(bufp + constant_table[opcode][state][1], &guessptr, 4);\ + memcpy(bufp + constant_table[opcode][state][2], &method, 4);\ + }\ + else { /* invokespecial, invokestatic */\ + memcpy(bufp + constant_table[opcode][state][1], &method, 4);\ + }\ + }\ + break + + case opc_invokespecial: + RC_CONST_INVOKE(special, 0, 0); + + case opc_invokestatic: + RC_CONST_INVOKE(static, 0, 0); + + case opc_invokeinterface: + RC_CONST_INVOKE(interface, 0, 1); + #ifdef COMPILE_DEBUG # define CONST_NEW_DEBUG1 printf(" index: %d\n", index); fflush(stdout); # define CONST_NEW_DEBUG2 printf(" name: %s\n", cbName(cb)); fflush(stdout); @@ -1289,13 +1545,6 @@ case opc_new: CONST_NEW1(new, 1); -#ifndef NO_REWRITE_NEW - /* to rewrite self */ - { - int32_t off = nativeoff - codep->length; - memcpy(bufp + constant_table[opcode][state][1], &off, 4); - } -#endif break; case opc_new_quick: @@ -1322,25 +1571,10 @@ #endif /* JITDO */ break; - case opc_newarray: - { - int32_t type = bytepc[1]; -#ifdef COMPILE_DEBUG - printf(" type: %d\n", type); fflush(stdout); -#endif - memcpy(bufp + constant_table[opcode][state][0], &type, 4); - } - break; - case opc_multianewarray: { int32_t index = GET_UINT16(bytepc + 1); ClassClass *cb; - int32_t dimensions = bytepc[3]; -#ifdef COMPILE_DEBUG - printf(" index: %d\n dimensions: %d\n", index, dimensions); - fflush(stdout); -#endif if (*bytepc == opc_multianewarray) { if (!(type_table[index] & CONSTANT_POOL_ENTRY_RESOLVED)) { if (!ResolveClassConstant(cbConstantPool(fieldclass(&mb->fb)), @@ -1352,21 +1586,10 @@ #ifdef COMPILE_DEBUG printf(" clazz: %s\n", cbName(cb)); fflush(stdout); #endif - memcpy(bufp + constant_table[opcode][state][0], &dimensions, 4); memcpy(bufp + constant_table[opcode][state][1], &cb, 4); } break; - case opc_invokeignored_quick: - case opc_invokeignored_nocheck: - { - int32_t args_size = bytepc[1]; -#ifdef COMPILE_DEBUG - printf(" args_size: %d\n", args_size); fflush(stdout); -#endif - memcpy(bufp + constant_table[opcode][state][0], &args_size, 4); - } - break; } /* resolve constants: switch (opcode) */ } /* for (i = 0; i < cc->pctablelen; i++) */ @@ -1712,7 +1935,8 @@ #endif #ifdef RES_FUNC_DEBUG - printf(" symb %s: 0x%08x at 0x%x(%d) + %d\n", + printf(" symb [%3d][%d] %s: 0x%08x at 0x%x(%d) + 0x%x\n", + opcode, state, funcp->name, (int)funcptr, pctable->nativeoff, pctable->nativeoff, funcp->offset); fflush(stdout); diff -aruN shujit-0.2.7/compiler.c shujit/compiler.c --- shujit-0.2.7/compiler.c Sat Jan 30 20:19:23 1999 +++ shujit/compiler.c Sun Feb 7 18:54:59 1999 @@ -10,11 +10,18 @@ */ #include /* for getenv(3) */ -#ifdef EXC_BY_SIGNAL -# if defined(linux) +#include /* for gdbm_open() */ + +#if defined(EXC_BY_SIGNAL) || defined(GET_SIGCONTEXT) +# ifdef linux # include # endif -#endif +#endif /* EXC_BY_SIGNAL || GET_SIGCONTEXT */ + +#ifdef CODE_DB +# include /* for O_... */ +# include /* for dl*() */ +#endif /* CODE_DB */ #include "monitor.h" /* for macro BINCLASS_{,UN}LOCK() */ #include "compiler.h" @@ -23,9 +30,11 @@ /* * Global Variables */ +#ifndef IGNORE_DISABLE bool_t compiler_enabled = TRUE; +#endif /* IGNORE_DISABLE */ -#if defined(EXC_BY_SIGNAL) && defined(SEARCH_SIGCONTEXT) +#if (defined(EXC_BY_SIGNAL) || defined(GET_SIGCONTEXT)) && defined(SEARCH_SIGCONTEXT) # ifdef linux unsigned short reg_gs; unsigned short reg_fs; @@ -36,7 +45,18 @@ unsigned short reg_cs; unsigned short reg_ss; # endif -#endif +#endif /* (EXC_BY_SIGNAL || GET_SIGCONTEXT) && SEARCH_SIGCONTEXT */ + +#ifdef CODE_DB +# ifdef GDBM +# include +GDBM_FILE db = NULL; +# else +# include +DBM *db = NULL; +# endif +int db_page = -1; +#endif /* CODE_DB */ int opt_quiet = 0; int opt_outcode = 0; @@ -44,6 +64,9 @@ int opt_dontcmplvmcls = 0; int opt_igndisable = 0; int opt_cmplclinit = 0; +#ifdef CODE_DB +int opt_codedb = 0; +#endif /* CODE_DB */ void *sym_compileAndInvokeMethod; void *sym_invokeJITCompiledMethod; @@ -51,6 +74,20 @@ void *sym_invokeSynchronizedJavaMethod; void *sym_invokeAbstractMethod; void *sym_invokeLazyNativeMethod; +#ifdef CODE_DB +# ifdef GDBM +GDBM_FILE (*sym_dbm_open)(char *,int,int,int,void (*)()); +void (*sym_dbm_close)(GDBM_FILE); +int (*sym_dbm_store)(GDBM_FILE,datum,datum,int); +datum (*sym_dbm_fetch)(GDBM_FILE,datum); +void (*sym_dbm_sync)(GDBM_FILE); +# else +DBM *(*sym_dbm_open)(const char *,int,int); +void (*sym_dbm_close)(DBM *); +int (*sym_dbm_store)(DBM *,datum,datum,int); +datum (*sym_dbm_fetch)(DBM *,datum); +# endif +#endif /* CODE_DB */ /* @@ -131,6 +168,12 @@ opt_cmplclinit = 1; if (!opt_quiet) printf(" option: cmplclinit\n"); } +#ifdef CODE_DB + else if (!strncmp(opt, "codedb", 7)) { + opt_codedb = 1; + if (!opt_quiet) printf(" option: codedb\n"); + } +#endif /* CODE_DB */ opt = strtok(NULL, ", "); } } @@ -164,7 +207,7 @@ /* initialization */ -#if defined(EXC_BY_SIGNAL) && defined(SEARCH_SIGCONTEXT) +#if (defined(EXC_BY_SIGNAL) || defined(GET_SIGCONTEXT))&& defined(SEARCH_SIGCONTEXT) #ifdef linux __asm__("movw %%gs,%0" : "=m" (reg_gs)); __asm__("movw %%fs,%0" : "=m" (reg_fs)); @@ -187,7 +230,7 @@ #endif /* __FreeBSD__ */ fflush(stdout); #endif -#endif /* EXC_BY_SIGNAL && SEARCH_SIGCONTEXT */ +#endif /* (EXC_BY_SIGNAL || GET_SIGCONTEXT) && SEARCH_SIGCONTEXT */ #ifdef __FreeBSD__ /* to get addresses of functions in lib[cm] with sysDynamicLink() */ @@ -265,10 +308,12 @@ *(char **)vector[4] = (char *)freeClass; *(char **)vector[5] = (char *)compileClass; *(char **)vector[6] = (char *)compileClasses; +#ifndef IGNORE_DISABLE if (!opt_igndisable) { *(char **)vector[7] = (char *)compilerEnable; *(char **)vector[8] = (char *)compilerDisable; } +#endif /* IGNORE_DISABLE */ *(char **)vector[10] = (char *)pcInCompiledCode; *(char **)vector[11] = (char *)compiledCodePC; *(char **)vector[70] = (char *)framePrev; @@ -285,6 +330,64 @@ } #endif +#ifdef CODE_DB + /* open DB and page file */ + if (opt_codedb) { + void *dl_dbm; + if (!(dl_dbm = dlopen(LIBDBM, RTLD_LAZY))) { + fputs(dlerror(), stderr); fputc('\n', stderr); + fprintf(stderr, "failed to open " LIBDBM ".\n"); + goto codedb_init_fail; + } +#ifdef GDBM + sym_dbm_open = (GDBM_FILE (*)(char *,int,int,int,void (*)())) + dlsym(dl_dbm, "gdbm_open"); + sym_dbm_close = (void (*)(GDBM_FILE))dlsym(dl_dbm, "gdbm_close"); + sym_dbm_store = (int (*)(GDBM_FILE,datum,datum,int)) + dlsym(dl_dbm, "gdbm_store"); + sym_dbm_fetch = (datum (*)(GDBM_FILE,datum))dlsym(dl_dbm, "gdbm_fetch"); + sym_dbm_sync = (void (*)(GDBM_FILE))dlsym(dl_dbm, "gdbm_sync"); +#else + sym_dbm_open = (DBM *(*)(const char *,int,int))dlsym(dl_dbm, "dbm_open"); + sym_dbm_close = (void (*)(DBM *))dlsym(dl_dbm, "dbm_close"); + sym_dbm_store = (int (*)(DBM *,datum,datum,int))dlsym(dl_dbm, "dbm_store"); + sym_dbm_fetch = (datum (*)(DBM *,datum))dlsym(dl_dbm, "dbm_fetch"); +#endif + if (!(((int32_t)sym_dbm_open) && ((int32_t)sym_dbm_close) && + ((int32_t)sym_dbm_store) && ((int32_t)sym_dbm_fetch)) +#ifdef GDBM + && ((int32_t)sym_dbm_sync) +#endif + ) { + fprintf(stderr, "cannot get symbols to handle DBM.\n"); + goto codedb_init_fail; + } + + if ((db_page = open(CODEDB_PAGE, + O_RDWR|O_CREAT, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH)) < 0) { + perror("open"); goto codedb_init_fail; + } + +#ifdef GDBM + if (!(db = sym_dbm_open(CODEDB_DB, 512, + GDBM_WRCREAT, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH, NULL))) { + perror("gdbm_open"); goto codedb_init_fail; + } +#else + if (!(db = sym_dbm_open(CODEDB_DB, O_RDWR|O_CREAT, 0))) { + perror("dbm_open"); goto codedb_init_fail; + } +#endif + + goto codedb_init_done; + codedb_init_fail: + fprintf(stderr, "disable codedb.\n"); opt_codedb = 0; + if (db_page >= 0) close(db_page); + exit(1); + codedb_init_done: + } +#endif /* CODE_DB */ + #ifdef COMPILE_DEBUG printf("java_lang_Compiler_start() done.\n"); fflush(stdout); @@ -309,12 +412,14 @@ mb = cbMethods(cb); mb_end = mb + cbMethodsCount(cb); for (; mb < mb_end; mb++) { + int access = mb->fb.access; + + if (access & ACC_ABSTRACT) continue; + /* initialize mb->CompiledCodeInfo */ if (!(mb->CompiledCodeInfo)) prepareCompiledCodeInfo(EE(), mb); - if (mb->fb.access & (ACC_ABSTRACT | ACC_NATIVE)) - /* methods not to be compiled */ - continue; + if (access & ACC_NATIVE) continue; INITIALIZE_METHOD(mb); } @@ -326,37 +431,46 @@ #else static void signalHandler(int sig, void *info, void *uc) { #endif -#ifdef EXC_BY_SIGNAL +#if defined(EXC_BY_SIGNAL) || defined(GET_SIGCONTEXT) # ifdef SEARCH_SIGCONTEXT - int32_t first_local_variable; static int sc_offset = 0; +#if 1 + int32_t *ptr = (int32_t *)&uc; +#else int32_t *ptr = ((int32_t *)&first_local_variable) + 4; /* 4: first...variable, esp, 2 arguments */ +#endif # endif /* SEARCH_SIGCONTEXT */ sigcontext *sc; struct methodblock *mb; CodeInfo *codeinfo; - int native_off; + uint32_t native_off; +#endif /* EXC_BY_SIGNAL || GET_SIGCONTEXT */ +#ifdef EXC_BY_SIGNAL throwentry *tentry; #endif /* EXC_BY_SIGNAL */ -#ifdef RUNTIME_DEBUG - printf("Signal handler for compiled code called. (sig: %d)\n", sig); +#if defined(RUNTIME_DEBUG) + printf("Signal handler: %d\n", sig); showStackFrames(EE()); #endif -#ifdef EXC_BY_SIGNAL +#if defined(EXC_BY_SIGNAL) || defined(GET_SIGCONTEXT) #ifdef SEARCH_SIGCONTEXT /* get signal context */ - ptr = ((int32_t *)&first_local_variable) + 4; - /* 4: first...variable, esp, 2 arguments */ if (sc_offset > 0) { sc = (sigcontext *)(ptr + sc_offset); } else { /* must search */ #define SEARCH_WIDTH 50 for (sc_offset = 0; sc_offset < SEARCH_WIDTH - 3; sc_offset++) { -#ifdef __FreeBSD__ +#if defined(linux) + if ( (*((unsigned short *)(ptr)) == reg_gs) && + (*((unsigned short *)(ptr + 1)) == reg_fs) && + (*((unsigned short *)(ptr + 2)) == reg_es) && + (*((unsigned short *)(ptr + 3)) == reg_ds) ) + break; +#elif defined(__FreeBSD__) if ( (*((unsigned short *)(ptr)) == reg_es) && (*((unsigned short *)(ptr + 1)) == reg_ds) && (*((unsigned short *)(ptr + 2)) == reg_cs) && @@ -366,16 +480,12 @@ break; } #else - if ( (*((unsigned short *)(ptr)) == reg_gs) && - (*((unsigned short *)(ptr + 1)) == reg_fs) && - (*((unsigned short *)(ptr + 2)) == reg_es) && - (*((unsigned short *)(ptr + 3)) == reg_ds) ) - break; + if (0) break; #endif else ptr += 1; } - if (sc_offset >= SEARCH_WIDTH - 3) { + if (sc_offset >= (SEARCH_WIDTH - 3)) { printf("FATAL: struct sigcontext is not found."); exit(1); } @@ -387,68 +497,85 @@ #else /* SEARCH_SIGCONTEXT*/ sc = (sigcontext *)uc; #endif /* SEARCH_SIGCONTEXT*/ -#ifdef RUNTIME_DEBUG - printf("sc: 0x%08x\n"); fflush(stdout); +#if defined(RUNTIME_DEBUG) || (defined(GET_SIGCONTEXT) && !defined(EXC_BY_SIGNAL)) + printf("sigcontext: 0x%08x\n", (int)sc); fflush(stdout); showSigcontext(sc); #endif +#endif /* EXC_BY_SIGNAL */ +#if defined(EXC_BY_SIGNAL) || defined(GET_SIGCONTEXT) if ((sig == SIGSEGV) || (sig == SIGBUS)) { - /* NullPointerException occurred */ - SignalError(EE(), JAVAPKG "NullPointerException", 0); - /* set ee->exception.exc, exception object */ - +#ifdef __FreeBSD__ + mb = EE()->current_frame->current_method; + /* EBP is broken on FreeBSD ??? */ +#else mb = (struct methodblock *) *(((int32_t *)sc->SC_EBP) + 3); /* mb is second argument of assembledCode(): 0xc(%ebp) */ -#ifdef RUNTIME_DEBUG - printf("method(0x%x): %s#%s %s\n", (int)mb, +#endif +#if defined(RUNTIME_DEBUG) + printf("method(0x%x):", (int)mb); fflush(stdout); + fflush(stdout); + printf(" %s#%s %s\n", cbName(mb->fb.clazz), mb->fb.name, mb->fb.signature); fflush(stdout); #endif codeinfo = (CodeInfo *)(mb->CompiledCodeInfo); native_off = - ((unsigned char *)sc->SC_EIP) - ((unsigned char *)mb->CompiledCode); -#ifdef RUNTIME_DEBUG - printf("native off: 0x%08x\n", native_off); + ((uint32_t)sc->SC_EIP) - ((uint32_t)mb->CompiledCode); +#if defined(RUNTIME_DEBUG) + printf("native off: 0x%x\n", native_off); fflush(stdout); #endif +#ifdef EXC_BY_SIGNAL tentry = throwtableGet(codeinfo, native_off); #ifdef RUNTIME_DEBUG printf("throwentry: "); + fflush(stdout); if (tentry) - printf("start: 0x%x, end: 0x%x, byteoff: 0x%x\n", - tentry->start, tentry->end, tentry->byteoff); + printf("start: 0x%x, len: 0x%x, byteoff: 0x%x\n", + tentry->start, tentry->len, tentry->byteoff); else printf(" (null)\n"); fflush(stdout); #endif + if (tentry) { + /* NullPointerException occurred */ + SignalError(EE(), JAVAPKG "NullPointerException", 0); + /* set ee->exception.exc, exception object */ #ifdef __FreeBSD__ - /* re-initialize signal handler */ - intrInitMD(); + /* re-initialize signal handler */ + intrInitMD(); #endif - /* set (int32_t)bytepcoff (local variable of assembledCode) */ - *(((int32_t *)sc->SC_EBP) - 1) = tentry->byteoff; + /* set (int32_t)bytepcoff (local variable of assembledCode) */ + *(((int32_t *)sc->SC_EBP) - 1) = tentry->byteoff; - /* jump to exception handler */ - { - register uint32_t orig_sp asm("ecx"); - register uint32_t orig_bp asm("edx"); - register uint32_t exc_handler asm("eax"); - - exc_handler = - (uint32_t)(mb->CompiledCode + codeinfo->exc_handler_nativeoff); - orig_sp = sc->SC_ESP; - orig_bp = sc->SC_EBP; - - __asm__("movl %%ecx,%%esp\n\t" - "movl %%edx,%%ebp\n\t" - "jmp *%%eax" + /* jump to exception handler */ + { + register uint32_t orig_sp asm("ecx"); + register uint32_t orig_bp asm("edx"); + register uint32_t exc_handler asm("eax"); + + exc_handler = + (uint32_t)(mb->CompiledCode + codeinfo->exc_handler_nativeoff); + orig_sp = sc->SC_ESP; + orig_bp = sc->SC_EBP; + + __asm__("movl %%ecx,%%esp\n\t" + "movl %%edx,%%ebp\n\t" + "jmp *%%eax" : : "r" (orig_sp), "r" (orig_bp), "r" (exc_handler)); - } /* jump to exception handler */ - } /* if ((sig == SIGSEGV) || (sig == SIGBUS)) */ + } /* jump to exception handler */ + } /* if (tentry) ... NullPointerException occurred */ + else { /* not NullPointerException ... error ! */ + printf("sigcontext: 0x%08x\n"); fflush(stdout); + showSigcontext(sc); + } #endif /* EXC_BY_SIGNAL */ + } /* if ((sig == SIGSEGV) || (sig == SIGBUS)) */ +#endif /* EXC_BY_SIGNAL || GET_SIGCONTEXT */ } @@ -485,6 +612,7 @@ } +#ifndef IGNORE_DISABLE /* * Enable and Disable the compiler. */ @@ -504,6 +632,7 @@ #endif compiler_enabled = FALSE; } +#endif /* IGNORE_DISABLE */ /* @@ -518,6 +647,7 @@ fflush(stdout); #endif +#ifndef IGNORE_DISABLE if (!compiler_enabled) { #ifdef COMPILE_DEBUG printf(" compiler has been disabled.\n return.\n"); @@ -525,12 +655,19 @@ #endif return TRUE; } +#endif /* IGNORE_DISABLE */ mb = cbMethods(cb); mb_end = mb + cbMethodsCount(cb); for (; mb < mb_end; mb++) { + int access = mb->fb.access; + + if (access & ACC_ABSTRACT) continue; + /* initialize mb->CompiledCodeInfo */ if (!(mb->CompiledCodeInfo)) prepareCompiledCodeInfo(EE(), mb); + + if (access & ACC_NATIVE) continue; if (!(mb->code)) { #ifdef COMPILE_DEBUG diff -aruN shujit-0.2.7/compiler.h shujit/compiler.h --- shujit-0.2.7/compiler.h Sat Jan 30 20:20:27 1999 +++ shujit/compiler.h Sun Feb 7 19:05:01 1999 @@ -55,21 +55,24 @@ /* Additional type definition */ -/* for Linux, and SunOS 5.5.1 or earlier */ -#if defined(linux) \ - || (defined(sun) && defined(__svr4__) && !defined(_ILP32) && !defined(_LP64)) -#ifndef _UINT16_T -#define _UINT16_T +#if !(defined(_ILP32) || defined(_LP64)) +# ifndef _UINT16_T +# define _UINT16_T typedef unsigned short uint16_t; -#endif /* _UINT16_T */ +# endif /* _UINT16_T */ -#ifndef __BIT_TYPES_DEFINED__ -#ifndef _INT16_T -#define _INT16_T +# ifndef __BIT_TYPES_DEFINED__ +# ifndef _INT16_T +# define _INT16_T typedef short int16_t; -#endif /* _INT16_T */ -#endif /* __BIT_TYPES_DEFINED__ */ -#endif /* OS */ +# endif /* _INT16_T */ +# endif /* __BIT_TYPES_DEFINED__ */ + +#endif /* _ILP32, LP64 */ + +# ifdef __FreeBSD__ +typedef u_int16_t uint16_t; +# endif /* __FreeBSD__ */ /* Additional macro definition */ @@ -77,9 +80,20 @@ /* - * OS dependent macro definition + * features */ + #define EXC_BY_SIGNAL +#define GET_SIGCONTEXT +#undef IGNORE_DISABLE + +#ifdef RUNTIME_DEBUG +#undef EXC_BY_SIGNAL +#endif + +/* + * OS dependent macro definition + */ #if defined (linux) # define EXECUTEJAVA_IN_ASM @@ -100,7 +114,7 @@ #endif -#ifdef EXC_BY_SIGNAL +#if defined(EXC_BY_SIGNAL) || defined(GET_SIGCONTEXT) # if defined(linux) # include /* for struct sigcontext */ # include /* for kernel version */ @@ -124,7 +138,25 @@ # define SC_EBP ebp # define SC_ESP esp # endif -#endif +#endif /* EXC_BY_SIGNAL || GET_SIGCONTEXT */ + + +#ifdef CODE_DB +# undef CODE_DB_DEBUG + +# define CODEDB_PREFIX "shujit-code" +# define CODEDB_DB_SUFFIX ".db" +# define CODEDB_PAGE_SUFFIX ".page" + +# define CODEDB_PAGE CODEDB_PREFIX CODEDB_PAGE_SUFFIX +# ifdef GDBM +# define LIBDBM "libgdbm.so" +# define CODEDB_DB CODEDB_PREFIX CODEDB_DB_SUFFIX +# else +# define LIBDBM "libndbm.so" +# define CODEDB_DB CODEDB_PREFIX +# endif +#endif /* CODE_DB */ /* @@ -169,34 +201,34 @@ #ifdef EXC_BY_SIGNAL typedef struct throw_entry { - unsigned int start; - unsigned int end; - unsigned int byteoff; + uint32_t start; + uint16_t len; + uint16_t byteoff; } throwentry; #endif /* EXC_BY_SIGNAL */ typedef struct compiled_code_info { - int code_size; - int ret_size; + int32_t code_size; + int32_t ret_size; char *argsizes; - unsigned int exc_handler_nativeoff; - unsigned int finish_return_nativeoff; + uint32_t exc_handler_nativeoff; + uint32_t finish_return_nativeoff; #ifdef EXC_BY_SIGNAL -#define DEFAULT_THROWTABLE_SIZE 8 +#define DEFAULT_THROWTABLE_SIZE 1024 throwentry *throwtable; - int throwtablelen; - int throwtablesize; + uint32_t throwtablelen; + uint32_t throwtablesize; #endif /* EXC_BY_SIGNAL */ } CodeInfo; typedef struct pcentry { - unsigned short opcode; - unsigned short state; - unsigned int byteoff; - unsigned int nativeoff; + uint16_t opcode; + uint16_t state; + uint32_t byteoff; + uint32_t nativeoff; } pcentry; typedef struct jpentry { @@ -209,19 +241,19 @@ struct methodblock *mb; /* buffer for compiled code */ -#define DEFAULT_BUF_SIZE 8192 +#define DEFAULT_BUF_SIZE 4096 unsigned char *buffer; int buf_size; unsigned char *bufp; /* program counter table */ -#define DEFAULT_PCTABLE_SIZE 100 +#define DEFAULT_PCTABLE_SIZE 128 int pctablesize; - int pctablelen; + uint32_t pctablelen; pcentry *pctable; /* jump instruction table */ -#define DEFAULT_JPTABLE_SIZE 100 +#define DEFAULT_JPTABLE_SIZE 128 int jptablesize; int jptablelen; jpentry *jptable; @@ -232,7 +264,12 @@ * Global Variables */ /* in compiler.c */ -#if defined(EXC_BY_SIGNAL) && defined(SEARCH_SIGCONTEXT) + +#ifndef IGNORE_DISABLE +extern bool_t compiler_enabled; +#endif /* IGNORE_DISABLE */ + +#if (defined(EXC_BY_SIGNAL) || defined(GET_SIGCONTEXT)) && defined(SEARCH_SIGCONTEXT) # ifdef linux extern unsigned short reg_gs; extern unsigned short reg_fs; @@ -243,9 +280,18 @@ extern unsigned short reg_cs; extern unsigned short reg_ss; # endif -#endif +#endif /* (EXC_BY_SIGNAL || GET_SIGCONTEXT) && SEARCH_SIGCONTEXT */ -extern bool_t compiler_enabled; +#ifdef CODE_DB +# ifdef GDBM +# include +extern GDBM_FILE db; +# else +# include +extern DBM *db; +# endif +extern int db_page; +#endif /* CODE_DB */ extern int opt_quiet; /* suppress initial message and some outputs */ @@ -260,6 +306,10 @@ /* make java.lang.Compiler#disable() void */ extern int opt_cmplclinit; /* compile class initializer */ +#ifdef CODE_DB +extern int opt_codedb; + /* save and re-use generated native code */ +#endif /* CODE_DB */ extern void *sym_compileAndInvokeMethod; extern void *sym_invokeJITCompiledMethod; @@ -267,6 +317,20 @@ extern void *sym_invokeSynchronizedJavaMethod; extern void *sym_invokeAbstractMethod; extern void *sym_invokeLazyNativeMethod; +#ifdef CODE_DB +# ifdef GDBM +extern GDBM_FILE (*sym_dbm_open)(char *,int,int,int,void (*)()); +extern void (*sym_dbm_close)(GDBM_FILE); +extern int (*sym_dbm_store)(GDBM_FILE,datum,datum,int); +extern datum (*sym_dbm_fetch)(GDBM_FILE,datum); +extern void (*sym_dbm_sync)(GDBM_FILE); +# else +extern DBM *(*sym_dbm_open)(const char *,int,int); +extern void (*sym_dbm_close)(DBM *); +extern int (*sym_dbm_store)(DBM *,datum,datum,int); +extern datum (*sym_dbm_fetch)(DBM *,datum); +# endif +#endif /* CODE_DB */ #ifdef JITDO /* in proxy.c */ @@ -297,6 +361,9 @@ extern void cancelOnBuffer(CompilerContext *cc, size_t); extern void ensureBufferSize(CompilerContext *cc, size_t req); +#ifdef CODE_DB +extern void pctableExtend(CompilerContext *cc, uint32_t size); +#endif /* CODE_DB */ extern void pctableAdd(CompilerContext *cc, int opcode, int state, unsigned int byteoff, unsigned int nativeoff); extern void pctableInsert(CompilerContext *cc, int index, @@ -309,10 +376,14 @@ extern CodeInfo *prepareCompiledCodeInfo(ExecEnv *ee, struct methodblock *mb); extern void freeCompiledCodeInfo(CodeInfo *info); + #ifdef EXC_BY_SIGNAL +#ifdef CODE_DB +extern void throwtableExtend(CodeInfo *info, uint32_t size); +#endif /* CODE_DB */ extern void throwtableAdd(CodeInfo *info, - unsigned int start, unsigned int end, unsigned int byteoff); -extern throwentry *throwtableGet(CodeInfo *info, unsigned int nativeoff); + uint32_t start, uint16_t len, uint16_t byteoff); +extern throwentry *throwtableGet(CodeInfo *info, uint32_t nativeoff); #endif /* EXC_BY_SIGNAL */ @@ -329,17 +400,35 @@ extern void initFunctionSymbols(); #endif +#ifdef CODE_DB +/* in codedb.c */ +void writeCompiledCode( +# ifdef GDBM +GDBM_FILE db +# else +DBM *db +# endif +, int fd, CompilerContext *cc); +int readCompiledCode( +# ifdef GDBM +GDBM_FILE db +# else +DBM *db +# endif +, int fd, CompilerContext *cc); +#endif /* CODE_DB */ + /* in runtime.c */ -#ifdef EXC_BY_SIGNAL +#if defined(EXC_BY_SIGNAL) || defined(GET_SIGCONTEXT) extern void showSigcontext(sigcontext *sc); -#endif +#endif /* EXC_BY_SIGNAL || GET_SIGCONTEXT */ extern int invokeMethod( #ifdef RUNTIME_DEBUG int runtime_debug, #endif - ExecEnv *ee, int narg, int retsize, - JHandle *obj, struct methodblock *method, - int bytepcoff, stack_item *stackpointer); + JHandle *obj, struct methodblock *method, int args_size, ExecEnv *ee, + int retsize, int bytepcoff, stack_item *stackpointer +); extern struct methodblock *getInterfaceMethod( #ifdef RUNTIME_DEBUG int runtime_debug, diff -aruN shujit-0.2.7/computil.c shujit/computil.c --- shujit-0.2.7/computil.c Sat Jan 30 15:43:09 1999 +++ shujit/computil.c Sat Feb 6 03:01:05 1999 @@ -195,6 +195,16 @@ /* PC table */ +#ifdef CODE_DB +void pctableExtend(CompilerContext *cc, uint32_t size) { + if (size < cc->pctablesize) return; + + cc->pctable = (pcentry *)sysRealloc(cc->pctable, sizeof(pcentry) * size); + cc->pctablesize = size; +} +#endif /* CODE_DB */ + + void pctableAdd(CompilerContext *cc, int opcode, int state, unsigned int byteoff, unsigned int nativeoff) { pcentry *entryp; @@ -392,8 +402,19 @@ #ifdef EXC_BY_SIGNAL +#ifdef CODE_DB +void throwtableExtend(CodeInfo *info, uint32_t size) { + if (size < info->throwtablesize) return; + + info->throwtable = + (throwentry *)sysRealloc(info->throwtable, sizeof(throwentry) * size); + info->throwtablesize = size; +} +#endif /* CODE_DB */ + + void throwtableAdd(CodeInfo *info, - unsigned int start, unsigned int end, unsigned int byteoff) { + uint32_t start, uint16_t len, uint16_t byteoff) { throwentry *entryp; if (info->throwtablelen >= info->throwtablesize) { /* extend table size */ @@ -406,14 +427,14 @@ entryp = info->throwtable + info->throwtablelen; entryp->start = start; - entryp->end = end; + entryp->len = len; entryp->byteoff = byteoff; (info->throwtablelen)++; } -throwentry *throwtableGet(CodeInfo *info, unsigned int nativeoff) { +throwentry *throwtableGet(CodeInfo *info, uint32_t nativeoff) { int l = 0; int h = info->throwtablelen; int index; @@ -423,17 +444,17 @@ index = l + ((h - l) >> 1); entryp = info->throwtable + index; - if ((entryp->start <= nativeoff) && (nativeoff < entryp->end)) { - /* found */ + if ((entryp->start <= nativeoff) && + (nativeoff < (entryp->start + entryp->len))) { /* found */ return entryp; } if (l == h) return NULL; /* not found */ - if (entryp->end <= nativeoff) - l = index + 1; - else + if (nativeoff < entryp->start) h = index; + else + l = index + 1; } } #endif /* EXC_BY_SIGNAL */ diff -aruN shujit-0.2.7/def.mk shujit/def.mk --- shujit-0.2.7/def.mk Wed Jan 27 11:51:07 1999 +++ shujit/def.mk Mon Feb 8 21:34:45 1999 @@ -1,12 +1,19 @@ 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 +# +# features +# + +# code DB +CODE_DB = 1 +GDBM = 1 + +# JIT Distributed Object +# now being implemented #JITDO = 1 diff -aruN shujit-0.2.7/invoker.c shujit/invoker.c --- shujit-0.2.7/invoker.c Sat Jan 30 16:16:49 1999 +++ shujit/invoker.c Sat Feb 6 19:56:37 1999 @@ -33,16 +33,18 @@ fflush(stdout); #endif +#ifndef IGNORE_DISABLE /* if compiler is disabled, call original invoker */ if (!compiler_enabled) { #ifdef RUNTIME_DEBUG - printf("Compiler is disabled, now call original invoker."); + printf("Compiler is disabled, now call original invoker.\n"); fflush(stdout); #endif access = mb->fb.access; norm_invoker = access2invoker(access); goto candi_call_normal_method; } +#endif /* IGNORE_DISABLE */ key = obj_monitor(fieldclass(&mb->fb)); #ifdef COMPILE_DEBUG @@ -121,7 +123,17 @@ JavaFrame *cur_frame;; cur_frame = ee->current_frame; +#ifdef RUNTIME_DEBUG + printf("call ExecuteJava(): %s#%s.\n", + cbName(mb->fb.clazz), mb->fb.name); + fflush(stdout); +#endif exec_ret = ExecuteJava(mb->code, ee); +#ifdef RUNTIME_DEBUG + printf("ExecuteJava() done: %s#%s.\n", + cbName(mb->fb.clazz), mb->fb.name); + fflush(stdout); +#endif old_optop = cur_frame->optop; #ifdef EXECUTEJAVA_IN_ASM if (cur_frame->monitor) monitorExit(obj_monitor(o)); @@ -186,12 +198,11 @@ 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), "sun/tools/tree/ArrayExpression")) - && (!strcmp(mb->fb.name, "codeValue"))) - runtime_debug = 1; else if ((!strcmp(cbName(mb->fb.clazz), "NET/shudo/jitdo/ThreadPool$AThread")) && (!strcmp(mb->fb.name, "run"))) runtime_debug = 1; + else if ((!strcmp(mb->fb.name, "main"))) + runtime_debug = 1; else runtime_debug = 0; # endif @@ -351,9 +362,6 @@ if (java_monitor) frame->mon_starttime = now(); #endif -#if 0 - printf("%x\n", mb->CompiledCode); -#endif #ifdef RUNTIME_DEBUG ((void (*) (JHandle *, struct methodblock *, int, ExecEnv *, int)) mb->CompiledCode)(o, mb, args_size, ee, runtime_debug); diff -aruN shujit-0.2.7/postcmpl.rb shujit/postcmpl.rb --- shujit-0.2.7/postcmpl.rb Sun Jan 3 08:48:48 1999 +++ shujit/postcmpl.rb Sat Feb 6 19:50:19 1999 @@ -1,10 +1,17 @@ #!/usr/local/bin/ruby while gets() - # translate "leal LC...,%esi" to "pushl LC..." + next if /PUSH/ + # translate "leal LC...,%esi" to "pushl LC..." if next line is `#APP' # Linux: .LC..., FreeBSD: LC... - gsub! /leal (\.?LC.*),.*/, 'pushl \1' + if /leal \.?LC/ + line = $_; + gets() + if /^#APP/ + line.gsub!(/leal (\.?LC.*),.*/, 'pushl \1') + end + print line + end # skip PUSH ... - next if /PUSH/ print end diff -aruN shujit-0.2.7/runtime.c shujit/runtime.c --- shujit-0.2.7/runtime.c Sat Jan 30 20:19:33 1999 +++ shujit/runtime.c Sat Feb 6 18:58:40 1999 @@ -17,7 +17,7 @@ #endif /* JITDO */ -#ifdef EXC_BY_SIGNAL +#if defined(EXC_BY_SIGNAL) || defined(GET_SIGCONTEXT) /* * show contents of structure sigcontext */ @@ -55,13 +55,14 @@ 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 + sc->sc_ss & 0xffff, sc->sc_cs & 0xffff, + sc->sc_ds & 0xffff, sc->sc_es & 0xffff #endif ); fflush(stdout); } -#endif /* EXC_BY_SIGNAL */ +#endif /* EXC_BY_SIGNAL || GET_SIGCONTEXT */ /* @@ -71,15 +72,14 @@ #ifdef RUNTIME_DEBUG int runtime_debug, #endif - ExecEnv *ee, int args_size, int retsize, - JHandle *obj, struct methodblock *method, - int bytepcoff, stack_item *stackpointer) { + JHandle *obj, struct methodblock *method, int args_size, ExecEnv *ee, + int retsize, int bytepcoff, stack_item *stackpointer +) { JavaFrame *cur_frame; /* ee->current_frame */ int access; - CodeInfo *info; - /* !compiler_enabled && (method->invoker == sym_compileAndInvokeMethod) */ #ifdef RUNTIME_DEBUG - info = (CodeInfo *)method->CompiledCodeInfo; + CodeInfo *info; + info= (CodeInfo *)method->CompiledCodeInfo; #endif #ifdef RUNTIME_DEBUG @@ -90,33 +90,36 @@ #endif /* set ee->current_frame->lastpc */ - { - cur_frame = ee->current_frame; - cur_frame->lastpc = cur_frame->current_method->code + bytepcoff; + cur_frame = ee->current_frame; + cur_frame->lastpc = cur_frame->current_method->code + bytepcoff; + + access = method->fb.access; + stackpointer += (args_size - 1); + #ifdef RUNTIME_DEBUG - if (runtime_debug) { - struct methodblock *cur_mb = cur_frame->current_method; + 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(" args_size, retsize, nlocals: %d, %d, %d\n", + printf(" ee: 0x%08x\n", (int)ee); + printf(" current_frame: 0x%08x\n", (int)cur_frame); + 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); - printf(" caller method:"); - if (cur_mb) - printf(" %s#%s %s", + printf(" obj: 0x%08x\n", (int)obj); + printf(" method: 0x%08x\n", (int)method); + printf(" caller method:"); + fflush(stdout); + if (cur_mb) + printf(" %s#%s %s", cbName(cur_mb->fb.clazz), cur_mb->fb.name, cur_mb->fb.signature); - else - printf(" (null)"); - printf(" (0x%08x)\n", (int)cur_mb); - printf(" bytepcoff: 0x%x(%d)\n", bytepcoff, bytepcoff); - fflush(stdout); - } -#endif + else + printf(" (null)"); + fflush(stdout); + printf(" (0x%08x)\n", (int)cur_mb); + printf(" bytepcoff: 0x%x(%d)\n", bytepcoff, bytepcoff); + fflush(stdout); } +#endif #ifdef RUNTIME_DEBUG /* let user know calling normal Java method */ @@ -133,57 +136,6 @@ #endif /* RUNTIME_DEBUG */ - 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 - - if ((access & ACC_MACHINE_COMPILED) && - /* is expected to be equal to: - ((method->invoker == sym_invokeJITCompiledMethod) || - (method->invoker == sym_compileAndInvokeMethod)) - */ - (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 { - /* call normal Java or native method */ - /* restack from native stack to JVM stack */ - stack_item *sp = stackpointer; - stack_item *optop = cur_frame->optop; - char *argsizes; - - argsizes = ((CodeInfo *)method->CompiledCodeInfo)->argsizes; - - while (*argsizes) { - if (*argsizes == 1) { - optop[0] = sp[0]; - optop++; sp--; - } - else { - optop[0] = sp[-1]; - optop[1] = sp[0]; - optop += 2; sp -= 2; - } - argsizes++; - } - } - - #ifdef RUNTIME_DEBUG if (runtime_debug) { char *sig = method->fb.signature; @@ -235,40 +187,95 @@ } #endif /* RUNTIME_DEBUG */ - if (!(method->invoker(obj, method, args_size, ee))) - return -1; + +#if 0 +#define CALL_INVOKER \ + __asm__("pushl 24(%ebp)");\ + __asm__("movl %0,%%eax" : : "m" (method->invoker));\ + __asm__("pushl 20(%ebp)\n\tpushl 16(%ebp)\n\tpushl 12(%ebp)");\ + __asm__("call *%eax\n\t"\ + "addl $16,%esp");\ + {\ + register int ret asm("eax");\ + if (!ret) return -1;\ + } +#else +#define CALL_INVOKER \ + if (!(method->invoker(obj, method, args_size, ee)))\ + return -1 /* obj is required for enter/exit a monitor of the object. */ +#endif + + if ((access & ACC_MACHINE_COMPILED) + /* is expected to be equal to: + ((method->invoker == sym_invokeJITCompiledMethod) || + (method->invoker == sym_compileAndInvokeMethod)) + */ +#ifndef IGNORE_DISABLE + && (compiler_enabled || (method->invoker != sym_compileAndInvokeMethod)) + /* not (invoker is compiler, but the method is not to be compiled) */ +#endif /* IGNORE_DISABLE */ + ) { + /* compiled method */ + cur_frame->returnpc = (unsigned char *)stackpointer; + + CALL_INVOKER; + } + else { + /* normal Java or native method */ + /* restack from native stack to JVM stack */ + stack_item *sp = stackpointer; + stack_item *optop = cur_frame->optop; + char *argsizes; + + argsizes = ((CodeInfo *)method->CompiledCodeInfo)->argsizes; - if (!(access & (ACC_ABSTRACT | ACC_NATIVE | ACC_MACHINE_COMPILED))) { + while (*argsizes) { + if (*argsizes == 1) { + optop[0] = sp[0]; + optop++; sp--; + } + else { + optop[0] = sp[-1]; + optop[1] = sp[0]; + optop += 2; sp -= 2; + } + argsizes++; + } + + CALL_INVOKER; + + if (!(access & (ACC_ABSTRACT | ACC_NATIVE | ACC_MACHINE_COMPILED))) { /* normal Java method */ - int exec_ret; - stack_item *optop, *old_optop; + int exec_ret; + stack_item *optop, *old_optop; - exec_ret = ExecuteJava(method->code, ee); - cur_frame = ee->current_frame; /* reload */ - old_optop = cur_frame->optop; + exec_ret = ExecuteJava(method->code, ee); + 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; + cur_frame = cur_frame->prev; + ee->current_frame = cur_frame; + if (!exec_ret) return -1; #ifdef EXECUTEJAVA_IN_ASM - /* These operation is required - only with x86 assembly ver. of executeJava.c */ - 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; + /* These operation is required + only with x86 assembly ver. of executeJava.c */ + 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; } - cur_frame->optop = optop; - } #endif - } /* normal Java method */ + } /* normal Java method */ + } /* normal Java or native method */ #ifdef RUNTIME_DEBUG if (runtime_debug) { @@ -550,8 +557,9 @@ while (frame) { struct methodblock *frameMb = frame->current_method; if (frameMb) { - printf(" %s#%s %s ", - cbName(frameMb->fb.clazz), frameMb->fb.name, frameMb->fb.signature); + printf(" %s#%s %s 0x%x ", + cbName(frameMb->fb.clazz), frameMb->fb.name, frameMb->fb.signature, + (int)frameMb); if (frame->lastpc) printf("pc: %d", frame->lastpc - frameMb->code); if (frameMb->fb.access & ACC_MACHINE_COMPILED) @@ -645,31 +653,35 @@ char *showObjectBody(char *sig, JHandle *obj) { switch (*sig) { case '[': + sig++; + if (*sig == 'L') while (*(sig++) != ';'); + else sig++; if (!obj) printf("(null)"); else { char buf[256]; +show_array: printf("len %ld", obj_length(obj)); - sig++; - switch (*sig) { - case 'B': + switch (obj_flags(obj)) { + case T_BYTE: printf(" `%s'", unhand((HArrayOfByte *)obj)->body); break; - case 'C': + case T_CHAR: printf(" `%s'", unicode2utf(unhand((HArrayOfChar *)obj)->body, obj_length(obj), buf, 256)); break; } } - if (*sig == 'L') while (*(sig++) != ';'); - else sig++; break; case 'L': + while (*(sig++) != ';'); if (!obj) printf("(null)"); else { - char *classname = cbName(obj_array_classblock(obj)); + char *classname; + if (obj_flags(obj) != T_NORMAL_OBJECT) goto show_array; + classname = cbName(obj_array_classblock(obj)); printf("class %s", classname); if (!strcmp(classname, "java/lang/String")) { int strlen = javaStringLength((Hjava_lang_String *)obj); @@ -678,7 +690,6 @@ printf("'"); } } - while (*(sig++) != ';'); break; default: sig++; diff -aruN shujit-0.2.7/txt/benchmark-SS3000 shujit/txt/benchmark-SS3000 --- shujit-0.2.7/txt/benchmark-SS3000 Sat Jan 30 20:05:24 1999 +++ shujit/txt/benchmark-SS3000 Sat Feb 6 16:35:33 1999 @@ -1,28 +1,21 @@ TOSHIBA Dynabook SS 3000 - Pentium/233MHz + Pentium with MMX technology / 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 - - plain TYA12v3 990120 990130 -Sieve 96 317 398 421 times -TestOpcodeField 4037 1310 1309 1202 msec + plain TYA12v3 990120 990201 +Sieve 98 317 398 423 times +TestOpcodeField 4062 1311 1309 1205 msec TestOpcodeStatic 3095 429 258 258 msec -TestFinalStatic 12299 7362(*) 1116(*) 772(*) msec -Iview Valetta.jpg 447 460 631 576 msec +TestFinalStatic 12298 2104(*) 1116(*) 772(*) msec +Iview Valetta.jpg 441 465 631 567 msec + (*) ばらつく [Linpack Benchmark -- Java Version] -plain TYA12 990104 990130 -1.973 5.086 4.213 4.488 +plain TYA12v3 990104 990201 +1.956 5.049 4.213 4.459 [E2 1MB 暗号化] @@ -33,50 +26,50 @@ 192 859 362 465 256 855 384 481 - plain TYA12v3 990120 990130 -128 809 348 398 373 -192 827 351 382 349 -256 853 348 400 359 + plain TYA12v3 990120 990201 +128 831 348 398 369 +192 854 335 382 350 +256 856 341 400 358 [CaffeineMark 3.0] interpreter 117v1a -Sieve 440 -Loop 498 -Logic 502 -String 764 -Float 446 -Method 461 -Graphics574 -Image 314 -Dialog 79 -CM3 391 +Sieve 437 +Loop 495 +Logic 501 +String 783 +Float 443 +Method 465 +Graphics630 +Image 326 +Dialog 73 +CM3 399 TYA 1.2 1.2(*) 1.2v3 -Sieve 822 780 822 -Loop 1558 1404 1543 -Logic 2887 2872 2895 -String 1410 1372 1496 -Float 993 915 992 -Method 888 877 933 -Graphics605 571 595 -Image 320 312 308 -Dialog 71 65 69 -CM3 735 699 737 +Sieve 822 780 823 +Loop 1558 1404 1541 +Logic 2887 2872 2893 +String 1410 1372 1413 +Float 993 915 993 +Method 888 877 931 +Graphics605 571 605 +Image 320 312 324 +Dialog 71 65 65 +CM3 735 699 732 (*) EXCEPTIONS_BY_SIGNALS を #undef shuJIT - 990104 990106 990120 990120 990121 990130 -Sieve 890 891 892 879 891 915 -Loop 1712 1710 1703 1712 1712 1893 -Logic 2882 2891 2881 2885 2877 2884 -String 1015 1007 1017 1004 1116 1113 -Float 1038 1030 1043 1046 1030 1121 -Method 146 144 189 187 199 198 -Graphics472 481 495 513 494 549 -Image 303 304 298 294 303 326 -Dialog 63 63 63 65 68 63 -CM3 567 567 582 587 600 621 + 990104 990106 990120 990120 990121 990201 990206 +Sieve 890 891 892 879 891 915 914 +Loop 1712 1710 1703 1712 1712 1891 1892 +Logic 2882 2891 2881 2885 2877 2881 2908 +String 1015 1007 1017 1004 1116 1099 1119 +Float 1038 1030 1043 1046 1030 1132 1133 +Method 146 144 189 187 199 196 214 +Graphics472 481 495 513 494 570 566 +Image 303 304 298 294 303 332 325 +Dialog 63 63 63 65 68 68 63 +CM3 567 567 582 587 600 630 630 (cmplclinit) diff -aruN shujit-0.2.7/txt/codesize shujit/txt/codesize --- shujit-0.2.7/txt/codesize Mon Sep 21 13:13:53 1998 +++ shujit/txt/codesize Sat Feb 6 16:48:52 1999 @@ -1,4 +1,5 @@ 生成コードのサイズ + 1998年 9月 21日 methodhead (eb, 235) 1f (31) diff -aruN shujit-0.2.7/txt/log-cm3 shujit/txt/log-cm3 --- shujit-0.2.7/txt/log-cm3 Mon Aug 24 04:33:50 1998 +++ shujit/txt/log-cm3 Thu Jan 1 00: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.7/txt/memo shujit/txt/memo --- shujit-0.2.7/txt/memo Sat Jan 30 19:55:41 1999 +++ shujit/txt/memo Mon Feb 8 21:31:57 1999 @@ -38,6 +38,7 @@ - invokeignored_quick にて、スタックのキャッシュ内容を無駄に push している。 Todo + - sysMalloc(), sysRealloc() の例外処理。 - クラスを初期化するタイミングを JLS 12.4.1 (When Initialization Occurs) の通りにする。first active use。 - SunOS 5, Win32 に移植。 @@ -59,6 +60,7 @@ javac の、フックをかけられる箇所を探す。 Done + - コンパイル結果を再利用できるようにする。オプション codedb。 - signal を利用して null check を省く。 - class initializer をコンパイルしない。 - java.lang.Compiler#enable(),disable() が働くようにする。 @@ -114,6 +116,9 @@ known bugs - 何かの理由でメソッドのコンパイルが失敗した際、 + - final フィールドへの putfield, putstatic で + IllegalAccessError が発生しない。 + 本来は bytecode verifier がはねるべき? - クラス初期化のタイミングが JLS 12.4.1 と違う。 クラス first active use 時ではなく、 first active use するメソッドのコンパイル時となってしまっている。 @@ -253,23 +258,27 @@ writeCode() writeForAnOpcode() native code をバッファに書く - 定数を解決 jump 命令 状態遷移コードを挿入 表に登録 + 定数 (static) を解決 native PC を update resolveJumpInstructions() jump 表を解決 - makeExcTable() - 例外表に native PC (offset) を書き込む + native code をコピー + (native code を保存) resolveExcRetSw() 以下を解決 bytepcoff exc. handler への jump method tail への jump tableswitch, lookupswitch の native PC 表を作成 - native code をコピー - 関数呼び出しを解決 + resolveDynamicConstants() + 定数 (dynamic) を解決 + makeExcTable() + 例外表に native PC (offset), handler の初期 state を書き込む + resolveFunctionSymbols() + 関数呼び出しを解決 定数 bipush