X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=src%2Forg%2Fibex%2Fnestedvm%2FRuntimeCompiler.java;h=443c217f7aaf8273ee5ea8e5dd18114b411c08bf;hb=beabe49c6d19528ab3d27081c7af4fd9fb74027b;hp=80f56ac2995ca51844ec5a4d03ea42bfb7f3d290;hpb=98f786ce8ee1fcd9568d1c367160851d32e1c786;p=nestedvm.git diff --git a/src/org/ibex/nestedvm/RuntimeCompiler.java b/src/org/ibex/nestedvm/RuntimeCompiler.java index 80f56ac..443c217 100644 --- a/src/org/ibex/nestedvm/RuntimeCompiler.java +++ b/src/org/ibex/nestedvm/RuntimeCompiler.java @@ -1,33 +1,62 @@ +// Copyright 2000-2005 the Contributors, as shown in the revision logs. +// Licensed under the Apache Public Source License 2.0 ("the License"). +// You may not use this file except in compliance with the License. + package org.ibex.nestedvm; import java.io.*; import org.ibex.nestedvm.util.*; -// FEATURE: This need a lot of work to support binaries spanned across many classes +// This need a lot of work to support binaries spanned across many classes public class RuntimeCompiler { - // FEATURE: Do we need to periodicly create a new classloader to allow old clases to be GCed? - private static SingleClassLoader singleClassLoader = new SingleClassLoader(); - // FEATURE: Is it ok if this overflows? - private static long nextID = 1; - private static synchronized String uniqueID() { return Long.toString(nextID++); } + private static SingleClassLoader singleClassLoader; + private static int nextID; - public static Class compile(Seekable data) throws IOException, Compiler.Exn { - String className = "nextedvm.runtimecompiled_" + uniqueID(); + public static Class compile(Seekable data) throws IOException, Compiler.Exn { return compile(data,null); } + public static Class compile(Seekable data, String extraoptions) throws IOException, Compiler.Exn { + int id; + synchronized(RuntimeCompiler.class) { + if(nextID == 32 || singleClassLoader == null) { + singleClassLoader = new SingleClassLoader(); + nextID = 0; + } + id = nextID++; + } + String className = "nestedvm.runtimecompiled_" + id; System.err.println("RuntimeCompiler: Building " + className); + byte[] bytecode; + try { + bytecode = runCompiler(data,className,extraoptions,null); + } catch(Compiler.Exn e) { + if(e.getMessage() != null || e.getMessage().indexOf("constant pool full") != -1) + bytecode = runCompiler(data,className,extraoptions,"lessconstants"); + else + throw e; + } + return singleClassLoader.fromBytes(className,bytecode); + } + + private static byte[] runCompiler(Seekable data, String name, String options, String moreOptions) throws IOException, Compiler.Exn { ByteArrayOutputStream baos = new ByteArrayOutputStream(); - ClassFileCompiler c = new ClassFileCompiler(data,className,baos); - // FEATURE: make this Optional, pass options on compile arguments - c.parseOptions("unixruntime"); - c.go(); + + try { + ClassFileCompiler c = new ClassFileCompiler(data,name,baos); + c.parseOptions("nosupportcall,maxinsnpermethod=256"); + if(options != null) c.parseOptions(options); + if(moreOptions != null) c.parseOptions(moreOptions); + c.go(); + } finally { + data.seek(0); + } + baos.close(); - byte[] bytecode = baos.toByteArray(); - return singleClassLoader.fromBytes(className,bytecode); + return baos.toByteArray(); } private static class SingleClassLoader extends ClassLoader { public Class loadClass(String name, boolean resolve) throws ClassNotFoundException { - System.err.println(this + ": loadClass(\"" + name + "," + resolve + ");"); + //System.err.println(this + ": loadClass(\"" + name + "," + resolve + ");"); return super.loadClass(name,resolve); } public Class fromBytes(String name, byte[] b) { return fromBytes(name,b,0,b.length); } @@ -39,13 +68,13 @@ public class RuntimeCompiler { } public static void main(String[] args) throws Exception { - if(args.length == 0) { - System.err.println("Usage: RuntimeCompiler mipsbinary"); + if(args.length == 0) { + System.err.println("Usage: RuntimeCompiler mipsbinary"); System.exit(1); } - UnixRuntime r = (UnixRuntime) compile(new Seekable.File(args[0])).newInstance(); + UnixRuntime r = (UnixRuntime) compile(new Seekable.File(args[0]),"unixruntime").newInstance(); System.err.println("Instansiated: "+ r); - System.exit(r.run(args)); + System.exit(UnixRuntime.runAndExec(r,args)); } private RuntimeCompiler() { }