diff -aruN shujit-0.6.7/ChangeLog shujit/ChangeLog --- shujit-0.6.7/ChangeLog Tue Sep 19 21:31:01 2000 +++ shujit/ChangeLog Tue Nov 14 21:49:26 2000 @@ -1,5 +1,97 @@ $Id$ +[20001114] + +code.c 中の STR(CONST) と書かれた定数を +code.o のディスアセンブル結果から探す際の正規表現を、 +「(0x606060|60 60 60 00)」から「(0x606060|e9 60 60 60 00)」に変更した。 +以前、e9 (jmp) 60 60 60 00 とマッチさせるために「60 60 60 00」を追加したが、 +これによって余分な行がマッチしてしまっていた。 +(gentable.rb) + +FreeBSD (>= 4) の JDK 1.1.X では、シグナルハンドラに渡される第 3引数の型を +struct sigcontext * ではなく struct osigcontext * とした。 +JDK 1.2.X では sigcontext のまま。 +(compiler.h) + +0.6.8 リリース。 + +[20001007] + +(MetaVM) 遠隔呼び出しのプロトコルを変更。 +slot, if (slot == 0) signature から、 +slot, if (slot == 0) methodblock配列中の index に変更。 +(Proxy.java, Skeleton.java) + +ネイティブメソッドを遠隔呼び出しする際に、ネイティブメソッドに +遠隔参照 (Proxy のインスタンス) が渡る場合は警告を表示するようにした。 +(Proxy.java, Skeleton.java) + +[20001005] + +(MetaVM) Class.forName(name) を +ClassLoader.getSystemClassLoader().loadClass(name) (相当) で置き換えた。 +JDK 1.2 以降では、システムクラスで Class.forName() を使って +アプリケーションのクラスをロードできなくなったため。 +メソッド ClassLoader#getSystemClassLoader() は JDK 1.1 以前には存在しないため、 +MetaVM は現在 JDK 1.1 では動作しなくなっている。 +(DistObjectInputStream.java, MetaVM.java, Skeleton.java) + +[20001004] + +(MetaVM) VMOperations#{instantiate,anewarray,multianewarray} にて、 +クラスが初期化されていない場合に初期化を行うようにした。 +(vmop.c) + +[20001003] + +(MetaVM) 関数 proxy_* (proxy.c) をすべて JNI から old style に変更した。 +(proxy.c) + +[20001002] + +(MetaVM) JNI で実装してあった isByValue (byvalue.c) を +old style で実装し直した。 +この関数を JNI で実装すると MkRefLocal() が必要で、 +MkRefLocal() は JDK 1.2 以降ではネイティブメソッド用 JavaFrame を要求する。 +この関数はネイティブメソッドとして Java のコードから呼ばれるとは限らないため +JavaFrame (ee->current_frame) がネイティブメソッド用でない場合がある。 +結論: ネイティブメソッドではない関数は JNI の流儀で書かないこと。 +(byvalue.c) + +[20001001] + +#undef DIRECT_INVOCATION できちんと動作しなくなっていたのを修整。 +(runtime.c) + +(MetaVM) MetaVM を JDK 1.2 以降で動作させる場合は、 +クラスの初期化時にネイティブメソッドをリンクしてしまうようにした。 +そうしないと、MetaVM#instantiationVM() が instantiationVM0() を呼んだ際に +instantiationVM0() に制御が移る前にリンクのための Java コードが実行されて +しまうため。 +これに伴い、initializeClassForJIT() (compiler.c) の引数に +bool_t linkNative を追加。 +(compiler.c, compiler.h) + +[20000930] + +`instanceof java.lang.Object' に対するコード生成を省くようにした。 +(compile.c) + +[20000929] + +(MetaVM) remote flag と remote address を初期化するための +内部命令 metavm_init を用意し、Thread#run() の先頭に生成するようにした。 +(compiler.h, code.c, compile.c) + +[20000920] + +NetBSD/i386 1.5ALPHA (ELF), egcs-1.1.2, JDK 1.1.8 RC1 で +動作したという報告があったので、#if defined(__FreeBSD__) を +defined(__FreeBSD__) || defined(__NetBSD__) に変更した。 +[Thanks 柳井裕之さん ] +(code.h, compiler.h, compile.c, linker.c, signal.c) + [20000919] compiled code が compiled code を呼ぶ際も @@ -8,7 +100,7 @@ このチェックを行うか否かを制御できる。 (code.c, signal.c, compiler.h) -クラスの初期化時に、final クラスのメソッドに final 属性を付けるようにした。 +クラスの初期化時に、final クラスの全メソッドに final 属性を付けるようにした。 (compiler.c) 末尾再帰のジャンプへの変換の適用範囲を広げた。 @@ -1473,7 +1565,7 @@ [19990424] 19990419 の変更によってコンパイル中のメソッドが -ineterpret 実行され得るようになったため、 +interpret 実行され得るようになったため、 interpret 時に inlining が行われて CompilerContext の pctable が バイトコードと食い違い得るようになった。(VoyagerClassLoader# で発生) メソッドが呼び出された回数を CodeInfo 中に記録するようにし、 diff -aruN shujit-0.6.7/GNUmakefile shujit/GNUmakefile --- shujit-0.6.7/GNUmakefile Tue Sep 19 21:21:15 2000 +++ shujit/GNUmakefile Tue Nov 14 21:26:11 2000 @@ -18,12 +18,12 @@ # command -CC = /usr/local/bin/gcc +CC = /usr/bin/gcc LD_DYNAMIC = ${CC} -shared# for GCC and GNU binutils #LD_DYNAMIC = ld -Bdynamic# for SunOS 4 ASFLAGS = OBJDUMP = /usr/bin/objdump -RUBY = /usr/local/bin/ruby +RUBY = /usr/bin/ruby CI = /usr/bin/ci CO = /usr/bin/co RM = /bin/rm @@ -46,7 +46,7 @@ GENCONST = gentable.rb POSTPROC = postcmpl.rb -INCDIR = -I${J_INCDIR} -I${J_INCDIR}/genunix -I${J_INCDIR}/linux -I${J_INCDIR}/freebsd -I/usr/local/include +INCDIR = -I${J_INCDIR} -I${J_INCDIR}/genunix -I${J_INCDIR}/linux -I${J_INCDIR}/freebsd -I${J_INCDIR}/netbsd -I/usr/local/include OPTFLAGS = -O2 CDEBUGFLAGS =# -g -DDEBUG -DCOMPILE_DEBUG# -DRUNTIME_DEBUG diff -aruN shujit-0.6.7/GNUmakefile.in shujit/GNUmakefile.in --- shujit-0.6.7/GNUmakefile.in Thu Aug 31 23:40:17 2000 +++ shujit/GNUmakefile.in Wed Sep 20 18:19:41 2000 @@ -46,7 +46,7 @@ GENCONST = gentable.rb POSTPROC = postcmpl.rb -INCDIR = -I${J_INCDIR} -I${J_INCDIR}/genunix -I${J_INCDIR}/linux -I${J_INCDIR}/freebsd -I/usr/local/include +INCDIR = -I${J_INCDIR} -I${J_INCDIR}/genunix -I${J_INCDIR}/linux -I${J_INCDIR}/freebsd -I${J_INCDIR}/netbsd -I/usr/local/include OPTFLAGS = -O2 CDEBUGFLAGS =# -g -DDEBUG -DCOMPILE_DEBUG# -DRUNTIME_DEBUG diff -aruN shujit-0.6.7/NET/shudo/metavm/ByValueUtil.java shujit/NET/shudo/metavm/ByValueUtil.java --- shujit-0.6.7/NET/shudo/metavm/ByValueUtil.java Tue Mar 2 01:23:53 1999 +++ shujit/NET/shudo/metavm/ByValueUtil.java Mon Oct 2 18:28:31 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 @@ -23,7 +23,7 @@ package NET.shudo.metavm; -class ByValueUtil { +final class ByValueUtil { public static boolean isByValue(Object obj) { boolean ret = false; diff -aruN shujit-0.6.7/NET/shudo/metavm/DistObjectInputStream.java shujit/NET/shudo/metavm/DistObjectInputStream.java --- shujit-0.6.7/NET/shudo/metavm/DistObjectInputStream.java Sat Mar 20 19:24:46 1999 +++ shujit/NET/shudo/metavm/DistObjectInputStream.java Thu Oct 5 19:48:27 2000 @@ -46,7 +46,7 @@ } - ClassLoader classLoader = null; + ClassLoader classLoader = MetaVM.systemClassLoader; /** Sets class loader and force this loader to make use of it. */ public void classLoader(ClassLoader cl) { classLoader = cl; @@ -102,7 +102,7 @@ throws IOException, ClassNotFoundException { Class clazz = null; if (classLoader != null) { - clazz = this.classLoader.loadClass(v.getName()); + clazz = classLoader.loadClass(v.getName()); } else { clazz = Class.forName(v.getName()); diff -aruN shujit-0.6.7/NET/shudo/metavm/ExportTable.java shujit/NET/shudo/metavm/ExportTable.java --- shujit-0.6.7/NET/shudo/metavm/ExportTable.java Tue Mar 16 13:42:43 1999 +++ shujit/NET/shudo/metavm/ExportTable.java Sat Sep 30 18:26:59 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 @@ -84,8 +84,10 @@ if (element.releaseTime() <= now) { element.removeFrom(table); - if (debug) + if (debug) { System.out.println("ExportTable#expire(): " + element.target()); + System.out.flush(); + } } } } diff -aruN shujit-0.6.7/NET/shudo/metavm/MetaVM.java shujit/NET/shudo/metavm/MetaVM.java --- shujit-0.6.7/NET/shudo/metavm/MetaVM.java Tue Sep 12 21:00:28 2000 +++ shujit/NET/shudo/metavm/MetaVM.java Thu Oct 5 19:48:17 2000 @@ -29,7 +29,10 @@ /** * An utility class for controlling a behavior of MetaVM. */ -public class MetaVM { +public final class MetaVM { + protected static ClassLoader systemClassLoader = + ClassLoader.getSystemClassLoader(); // cache + protected static boolean debug = false; /* global debug flag */ protected static int bufsize = 1; @@ -110,33 +113,37 @@ static protected boolean aServerExists = false; - synchronized public static void instantiationVM(VMAddress addr) { - if (!aServerExists) { // invoke a MetaVMServer - aServerExists = true; - - Thread t = new Thread(new MetaVMServer()); - t.setName("MetaVM server"); - t.setDaemon(true); // daemon thread - t.setPriority(Thread.NORM_PRIORITY + 1); - t.start(); - - Thread.yield(); - // yield to MetaVM server to determine local port number - } - - instantiationVM0(addr); + synchronized public static VMAddress instantiationVM(VMAddress addr) { + if (!aServerExists) { + synchronized (MetaVM.class) { + if (!aServerExists) { + aServerExists = true; + + // invoke a MetaVMServer + Thread t = new Thread(new MetaVMServer()); + t.setName("MetaVM server"); + t.setDaemon(true); // daemon thread + t.setPriority(Thread.NORM_PRIORITY + 1); + t.start(); + + Thread.yield(); + // yield to MetaVM server to determine local port number + } + } + } + + Object origaddr = instantiationVM0(addr); + if ((addr != null) && (origaddr instanceof VMAddress)) + return (VMAddress)origaddr; + else + return null; } public static VMAddress instantiationVM() { - Object addr = instantiationVM0(); - if ((addr != null) && (addr instanceof VMAddress)) { - return (VMAddress)addr; - } - return null; + return instantiationVM(null); } - private static native void instantiationVM0(VMAddress addr); - private static native VMAddress instantiationVM0(); + private static native Object instantiationVM0(VMAddress addr); public static VMAddress address(Object obj) { diff -aruN shujit-0.6.7/NET/shudo/metavm/MetaVMServer.java shujit/NET/shudo/metavm/MetaVMServer.java --- shujit-0.6.7/NET/shudo/metavm/MetaVMServer.java Tue Mar 30 18:13:53 1999 +++ shujit/NET/shudo/metavm/MetaVMServer.java Sun Oct 8 22:34:38 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 @@ -59,14 +59,16 @@ private void usage() { - System.out.println("usage: " + this.PROGRAM + " [-h] [-d] [-b ]"); - System.out.println("\t-h: Show this help message."); - System.out.println("\t-p : specifies port number."); - System.out.println("\t-n: Set TCP_NODELAY to socket."); - System.out.println("\t-b : specifies buffer size of BufferedStream in KB."); - System.out.println("\t-l: Always load classes from local disk."); - System.out.println("\t-q: Quiet."); - System.out.println("\t-d: For debug."); + System.out.println("Usage: " + this.PROGRAM + " [OPTION]...\n"); + System.out.println(" -h:\t\tShow this help message."); + System.out.println(" -p :\tspecifies port number. (default = 10050)"); + System.out.println(" -n:\t\tSet TCP_NODELAY to socket."); + System.out.println(" -b :\tspecifies buffer size of BufferedStream in KB. (default = 1)"); + System.out.println(" -l:\t\tAlways load classes from local disk."); + System.out.println(" -q:\t\tQuiet."); + System.out.println(" -d:\t\tFor debug."); + + System.out.println(); } @@ -83,7 +85,7 @@ String s = null; try { s = args[++i]; } catch (ArrayIndexOutOfBoundsException e) { - System.out.println("-p option require an argument."); + System.out.println("-p option requires an argument."); break; } @@ -95,7 +97,7 @@ } VMAddress.localPort(port); if (debug) - System.out.println("port number:" + VMAddress.localPort()); + System.out.println("port number: " + VMAddress.localPort()); } else if (args[i].equals("-n")) { MetaVM.tcp_nodelay = true; @@ -104,7 +106,7 @@ String s = null; try { s = args[++i]; } catch (ArrayIndexOutOfBoundsException e) { - System.out.println("-b option require an argument."); + System.out.println("-b option requires an argument."); break; } @@ -244,7 +246,7 @@ public static void main(String[] args) { - System.runFinalizersOnExit(true); +// System.runFinalizersOnExit(true); try { new MetaVMServer().start(args); diff -aruN shujit-0.6.7/NET/shudo/metavm/Proxy.java shujit/NET/shudo/metavm/Proxy.java --- shujit-0.6.7/NET/shudo/metavm/Proxy.java Tue Sep 12 19:49:32 2000 +++ shujit/NET/shudo/metavm/Proxy.java Sun Oct 8 22:23:54 2000 @@ -39,7 +39,7 @@ public class Proxy implements ByValue, Cloneable { private VMAddress vmaddr; - private Class clazz; + private Class clz; private int id; private int length; @@ -58,7 +58,7 @@ protected Object clone() throws CloneNotSupportedException { - return new Proxy(vmaddr, clazz, id, length); + return new Proxy(vmaddr, clz, id, length); } @@ -70,7 +70,7 @@ private Proxy(VMAddress addr, Class clazz, int id, int length) { this.vmaddr = addr; - this.clazz = clazz; + this.clz = clazz; this.id = id; this.length = length; @@ -186,11 +186,11 @@ out.writeInt(count); out.flush(); - proxy.clazz = TypeUtil.arrayType(TypeUtil.primTypeByCode(type)); + proxy.clz = TypeUtil.arrayType(TypeUtil.primTypeByCode(type)); id = in.readInt(); if (id == 0) - throw new IOException("instantiation failure: " + proxy.clazz.getName()); + throw new IOException("instantiation failure: " + proxy.clz.getName()); proxy.id = id; proxy.length = count; @@ -232,7 +232,7 @@ out.writeInt(count); out.flush(); - proxy.clazz = TypeUtil.arrayType(clazz); + proxy.clz = TypeUtil.arrayType(clazz); id = in.readInt(); if (id == 0) @@ -273,7 +273,7 @@ out.writeObject(new ArrayOfIntWrapper(sizes)); out.flush(); - proxy.clazz = TypeUtil.arrayType(clazz); + proxy.clz = TypeUtil.arrayType(clazz); id = in.readInt(); if (id == 0) @@ -317,20 +317,21 @@ String classname = in.readUTF(); try { + ClassLoader cl; if (MetaVM.load_class_locally || classsrc.isLocalAddress()) { // load the class from local disk - clazz = Class.forName(classname); + cl = MetaVM.systemClassLoader; } else { // load via network - ClassLoader cl = RemoteClassLoader.get(classsrc); - in.classLoader(cl); // set class loader - - clazz = cl.loadClass(classname); + cl = RemoteClassLoader.get(classsrc); } + in.classLoader(cl); // set class loader + + this.clz = cl.loadClass(classname); } catch (ClassNotFoundException e) { - throw new IOException(e.getMessage()); + throw new IOException("class not found: " + e.getMessage()); } this.length = in.readInt(); @@ -475,7 +476,9 @@ Object ret = null; try { ret = in.readDistObject(); } - catch (ClassNotFoundException e) { throw new IOException(e.getMessage()); } + catch (ClassNotFoundException e) { + throw new IOException("class not found: " + e.getMessage()); + } MetaVM.remoteTransparency(orig); @@ -570,7 +573,9 @@ Object exc = null; try { exc = in.readDistObject(); } - catch (ClassNotFoundException e) { throw new IOException(e.getMessage()); } + catch (ClassNotFoundException e) { + throw new IOException("class not found: " + e.getMessage()); + } if (exc != null) // Exception is occurred throw (ArrayIndexOutOfBoundsException)exc; @@ -593,7 +598,9 @@ Object exc = null; try { exc = in.readDistObject(); } - catch (ClassNotFoundException e) { throw new IOException(e.getMessage()); } + catch (ClassNotFoundException e) { + throw new IOException("class not found: " + e.getMessage()); + } if (exc != null) // Exception is occurred throw (ArrayIndexOutOfBoundsException)exc; @@ -616,13 +623,17 @@ Object exc = null; try { exc = in.readDistObject(); } - catch (ClassNotFoundException e) { throw new IOException(e.getMessage()); } + catch (ClassNotFoundException e) { + throw new IOException("class not found: " + e.getMessage()); + } if (exc != null) // Exception is occurred throw (ArrayIndexOutOfBoundsException)exc; Object ret = null; try { ret = in.readDistObject(); } - catch (ClassNotFoundException e) { throw new IOException(e.getMessage()); } + catch (ClassNotFoundException e) { + throw new IOException("class not found: " + e.getMessage()); + } MetaVM.remoteTransparency(orig); @@ -642,7 +653,9 @@ Object exc = null; try { exc = in.readDistObject(); } - catch (ClassNotFoundException e) { throw new IOException(e.getMessage()); } + catch (ClassNotFoundException e) { + throw new IOException("class not found: " + e.getMessage()); + } if (exc != null) // Exception is occurred throw (ArrayIndexOutOfBoundsException)exc; @@ -662,7 +675,9 @@ Object exc = null; try { exc = in.readDistObject(); } - catch (ClassNotFoundException e) { throw new IOException(e.getMessage()); } + catch (ClassNotFoundException e) { + throw new IOException("class not found: " + e.getMessage()); + } if (exc != null) // Exception is occurred throw (ArrayIndexOutOfBoundsException)exc; @@ -682,7 +697,9 @@ Object exc = null; try { exc = in.readDistObject(); } - catch (ClassNotFoundException e) { throw new IOException(e.getMessage()); } + catch (ClassNotFoundException e) { + throw new IOException("class not found: " + e.getMessage()); + } if (exc != null) // Exception is occurred throw (ArrayIndexOutOfBoundsException)exc; @@ -690,15 +707,15 @@ } - public Object invoke(int slot, String sig, Object[] args) + public Object invoke(int slot, int mbindex, Object[] args) throws Throwable { boolean orig = MetaVM.remoteTransparency(false); if (debug) { System.out.println("Proxy.invoke() called."); - System.out.println(" clazz: " + clazz.getName()); + System.out.println(" clazz: " + this.clz.getName()); System.out.println(" slot: " + slot); - System.out.println(" sig : " + sig); + System.out.println(" mbindex: " + mbindex); System.out.println(" args: " + args); System.out.flush(); @@ -721,13 +738,34 @@ } } +/* + if (VMOperations.isNativeMethod(this.clz, slot, mbindex) && + args != null) { + // check if there are args which is Proxy class + for (int i = 0; i < args.length; i++) { + boolean remoteRef = false; + if (args[i] instanceof Proxy) { // Proxy + Proxy anArg = (Proxy)args[i]; + if (!(anArg.address().equals(vmaddr))) remoteRef = true; + } + else { // not Proxy + if (!vmaddr.isLocalAddress()) remoteRef = true; + } + if (remoteRef) + System.err.println( + "[MetaVM: (at Proxy) Remote refs passed to the native method: " + + this.clz.getName() + "#" + + VMOperations.MethodName(this.clz, slot, mbindex) + + ", slot: " + slot + ", arg#: " + i + "]"); + } + } +*/ + if (sock == null) reference(); out.writeByte(Protocol.INVOKE); out.writeShort(slot); - if (slot == 0) { // caller is a constructor - out.writeUTF(sig); - } + if (slot == 0) out.writeShort(mbindex); out.writeDistObject(new ArrayOfObjectWrapper(args)); out.flush(); @@ -735,7 +773,7 @@ Object thrw = null; try { thrw = in.readDistObject(); } catch (ClassNotFoundException e) { - throw new IOException(e.getMessage()); + throw new IOException("class not found: " + e.getMessage()); } if (thrw != null) { // Throwable is thrown at remote machine throw (Throwable)thrw; @@ -744,7 +782,9 @@ Object ret = null; try { ret = in.readDistObject(); } - catch (ClassNotFoundException e) { throw new IOException(e.getMessage()); } + catch (ClassNotFoundException e) { + throw new IOException("class not found " + e.getMessage()); + } MetaVM.remoteTransparency(orig); diff -aruN shujit-0.6.7/NET/shudo/metavm/Skeleton.java shujit/NET/shudo/metavm/Skeleton.java --- shujit-0.6.7/NET/shudo/metavm/Skeleton.java Tue Mar 30 18:14:45 1999 +++ shujit/NET/shudo/metavm/Skeleton.java Sun Oct 8 22:23:37 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 @@ -44,11 +44,13 @@ private Object obj = null; + private Class clz = null; private String signature = null; private char elemsig; private void setSignature() { if (obj != null) { - this.signature = obj.getClass().getName(); + this.clz = obj.getClass(); + this.signature = clz.getName(); if (debug) System.out.println("sig: " + this.signature); try { if (this.signature.charAt(0) == '[') @@ -209,15 +211,14 @@ } try { - if (MetaVM.load_class_locally || classsrc.isLocalAddress()) { - clazz = Class.forName(classname); - } - else { - ClassLoader cl = RemoteClassLoader.get(classsrc); - in.classLoader(cl); // set class loader + ClassLoader cl; + if (MetaVM.load_class_locally || classsrc.isLocalAddress()) + cl = MetaVM.systemClassLoader; + else + cl = RemoteClassLoader.get(classsrc); + in.classLoader(cl); // set class loader - clazz = cl.loadClass(classname); - } + clazz = cl.loadClass(classname); this.obj = VMOperations.instantiate(clazz); id = ObjectID.idByObject(this.obj); @@ -248,12 +249,14 @@ int count; try { + ClassLoader cl; classsrc = (VMAddress)in.readObject(); - if (!MetaVM.load_class_locally && !classsrc.isLocalAddress()) { - ClassLoader cl = RemoteClassLoader.get(classsrc); - in.classLoader(cl); // set class loader - } + if (MetaVM.load_class_locally || classsrc.isLocalAddress()) + cl = MetaVM.systemClassLoader; + else + cl = RemoteClassLoader.get(classsrc); + in.classLoader(cl); // set class loader } catch (ClassNotFoundException e) { // not reached @@ -293,10 +296,11 @@ try { classsrc = (VMAddress)in.readObject(); - if (!MetaVM.load_class_locally && !classsrc.isLocalAddress()) { + if (MetaVM.load_class_locally || classsrc.isLocalAddress()) + cl = MetaVM.systemClassLoader; + else cl = RemoteClassLoader.get(classsrc); - in.classLoader(cl); // set class loader - } + in.classLoader(cl); // set class loader } catch (ClassNotFoundException e) { // not reached @@ -347,10 +351,11 @@ try { classsrc = (VMAddress)in.readObject(); - if (!MetaVM.load_class_locally && !classsrc.isLocalAddress()) { + if (MetaVM.load_class_locally || classsrc.isLocalAddress()) + cl = MetaVM.systemClassLoader; + else cl = RemoteClassLoader.get(classsrc); - in.classLoader(cl); // set class loader - } + in.classLoader(cl); // set class loader } catch (ClassNotFoundException e) { // not reached @@ -727,7 +732,8 @@ val = in.readInt(); if (debug) { boolean orig = MetaVM.remoteTransparency(false); - System.out.println("index, val: " + index + ", " + val); + System.out.println("index, val: " + index + ", " + val + + ", " + Float.intBitsToFloat(val)); MetaVM.remoteTransparency(orig); } @@ -780,7 +786,8 @@ val = in.readLong(); if (debug) { boolean orig = MetaVM.remoteTransparency(false); - System.out.println("index, val: " + index + ", " + val); + System.out.println("index, val: " + index + ", " + val + + ", " + Double.longBitsToDouble(val)); MetaVM.remoteTransparency(orig); } @@ -849,21 +856,22 @@ if (debug) System.out.println("INVOKE"); { - String sig = null; + int mbindex = 0; Object[] args = null; Object result; + boolean proxyArgs = false; + // receive slot no. of the callee slot = (int)in.readUnsignedShort(); + if (slot == 0) mbindex = (int)in.readUnsignedShort(); + if (debug) { boolean orig = MetaVM.remoteTransparency(false); System.out.println("slot: " + slot); MetaVM.remoteTransparency(orig); } - if (slot == 0) { // caller is a constructor - sig = in.readUTF(); - } - + // receive arguments try { ArrayOfObjectWrapper args_wrapper = (ArrayOfObjectWrapper)in.readDistObject(); @@ -876,8 +884,26 @@ MetaVM.remoteTransparency(orig); } +/* + if (VMOperations.isNativeMethod(this.clz, slot, mbindex) && + args != null) { + // check if there are args which is Proxy class + boolean orig = MetaVM.remoteTransparency(false); + for (int i = 0; i < args.length; i++) { + if (args[i] instanceof Proxy) { + System.err.println( + "[MetaVM: (at Skeleton) Remote refs passed to the native method: " + + this.clz.getName() + "#" + + VMOperations.MethodName(this.clz, slot, mbindex) + + ", slot: " + slot + ", arg#: " + i + "]"); + } + } + MetaVM.remoteTransparency(orig); + } +*/ + try { - result = VMOperations.invoke(this.obj, slot, sig, args); + result = VMOperations.invoke(this.obj, slot, mbindex, args); out.writeByte(Protocol.OK); out.writeDistObject(result); diff -aruN shujit-0.6.7/NET/shudo/metavm/VMOperations.java shujit/NET/shudo/metavm/VMOperations.java --- shujit-0.6.7/NET/shudo/metavm/VMOperations.java Tue Sep 12 19:49:45 2000 +++ shujit/NET/shudo/metavm/VMOperations.java Sun Oct 8 01:13:26 2000 @@ -40,14 +40,22 @@ public static native void put64Field(Object obj, int slot, long val); public static native void putObjectField(Object obj, int slot, Object val); - public static native Object invoke(Object obj, + public static native Object invoke(Object receiver, String name, String sig, Object[] args) throws Throwable; - public static native Object invoke(Object obj, - int slot, String sig/* for constructor */, Object[] args) + public static native Object invoke(Object receiver, + int slot, int mbindex, Object[] args) throws Throwable; public static native void monitorEnter(Object obj); public static native void monitorExit(Object obj); + + + public static native boolean isNativeMethod(Class clazz, + int slot, int mbindex); + public static native String MethodName(Class clazz, + int slot, int mbindex); + public static native String MethodSignature(Class clazz, + int slot, int mbindex); public static native void printStackTrace(); diff -aruN shujit-0.6.7/README shujit/README --- shujit-0.6.7/README Wed Sep 13 19:40:35 2000 +++ shujit/README Tue Nov 14 22:06:38 2000 @@ -1,6 +1,6 @@ shuJIT - JIT compiler for Sun JVM/x86 http://www.shudo.net/jit/ - SHUDO Kazuyuki + Kazuyuki Shudo * What this is @@ -13,12 +13,16 @@ 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-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 + - Blackdown JDK 1.2.2 FCS, pgcc 2.95.3, glibc 2.1.95 + and Linux 2.4.0-test11-pre3 + - JDK 1.1.8v1, pgcc 2.95.3, glibc 2.1.95 and Linux 2.4.0-test11-pre3 + - JDK 1.1.7v1a, egcs 1.1.2, libc 5.4.38 and Linux 2.0.35 - FreeBSD - - JDK 1.1.8 (ELF, V1999-11-9), gcc 2.95.2, FreeBSD 3.3R + - JDK 1.2.2 patch10, gcc 2.95.2 and FreeBSD 5.0-CURRENT + - JDK 1.1.8 (ELF, V1999-11-9), gcc 2.95.2 and FreeBSD 5.0-CURRENT + - JDK 1.1.8 (ELF, V1999-11-9), gcc 2.95.2 and FreeBSD 4.4.1R + - JDK 1.1.8 (ELF, V1999-11-9), gcc 2.95.2 and FreeBSD 3.3R * Installation @@ -44,28 +48,28 @@ * Compilation -You need some tools to compile this JIT. +You need the following tools to compile this JIT. - JDK 1.1.X or 1.2.X - This JIT can work with JDK Sun's classic VM. - For example, Linux JDK by Blackdown and Sun/Inprise, - and FreeBSD JDK are supported, but IBM JDK is not. -- gcc 2.95.X or EGCS - You can examine version of your `gcc' command with -v option. - % gcc -v - Currently, gcc 2.7.X will be not able to compile shuJIT. + shuJIT can work with Sun's classic VM included in JDK. + Other JVMs such as IBM JDK and HotSpot VM are not supported. +- gcc 2.95.2 or EGCS + You can examine the version number of your GCC with -v option. + % gcc -v + gcc 2.96, which is a snapshot for developers, and gcc 2.7.X + causes problems. You cannot use them to compile shuJIT. - objdump (in GNU binutils) Most Linux distributions and ELF FreeBSD systems have it. - Ruby A script which generate some tables was written in Ruby. - http://www.ruby-lang.org/ + See http://www.ruby-lang.org/ - GNU make 1. Run configure script. % ./configure 2. Type `make'. You will get libshujit.so % make - Instead of above, on FreeBSD type to use GNU make. + Or, on FreeBSD systems % gmake * Bugs and Problems @@ -75,7 +79,7 @@ * Copying This program is free software which is copyrighted by -Kazuyuki SHUDO. You may redistribute and modify it under +Kazuyuki Shudo. You may redistribute and modify it under the terms of GNU General Public License; either version 2 of the License, or any later version. See GPL.txt for more details. @@ -91,6 +95,7 @@ MIURA Toshitaka (preparation of FreeBSD) KATO Jun'ya (preparation of FreeBSD) MARUYAMA Fuyuhiko (discussion and code) +SHIMOKAWA Toshihiko (preparetion of FreeBSD) and my wife Mari. diff -aruN shujit-0.6.7/acconfig.h shujit/acconfig.h --- shujit-0.6.7/acconfig.h Sat May 22 20:17:52 1999 +++ shujit/acconfig.h Thu Jan 1 09:00:00 1970 @@ -1,23 +0,0 @@ -/* Version number of JDK */ -#undef JDK_VER - -/* defined if version of gcc is 2.X (X <= 7) */ -#undef GCC27 - -/* defined if the libc is glibc2 (libc6) */ -#undef GLIBC2 - -/* type of signal context */ -#undef SIGCONTEXT - -/* type of an argument of monitor{Enter,Exit}{,2} */ -#undef MONITOR_T - -/* defined if the code DB function is enabled */ -#undef CODE_DB -/* defined if DB library for code DB is gdbm */ -#undef GDBM - -/* defined if shuJIT is built to support MetaVM */ -#undef METAVM -#undef METAVM_NO_ARRAY diff -aruN shujit-0.6.7/code.c shujit/code.c --- shujit-0.6.7/code.c Tue Sep 19 19:58:31 2000 +++ shujit/code.c Sun Oct 8 02:08:44 2000 @@ -165,11 +165,25 @@ FFLUSH;\ DEBUG_OUT;\ } +# define VALUE64_DEBUG(LREG, HREG) \ + if (runtime_debug) {\ + DEBUG_IN;\ + asm("pushl " #HREG "\n\tpushl " #LREG "\n\t"\ + "fldl (%esp)\n\tfstpl (%esp)\n\t"\ + "pushl " #HREG "\n\tpushl " #LREG "\n\t"\ + "pushl " #HREG "\n\tpushl " #LREG);\ + PUSH_CONSTSTR(" 0x%016llx %lld %g\n");\ + asm("call " SYMBOL(printf) "@PLT\n\t"\ + "addl $28,%esp");\ + FFLUSH;\ + DEBUG_OUT;\ + } #else # define CLAZZ_DEBUG(CB) # define METHOD_DEBUG(MB, LABEL) # define OBJ_DEBUG(OBJ) # define VALUE_DEBUG(REG) +# define VALUE64_DEBUG(LREG, HREG) #endif @@ -565,6 +579,24 @@ } +#ifdef METAVM + CODE(opc_metavm_init, metavm_init, STANY, STSTA, OPC_NONE) { + asm("movl %0,%%edi" : : "m" (ee)); +# ifdef RUNTIME_DEBUG + DEBUG_IN; + asm("pushl %edi"); + PUSH_CONSTSTR(" ee: 0x%x\n"); + asm("call " SYMBOL(printf) "@PLT\n\t" + "addl $8,%esp"); + FFLUSH; + DEBUG_OUT; +# endif + asm("movl $0," EE_REMOTE_ADDR(%edi) "\n\t" + "movb $1," EE_REMOTE_FLAG(%edi)); + } +#endif // METAVM + + CODE(opc_strict_enter, strict_enter, STANY, STSTA, OPC_NONE) { #ifdef STRICT_PRELOAD // push scales into FPU register @@ -871,54 +903,36 @@ // ldc2_w // const: val[32:63], val[0:31] -#ifdef RUNTIME_DEBUG -# define LDC2_W_DEBUG1(OPTOP1_REG, OPTOP2_REG) \ - if (runtime_debug) {\ - DEBUG_IN;\ - asm("pushl " #OPTOP2_REG "\n\tpushl " #OPTOP1_REG "\n\t"\ - "fldl (%esp)\n\tfstpl (%esp)\n\t"\ - "pushl " #OPTOP2_REG "\n\tpushl " #OPTOP1_REG "\n\t"\ - "pushl " #OPTOP2_REG "\n\tpushl " #OPTOP1_REG);\ - PUSH_CONSTSTR(" 0x%016llx %lld %g\n");\ - asm("call " SYMBOL(printf) "@PLT\n\t"\ - "addl $28,%esp");\ - FFLUSH;\ - DEBUG_OUT;\ - } -#else -# define LDC2_W_DEBUG1(OPTOP1_REG, OPTOP2_REG) -#endif - CODE(opc_ldc2_w, ldc2_w, ST0, ST2, OPC_NONE) { asm("movl $" STR(CONST) ",%edx\n\t" "movl $" STR(CONST) ",%ecx"); - LDC2_W_DEBUG1(%ecx, %edx); + VALUE64_DEBUG(%ecx, %edx); } CODE(opc_ldc2_w, ldc2_w, ST1, ST4, OPC_NONE) { asm("pushl %edx\n\t" "movl $" STR(CONST) ",%ecx\n\t" "movl $" STR(CONST) ",%edx"); - LDC2_W_DEBUG1(%edx, %ecx); + VALUE64_DEBUG(%edx, %ecx); } CODE(opc_ldc2_w, ldc2_w, ST2, ST2, OPC_NONE) { asm("pushl %edx\n\t" "pushl %ecx\n\t" "movl $" STR(CONST) ",%edx\n\t" "movl $" STR(CONST) ",%ecx"); - LDC2_W_DEBUG1(%ecx, %edx); + VALUE64_DEBUG(%ecx, %edx); } CODE(opc_ldc2_w, ldc2_w, ST3, ST2, OPC_NONE) { asm("pushl %ecx\n\t" "movl $" STR(CONST) ",%edx\n\t" "movl $" STR(CONST) ",%ecx"); - LDC2_W_DEBUG1(%ecx, %edx); + VALUE64_DEBUG(%ecx, %edx); } CODE(opc_ldc2_w, ldc2_w, ST4, ST4, OPC_NONE) { asm("pushl %ecx\n\t" "pushl %edx\n\t" "movl $" STR(CONST) ",%ecx\n\t" "movl $" STR(CONST) ",%edx"); - LDC2_W_DEBUG1(%edx, %ecx); + VALUE64_DEBUG(%edx, %ecx); } @@ -1239,12 +1253,10 @@ // laload // compile: fill_cache, array_check, laload #ifdef METAVM -# define METAVM_READ2(HANDLE, SLOT, TGT_LOW, TGT_HIGH, LABEL, STATE, FUNC) \ +# define METAVM_READ2(HANDLE, SLOT, TGT_LOW, TGT_HIGH, LABEL, FUNC) \ JUMP_IF_NOT_PROXY(HANDLE, LABEL "_local");\ JUMP_IF_NOT_REMOTE(LABEL "_local");\ \ - FUNCCALL_IN(STATE);\ - \ asm("pushl " #SLOT "\n\t" /* slot */\ "pushl " #HANDLE); /* obj (Proxy) */\ asm("pushl %0" : : "m" (ee)); /* ee */\ @@ -1255,8 +1267,6 @@ "movl %eax," #TGT_LOW "\n\t"\ "addl $8,%esp");\ \ - FUNCCALL_OUT(STATE);\ - \ JUMP_IF_EXC_HASNT_OCCURRED(%edi /* is ee */, LABEL "_done");\ DEBUG_IN;\ PUSH_CONSTSTR("METAVM_READ2 exc. occurred.\n");\ @@ -1267,49 +1277,49 @@ SIGNAL_ERROR_JUMP();\ \ asm(LABEL "_local:") -# define METAVM_GETFIELD2(HANDLE, SLOT, TGT_LOW, TGT_HIGH, LABEL, STATE) \ - METAVM_READ2(HANDLE, SLOT, TGT_LOW, TGT_HIGH, LABEL, STATE, proxy_get64field) +# define METAVM_GETFIELD2(HANDLE, SLOT, TGT_LOW, TGT_HIGH, LABEL) \ + METAVM_READ2(HANDLE, SLOT, TGT_LOW, TGT_HIGH, LABEL, proxy_get64field) #else -# define METAVM_GETFIELD2(HANDLE, SLOT, TGT_LOW, TGT_HIGH, LABEL, STATE) +# define METAVM_GETFIELD2(HANDLE, SLOT, TGT_LOW, TGT_HIGH, LABEL) #endif // METAVM #if defined(METAVM) && !defined(METAVM_NO_ARRAY) -# define METAVM_ALOAD2(HANDLE, SLOT, TGT_LOW, TGT_HIGH, LABEL, STATE) \ - METAVM_READ2(HANDLE, SLOT, TGT_LOW, TGT_HIGH, LABEL, STATE, proxy_aload64) +# define METAVM_ALOAD2(HANDLE, SLOT, TGT_LOW, TGT_HIGH, LABEL) \ + METAVM_READ2(HANDLE, SLOT, TGT_LOW, TGT_HIGH, LABEL, proxy_aload64) #else -# define METAVM_ALOAD2(HANDLE, SLOT, TGT_LOW, TGT_HIGH, LABEL, STATE) +# define METAVM_ALOAD2(HANDLE, SLOT, TGT_LOW, TGT_HIGH, LABEL) #endif // METAVM_NO_ARRAY CODE(opc_laload, [ld]aload, ST2, ST4, OPC_THROW) { - METAVM_ALOAD2(%edx, %ecx, %edx, %ecx, "laload_st2", 2); + METAVM_ALOAD2(%edx, %ecx, %edx, %ecx, "laload_st2"); UNHAND(%edx, %eax); asm("leal (%eax,%ecx,8),%edi\n\t" "movl (%edi),%edx\n\t" "movl 4(%edi),%ecx"); asm("laload_st2_done:"); - LDC2_W_DEBUG1(%edx, %ecx); + VALUE64_DEBUG(%edx, %ecx); } CODE(opc_laload, [ld]aload, ST4, ST2, OPC_THROW) { - METAVM_ALOAD2(%ecx, %edx, %ecx, %edx, "laload_st4", 4); + METAVM_ALOAD2(%ecx, %edx, %ecx, %edx, "laload_st4"); UNHAND(%ecx, %eax); asm("leal (%eax,%edx,8),%edi\n\t" "movl (%edi),%ecx\n\t" "movl 4(%edi),%edx"); asm("laload_st4_done:"); - LDC2_W_DEBUG1(%ecx, %edx); + VALUE64_DEBUG(%ecx, %edx); } #ifdef OPTIMIZE_INTERNAL_CODE CODE(opc_daload_dld, [ld]aload, ST2, ST2, OPC_THROW) { - METAVM_ALOAD2(%edx, %ecx, %edx, %ecx, "daload_dld_st2", 2); + METAVM_ALOAD2(%edx, %ecx, %edx, %ecx, "daload_dld_st2"); UNHAND(%edx, %eax); asm("fldl (%eax,%ecx,8)"); // omit asm("subl $8,%esp"); asm("daload_dld_st2_done:"); } CODE(opc_daload_dld, [ld]aload, ST4, ST2, OPC_THROW) { - METAVM_ALOAD2(%ecx, %edx, %ecx, %edx, "daload_dld_st4", 4); + METAVM_ALOAD2(%ecx, %edx, %ecx, %edx, "daload_dld_st4"); UNHAND(%ecx, %eax); asm("fldl (%eax,%edx,8)"); // omit asm("subl $8,%esp"); @@ -1665,7 +1675,7 @@ "movl " #OPTOP1_REG ",(%edi)\n\t"\ "movl " #OPTOP2_REG ",4(%edi)");\ asm("lastore_st" #STATE "_done:");\ - LDC2_W_DEBUG1(OPTOP1_REG, OPTOP2_REG);\ + VALUE64_DEBUG(OPTOP1_REG, OPTOP2_REG);\ } CODE_LASTORE(%ecx, %edx, 2); @@ -2622,7 +2632,7 @@ asm("negl " #OPTOP1_REG "\n\t"\ "adcl $0," #OPTOP2_REG "\n\t"\ "negl " #OPTOP2_REG);\ - LDC2_W_DEBUG1(OPTOP1_REG, OPTOP2_REG) + VALUE64_DEBUG(OPTOP1_REG, OPTOP2_REG) // now state [24] CODE(opc_lneg, lneg, ST0, ST2, OPC_NONE) { @@ -2754,32 +2764,32 @@ "popl %eax\n\t" /* eax = [0:31] */\ "popl %edx"); /* edx = [32:63] */\ SHIFT_##SIGNEDP##_LONG(ROP64, ROP32, REG_A, REG_B, #VOP "_st0");\ - LDC2_W_DEBUG1(%ecx, %edx);\ + VALUE64_DEBUG(%ecx, %edx);\ }\ CODE(opc_l##VOP, l##VOP, ST1, ST2, OPC_NONE) {\ asm("movl %edx,%ecx\n\t" /* ecx = shift count (%edx) */\ "popl %eax\n\t" /* eax = [0:31] */\ "popl %edx"); /* edx = [32:63] */\ SHIFT_##SIGNEDP##_LONG(ROP64, ROP32, REG_A, REG_B, #VOP "_st1");\ - LDC2_W_DEBUG1(%ecx, %edx);\ + VALUE64_DEBUG(%ecx, %edx);\ }\ CODE(opc_l##VOP, l##VOP, ST2, ST4, OPC_NONE) {\ asm("popl %eax"); /* eax = [32:63] */\ SHIFT_##SIGNEDP##_LONG(ROP64, ROP32, REG_B, REG_A, #VOP "_st2");\ - LDC2_W_DEBUG1(%edx, %ecx);\ + VALUE64_DEBUG(%edx, %ecx);\ }\ CODE(opc_l##VOP, l##VOP, ST3, ST2, OPC_NONE) {\ asm("popl %eax\n\t" /* eax = [0:31] */\ "popl %edx"); /* edx = [32:63] */\ SHIFT_##SIGNEDP##_LONG(ROP64, ROP32, REG_A, REG_B, #VOP "_st3");\ - LDC2_W_DEBUG1(%ecx, %edx);\ + VALUE64_DEBUG(%ecx, %edx);\ }\ CODE(opc_l##VOP, l##VOP, ST4, ST2, OPC_NONE) {\ asm("movl %ecx,%eax\n\t" /* eax = [0:31] (ecx) */\ "movl %edx,%ecx\n\t" /* ecx = shift count (edx) */\ "popl %edx"); /* edx = [32:63] */\ SHIFT_##SIGNEDP##_LONG(ROP64, ROP32, REG_A, REG_B, #VOP "_st4");\ - LDC2_W_DEBUG1(%ecx, %edx);\ + VALUE64_DEBUG(%ecx, %edx);\ } CODE_SHIFT_LONG(UNSIGNED, shl, shld, shl, %eax, %edx); @@ -3765,14 +3775,14 @@ CODE(opc_getfield2, getfield2, ST0, ST2, OPC_SIGNAL) { asm("popl %edx"); // now state 1 FIELD_ACC(%edx, getfield2, 0); - METAVM_GETFIELD2(%edx, %eax, %ecx, %edx, "getfield2_st0", 1); + METAVM_GETFIELD2(%edx, %eax, %ecx, %edx, "getfield2_st0"); OBJ_GETSLOT2(%edx, %eax, %ecx, %edx); asm("getfield2_st0_done:"); LLOAD_DEBUG1(%ecx, %edx); } CODE(opc_getfield2, getfield2, ST1, ST2, OPC_SIGNAL) { FIELD_ACC(%edx, getfield2, 1); - METAVM_GETFIELD2(%edx, %eax, %ecx, %edx, "getfield2_st1", 2); + METAVM_GETFIELD2(%edx, %eax, %ecx, %edx, "getfield2_st1"); OBJ_GETSLOT2(%edx, %eax, %ecx, %edx); asm("getfield2_st1_done:"); LLOAD_DEBUG1(%ecx, %edx); @@ -3780,14 +3790,14 @@ CODE(opc_getfield2, getfield2, ST2, ST4, OPC_SIGNAL) { asm("pushl %edx"); // now state 3 FIELD_ACC(%ecx, getfield2, 2); - METAVM_GETFIELD2(%ecx, %eax, %edx, %ecx, "getfield2_st2", 2); + METAVM_GETFIELD2(%ecx, %eax, %edx, %ecx, "getfield2_st2"); OBJ_GETSLOT2(%ecx, %eax, %edx, %ecx); asm("getfield2_st2_done:"); LLOAD_DEBUG1(%edx, %ecx); } CODE(opc_getfield2, getfield2, ST3, ST4, OPC_SIGNAL) { FIELD_ACC(%ecx, getfield2, 3); - METAVM_GETFIELD2(%ecx, %eax, %edx, %ecx, "getfield2_st3", 3); + METAVM_GETFIELD2(%ecx, %eax, %edx, %ecx, "getfield2_st3"); OBJ_GETSLOT2(%ecx, %eax, %edx, %ecx); asm("getfield2_st3_done:"); LLOAD_DEBUG1(%edx, %ecx); @@ -3795,7 +3805,7 @@ CODE(opc_getfield2, getfield2, ST4, ST2, OPC_SIGNAL) { asm("pushl %ecx"); // now state 1 FIELD_ACC(%edx, getfield2, 4); - METAVM_GETFIELD2(%edx, %eax, %ecx, %edx, "getfield2_st4", 4); + METAVM_GETFIELD2(%edx, %eax, %ecx, %edx, "getfield2_st4"); OBJ_GETSLOT2(%edx, %eax, %ecx, %edx); asm("getfield2_st4_done:"); LLOAD_DEBUG1(%ecx, %edx); @@ -3968,7 +3978,7 @@ asm("inv_core_invoke_normal:");\ asm("call " SYMBOL(invocationHelper) "@PLT");\ asm("inv_core_invoke_done:") -#else +#else // DIRECT_INVOCATION # define INVCORE_INVOKE \ /* cur_frame->returnpc = -1 */\ asm("movl $-1," FRAME_RETURNPC(%edi));\ @@ -4015,13 +4025,15 @@ // const: retsize, args_size #define INVOKE_CORE(VOP, CORE_TYPE) \ - CODE(opc_##VOP, VOP, STANY, ST0, OPC_SIGNAL) {\ + CODE_WITHOUT_DEBUG(opc_##VOP, VOP, STANY, ST0, OPC_SIGNAL) {\ /* CAUSE_STACKOVERFLOW needs OPC_SIGNAL */\ asm(".globl " #VOP "\n\t.type " #VOP ",@function");\ asm(#VOP ":");\ \ + CODE_DEBUG(#VOP);\ + \ asm("subl %edi,%esp\n\t"\ - "pushl %edi\n\t" /* save */\ + "pushl %edi\n\t" /* save var. space */\ "leal 4(%esp,%edi),%edi"); /* edi = original esp */\ \ asm("leal -4(%edi,%ecx,4),%edi"); /* base of native stack */\ @@ -4147,13 +4159,11 @@ "popl %eax"); // restore asm("pushl %ecx\n\t" // stack pointer - "pushl " METHOD_SIGNATURE(%eax) "\n\t" // signature - "pushl " METHOD_FB_U_OFFSET(%eax) "\n\t" // index in methodtable "pushl %eax\n\t" // methodblock "pushl %edx"); // obj (Proxy) asm("pushl %0" : : "m" (ee)); // ee asm("call " SYMBOL(proxy_invoke) "@PLT\n\t" - "addl $24,%esp"); + "addl $16,%esp"); asm("popl %ecx"); // restore asm(".byte 0xe9\n\t.long " STR(CONST)); // jump to invoke_core_done @@ -4486,13 +4496,6 @@ 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");\ \ @@ -4760,8 +4763,8 @@ register Hjava_lang_Class *clz asm("edi");\ \ UNHAND(OPTOP1_REG, %edi);\ - clz = edi->clazz;\ - } /* edi = Proxy.clazz */\ + clz = edi->clz;\ + } /* edi = Proxy.clz */\ asm("cmpl %eax,%edi\n\t"\ "jnz " LABEL "_fail\n\t"\ "jmp " LABEL "_done\n\t"\ @@ -4802,19 +4805,30 @@ # define CHECKCAST_DEBUG(HANDLE, CB, LABEL) #endif -#define CHECKCAST(OPTOP1_REG, LABEL, STATE) \ - asm("testl " #OPTOP1_REG "," #OPTOP1_REG "\n\t"\ +#if 0 +#define CHECKCAST(HANDLE, LABEL, STATE) \ + asm("testl " #HANDLE "," #HANDLE "\n\t"\ "jz " LABEL "_done");\ + \ asm("movl $" STR(CONST) ",%eax"); /* cb */\ - METAVM_CHECKCAST(OPTOP1_REG, LABEL, STATE);\ - CHECKCAST_DEBUG(OPTOP1_REG, %eax, LABEL);\ + METAVM_CHECKCAST(HANDLE, LABEL, STATE);\ + CHECKCAST_DEBUG(HANDLE, %eax, LABEL);\ + \ + OBJ_METHODTABLE(HANDLE, %edi);\ + asm("testl $0x1f,%edi\n\t"\ + "jnz " LABEL "_call");\ + MT_CLASSDESCRIPTOR(%edi, %edi);\ + asm("cmpl %edi,%eax\n\t"\ + "je " LABEL "_done");\ \ + asm(LABEL "_call:");\ FUNCCALL_IN(STATE);\ asm("pushl %0" : : "m" (ee)); /* ee */\ asm("pushl %eax\n\t" /* cb */\ - "pushl " #OPTOP1_REG "\n\t"\ + "pushl " #HANDLE "\n\t"\ "call " SYMBOL(is_instance_of) "@PLT\n\t"\ - "addl $12,%esp");\ + "popl " #HANDLE "\n\t"\ + "addl $8,%esp");\ FUNCCALL_OUT(STATE);\ \ asm("testl %eax,%eax\n\t"\ @@ -4822,22 +4836,46 @@ LABEL "_fail:");\ SIGNAL_ERROR0(EXCID_ClassCastException);\ asm(LABEL "_done:") +#else +#define CHECKCAST(HANDLE, LABEL, STATE) \ + asm("testl " #HANDLE "," #HANDLE "\n\t"\ + "jz " LABEL "_done");\ + \ + asm("movl $" STR(CONST) ",%eax"); /* cb */\ + METAVM_CHECKCAST(HANDLE, LABEL, STATE);\ + CHECKCAST_DEBUG(HANDLE, %eax, LABEL);\ + \ + FUNCCALL_IN(STATE);\ + asm("pushl %0" : : "m" (ee)); /* ee */\ + asm("pushl %eax\n\t" /* cb */\ + "pushl " #HANDLE "\n\t"\ + "call " SYMBOL(is_instance_of) "@PLT\n\t"\ + "popl " #HANDLE "\n\t"\ + "addl $8,%esp");\ + FUNCCALL_OUT(STATE);\ + \ + asm("testl %eax,%eax\n\t"\ + "jnz " LABEL "_done\n\t"\ + LABEL "_fail:");\ + SIGNAL_ERROR0(EXCID_ClassCastException);\ + asm(LABEL "_done:") +#endif CODE(opc_checkcast, checkcast, ST0, ST1, OPC_THROW) { asm("popl %edx"); // now state 1 - CHECKCAST(%edx, "checkcast_st0", 1); + CHECKCAST(%edx, "checkcast_st0", 0); } CODE(opc_checkcast, checkcast, ST1, ST1, OPC_THROW) { - CHECKCAST(%edx, "checkcast_st1", 1); + CHECKCAST(%edx, "checkcast_st1", 0); } CODE(opc_checkcast, checkcast, ST2, ST2, OPC_THROW) { - CHECKCAST(%ecx, "checkcast_st2", 2); + CHECKCAST(%ecx, "checkcast_st2", 1); } CODE(opc_checkcast, checkcast, ST3, ST3, OPC_THROW) { - CHECKCAST(%ecx, "checkcast_st3", 3); + CHECKCAST(%ecx, "checkcast_st3", 0); } CODE(opc_checkcast, checkcast, ST4, ST4, OPC_THROW) { - CHECKCAST(%edx, "checkcast_st4", 4); + CHECKCAST(%edx, "checkcast_st4", 3); } @@ -4861,8 +4899,8 @@ register Hjava_lang_Class *clz asm("edi");\ \ UNHAND(OPTOP1_REG, %edi);\ - clz = edi->clazz;\ - } /* edi = Proxy.clazz */\ + clz = edi->clz;\ + } /* edi = Proxy.clz */\ asm("cmpl %eax,%edi\n\t"\ "jz " LABEL "_false\n\t"\ LABEL "_true:"\ @@ -4879,6 +4917,7 @@ #define INSTANCEOF(OPTOP1_REG, LABEL, STATE) \ asm("testl " #OPTOP1_REG "," #OPTOP1_REG "\n\t"\ "jz " LABEL "_done");\ + \ asm("movl $" STR(CONST) ",%eax"); /* cb */\ METAVM_INSTANCEOF(OPTOP1_REG, LABEL, STATE);\ CHECKCAST_DEBUG(OPTOP1_REG, %eax, LABEL);\ @@ -4888,25 +4927,25 @@ "pushl " #OPTOP1_REG "\n\t"\ "call " SYMBOL(is_instance_of) "@PLT\n\t"\ "addl $12,%esp");\ + asm("movl %eax," #OPTOP1_REG);\ FUNCCALL_OUT(STATE);\ - asm("movl %eax," #OPTOP1_REG "\n\t"\ - LABEL "_done:") + asm(LABEL "_done:") CODE(opc_instanceof, instanceof, ST0, ST1, OPC_NONE) { asm("popl %edx"); // now state 1 - INSTANCEOF(%edx, "instanceof_st0", 1); + INSTANCEOF(%edx, "instanceof_st0", 0); } CODE(opc_instanceof, instanceof, ST1, ST1, OPC_NONE) { - INSTANCEOF(%edx, "instanceof_st1", 1); + INSTANCEOF(%edx, "instanceof_st1", 0); } CODE(opc_instanceof, instanceof, ST2, ST2, OPC_NONE) { - INSTANCEOF(%ecx, "instanceof_st2", 2); + INSTANCEOF(%ecx, "instanceof_st2", 1); } CODE(opc_instanceof, instanceof, ST3, ST3, OPC_NONE) { - INSTANCEOF(%ecx, "instanceof_st3", 3); + INSTANCEOF(%ecx, "instanceof_st3", 0); } CODE(opc_instanceof, instanceof, ST4, ST4, OPC_NONE) { - INSTANCEOF(%edx, "instanceof_st4", 4); + INSTANCEOF(%edx, "instanceof_st4", 3); } diff -aruN shujit-0.6.7/code.h shujit/code.h --- shujit-0.6.7/code.h Mon Sep 18 18:38:46 2000 +++ shujit/code.h Wed Oct 4 19:26:32 2000 @@ -112,7 +112,7 @@ asm("movl stdout@GOT(%ebx),%eax\n\t"\ "pushl (%eax)"); # endif // __GLIBC__ -#elif defined(__FreeBSD__) +#elif defined(__FreeBSD__) || defined(__NetBSD__) # define PUSH_STDOUT \ asm("movl " SYMBOL(__sF) "@GOT(%ebx),%eax\n\t"\ "leal 88(%eax),%eax\n\t"\ @@ -207,6 +207,7 @@ CODE_WITHOUT_DEBUG(OPCODE, LABEL, STATE, NEXTST, THROW_EXC) #endif +#ifdef RUNTIME_DEBUG # define CODE_DEBUG(LABEL) \ asm("pushl %eax\n\t"\ "leal 4(%esp),%eax");\ @@ -220,6 +221,9 @@ }\ DEBUG_OUT;\ asm("popl %eax") +#else +# define CODE_DEBUG(LABEL) +#endif // RUNTIME_DEBUG #define CODE_WITH_DEBUG(OPCODE, LABEL, STATE, NEXTST, THROW_EXC) \ _CODE_WITH_DEBUG(OPCODE, LABEL, STATE, NEXTST, THROW_EXC) @@ -388,13 +392,13 @@ #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_ADDR(EE) "120(" #EE ")" + // ee->RESERVED3 +#endif +#else // JDK_VER #define EE_REMOTE_FLAG(EE) "61(" #EE ")" // ee->alloc_cache.cache_pad[0] #define EE_REMOTE_ADDR(EE) "16(" #EE ")" diff -aruN shujit-0.6.7/compile.c shujit/compile.c --- shujit-0.6.7/compile.c Tue Sep 19 18:49:11 2000 +++ shujit/compile.c Tue Oct 10 23:44:22 2000 @@ -23,7 +23,7 @@ #include // for memcpy(), strlen() #include // for malloc() -#ifdef __FreeBSD__ +#if defined(__FreeBSD__) || defined(__NetBSD__) # include // for a type u_long #endif #include // for ntohl(), htonl() @@ -147,8 +147,9 @@ printf("\n"); # ifdef METAVM - printf(" excKind: %d\n", cc->ee->exceptionKind); + printf(" remote flag: 0x%x (%x)\n", GET_REMOTE_FLAG(cc->ee) & 0xff, EE()); printf(" remote addr: 0x%x\n", REMOTE_ADDR(cc->ee)); + printf(" excKind: %d\n", cc->ee->exceptionKind); # endif fflush(stdout); @@ -424,6 +425,14 @@ makepctable_start: processAnOpcode(cc, opc_methodhead, -1); + if (!strcmp(cbName(fieldclass(&mb->fb)), JAVAPKG "Thread") && + !strcmp(mb->fb.name, "run")) { +#ifdef COMPILE_DEBUG + printf("generate `metavm_init' for Thread#run.\n"); fflush(stdout); +#endif + processAnOpcode(cc, opc_metavm_init, -1); + } + if (((mb->fb.access & ACC_STRICT) && !OPT_SETQ(OPT_IGNSTRICTFP)) || OPT_SETQ(OPT_FRCSTRICTFP)) { #ifndef FORCE_DOUBLE_PRECISION @@ -1113,7 +1122,6 @@ */ static int processAnOpcode(CompilerContext *cc, int opcode, int byteoff) { 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; @@ -1343,6 +1351,7 @@ if (obj_classblock(exc) == classJavaLangNoClassDefFoundError) {\ exceptionClear(cc->ee);\ code_opcode = opc_throw_noclassdef;\ + byteinc = 3; /* opcode_length[{get,put}static] */\ break;\ }\ return -1;\ @@ -1388,6 +1397,7 @@ sysAssert(exc != NULL);\ if (obj_classblock(exc) == classJavaLangNoClassDefFoundError) {\ exceptionClear(cc->ee);\ + byteinc = 3; /* opcode_length[{get,put}field] */\ code_opcode = opc_throw_noclassdef;\ break;\ }\ @@ -1485,6 +1495,7 @@ #endif // COMPILE_DEBUG if (obj_classblock(exc) == classJavaLangNoClassDefFoundError) { exceptionClear(cc->ee); + byteinc = 3; // opcode_length[{new,new_quick,anewarray}] code_opcode = opc_throw_noclassdef; break; } @@ -1528,6 +1539,28 @@ case opc_instanceof_quick: code_opcode = opc_instanceof; operand = GET_UINT16(bytepc + 1); + + if (!CONSTANT_POOL_TYPE_TABLE_IS_RESOLVED(type_table, operand)) { + if (!ResolveClassConstantFromClass2(fieldclass(&mb->fb), operand, + cc->ee, 1 << CONSTANT_Class, FALSE)) { + JHandle *exc = cc->ee->exception.exc; + if (obj_classblock(exc) == classJavaLangNoClassDefFoundError) { + exceptionClear(cc->ee); + byteinc = 3; // opcode_length[instanceof] + code_opcode = opc_throw_noclassdef; + break; + } + } + } + + { + ClassClass *dest_clazz = constant_pool[operand].clazz; + if (dest_clazz == classJavaLangObject) { + // omit + return 3; // opcode_length[opc_checkcast] + } + } + break; case opc_methodtail: @@ -1572,7 +1605,7 @@ } if (opc_is_get || opc_is_put) { - int index; struct fieldblock *fb; + struct fieldblock *fb; struct methodblock *src_mb; int fb_access; ClassClass *fb_class; @@ -1584,6 +1617,7 @@ printf("Illegal field access: methodblock is null.\n"); fflush(stdout); #endif + byteinc = 3; // opcode_length[{get,put}{field,static}] code_opcode = opc_throw_illegalaccess; goto check_access_done; } @@ -1602,6 +1636,7 @@ printf("\tto : %s#%s\n", cbName(fb_class), fb->name); fflush(stdout); #endif + byteinc = 3; code_opcode = opc_throw_illegalaccess; goto check_access_done; } @@ -1614,6 +1649,7 @@ printf("IllegalAccessError: A final field is accessed.\n"); fflush(stdout); #endif + byteinc = 3; code_opcode = opc_throw_illegalaccess; goto check_access_done; } @@ -1648,7 +1684,8 @@ // update bytecode PC - if (opcode <= opc_nonnull_quick) { // an original, not added insn. + if ((byteinc == 0) // byteinc has been not modified. + && (opcode <= opc_nonnull_quick)) { // not internal insn. switch (opcode) { case opc_tableswitch: { @@ -1884,8 +1921,6 @@ { cp_item_type *constant_pool = cbConstantPool(fieldclass(&cc->mb->fb)); - unsigned char *type_table = - constant_pool[CONSTANT_POOL_TYPE_TABLE_INDEX].type; int32_t operand = pctable->operand; struct methodblock *method; CodeInfo *info; @@ -2750,7 +2785,8 @@ # endif // search opc_invoke_core - int j = i, jump_arg = 0; + int j = i + 1; // points to the next instruction of inv_metavm + int jump_arg = 0; while (TRUE) { succ_pctable = cc->pctable + j; succ_opcode = succ_pctable->opcode; @@ -2794,7 +2830,6 @@ 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; @@ -3262,10 +3297,11 @@ #endif memcpy(p, &arg, 4); +#ifdef SHORTEN_JUMP_INSN // rewrite `0xe9 XX XX XX XX' to `0xeb XX' -#if 0 +# if 0 if ((arg >= -132) && (arg <= 124)) // preliminary check -#endif +# endif { char carg; if (*(--p) == 0xe9) { @@ -3277,7 +3313,7 @@ p[4] = p[3] = p[2] = 0x90; // 0x90: nop } } -#if 0 +# if 0 else { arg += 4; carg = (char)arg; @@ -3288,8 +3324,9 @@ *((int32_t *)(p + 2)) = 0x909002eb; // 0x90: nop } } -#endif +# endif } +#endif // SHORTEN_JUMP_INSN jptable++; } @@ -3371,6 +3408,7 @@ #endif memcpy(p, &relative_off, 4); +#ifdef SHORTEN_JUMP_INSN // rewrite `0xe9 XX XX XX XX' to `0xeb XX' { char carg; @@ -3383,6 +3421,7 @@ } } } +#endif // SHORTEN_JUMP_INSN i++; } @@ -3409,6 +3448,7 @@ #endif memcpy(p, &relative_off, 4); +#ifdef SHORTEN_JUMP_INSN // rewrite `0xe9 XX XX XX XX' to `0xeb XX' { char carg; @@ -3421,6 +3461,7 @@ } } } +#endif // SHORTEN_JUMP_INSN } diff -aruN shujit-0.6.7/compiler.c shujit/compiler.c --- shujit-0.6.7/compiler.c Tue Sep 19 02:46:21 2000 +++ shujit/compiler.c Sun Oct 8 02:14:38 2000 @@ -145,12 +145,12 @@ #endif ) { ExecEnv *ee = EE(); - MONITOR_T key; int version; int compilerVersion; #ifdef COMPILE_DEBUG printf("java_lang_Compiler_start() called.\n"); + printf("ee: 0x%x\n", ee); fflush(stdout); #endif @@ -207,6 +207,13 @@ #else version = *(jitinterface->JavaVersion); #endif +#ifdef COMPILE_DEBUG + { + printf("Version num. of class file format: %d.%d\n", + (version >> 16) & 0xff, version & 0xffff); + } +#endif // COMPILE_DEBUG + compilerVersion = version >> 24; if (compilerVersion != COMPILER_VERSION) { @@ -214,16 +221,6 @@ COMPILER_VERSION, compilerVersion); } -#ifdef COMPILE_DEBUG - { - int javaVersion, javaMinorVersion; - javaVersion = (version >> 16) & 0xff; - javaMinorVersion = version & 0xffff; - - printf("Version num. of class file format: %d.%d\n", - javaVersion, javaMinorVersion); - } -#endif // COMPILE_DEBUG // get options @@ -348,10 +345,10 @@ // initialize for (i = nbinclasses, clazzptr = binclasses; --i >= 0; clazzptr++) { #ifdef COMPILE_DEBUG - printf("init. a class in VM: %x,%s\n", *clazzptr, cbName(*clazzptr)); + printf("init: %x %s\n", *clazzptr, cbName(*clazzptr)); fflush(stdout); #endif - initializeClassForJIT(*clazzptr, TRUE); + initializeClassForJIT(*clazzptr, FALSE, TRUE); } if (OPT_SETQ(OPT_CMPLATLOAD)) { @@ -360,7 +357,6 @@ classes = (ClassClass **)sysMalloc(sizeof(ClassClass *) * nbinclasses); memcpy(classes, binclasses, sizeof(ClassClass *) * nbinclasses); - clazzptr = classes; for (i = nbinclasses, clazzptr = classes; --i >= 0; clazzptr++) { #ifdef COMPILE_DEBUG printf("compile a class in VM: %x,%s\n", *clazzptr, cbName(*clazzptr)); @@ -539,6 +535,7 @@ #ifdef METAVM // set remote flag on + REMOTE_ADDR(ee) = NULL; REMOTE_FLAG_ON(ee); #endif // METAVM @@ -553,25 +550,27 @@ /* * Initialize the class at the time one is loaded. */ -void initializeClassForJIT(ClassClass *cb, bool_t initInvoker) { +void initializeClassForJIT(ClassClass *cb, + bool_t linkNative, bool_t initInvoker) { struct methodblock *mb; int mb_count; + ExecEnv *ee = EE(); #ifdef METAVM // force a loaded class to implement java.io.Serializable { - ExecEnv *ee = EE(); JNIEnv *env = EE2JNIEnv(ee); + JNIEnv *env = EE2JNIEnv(ee); static ClassClass *clz_Serializable = NULL; if (!clz_Serializable) { jclass jclz_Ser = (*env)->FindClass(env, "java/io/Serializable"); (*env)->NewGlobalRef(env, jclz_Ser); - clz_Serializable = DeRef(env, jclz_Ser); + clz_Serializable = (ClassClass *)DeRef(env, jclz_Ser); } if (!cbIsInterface(cb) && (cb != classJavaLangObject)) forceToImplement(ee, cb, clz_Serializable); } -#endif +#endif // METAVM mb = cbMethods(cb); mb_count = cbMethodsCount(cb); @@ -582,13 +581,67 @@ // initialize mb->CompiledCodeInfo if (!(mb->CompiledCodeInfo)) - if (!prepareCompiledCodeInfo(EE(), mb)) continue; + if (!prepareCompiledCodeInfo(ee, mb)) { + printf("FATAL: could not create CompiledCodeInfo for %s#%s %s.\n", + cbName(fieldclass(&mb->fb)), mb->fb.name, mb->fb.signature); + JVM_Exit(1); + } // if the class is final, make the method final if (cbAccess(cb) & ACC_FINAL) mb->fb.access |= ACC_FINAL; - if (access & ACC_NATIVE) continue; + if (access & ACC_NATIVE) { +#if defined(METAVM) && (JDK_VER >= 12) + if (linkNative) { + // link native code + void *code; + LINKCLASS_LOCK(EE2SysThread(ee)); + code = mb->code; + LINKCLASS_UNLOCK(EE2SysThread(ee)); + if (code == NULL) { + uint32_t isJNI; + char orig = GET_REMOTE_FLAG(ee); + + REMOTE_FLAG_OFF(ee); + code = dynoLink(mb, &isJNI); // link, which executes Java code + SET_REMOTE_FLAG(ee, orig); + + if (code != NULL) { + LINKCLASS_LOCK(EE2SysThread(ee)); + if (mb->code == NULL) { + mb->code = code; + if (isJNI) { // JNI style + if (mb->fb.access & ACC_SYNCHRONIZED) + mb->invoker = invokeJNISynchronizedNativeMethod; + else { + Invoker inv = getCustomInvoker(methodTerseSig(mb)); + if (inv) mb->invoker = inv; + else mb->invoker = invokeJNINativeMethod; + } + } + else { // old style + mb->invoker = (mb->fb.access & ACC_SYNCHRONIZED) ? + invokeSynchronizedNativeMethod : invokeNativeMethod; + } + } + LINKCLASS_UNLOCK(EE2SysThread(ee)); + } + } + +# ifdef COMPILE_DEBUG + if (mb->code == NULL) { + // fail in linking + // because the native library has not been loaded yet. + printf("could not link now: %s#%s %s\n", + cbName(fieldclass(&mb->fb)), mb->fb.name, mb->fb.signature); + fflush(stdout); + } +# endif + } // if (linkNative) +#endif // METAVM && JDK_VER >= 12 + continue; + } if (!initInvoker) continue; @@ -613,7 +666,7 @@ fflush(stdout); #endif - initializeClassForJIT(cb, TRUE); + initializeClassForJIT(cb, TRUE, TRUE); if (OPT_SETQ(OPT_CMPLATLOAD)) { // have to done after initialization compileClass(cb); diff -aruN shujit-0.6.7/compiler.h shujit/compiler.h --- shujit-0.6.7/compiler.h Tue Sep 19 20:57:53 2000 +++ shujit/compiler.h Tue Nov 14 21:47:34 2000 @@ -83,6 +83,7 @@ #define DIRECT_INVOCATION #define EAGER_COMPILATION #define ELIMINATE_TAIL_RECURSION +#define SHORTEN_JUMP_INSN #define CAUSE_STACKOVERFLOW #define GET_SIGCONTEXT #define NULLEXC_BY_SIGNAL @@ -122,7 +123,7 @@ #if defined(linux) # define SEARCH_SIGCONTEXT -#elif defined(__FreeBSD__) +#elif defined(__FreeBSD__) || defined(__NetBSD__) # undef SEARCH_SIGCONTEXT #else # undef SEARCH_SIGCONTEXT @@ -130,8 +131,8 @@ #if defined(EXC_BY_SIGNAL) || defined(GET_SIGCONTEXT) -# define SIGCONTEXT struct sigcontext # if defined(linux) +# define SIGCONTEXT struct sigcontext # define sigcontext_struct sigcontext // to permute if asm/sigcontext.h defines sigcontext_struct # include // for struct sigcontext @@ -153,8 +154,20 @@ # define SC_SS ss # define SC_TRAPNO trapno # define SC_ERR err -# elif defined(__FreeBSD__) -# include // for struct sigcontext +# elif defined(__FreeBSD__) || defined(__NetBSD__) +# ifdef __FreeBSD__ + // The type of the 3rd arg. of sig. handler depends on JDK ver. +# if __FreeBSD__ >= 4 && JDK_VER < 12 +# define SIGCONTEXT struct osigcontext +# else +# define SIGCONTEXT struct sigcontext +# endif +# include // for sigset_t which sigcontext needs +# include // for struct sigcontext +# else // NetBSD +# define SIGCONTEXT struct sigcontext +# include // for struct sigcontext +# endif # define SC_EAX sc_eax # define SC_ECX sc_ecx # define SC_EDX sc_edx @@ -309,7 +322,7 @@ #define _STR(T) #T #define STR(MACRO) _STR(MACRO) -#if defined(__FreeBSD__) && !defined(__ELF__) +#if (defined(__FreeBSD__) || defined(__NetBSD__)) && !defined(__ELF__) # define SYMBOL(SYM) "_" STR(SYM) #else # define SYMBOL(SYM) STR(SYM) @@ -535,17 +548,18 @@ // Global Functions // // in compiler.c -void initializeClassForJIT(ClassClass *, bool_t initInvoker); +void initializeClassForJIT(ClassClass *, + bool_t linkNative, bool_t initInvoker); // in signal.c #if (defined(EXC_BY_SIGNAL) || defined(GET_SIGCONTEXT)) && defined(SEARCH_SIGCONTEXT) -#ifdef __FreeBSD__ +#if defined(__FreeBSD__) || defined(__NetBSD__) bool_t examineSigcontextNestCount(int sig, int code, struct sigcontext *uc); #else bool_t examineSigcontextNestCount(int sig, void *info, void *uc); #endif #endif // SEARCH_SIGCONTEXT -#ifdef __FreeBSD__ +#if defined(__FreeBSD__) || defined(__NetBSD__) bool_t signalHandler(int sig, int code, struct sigcontext *uc); #else bool_t signalHandler(int sig, void *info, void *uc); @@ -764,7 +778,7 @@ #define CREATE_JAVAFRAME_0(EE, MB, OLD_FRAME, NEW_FRAME,\ - TENTATIVE_FRAME_OFFSET /* Java method: nlocal, Native method: args_size*/,\ + TENTATIVE_FRAME_OFFSET /* Java method: nlocal, Native method: args_size */,\ ARGS_SIZE, NLOCAL)\ {\ JavaStack *stack = OLD_FRAME->javastack;\ diff -aruN shujit-0.6.7/configure shujit/configure --- shujit-0.6.7/configure Wed Aug 9 23:53:37 2000 +++ shujit/configure Tue Sep 26 16:43:47 2000 @@ -1608,7 +1608,7 @@ echo $ac_n "checking version of JDK""... $ac_c" 1>&6 echo "configure:1611: checking version of JDK" >&5 -ac_jver_string=`$ac_java -green -Djava.compiler= -version 2>&1` +ac_jver_string=`$ac_java -Djava.compiler= -version 2>&1` case "$ac_jver_string" in *\"1.1*) ac_jver=11 @@ -1648,7 +1648,7 @@ ac_executejava_in_asm=yes case "$host_os" in freebsd*) - ac_jver_string=`$ac_java -green -Djava.compiler= -fullversion 2>&1` + ac_jver_string=`$ac_java -Djava.compiler= -fullversion 2>&1` ac_jver_string=`echo $ac_jver_string | sed 's+.*:\([0-9]*\)/\([0-9]*\)/.*+\1/\2+'` echo -n "(date: $ac_jver_string) " case "$ac_jver_string" in diff -aruN shujit-0.6.7/configure.in shujit/configure.in --- shujit-0.6.7/configure.in Mon Jul 31 21:25:14 2000 +++ shujit/configure.in Tue Sep 26 16:43:37 2000 @@ -165,7 +165,7 @@ AC_SUBST(ac_javadoc) AC_MSG_CHECKING(version of JDK) -ac_jver_string=`$ac_java -green -Djava.compiler= -version 2>&1` +ac_jver_string=`$ac_java -Djava.compiler= -version 2>&1` case "$ac_jver_string" in *\"1.1*) ac_jver=11 @@ -199,7 +199,7 @@ ac_executejava_in_asm=yes case "$host_os" in freebsd*) - ac_jver_string=`$ac_java -green -Djava.compiler= -fullversion 2>&1` + ac_jver_string=`$ac_java -Djava.compiler= -fullversion 2>&1` changequote(, )dnl ac_jver_string=`echo $ac_jver_string | sed 's+.*:\([0-9]*\)/\([0-9]*\)/.*+\1/\2+'` changequote([, ])dnl diff -aruN shujit-0.6.7/gentable.rb shujit/gentable.rb --- shujit-0.6.7/gentable.rb Mon Sep 18 19:04:42 2000 +++ shujit/gentable.rb Tue Nov 14 21:10:31 2000 @@ -4,7 +4,7 @@ CONST_C_FNAME = 'constants.c' CONST_H_FNAME = 'constants.h' -NOPCODES = 318 +NOPCODES = 319 NSTATES = 5 STANY = 5 STSTA = 5 @@ -201,9 +201,10 @@ else func_table[opcode][init_state] = array end - elsif /(0x606060|60 60 60 00)/ # constant - # must match with `e9 60 60 60 00' (jmp) - # and `... 60 60 6000 ... 0x606060 ...'. + elsif /(0x606060|e9 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.7/invoker.c shujit/invoker.c --- shujit-0.6.7/invoker.c Tue Sep 19 18:27:40 2000 +++ shujit/invoker.c Tue Nov 14 21:26:25 2000 @@ -63,10 +63,9 @@ #ifdef COMPILE_DEBUG printf("\n"); - printf("cmpl&InvMtd: %s#%s %s\n", + printf("cmpl&InvMtd: 0x%x, %s#%s %s\n", mb, cbName(fieldclass(&mb->fb)), mb->fb.name, mb->fb.signature); printf(" sys_th: %x sys_mon_t *: %x\n", (int)sysThreadSelf(), (int)mon); - fflush(stdout); #if 1 if (debugp(mb)) { @@ -290,7 +289,7 @@ if (runtime_debug) { printf("\n"); printf("invokeJITCompiledMethod() called by %x:\n %s#%s %s 0x%x\n", - (int)sysThreadSelf(), + (int)ee, cbName(fieldclass(&mb->fb)), mb->fb.name, mb->fb.signature, (int)mb); if (exceptionOccurred(ee)) { printf(" An exception not handled remains!\n"); @@ -319,64 +318,9 @@ old_frame = ee->current_frame; // creates a new frame -#if 1 - CREATE_JAVAFRAME(ee, mb, old_frame, frame, - args_size, mb->nlocals, mb->maxstack); -#else - { - JavaStack *stack = old_frame->javastack; - stack_item *optop = old_frame->optop; + CREATE_JAVAFRAME(ee, mb, old_frame, frame, args_size, + mb->nlocals, mb->maxstack); - frame = (JavaFrame *)(optop + mb->nlocals); - if (frame->ostack + mb->maxstack >= stack->end_data) - { -# ifdef RUNTIME_DEBUG - if (runtime_debug) { - printf("stack chunk overflow, provide next chunk.\n"); - fflush(stdout); - } -# endif // RUNTIME_DEBUG -# if JDK_VER < 12 - if (stack->next) stack = stack->next; - else { - if (stack->stack_so_far + JAVASTACK_CHUNK_SIZE * sizeof(stack_item) - > JavaStackSize) { - SignalError(ee, JAVAPKG "StackOverflowError", 0); - return FALSE; - } - if (!(stack = CreateNewJavaStack(ee, stack))) { - SignalError(ee, JAVAPKG "OutOfMemoryError", 0); - return FALSE; - } - } - frame = (JavaFrame *)(stack->data + mb->nlocals); - // needless to copy args to a frame on new stack chunk -# else - { - JavaStack *tmp_stack = stack; - JavaFrame *tmp_frame = frame; - stack_item *tmp_optop = optop; - if (!ExpandJavaStack(ee, &tmp_stack, &tmp_frame, &tmp_optop, - args_size, mb->nlocals, mb->maxstack)) - return FALSE; - stack = tmp_stack; - frame = tmp_frame; - optop = tmp_optop; - } -# endif // JDK_VER - } - //frame->constant_pool = cbConstantPool(fieldclass(&mb->fb)); - frame->returnpc = frame->lastpc = mb->code; - // lastpc is not initialized in invoke*JavaMethod() - frame->optop = frame->ostack; - frame->vars = optop; - frame->prev = old_frame; - frame->javastack = stack; - frame->current_method = mb; - - ee->current_frame = frame; - } // create a new frame -#endif // if 1 #ifdef DIRECT_INVOCATION frame->constant_pool = NULL; #endif @@ -551,7 +495,7 @@ if (info->ret_size != 2) { stack_item *optop = old_frame->optop; - printf(" ret val: (%s)", info->ret_sig); + printf(" ret val: 0x%x (%s)", optop[-1].i, info->ret_sig); showObjectBody(info->ret_sig, optop[-1].h); printf("\n"); fflush(stdout); @@ -582,10 +526,12 @@ if (!mb) return 0; -# if 0 - runtime_debug = 1; -# else - if ((!strcmp(cbName(fieldclass(&mb->fb)), "sun/tools/java/Constants")) + if ((!strcmp(cbName(fieldclass(&mb->fb)), "NET/shudo/metavm/Proxy"))) + runtime_debug = 1; + else if ((!strcmp(cbName(fieldclass(&mb->fb)), "NET/shudo/metavm/Skeleton"))) + runtime_debug = 1; +#if 1 + else if ((!strcmp(cbName(fieldclass(&mb->fb)), "sun/tools/java/Constants")) && (!strcmp(mb->fb.name, ""))) runtime_debug = 1; else if ((!strcmp(cbName(fieldclass(&mb->fb)), "java/lang/System")) @@ -594,35 +540,40 @@ else if ((!strcmp(cbName(fieldclass(&mb->fb)), "com/sun/media/protocol/file/DataSource")) && (!strcmp(mb->fb.name, "connect"))) runtime_debug = 1; - else if ((!strcmp(cbName(fieldclass(&mb->fb)), "java/lang/Thread")) - && (!strcmp(mb->fb.name, "init"))) - runtime_debug = 1; else if ((!strcmp(cbName(fieldclass(&mb->fb)), "java/lang/ThreadGroup")) && (!strcmp(mb->fb.name, "uncaughtException"))) runtime_debug = 1; 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)), "java/lang/ClassLoader")) - && (!strcmp(mb->fb.name, "getSystemClassLoader"))) + else if ((!strcmp(cbName(fieldclass(&mb->fb)), "NET/shudo/metavm/DistObjectInputStream")) + && (!strcmp(mb->fb.name, "resolveClass"))) runtime_debug = 1; - else if ((!strcmp(cbName(fieldclass(&mb->fb)), "Overflow")) - && (!strcmp(mb->fb.name, "recurse"))) + else if ((!strcmp(cbName(fieldclass(&mb->fb)), "java/lang/ClassLoader")) + && ( + (!strcmp(mb->fb.name, "getSystemClassLoader")) || + (!strcmp(mb->fb.name, "findNative")) || + (!strcmp(mb->fb.name, "check")) || + (!strcmp(mb->fb.name, "findBootstrapClass0")) + )) runtime_debug = 1; - else if ((!strcmp(cbName(fieldclass(&mb->fb)), "Test")) - && (!strcmp(mb->fb.name, "loop"))) + else if ((!strcmp(cbName(fieldclass(&mb->fb)), "java/lang/StringBuffer")) + && (!strcmp(mb->fb.name, ""))) runtime_debug = 1; - else if (!strcmp(mb->fb.name, "dtoa")) + else if ((!strcmp(cbName(fieldclass(&mb->fb)), "java/lang/String")) + && (!strcmp(mb->fb.name, "getChars"))) runtime_debug = 1; -#if 1 +# if 1 else if (!strcmp(mb->fb.name, "main")) runtime_debug = 1; else if (!strcmp(mb->fb.name, "start")) runtime_debug = 1; else if (!strcmp(mb->fb.name, "run")) runtime_debug = 1; + else if (!strcmp(mb->fb.name, "findNative")) + runtime_debug = 1; +# endif #endif -#endif // 0 or 1 return runtime_debug; diff -aruN shujit-0.6.7/linker.c shujit/linker.c --- shujit-0.6.7/linker.c Tue Sep 12 19:57:38 2000 +++ shujit/linker.c Wed Sep 20 18:25:07 2000 @@ -100,7 +100,7 @@ SEARCH_LIB("java", "", java_handle); SEARCH_LIB(JIT_LIB_NAME, "", jit_handle); -#if defined(__FreeBSD__) && (JDK_VER >= 12) +#if (defined(__FreeBSD__) || defined(__NetBSD__))&& (JDK_VER >= 12) SEARCH_LIB("jvm", "classic/", jvm_handle); #endif } diff -aruN shujit-0.6.7/metavm/byvalue.c shujit/metavm/byvalue.c --- shujit-0.6.7/metavm/byvalue.c Wed Sep 6 12:07:55 2000 +++ shujit/metavm/byvalue.c Sun Oct 8 01:28:21 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 @@ -30,14 +30,11 @@ #define BYVALUEUTIL_CLASSNAME METAVM_PKG "ByValueUtil" -static jclass clz_ByValueUtil = NULL; - - bool_t isByValue(ExecEnv *ee, ClassClass *clazz) { - JNIEnv *env = EE2JNIEnv(ee); - static jmethodID mid_isByValue = NULL; + static ClassClass *cb_ByValueUtil = NULL; + static struct methodblock *mb_isByValue = NULL; - jboolean result; + bool_t result; #ifdef RUNTIME_DEBUG printf("isByValue(0x%08x, 0x%08x) called: ", (int)ee, (int)clazz); fflush(stdout); @@ -45,32 +42,50 @@ fflush(stdout); #endif - if (!mid_isByValue) { - clz_ByValueUtil = (*env)->FindClass(env, BYVALUEUTIL_CLASSNAME); -#if 0 - if (!clz_ByValueUtil) { - /* NOTREACHED */ - printf("FATAL: class \"" BYVALUEUTIL_CLASSNAME "\" is not found.\n"); - } + if (mb_isByValue == NULL) { + int i; + struct methodblock *mb; +#if JDK_VER >= 12 + HashedNameAndType hashed; +#else + unsigned hashed; #endif - clz_ByValueUtil = (*env)->NewGlobalRef(env, clz_ByValueUtil); - mid_isByValue = (*env)->GetStaticMethodID(env, clz_ByValueUtil, - "isByValue", "(Ljava/lang/Class;)Z"); + + cb_ByValueUtil = FindClass(ee, BYVALUEUTIL_CLASSNAME, TRUE); #if 0 - if (!clz_ByValueUtil) { + if (cb_ByValueUtil == NULL) { /* NOTREACHED */ printf("FATAL: class \"" BYVALUEUTIL_CLASSNAME "\" is not found.\n"); } #endif +#if JDK_VER >= 12 + HashNameAndType(ee, "isByValue", "(Ljava/lang/Class;)Z", &hashed); +#else + hashed = NameAndTypeToHash("isByValue", "(Ljava/lang/Class;)Z"); +#endif + for (i = cbMethodsCount(cb_ByValueUtil) - 1; i >= 0; i--) { + mb = &(cbMethods(cb_ByValueUtil)[i]); +#if JDK_VER >= 12 + if (NAMETYPE_MATCH(&hashed, &(mb->fb))) goto mb_found; +#else + if (mb->fb.ID == hashed) goto mb_found; +#endif + } + fprintf(stderr, "FATAL: cannot find isByValue() method.\n"); + JVM_Exit(1); + mb_found: + mb_isByValue = mb; } - result = (*env)->CallStaticBooleanMethod(env, - clz_ByValueUtil, mid_isByValue, - MK_REF_LOCAL(env, (void *)clazz)); + result = (bool_t)do_execute_java_method(ee, cb_ByValueUtil, + "isByValue", "(Ljava/lang/Class;)Z", + mb_isByValue, // struct methodblock * + TRUE, // isStaticCall + clazz); #ifdef RUNTIME_DEBUG printf("isByValue() returns: %s\n", (result?"true":"false")); fflush(stdout); #endif - return (bool_t)result; + return result; } diff -aruN shujit-0.6.7/metavm/controller.c shujit/metavm/controller.c --- shujit-0.6.7/metavm/controller.c Thu Sep 7 22:46:47 2000 +++ shujit/metavm/controller.c Mon Oct 2 22:59:04 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 @@ -91,25 +91,18 @@ } -JNIEXPORT void JNICALL Java_NET_shudo_metavm_MetaVM_instantiationVM0__LNET_shudo_metavm_VMAddress_2 +JNIEXPORT jobject JNICALL Java_NET_shudo_metavm_MetaVM_instantiationVM0__LNET_shudo_metavm_VMAddress_2 (JNIEnv *env, jclass clazz, jobject vmaddr) { ExecEnv *ee = JNIEnv2EE(env); - - REMOTE_ADDR(ee) = (JHandle *)DeRef(env, vmaddr); -} - -JNIEXPORT jobject JNICALL Java_NET_shudo_metavm_MetaVM_instantiationVM0__ - (JNIEnv *env, jclass clazz) { - ExecEnv *ee = JNIEnv2EE(env); JHandle *h; - if (!ee) return NULL; +#ifdef RUNTIME_DEBUG + printf("remote flag: 0x%x (%x)\n", GET_REMOTE_FLAG(ee) & 0xff, ee); + fflush(stdout); +#endif h = REMOTE_ADDR(ee); - REMOTE_ADDR(ee) = NULL; + REMOTE_ADDR(ee) = (vmaddr != NULL) ? (JHandle *)DeRef(env, vmaddr) : NULL; - if (h) - return MK_REF_LOCAL(env, (void *)h); - else - return NULL; + return (h != NULL) ? MK_REF_LOCAL(env, (void *)h) : NULL; } diff -aruN shujit-0.6.7/metavm/metavm.h shujit/metavm/metavm.h --- shujit-0.6.7/metavm/metavm.h Tue Sep 12 14:35:13 2000 +++ shujit/metavm/metavm.h Sun Oct 8 02:08:32 2000 @@ -38,11 +38,15 @@ #if JDK_VER >= 12 # define GET_REMOTE_FLAG(EE) \ - (*(((char *)&(EE)) + 17)) + (*(((char *)(EE)) + 17)) # define SET_REMOTE_FLAG(EE, FLAG) \ - (*(((char *)&(EE)) + 17) = (char)(FLAG)) -# define REMOTE_ADDR(EE) ((JHandle *)(EE)->RESERVED3) + (*(((char *)(EE)) + 17) = (char)(FLAG)) +#if 1 +# define REMOTE_ADDR(EE) ((JHandle *)(EE)->exception.exc) #else +# define REMOTE_ADDR(EE) ((JHandle *)(EE)->RESERVED3) +#endif +#else // JDK_VER # define GET_REMOTE_FLAG(EE) \ ((EE)->alloc_cache.cache_pad[0]) # define SET_REMOTE_FLAG(EE, FLAG) \ @@ -85,7 +89,8 @@ int dim, stack_item *stackpointer); #define DECL_GET_FIELD(NAME, CTYPE) \ - extern CTYPE proxy_##NAME(ExecEnv *, JHandle *proxy, int32_t slot) + 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 *); @@ -103,8 +108,7 @@ 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); + struct methodblock *mb, stack_item *stackpointer); extern int proxy_monitorenter(ExecEnv *, JHandle *proxy); extern int proxy_monitorexit(ExecEnv *, JHandle *proxy); diff -aruN shujit-0.6.7/metavm/proxy.c shujit/metavm/proxy.c --- shujit-0.6.7/metavm/proxy.c Tue Sep 12 21:26:27 2000 +++ shujit/metavm/proxy.c Sun Oct 8 02:13:50 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 @@ -22,6 +22,7 @@ */ #include // for strlen(), memcpy() +#include // for va_*() #include "metavm.h" #include "native.h" @@ -47,36 +48,33 @@ struct methodtable *proxy_methodtable; -static jclass jclz_Boolean = NULL; -static ClassClass *clz_Boolean = NULL; -static jclass jclz_Byte = NULL; -static ClassClass *clz_Byte = NULL; -static jclass jclz_Character = NULL; -static ClassClass *clz_Character = NULL; -static jclass jclz_Short = NULL; -static ClassClass *clz_Short = NULL; -static jclass jclz_Integer = NULL; -static ClassClass *clz_Integer = NULL; -static jclass jclz_Long = NULL; -static ClassClass *clz_Long = NULL; -static jclass jclz_Float = NULL; -static ClassClass *clz_Float = NULL; -static jclass jclz_Double = NULL; -static ClassClass *clz_Double = NULL; - -static jclass jclz_ArrayOfObject = NULL; -static ClassClass *clz_ArrayOfObject = NULL; - -jclass jclz_Proxy = NULL; -static ClassClass *clz_Proxy = NULL; - -#define MID_DECL(METHOD_NAME) jmethodID mid_##METHOD_NAME = NULL -MID_DECL(get32field); -MID_DECL(get64field); -MID_DECL(getobjfield); -MID_DECL(aload32); -MID_DECL(aload64); -MID_DECL(aloadobj); +static ClassClass *cb_Boolean = NULL; +static ClassClass *cb_Byte = NULL; +static ClassClass *cb_Character = NULL; +static ClassClass *cb_Short = NULL; +static ClassClass *cb_Integer = NULL; +static ClassClass *cb_Long = NULL; +static ClassClass *cb_Float = NULL; +static ClassClass *cb_Double = NULL; + +static ClassClass *cb_ArrayOfObject = NULL; + +static ClassClass *cb_Proxy = NULL; + +#define MB_DECL(METHOD_NAME) \ + static struct methodblock *mb_##METHOD_NAME = NULL +MB_DECL(get32field); +MB_DECL(get64field); +MB_DECL(getobjfield); +MB_DECL(aload32); +MB_DECL(aload64); +MB_DECL(aloadobj); +MB_DECL(put32field); +MB_DECL(put64field); +MB_DECL(putobjfield); +MB_DECL(astore32); +MB_DECL(astore64); +MB_DECL(astoreobj); JNIEXPORT void JNICALL Java_NET_shudo_metavm_Proxy_initNative @@ -87,16 +85,8 @@ 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 = (ClassClass *)DeRef(env, jclz_##JCLASS) + cb_##JCLASS = FindClass(ee, CLASSNAME, TRUE) #define LANG_CLAZZ_INIT(JCLASS) \ CLAZZ_INIT(JCLASS, "java/lang/" #JCLASS) @@ -110,19 +100,88 @@ LANG_CLAZZ_INIT(Double); CLAZZ_INIT(ArrayOfObject, "[Ljava/lang/Object;"); - CLAZZ_INIT(Proxy, PROXY_CLASSNAME); +#if JDK_VER < 12 + // prevent class unloading + (*env)->NewGlobalRef(env, MK_REF_LOCAL(env, (JHandle *)cb_ArrayOfObject)); + (*env)->NewGlobalRef(env, MK_REF_LOCAL(env, (JHandle *)cb_Proxy)); +#endif // JDK_VER + + proxy_methodtable = unhand(cb)->methodtable; +#if 0 +printf("proxy_methodtable: 0x%08x\n", (int)proxy_methodtable); +fflush(stdout); +#endif + + // initialize methodblock + { + int i; + struct methodblock *mb; + +#if JDK_VER >= 12 + HashedNameAndType +#else + unsigned +#endif + hashed_get32field, hashed_get64field, hashed_getobjfield, + hashed_aload32, hashed_aload64, hashed_aloadobj, + hashed_put32field, hashed_put64field, hashed_putobjfield, + hashed_astore32, hashed_astore64, hashed_astoreobj; + +#if JDK_VER >= 12 +# define HASH_METHOD(NAME, SIG) \ + HashNameAndType(ee, #NAME, SIG, &hashed_##NAME) +#else +# define HASH_METHOD(NAME, SIG) \ + hashed_##NAME = NameAndTypeToHash(#NAME, SIG) +#endif + + HASH_METHOD(get32field, "(I)I"); + HASH_METHOD(get64field, "(I)J"); + HASH_METHOD(getobjfield, "(I)Ljava/lang/Object;"); + HASH_METHOD(aload32, "(I)I"); + HASH_METHOD(aload64, "(I)J"); + HASH_METHOD(aloadobj, "(I)Ljava/lang/Object;"); + HASH_METHOD(put32field, "(II)V"); + HASH_METHOD(put64field, "(IJ)V"); + HASH_METHOD(putobjfield, "(ILjava/lang/Object;)V"); + HASH_METHOD(astore32, "(II)V"); + HASH_METHOD(astore64, "(IJ)V"); + HASH_METHOD(astoreobj, "(ILjava/lang/Object;)V"); + + for (i = cbMethodsCount(cb_Proxy) - 1; i >= 0; i--) { + mb = &(cbMethods(cb_Proxy)[i]); +#if JDK_VER >= 12 +# define IF_METHOD(NAME) \ + if (NAMETYPE_MATCH(&hashed_##NAME, &(mb->fb)))\ + mb_##NAME = mb +#else +# define IF_METHOD(NAME) \ + if (mb->fb.ID == hashed_##NAME) mb_##NAME = mb +#endif +#define ELIF_METHOD(NAME) else IF_METHOD(NAME) + + IF_METHOD(get32field); + ELIF_METHOD(get64field); + ELIF_METHOD(getobjfield); + ELIF_METHOD(aload32); + ELIF_METHOD(aload64); + ELIF_METHOD(aloadobj); + ELIF_METHOD(put32field); + ELIF_METHOD(put64field); + ELIF_METHOD(putobjfield); + ELIF_METHOD(astore32); + ELIF_METHOD(astore64); + ELIF_METHOD(astoreobj); + } -#define MID_INIT(METHOD_NAME, SIG) \ - mid_##METHOD_NAME =\ - (*env)->GetMethodID(env, jclz_Proxy, #METHOD_NAME, "(I)" #SIG) - - MID_INIT(get32field, I); - MID_INIT(get64field, J); - MID_INIT(getobjfield, Ljava/lang/Object;); - MID_INIT(aload32, I); - MID_INIT(aload64, J); - MID_INIT(aloadobj, Ljava/lang/Object;); + sysAssert((mb_get32field != NULL) && (mb_get64field) && + (mb_getobjfield != NULL) && (mb_aload32) && + (mb_aload64 != NULL) && (mb_aloadobj) && + (mb_put32field != NULL) && (mb_put64field) && + (mb_putobjfield != NULL) && (mb_astore32) && + (mb_astore64 != NULL) && (mb_astoreobj)); + } } @@ -136,11 +195,13 @@ printf("proxy_new(0x%08x, 0x%08x, %s(0x%08x)) called.\n", (int)ee, (int)addr, (cb?cbName(cb):"null"), (int)cb); fflush(stdout); + printf(" port no: %d\n", unhand(addr)->port); + fflush(stdout); #endif - sysAssert(clz_Proxy != NULL); + sysAssert(cb_Proxy != NULL); - obj = (JHandle *)do_execute_java_method(ee, clz_Proxy, + obj = (JHandle *)do_execute_java_method(ee, cb_Proxy, "get", "(Ljava/lang/Class;L" METAVM_PKG "VMAddress;Ljava/lang/Class;)L" METAVM_PKG "Proxy;", NULL, // struct methodblock @@ -174,9 +235,9 @@ fflush(stdout); #endif - sysAssert(clz_Proxy != NULL); + sysAssert(cb_Proxy != NULL); - obj = (JHandle *)do_execute_java_method(ee, clz_Proxy, + obj = (JHandle *)do_execute_java_method(ee, cb_Proxy, "get", "(Ljava/lang/Class;L" METAVM_PKG "VMAddress;II)L" METAVM_PKG "Proxy;", NULL, // struct methodblock @@ -206,9 +267,9 @@ char orig = GET_REMOTE_FLAG(ee); REMOTE_FLAG_OFF(ee); - sysAssert(clz_Proxy != NULL); + sysAssert(cb_Proxy != NULL); - obj = (JHandle *)do_execute_java_method(ee, clz_Proxy, + obj = (JHandle *)do_execute_java_method(ee, cb_Proxy, "get", "(Ljava/lang/Class;L" METAVM_PKG "VMAddress;Ljava/lang/Class;I)L" METAVM_PKG "Proxy;", NULL, // struct methodblock @@ -267,9 +328,9 @@ (*env)->ReleaseIntArrayElements(env, sizes, csizes, JNI_COMMIT); - sysAssert(clz_Proxy != NULL); + sysAssert(cb_Proxy != NULL); - obj = (JHandle *)do_execute_java_method(ee, clz_Proxy, + obj = (JHandle *)do_execute_java_method(ee, cb_Proxy, "get", "(Ljava/lang/Class;L" METAVM_PKG "VMAddress;Ljava/lang/Class;[I)L" METAVM_PKG "Proxy;", NULL, // struct methodblock @@ -293,29 +354,39 @@ // 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)MK_REF_LOCAL(env, proxy);\ - jvalue args[1];\ - JNITYPE val;\ +#define GET_FIELD(METHOD_NAME, SIG, CTYPE, POSTPROC) \ +CTYPE proxy_##METHOD_NAME(ExecEnv *ee, JHandle *proxy, ... /*int32_t slot*/) {\ + CTYPE val;\ + int32_t ret;\ + va_list args;\ + \ \ char orig = GET_REMOTE_FLAG(ee);\ REMOTE_FLAG_OFF(ee);\ \ - /* prepare arguments */\ - args[0].i = (jint)slot;\ - \ - val = (*env)->Call##JTYPE##MethodA(env, obj, mid_##METHOD_NAME, args);\ + va_start(args, proxy);\ + ret = (int32_t)do_execute_java_method_vararg(ee, proxy,\ + #METHOD_NAME, "(I)" #SIG,\ + mb_##METHOD_NAME, /* struct methodblock */\ + FALSE, /* isStaticCall */\ + args, (long *)&val, FALSE);\ + va_end(args);\ \ SET_REMOTE_FLAG(ee, orig);\ \ - return POSTPROC;\ + POSTPROC;\ + \ + return val;\ } -GET_FIELD(get32field, Int, I, int32_t, jint, (int32_t)val); -GET_FIELD(get64field, Long, J, int64_t, jlong, (int64_t)val); -GET_FIELD(getobjfield, Object, Ljava/lang/Object;, JHandle *, jobject, DeRef(env, val)); +GET_FIELD(get32field, I, int32_t, val = (int32_t)ret); +GET_FIELD(get64field, J, int64_t, *((int32_t *)&val + 1) = ret); +GET_FIELD(getobjfield, Ljava/lang/Object;, JHandle *, val = (JHandle *)ret); + +// definitions of proxy_aload*() +GET_FIELD(aload32, I, int32_t, val = (int32_t)ret); +GET_FIELD(aload64, J, int64_t, *((int32_t *)&val + 1) = ret); +GET_FIELD(aloadobj, Ljava/lang/Object;, JHandle *, val = (JHandle *)ret); // definitions of proxy_put*field() @@ -326,10 +397,10 @@ REMOTE_FLAG_OFF(ee);\ \ do_execute_java_method(ee, proxy,\ - #METHOD_NAME, "(I" #SIG ")V",\ - NULL, /* struct methodblock */\ - FALSE, /* isStaticCall */\ - slot, val);\ + #METHOD_NAME, "(I" #SIG ")V",\ + mb_##METHOD_NAME, /* struct methodblock */\ + FALSE, /* isStaticCall */\ + slot, val);\ \ SET_REMOTE_FLAG(ee, orig);\ } @@ -338,13 +409,6 @@ PUT_FIELD(put64field, J, int64_t); PUT_FIELD(putobjfield, Ljava/lang/Object;, JHandle *); - -// 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*() PUT_FIELD(astore32, I, int32_t); PUT_FIELD(astore64, J, int64_t); @@ -375,15 +439,17 @@ int proxy_invoke(ExecEnv *ee, JHandle *proxy, - struct methodblock *mb, int32_t slot, char *sig, - stack_item *stackpointer) { - JNIEnv *env = EE2JNIEnv(ee); + struct methodblock *mb, stack_item *stackpointer) { + int slot, mbindex; + int args_size; // in 4byte, mb->args_size stack_item *var_base, *spptr; int args_len; // number of elements, NOT size + char *sig = mb->fb.signature; char *p; - HArrayOfObject *args = NULL; JHandle **args_body; JHandle *args_elem; - JHandle *ret; + + HArrayOfObject *args = NULL; + JHandle **args_body; JHandle *args_elem; int ret_size; int i; @@ -393,22 +459,29 @@ #ifdef RUNTIME_DEBUG printf("proxy_invoke(sp: 0x%08x) called.\n", (int)stackpointer); printf(" proxy: 0x%08x\n", (int)proxy); - printf(" slot : %d\n", slot); - printf(" sig : %s\n", sig); - printf(" remote flag: %d\n", GET_REMOTE_FLAG(ee)); fflush(stdout); #endif + slot = mb->fb.u.offset; + if (slot == 0) { // determine method index + mbindex = mb - cbMethods(mb->fb.clazz); + } + else + mbindex = 0; +#ifdef RUNTIME_DEBUG + printf(" slot, mbindex: %d, %d\n", slot, mbindex); fflush(stdout); +#endif + // args_size and var_base args_size = mb->args_size; var_base = stackpointer + args_size - 1; #ifdef RUNTIME_DEBUG - printf("args_size: %d\n", args_size); + printf(" args_size: %d\n", args_size); fflush(stdout); spptr = var_base; - printf("args on stack: 0x%x", *(int *)(spptr--)); + printf(" args on stack: 0x%x", *(int *)(spptr--)); for (i = 1; i < args_size; i++) printf(", 0x%x", *(int *)(spptr--)); printf("\n"); @@ -431,7 +504,7 @@ } } #ifdef RUNTIME_DEBUG - printf("args_len: %d\n", args_len); + printf(" args_len: %d\n", args_len); #endif p = sig + 1; @@ -441,8 +514,15 @@ double doubleVal; args = (HArrayOfObject *)ArrayAlloc(T_CLASS, args_len); +#if 0 + { // (*env)->NewGlobalRef() + extern JavaFrame *globalRefFrame; + GLOBALREF_LOCK(EE2SysThread(ee)); + args_ref = (jobject)jni_addRef(globalRefFrame, args); + GLOBALREF_UNLOCK(EE2SysThread(ee)); + } +#endif unhand(args)->body[args_len] = (HObject *)classJavaLangObject; - MK_REF_LOCAL(env, args); // register as local ref #ifdef RUNTIME_DEBUG printf("classJavaLangObject: 0x%08x\n", (int)classJavaLangObject); fflush(stdout); @@ -456,7 +536,7 @@ #define COPY_ARG(JCLASS, SIG, QUOTED_SIG, SP_PREPROC, SP_ELEM, SP_POSTPROC) \ case QUOTED_SIG:\ - args_elem = newobject(clz_##JCLASS, NULL, ee);\ + args_elem = newobject(cb_##JCLASS, NULL, ee);\ \ SP_PREPROC;\ do_execute_java_method(ee, args_elem,\ @@ -523,6 +603,7 @@ default: printf("FATAL: invalid signature of return type : %c\n", *p); fflush(stdout); + ret_size = 0; break; } @@ -538,14 +619,20 @@ #endif ret = (JHandle *)do_execute_java_method(ee, proxy, - "invoke", "(ILjava/lang/String;[Ljava/lang/Object;)Ljava/lang/Object;", - NULL, // struct methodblock + "invoke", + "(II[Ljava/lang/Object;)Ljava/lang/Object;", + NULL, // struct methodblock * FALSE, // isStaticCall - slot, makeJavaStringUTF(sig), args); + slot, mbindex, args); + +#if 0 + (*env)->DeleteGlobalRef(env, args_ref); +#endif + if (exceptionOccurred(ee)) return -1; #ifdef RUNTIME_DEBUG - printf("ret: 0x%08x\n", (int)ret); + printf("returned obj: 0x%08x\n", (int)ret); fflush(stdout); #endif @@ -568,23 +655,35 @@ cur_frame->optop++; break; case 'I': optop->i = unhand((Hjava_lang_Integer *)ret)->value; +#ifdef RUNTIME_DEBUG + printf("ret: (int)%d\n", optop->i); fflush(stdout); +#endif cur_frame->optop++; break; case 'J': { int64_t val = unhand((Hjava_lang_Long *)ret)->value; optop[0].i = ((int32_t *)&val)[0]; optop[1].i = ((int32_t *)&val)[1]; +#ifdef RUNTIME_DEBUG + printf("ret: (long)%lld\n", *((int64_t *)optop)); fflush(stdout); +#endif cur_frame->optop += 2; } break; case 'F': optop->f = unhand((Hjava_lang_Float *)ret)->value; +#ifdef RUNTIME_DEBUG + printf("ret: (float)%g\n", *((float *)optop)); fflush(stdout); +#endif cur_frame->optop++; break; case 'D': { double val = unhand((Hjava_lang_Double *)ret)->value; optop[0].i = ((int32_t *)&val)[0]; optop[1].i = ((int32_t *)&val)[1]; +#ifdef RUNTIME_DEBUG + printf("ret: (double)%g\n", *((double *)optop)); fflush(stdout); +#endif cur_frame->optop += 2; } break; @@ -597,6 +696,16 @@ printf("proxy_invoke() done.\n"); fflush(stdout); #endif + + // set return value to %edx and %ecx + { + register stack_item *optop asm("%edi"); + optop = ee->current_frame->optop - ret_size; + + asm("movl %0,%%edx" : : "m" (optop[0].i) : "edx"); + asm("movl %0,%%ecx" : : "m" (optop[1].i) : "ecx"); + } + return ret_size; } diff -aruN shujit-0.6.7/metavm/vmop.c shujit/metavm/vmop.c --- shujit-0.6.7/metavm/vmop.c Tue Sep 12 02:24:17 2000 +++ shujit/metavm/vmop.c Sun Oct 8 01:27:18 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 @@ -22,6 +22,7 @@ */ #include "metavm.h" +#include "../compiler.h" // for CB_INITIALIZED #include "native.h" // for old style native methods #include "sys_api.h" // sys*() @@ -51,7 +52,7 @@ // Local Functions // static jobject invokeMethod(JNIEnv *env, - jobject, jmethodID, const char *csig, jobjectArray); + jobject, jmethodID, jobjectArray); @@ -68,6 +69,12 @@ fflush(stdout); #endif + // initialize the class + { + ClassClass *cb = (ClassClass *)DeRef(env, tgtclz); + if (!CB_INITIALIZED(cb)) InitClass(cb); + } + obj = (*env)->AllocObject(env, tgtclz); #ifdef RUNTIME_DEBUG if ((*env)->ExceptionOccurred(env)) { @@ -104,12 +111,19 @@ JNIEXPORT jobject JNICALL Java_NET_shudo_metavm_VMOperations_anewarray (JNIEnv *env, jclass clazz, jclass tgtclz, jint count) { + + // initialize the class + { + ClassClass *cb = (ClassClass *)DeRef(env, tgtclz); + if (!CB_INITIALIZED(cb)) InitClass(cb); + } + return (*env)->NewObjectArray(env, count, tgtclz, NULL); } JNIEXPORT jobject JNICALL Java_NET_shudo_metavm_VMOperations_multianewarray - (JNIEnv *env , jclass clzz, jclass aryclz, jintArray sizes) { + (JNIEnv *env , jclass clazz, jclass aryclz, jintArray sizes) { int dim; jint *csizes; stack_item *s; @@ -117,21 +131,23 @@ JHandle *array; dim = (int)(*env)->GetArrayLength(env, sizes); -printf("multianewarray() len of sizes: %d\n", dim); -fflush(stdout); csizes = (*env)->GetIntArrayElements(env, sizes, NULL); s = malloc(sizeof(stack_item) * dim); for (i = 0; i < dim; i++) { -printf(" size[%d]: %d\n", i, csizes[i]); s[i].i = (int)csizes[i]; } -fflush(stdout); (*env)->ReleaseIntArrayElements(env, sizes, csizes, JNI_ABORT); // JNI_ABORT: copy back isn't required + // initialize the class + { + ClassClass *cb = (ClassClass *)DeRef(env, aryclz); + if (!CB_INITIALIZED(cb)) InitClass(cb); + } + array = MultiArrayAlloc((int)dim, (ClassClass *)DeRef(env, aryclz), s); free(s); @@ -246,7 +262,7 @@ } // invoke the method - result = invokeMethod(env, obj, mid, csig, args); + result = invokeMethod(env, obj, mid, args); (*env)->ReleaseStringUTFChars(env, name, cname); (*env)->ReleaseStringUTFChars(env, sig, csig); @@ -260,70 +276,46 @@ } -JNIEXPORT jobject JNICALL Java_NET_shudo_metavm_VMOperations_invoke__Ljava_lang_Object_2ILjava_lang_String_2_3Ljava_lang_Object_2 - (JNIEnv *env, jclass clazz, jobject obj, jint slot, jstring sig, jobjectArray args) { - const char *csig; +JNIEXPORT jobject JNICALL Java_NET_shudo_metavm_VMOperations_invoke__Ljava_lang_Object_2II_3Ljava_lang_Object_2 + (JNIEnv *env, jclass clazz, + jobject receiver, jint slot, jint mbindex, jobjectArray args) { jclass objClazz; - ClassClass *cb; jmethodID mid; - struct methodblock *mb; jobject result; #ifdef RUNTIME_DEBUG - printf("vmop#invoke(slot) called.\n"); - printf(" obj: 0x%08x\n", (int)obj); - printf(" slot: %d\n", (int)slot); + printf("vmop#invoke(slot, mbindex) called.\n"); + printf(" receiver: 0x%x\n", (int)receiver); + printf(" slot, mbindex: %d, %d\n", (int)slot, (int)mbindex); fflush(stdout); #endif - objClazz = (*env)->GetObjectClass(env, obj); + objClazz = (*env)->GetObjectClass(env, receiver); #ifdef RUNTIME_DEBUG - printf(" objClazz: 0x%08x\n", (int)objClazz); + printf(" objClazz: 0x%x\n", (int)objClazz); fflush(stdout); - printf(" name: %s\n", cbName((Hjava_lang_Class *)DeRef(env, objClazz))); + printf(" class name: %s\n", cbName((ClassClass *)DeRef(env, objClazz))); fflush(stdout); #endif - cb = (Hjava_lang_Class *)DeRef(env, objClazz); // get method ID - if (slot == 0) { // caller is a constructor - csig = (*env)->GetStringUTFChars(env, sig, NULL); - mid = (*env)->GetMethodID(env, objClazz, "", csig); + if (slot != 0) { + mid = (jmethodID) + mt_slot(obj_array_methodtable((JHandle *)DeRef(env, receiver)), slot); + if (!mid) return NULL; // haven't to be called } else { -#if 0 mid = (jmethodID) - mt_slot(obj_array_methodtable((JHandle *)DeRef(env, obj)), slot); -#ifdef RUNTIME_DEBUG - printf(" mb by obj : 0x%08x\n", (int)mid); - fflush(stdout); -#endif -#else - mid = (jmethodID) - mt_slot(cbMethodTable(cb), slot); -#ifdef RUNTIME_DEBUG - printf(" mb by clz: 0x%08x\n", (int)mid); - fflush(stdout); -#endif -#endif - if (!mid) return NULL; // haven't to be called - csig = ((struct methodblock *)mid)->fb.signature; + (cbMethods((ClassClass *)DeRef(env, objClazz)) + mbindex); } #ifdef RUNTIME_DEBUG - printf(" name: %s\n", (int)((struct methodblock *)mid)->fb.name); - printf(" sig : %s\n", csig); - fflush(stdout); -#endif -#ifdef RUNTIME_DEBUG - printf(" sig: %s\n", csig); + printf(" mb: 0x%x\n", (int)mid); + if (slot != 0) + printf(" name: %s\n", (int)((struct methodblock *)mid)->fb.name); fflush(stdout); #endif // invoke the method - result = invokeMethod(env, obj, mid, csig, args); - - if (slot == 0) { - (*env)->ReleaseStringUTFChars(env, sig, csig); - } + result = invokeMethod(env, receiver, mid, args); #ifdef RUNTIME_DEBUG printf("vmop#invoke done.\n"); @@ -335,12 +327,13 @@ static jobject invokeMethod(JNIEnv *env, - jobject obj, jmethodID mid, const char *csig, jobjectArray args) { + jobject receiver, jmethodID mid, jobjectArray args) { jsize arrayLength; #define PREALLOC_SIZE 10 jvalue cargsArray[PREALLOC_SIZE]; jvalue *cargs; jobject result; + char *csig = ((struct methodblock *)mid)->fb.signature; int i; // prepare arguments @@ -417,7 +410,7 @@ #define INVOKE_METHOD(JCLASS, JTYPE, jtype, SIG)\ {\ j##jtype ret;\ - ret = (*env)->Call##JTYPE##MethodA(env, obj, mid, cargs);\ + ret = (*env)->Call##JTYPE##MethodA(env, receiver, mid, cargs);\ if (!jclz_##JCLASS) {\ jclz_##JCLASS = (*env)->FindClass(env, "java/lang/" #JCLASS);\ jclz_##JCLASS = (*env)->NewGlobalRef(env, jclz_##JCLASS);\ @@ -430,12 +423,12 @@ switch (*p) { case 'V': - (*env)->CallVoidMethodA(env, obj, mid, cargs); + (*env)->CallVoidMethodA(env, receiver, mid, cargs); result = NULL; break; case 'L': case '[': - result = (*env)->CallObjectMethodA(env, obj, mid, cargs); + result = (*env)->CallObjectMethodA(env, receiver, mid, cargs); break; case 'Z': INVOKE_METHOD(Boolean, Boolean, boolean, Z); break; case 'B': INVOKE_METHOD(Byte, Byte, byte, B); break; @@ -470,4 +463,62 @@ JNIEXPORT void JNICALL Java_NET_shudo_metavm_VMOperations_printStackTrace (JNIEnv *env, jclass clazz) { showStackFrames(JNIEnv2EE(env)); // in runtime.c +} + + +JNIEXPORT jboolean JNICALL Java_NET_shudo_metavm_VMOperations_isNativeMethod + (JNIEnv *env, jclass clz, jclass clazz, jint slot, jint mbindex) { + ClassClass *cb = (ClassClass *)DeRef(env, clazz); + struct methodblock *mb; + + if (slot != 0) + mb = mt_slot(cbMethodTable(cb), slot); + else if (mbindex != 0) + mb = cbMethods(cb) + mbindex; + else + return JNI_FALSE; // constructor + + return ((mb->fb.access & ACC_NATIVE) != 0); +} + + +JNIEXPORT jstring JNICALL Java_NET_shudo_metavm_VMOperations_MethodName + (JNIEnv *env, jclass clz, jclass clazz, jint slot, jint mbindex) { + ClassClass *cb = (ClassClass *)DeRef(env, clazz); + struct methodblock *mb; + char *name; + + if (slot != 0) { + mb = mt_slot(cbMethodTable(cb), slot); + name = mb->fb.name; + } + else if (mbindex != 0) { + mb = cbMethods(cb) + mbindex; + name = mb->fb.name; + } + else + name = ""; // constructor + + return MK_REF_LOCAL(env, (JHandle *)makeJavaStringUTF(name)); +} + + +JNIEXPORT jstring JNICALL Java_NET_shudo_metavm_VMOperations_MethodSignature + (JNIEnv *env, jclass clz, jclass clazz, jint slot, jint mbindex) { + ClassClass *cb = (ClassClass *)DeRef(env, clazz); + struct methodblock *mb; + char *sig; + + if (slot != 0) { + mb = mt_slot(cbMethodTable(cb), slot); + sig = mb->fb.name; + } + else if (mbindex != 0) { + mb = cbMethods(cb) + mbindex; + sig = mb->fb.name; + } + else + sig = "()V"; // constructor + + return MK_REF_LOCAL(env, (JHandle *)makeJavaStringUTF(sig)); } diff -aruN shujit-0.6.7/opcodes_internal.h shujit/opcodes_internal.h --- shujit-0.6.7/opcodes_internal.h Mon Sep 18 16:36:19 2000 +++ shujit/opcodes_internal.h Fri Sep 29 16:51:48 2000 @@ -137,4 +137,7 @@ #define opc_istld 316 // 0x13c #define opc_lstld 317 -#define NOPCODES 318 +// for MetaVM +#define opc_metavm_init 318 + +#define NOPCODES 319 diff -aruN shujit-0.6.7/optimize.c shujit/optimize.c --- shujit-0.6.7/optimize.c Sun Sep 10 12:01:03 2000 +++ shujit/optimize.c Sun Oct 8 02:19:09 2000 @@ -33,7 +33,6 @@ int compile_debug = cc->compile_debug; #endif pcentry *entry; - int opcode, opcode1; int i; #ifdef COMPILE_DEBUG diff -aruN shujit-0.6.7/runtime.c shujit/runtime.c --- shujit-0.6.7/runtime.c Tue Sep 19 18:47:36 2000 +++ shujit/runtime.c Sun Oct 8 02:18:34 2000 @@ -47,8 +47,8 @@ int retsize; int access; -#ifdef RUNTIME_DEBUG info = (CodeInfo *)method->CompiledCodeInfo; +#ifdef RUNTIME_DEBUG if (!info) { printf("WARNING: CompiledCodeInfo is NULL. (invocationHelper())\n"); printf(" %s#%s %s\n", cbName(fieldclass(&method->fb)), @@ -58,20 +58,16 @@ #endif sysAssert(method->CompiledCodeInfo != NULL); -#ifdef RUNTIME_DEBUG - if (runtime_debug) { - printf(" invoker: %s (0x%x)\n", - nameOfInvoker(method->invoker), (int)(method->invoker)); - fflush(stdout); - } -#endif + retsize = info->ret_size; #ifdef RUNTIME_DEBUG if (runtime_debug) { struct methodblock *cur_mb; char *sig; int i; - retsize = info->ret_size; + printf(" invoker: %s (0x%x)\n", + nameOfInvoker(method->invoker), (int)(method->invoker)); + access = method->fb.access; cur_frame = ee->current_frame; @@ -82,8 +78,6 @@ printf(" 0x%x\n", *(int32_t *)var_base); printf(" ee: 0x%08x\n", (int)ee); printf(" current_frame: 0x%08x\n", (int)cur_frame); - printf(" retsize, args_size, nlocals: %d, %d, %d\n", - retsize, args_size, method->nlocals); printf(" caller method:"); fflush(stdout); if (cur_mb) @@ -96,14 +90,18 @@ printf(" (0x%08x)\n", (int)cur_mb); fflush(stdout); - printf(" obj: "); + printf(" obj: 0x%x\n", obj); fflush(stdout); if (obj) { - if (access & ACC_STATIC) + printf(" "); + if (access & ACC_STATIC) { printf("%s", unhand((Hjava_lang_Class *)obj)->name); - else if (obj_flags(obj) == T_NORMAL_OBJECT) + } + else if (obj_flags(obj) == T_NORMAL_OBJECT) { printf("%s", cbName(obj->methods->classdescriptor)); - else // array object + } + else { // array object printf("array"); + } printf(" (0x%x)", (int)obj); } else @@ -124,7 +122,8 @@ if (access & ACC_SYNCHRONIZED) printf(" synchronized"); if (access & ACC_ABSTRACT) printf(" abstract"); printf("\n"); - printf(" retsize, args_size: %d, %d\n", retsize, args_size); + printf(" retsize, args_size, nlocals: %d, %d, %d\n", + retsize, args_size, method->nlocals); fflush(stdout); i = 0; if (!(access & ACC_STATIC)) { @@ -132,6 +131,7 @@ fflush(stdout); showObjectBody("L;", var_base[0].h); printf("\n"); + fflush(stdout); i++; } if (sig[0] == '(') sig++; @@ -157,21 +157,20 @@ sig = showObjectBody(sig, arg); printf("\n"); } + fflush(stdout); } - fflush(stdout); } #endif // RUNTIME_DEBUG #define CALL_INVOKER(TAG) \ {\ - int ret asm("eax");\ + register int ret asm("eax");\ ret = ((bool_t (*)(JHandle*,struct methodblock*,int,ExecEnv*,stack_item*))\ invoker)(obj, method, args_size, ee, var_base);\ if (!ret) goto invhelper_return;\ } - invoker = method->invoker; #ifndef DIRECT_INVOCATION if (invoker == sym_invokeJITCompiledMethod) { // compiled method is called @@ -223,7 +222,7 @@ if (runtime_debug) { printf("call JNI: %s#%s %s\n", cbName(fieldclass(&method->fb)), method->fb.name, method->fb.signature); - printf(" argsize: %x\n", argsize); + printf(" argsize: %d\n", argsize); printf(" old_frame: %x\n", old_frame); printf(" optop: %x\n", optop); printf(" ee,env: %x,%x\n", ee,env); @@ -527,7 +526,7 @@ else if ((invoker == sym_invokeNativeMethod) || (invoker == sym_invokeSynchronizedNativeMethod)) { // old fashion (NMI) native method - JavaFrame *old_frame, *frame; + JavaFrame *old_frame; stack_item *optop; int is_static, is_sync; char *terse_sig; @@ -826,7 +825,8 @@ #ifdef RUNTIME_DEBUG if (runtime_debug) { - stack_item *optop = ee->current_frame->optop; + stack_item *optop; + optop = ee->current_frame->optop; if (retsize > 0) { printf(" optop[-1]: 0x%x %d %g\n", @@ -852,6 +852,7 @@ { JavaFrame *frame = ee->current_frame; stack_item *optop; + sysAssert((retsize >= 0) && (retsize <= 2)); optop = (frame->optop -= retsize); asm("movl %0,%%edx" : : "m" (optop[0].i) : "edx"); @@ -919,7 +920,7 @@ #ifdef METAVM if ((mtable == proxy_methodtable) && (GET_REMOTE_FLAG(ee))) { // obj instanceof Proxy - cb = unhand((HNET_shudo_metavm_Proxy *)obj)->clazz; + cb = unhand((HNET_shudo_metavm_Proxy *)obj)->clz; mtable = cbMethodTable(cb); } #endif // METAVM @@ -1046,7 +1047,7 @@ fflush(stdout); #endif - initializeClassForJIT(cb, FALSE); + initializeClassForJIT(cb, TRUE, FALSE); // This is necessary because methodblock->info can be required // before ResolveClass() calls InitializeForCompiler() @@ -1171,7 +1172,7 @@ } #ifdef RUNTIME_DEBUG else { - printf(" already resolved yet: %d\n", typeindex); + printf(" already resolved: %d\n", typeindex); fflush(stdout); } #endif @@ -1226,7 +1227,7 @@ fflush(stdout); return; } - printf("stack frames (ee:%x)\n", ee); + printf("stack frames (ee:%x)\n", (int)ee); fflush(stdout); frame = ee->current_frame; while (frame) { diff -aruN shujit-0.6.7/signal.c shujit/signal.c --- shujit-0.6.7/signal.c Tue Sep 19 04:07:55 2000 +++ shujit/signal.c Tue Nov 14 20:44:30 2000 @@ -51,7 +51,7 @@ #if JDK_VER >= 12 # define SIGRETURN(SC, EBP) return TRUE; #else -# if defined(__FreeBSD__) +# if defined(__FreeBSD__) || defined(__NetBSD__) # define SIGRETURN(SC, EBP) sigreturn(SC); # elif defined(sun) # define SIGRETURN(SC, EBP) sigcontext(SC); @@ -77,7 +77,7 @@ #if (defined(EXC_BY_SIGNAL) || defined(GET_SIGCONTEXT)) && defined(SEARCH_SIGCONTEXT) -#ifdef __FreeBSD__ +#if defined(__FreeBSD__) || defined(__NetBSD__) bool_t examineSigcontextNestCount(int sig, int code, struct sigcontext *uc0) { #else bool_t examineSigcontextNestCount(int sig, void *info, void *uc0) { @@ -156,7 +156,7 @@ #endif // (EXC_BY_SIGNAL || GET_SIGCONTEXT) && SEARCH_SIGCONTEXT -#ifdef __FreeBSD__ +#if defined(__FreeBSD__) || defined(__NetBSD__) bool_t signalHandler(int sig, int code, struct sigcontext *uc0) { #else bool_t signalHandler(int sig, void *info, void *uc0) { @@ -199,7 +199,7 @@ #if defined(EXC_BY_SIGNAL) || defined(GET_SIGCONTEXT) #ifndef SEARCH_SIGCONTEXT -# ifdef __FreeBSD__ +# if defined(__FreeBSD__) || defined(__NetBSD__) sc = (SIGCONTEXT *)uc0; # else // linux sc = (SIGCONTEXT *) &((struct ucontext *)uc0)->uc_mcontext; @@ -414,7 +414,7 @@ sigaction(sig, &sigAct, (struct sigaction *)NULL); } -#ifdef __FreeBSD__ +#if defined(__FreeBSD__) || defined(__NetBSD__) // unmask the signal { sigset_t sigmask; @@ -422,7 +422,7 @@ sigaddset(&sigmask, sig); sigprocmask(SIG_UNBLOCK, &sigmask, NULL); } -#endif // __FreeBSD__ +#endif // __FreeBSD__ || __NetBSD__ #endif // 0 @@ -512,7 +512,7 @@ */ void showSigcontext(SIGCONTEXT *sc) { printf("SS: %04x, CS: %04x, DS: %04x, ES: %04x, FS: %04x, GS: %04x\n", -#if defined(__FreeBSD__) +#if defined(__FreeBSD__) || defined(__NetBSD__) sc->sc_ss & 0xffff, sc->sc_cs & 0xffff, sc->sc_ds & 0xffff, sc->sc_es & 0xffff, sc->sc_fs & 0xffff, sc->sc_gs & 0xffff @@ -536,8 +536,11 @@ { uint32_t *esp = (uint32_t *)sc->SC_ESP; + uint32_t *ebp = (uint32_t *)sc->SC_EBP; if (esp) printf("(ESP+4): %08x, (ESP): %08x\n", *(esp+1), *esp); + if (ebp) + printf("(EBP+4): %08x (retrun addr.)\n", *(ebp+1)); } { unsigned char *eip = (unsigned char *)sc->SC_EIP; @@ -550,7 +553,49 @@ } printf("trapno: %02x\n", sc->SC_TRAPNO); - fflush(stdout); + + // search the method where the signal thrown + { + uint32_t off = (uint32_t)sc->SC_EIP; + struct methodblock *mb_in_frame = + *(struct methodblock **)((unsigned char *)sc->SC_EBP + 12); + ClassClass **classes, **clazzptr; + struct methodblock *mb, *mb_end; + int i; + + classes = (ClassClass **)sysMalloc(sizeof(ClassClass *) * nbinclasses); + memcpy(classes, binclasses, sizeof(ClassClass *) * nbinclasses); + + for (i = nbinclasses, clazzptr = classes; --i >= 0; clazzptr++) { + mb = cbMethods(*clazzptr); + mb_end = mb + cbMethodsCount(*clazzptr); + for (; mb < mb_end; mb++) { + //int access = mb->fb.access; + //if (access & (ACC_ABSTRACT | ACC_NATIVE)) continue; + + if (mb == mb_in_frame) goto mb_found; + + if (mb->invoker != sym_invokeJITCompiledMethod) continue; + + off -= (uint32_t)mb->CompiledCode; + if (off < ((CodeInfo *)(mb->CompiledCodeInfo))->code_size) + goto mb_found; + } + } + mb = NULL; + + mb_found: + if (mb != NULL) { + printf("method by EIP: %s#%s %s\n", + cbName(fieldclass(&mb->fb)), mb->fb.name, mb->fb.signature); + } + else { + printf("method not found by EIP.\n"); + } + fflush(stdout); + + sysFree(classes); + } } #endif // EXC_BY_SIGNAL || GET_SIGCONTEXT diff -aruN shujit-0.6.7/txt/SPECjvm98 shujit/txt/SPECjvm98 --- shujit-0.6.7/txt/SPECjvm98 Tue Sep 19 20:53:08 2000 +++ shujit/txt/SPECjvm98 Thu Sep 21 20:03:03 2000 @@ -6,7 +6,7 @@ * shuJIT * OpenJIT 1.1.14 -* JBuilder JIT 1.2.15 +* JBuilder Java 2 JIT 1.2.15 * TYA 1.7v2 * interpreter diff -aruN shujit-0.6.7/txt/benchmark-PJ2X3 shujit/txt/benchmark-PJ2X3 --- shujit-0.6.7/txt/benchmark-PJ2X3 Tue Sep 19 21:12:21 2000 +++ shujit/txt/benchmark-PJ2X3 Tue Oct 10 23:46:18 2000 @@ -3,12 +3,45 @@ [TYA 付属のもの] - interp. TYA17v2 Inp1215 000429 0.6.4 0.6.5 0.6.6 0.6.7 -Sieve 125 586 1096 634 629 618 632 632 + interp. TYA17v2 Inp1215 +Sieve 125 586 1096 + GCJ(O2,.java) GCJ(O2,.class) GCJ(O0,.java) GCJ(O0,.class) +Sieve 1810 1377 578 536 + 000429 0.6.4 0.6.5 0.6.6 0.6.7 +Sieve 634 629 618 632 632 [Linpack Benchmark -- Java Version] + 500 x 500 + +IBM JDK 1.3.0 23.675 3.54 +IBM JDK 1.1.8 17.994 4.66 +Server VM, Sun 16.783 5.0 +Server VM, BD 16.627 5.04 +Client VM, Sun 15.035 5.58 +Client VM, BD 14.949 5.61 +GCJ (O2,.java) 14.284 5.87 +GCJ (O2,.class) 13.813 6.07 +shuJIT 001010 11.277 7.43 +Inprise 1.2.15 10.734 7.81 +Kaffe 1.0.6 10.584 7.92 +OpenJIT 1.1.14 9.455 8.87 +TYA 1.7v2 9.449 8.87 +GCJ (O0,.java) 9.18 9.13 +GCJ (O0,.class) 7.96 10.53 +sunwjit 2.362 35.49 +interpreter 2.361 35.51 + +(Native Threads) +Inprise 1.2.15 10.731 7.81 +shuJIT 001005 10.245 8.18 +TYA 1.7v2 9.542 8.79 +sunwjit 2.382 35.19 +interpreter 2.369 35.39 + + 200 x 200 + shuJIT-000423 7.007 0.1 shuJIT-000429 7.803 0.09 shuJIT-000706 7.893 0.09 @@ -25,6 +58,11 @@ OpenJIT-1.1.14 10.899 0.06 Inprise-1.2.15 11.257 0.06 Inprise-1.2.15 11.638 0.06 JAVA_COMPILER_THRESHOLD = 0 +GCJ (O2,.java) 26.41 0.03 +GCJ (O2,.class) 24.524 0.03 +GCJ (O0,.java) 12.716 0.06 +GCJ (O0,.class) 9.671 0.07 +Kaffe 1.0.6 9.81 0.07 sunwjit 2.229 0.31 ??? interpreter 2.393 0.29 diff -aruN shujit-0.6.7/txt/benchmark-X20 shujit/txt/benchmark-X20 --- shujit-0.6.7/txt/benchmark-X20 Thu Jan 1 09:00:00 1970 +++ shujit/txt/benchmark-X20 Tue Nov 14 11:45:34 2000 @@ -0,0 +1,35 @@ +IBM ThinkPad X20 + Mobile Pentium III / 600MHz + +[Linpack Benchmark -- Java Version] + + 500 x 500 + +IBM JDK 1.3.0 37.577 2.23 +IBM JDK 1.1.8 35.949 2.33 +Client VM, Sun 27.095 3.09 +Server VM, Sun 26.035 3.22 +shuJIT 001010, JDK118 19.29 4.35 +shuJIT 001010, JDK122 19.088 4.39 +Inprise 1.2.15, JDK122 18.284 4.59 +TYA 1.7v2, JDK122 16.094 5.21 +OpenJIT 1.1.14, JDK122 12.539 6.69 +GCJ (O2, java) 22.993 3.65 +GCJ (O2, class) 25.243 3.32 +GCJ (O0, java) 16.256 5.16 +GCJ (O0, class) 13.807 6.07 + + 200 x 200 + +GCJ (O2, java) 49.048 0.01 +GCJ (O2, class) 45.778 0.01 +Client VM, Sun 29.855 0.02 +shuJIT 001010, JDK118 27.467 0.03 +IBM JDK 1.1.8 27.467 0.03 +GCJ (O0, java) 22.889 0.03 +OpenJIT 1.1.14, JDK122 22.151 0.03 +shuJIT 001010, JDK122 21.458 0.03 +Inprise 1.2.15, JDK122 20.808 0.03 +TYA 1.7v2, JDK122 20.196 0.03 +GCJ (O0, class) 17.167 0.04 +IBM JDK 1.3.0 10.404 0.07