/*
* $Id$
*
* Copyright (C) 2003-2014 JNode.org
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation; either version 2.1 of the License, or
* (at your option) any later version.
*
* This library is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
* License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this library; If not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
package org.jnode.test.core;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.net.URL;
import org.jnode.assembler.ObjectResolver;
import org.jnode.assembler.x86.X86TextAssembler;
import org.jnode.vm.VmImpl;
import org.jnode.vm.BaseVmArchitecture;
import org.jnode.vm.VmSystemClassLoader;
import org.jnode.vm.classmgr.VmMethod;
import org.jnode.vm.classmgr.VmType;
import org.jnode.vm.compiler.NativeCodeCompiler;
import org.jnode.vm.x86.VmX86Architecture;
import org.jnode.vm.x86.VmX86Architecture32;
import org.jnode.vm.x86.VmX86Architecture64;
import org.jnode.vm.x86.X86CpuID;
import org.jnode.vm.x86.compiler.l1a.X86Level1ACompiler;
import org.jnode.vm.x86.compiler.l2.X86Level2Compiler;
/**
* Bytecode to native compiler test.
* Runt this class in the root directory of the JNode source tree.
*
* @author epr
*/
public class CompilerTest {
public static final String[] clsNames = {
// "java.util.zip.ZipFile$PartialInputStream",
// "java.security.SecureRandom",
// "java.lang.Boolean",
// "java.lang.Integer",
// "java.lang.String",
//"java.lang.StrictMath",
// "java.lang.VMDouble",
// "java.io.StringBufferInputStream",
// "java.net.MimeTypeMapper",
// "gnu.java.io.ObjectIdentityWrapper",
// "gnu.java.io.encode.EncoderEightBitLookup",
// "java.io.ObjectInputStream$3",
// "java.io.PrintWriter",
// "java.nio.ByteOrder",
// "org.jnode.assembler.x86.X86BinaryAssembler",
// "org.jnode.assembler.x86.X86BinaryAssembler$X86ObjectInfo",
// "org.jnode.fs.ext2.Ext2FileSystem",
// "org.jnode.vm.Unsafe$UnsafeObjectResolver",
// "org.jnode.vm.MemoryBlockManager",
// "org.jnode.vm.SoftByteCodes",
// "org.jnode.vm.VmSystem",
// "org.jnode.vm.VmStacReader",
// "org.jnode.vm.classmgr.VmType",
// "org.jnode.test.ArrayLongTest",
// "org.jnode.test.ArrayTest",
"org.jnode.vm.compiler.ir.PrimitiveTest",
// "org.jnode.vm.compiler.ir.CompilerTest",
// "org.jnode.games.tetris.Tetris",
// "org.jnode.test.Linpack",
// "org.jnode.test.MultiANewArrayTest",
// "org.jnode.test.Sieve",
// "org.jnode.test.PrimitiveIntTest",
// "org.jnode.test.PrimitiveLongTest",
// "org.jnode.test.PrimitiveFloatTest",
// "org.jnode.test.PrimitiveDoubleTest", "org.jnode.test.InvokeTest",
// "org.jnode.test.InvokeInterfaceTest",
// "org.jnode.test.InvokeStaticTest",
// "org.jnode.plugin.model.PluginJar",
// "org.jnode.test.ArithOpt",
// "org.jnode.test.InlineTestClass",
// "org.jnode.test.CastTest",
// "org.jnode.test.InstanceOfTest",
//"org.jnode.test.ConvertTest",
// "org.jnode.vm.MonitorManager",
// "org.jnode.vm.memmgr.def.VmBootHeap",
// "org.jnode.vm.classmgr.VmCP",
// "java.util.zip.ZipInputStream",
// "org.jnode.test.MagicWordTest",
// "gnu.java.awt.color.SrgbConverter",
// "gnu.classpath.SystemProperties",
// "org.jnode.test.ArrayTest",
// "org.jnode.test.IfNullTest",
// "org.jnode.vm.bytecode.BytecodeParser",
};
public static void main(String[] args) throws Exception {
final String processorId = System.getProperty("cpu", "p5");
final String dir = System.getProperty("classes.dir", ".");
final String archName = System.getProperty("arch", "x86");
final VmX86Architecture arch;
if (archName.equals("x86_64")) {
arch = new VmX86Architecture64();
} else {
arch = new VmX86Architecture32();
}
final VmSystemClassLoader cl = new VmSystemClassLoader(new java.net.URL[]{
new File("./core/build/classes/").getCanonicalFile().toURI().toURL(),
new File("./distr/build/classes/").getCanonicalFile().toURI().toURL(),
new URL("jar:" + new File("./all/lib/classlib.jar").getCanonicalFile().toURI().toURL() + "!/"),
}, arch);
final VmImpl vm = new VmImpl("?", arch, cl.getSharedStatics(), false, cl, null);
vm.toString();
VmType.initializeForBootImage(cl);
System.out.println("Architecture: " + arch.getFullName());
//final ObjectResolver resolver = new DummyResolver();
final X86CpuID cpuId = X86CpuID.createID(processorId);
//NativeCodeCompiler c = cs[0];
final NativeCodeCompiler[] cs = {
//new X86Level1Compiler(),
new X86Level1ACompiler(),
new X86Level2Compiler()
};
for (int i = 0; i < cs.length; i++) {
cs[i].initialize(cl);
}
long times[] = new long[cs.length];
int counts[] = new int[cs.length];
for (int ci = 0; ci < cs.length; ci++) {
final long start = System.currentTimeMillis();
for (int k = 0; k < clsNames.length; k++) {
final String clsName = clsNames[k];
System.out.println("Compiling " + clsName);
final VmType type = cl.loadClass(clsName, true);
final int cnt = type.getNoDeclaredMethods();
for (int i = 0; i < cnt; i++) {
final VmMethod method = type.getDeclaredMethod(i);
if (
"<init>".equals(method.getName()) ||
"main".equals(method.getName()) ||
!X86Level2Compiler.canCompile(method)
)
continue;
System.out.println("Compiling method " + clsName + "#" + method.getName());
counts[ci]++;
try {
compile(method, arch, cs[ci], cpuId, ci + 1);
} catch (Exception x) {
x.printStackTrace();
}
}
}
final long end = System.currentTimeMillis();
times[ci] += end - start;
}
for (int ci = 0; ci < cs.length; ci++) {
System.out.println("Compiled " + counts[ci] + " methods using "
+ cs[ci].getName() + " in " + times[ci] + "ms");
}
}
static void compile(VmMethod method, BaseVmArchitecture arch, NativeCodeCompiler c, X86CpuID cpuId,
int level) throws IOException {
final String cname = method.getDeclaringClass().getName();
final String mname = method.getName();
final String fname = cname + "#"
+ mname.replace('<', '_').replace('>', '_') + "." + c.getName()
+ ".method";
final File outDir = new File("./core/build/compiler-test");
outDir.mkdirs();
final FileOutputStream out = new FileOutputStream(new File(outDir, fname));
try {
// if (!method.isAbstract()) {
// final PrintStream ps = new PrintStream(out);
// BytecodeViewer viewer = new BytecodeViewer(
// new ControlFlowGraph(method.getBytecode()), ps);
// BytecodeParser.parse(method.getBytecode(), viewer);
// ps.flush();
// }
X86TextAssembler os = new X86TextAssembler(new OutputStreamWriter(out),
cpuId, ((VmX86Architecture) arch).getMode(), method.getMangledName());
// X86BinaryAssembler os = new X86BinaryAssembler(cpuId, ((VmX86Architecture) arch).getMode(), 0);
try {
c.compileBootstrap(method, os, level);
//c.compileRuntime(method, resolver, level, os);
} finally {
// out.write(os.getBytes());
os.flush();
}
} catch (Throwable ex) {
System.out.println("Error in ### Method " + mname + " -> " + fname);
ex.printStackTrace();
System.exit(1);
} finally {
out.close();
}
}
static class DummyResolver extends ObjectResolver {
/**
* @see org.jnode.assembler.ObjectResolver#addressOf32(java.lang.Object)
*/
public int addressOf32(Object object) {
return 0;
}
/**
* @see org.jnode.assembler.ObjectResolver#addressOf64(java.lang.Object)
*/
public long addressOf64(Object object) {
return 0L;
}
}
}