# HG changeset patch # User Lukas Stadler # Date 1302698413 -7200 # Node ID 34354e2e40a3f3ae51f7c900337b0e0e0cc4234d # Parent 160aacf936ad0b66bc76e3f741bf726a575ac4ce cleanups and client/server fixes: * explicit init of CompilerImpl * CompilationServer terminates without EOFException * moved C1XOptions initialization code into separate class (static initializer changed to static method) * added ConnectionObserver to CompilationServer diff -r 160aacf936ad -r 34354e2e40a3 c1x4hotspotsrc/HotSpotVM/src/com/sun/hotspot/c1x/CompilerImpl.java --- a/c1x4hotspotsrc/HotSpotVM/src/com/sun/hotspot/c1x/CompilerImpl.java Tue Apr 12 16:58:56 2011 +0200 +++ b/c1x4hotspotsrc/HotSpotVM/src/com/sun/hotspot/c1x/CompilerImpl.java Wed Apr 13 14:40:13 2011 +0200 @@ -26,6 +26,8 @@ import com.sun.c1x.*; import com.sun.c1x.target.amd64.*; +import com.sun.cri.ci.*; +import com.sun.cri.ri.*; import com.sun.cri.xir.*; import com.sun.hotspot.c1x.logging.*; import com.sun.hotspot.c1x.server.*; @@ -40,39 +42,43 @@ private static Compiler theInstance; private static boolean PrintGCStats = false; - private final VMEntries vmEntries; - private final VMExits vmExits; + public static Compiler getInstance() { + return theInstance; + } + + public static void initialize() { + if (theInstance != null) { + throw new IllegalStateException("Compiler already initialized"); + } - private C1XCompiler compiler; - private final HotSpotRuntime runtime; - private final RiXirGenerator generator; - private final HotSpotTarget target; - private final HotSpotRegisterConfig registerConfig; + String remote = System.getProperty("c1x.remote"); + if (remote != null) { + // remote compilation (will not create a local Compiler) + try { + System.out.println("C1X compiler started in client/server mode, server: " + remote); + Socket socket = new Socket(remote, 1199); + ReplacingStreams streams = new ReplacingStreams(socket.getOutputStream(), socket.getInputStream()); + streams.getInvocation().sendResult(new VMEntriesNative()); - public static Compiler getInstance() { - if (theInstance == null) { - // remote compilation (will not create a C1XCompiler) - String remote = System.getProperty("c1x.remote"); - if (remote != null) { - try { - System.out.println("C1X compiler started in client/server mode, server: " + remote); - Socket socket = new Socket(remote, 1199); - ReplacingStreams streams = new ReplacingStreams(socket.getOutputStream(), socket.getInputStream()); - streams.getInvocation().sendResult(new VMEntriesNative()); + theInstance = (Compiler) streams.getInvocation().waitForResult(false); + } catch (IOException e1) { + System.out.println("Connection to compilation server FAILED."); + throw new RuntimeException(e1); + } catch (ClassNotFoundException e2) { + System.out.println("Connection to compilation server FAILED."); + throw new RuntimeException(e2); + } + } else { + // ordinary local compilation + theInstance = new CompilerImpl(null); + Runtime.getRuntime().addShutdownHook(new ShutdownThread()); + } + } - theInstance = (Compiler) streams.getInvocation().waitForResult(); - } catch (IOException e1) { - System.out.println("Connection to compilation server FAILED."); - throw new RuntimeException(e1); - } catch (ClassNotFoundException e2) { - System.out.println("Connection to compilation server FAILED."); - throw new RuntimeException(e2); - } - } else { - theInstance = new CompilerImpl(null); - Runtime.getRuntime().addShutdownHook(new ShutdownThread()); - } - } + public static Compiler initializeServer(VMEntries entries) { + assert theInstance == null; + theInstance = new CompilerImpl(entries); + Runtime.getRuntime().addShutdownHook(new ShutdownThread()); return theInstance; } @@ -113,22 +119,14 @@ System.out.println("Total Garbage Collection Time (ms): " + garbageCollectionTime); } - public static Compiler initializeServer(VMEntries entries) { - assert theInstance == null; - theInstance = new CompilerImpl(entries); - Runtime.getRuntime().addShutdownHook(new ShutdownThread()); - return theInstance; - } + private final VMEntries vmEntries; + private final VMExits vmExits; + private C1XCompiler compiler; - @Override - public VMEntries getVMEntries() { - return vmEntries; - } - - @Override - public VMExits getVMExits() { - return vmExits; - } + private final HotSpotRuntime runtime; + private final CiTarget target; + private final RiXirGenerator generator; + private final RiRegisterConfig registerConfig; private CompilerImpl(VMEntries entries) { @@ -173,9 +171,11 @@ RiXirGenerator generator = new HotSpotXirGenerator(config, target, registerConfig, this); if (Logger.ENABLED) { - generator = LoggingProxy.getProxy(RiXirGenerator.class, generator); + this.generator = LoggingProxy.getProxy(RiXirGenerator.class, generator); + } else { + this.generator = generator; } - this.generator = generator; + } @Override @@ -186,4 +186,14 @@ return compiler; } + @Override + public VMEntries getVMEntries() { + return vmEntries; + } + + @Override + public VMExits getVMExits() { + return vmExits; + } + } diff -r 160aacf936ad -r 34354e2e40a3 c1x4hotspotsrc/HotSpotVM/src/com/sun/hotspot/c1x/HotSpotOptions.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/c1x4hotspotsrc/HotSpotVM/src/com/sun/hotspot/c1x/HotSpotOptions.java Wed Apr 13 14:40:13 2011 +0200 @@ -0,0 +1,104 @@ +/* + * Copyright (c) 2011 Sun Microsystems, Inc. All rights reserved. + * + * Sun Microsystems, Inc. has intellectual property rights relating to technology embodied in the product + * that is described in this document. In particular, and without limitation, these intellectual property + * rights may include one or more of the U.S. patents listed at http://www.sun.com/patents and one or + * more additional patents or pending patent applications in the U.S. and in other countries. + * + * U.S. Government Rights - Commercial software. Government users are subject to the Sun + * Microsystems, Inc. standard license agreement and applicable provisions of the FAR and its + * supplements. + * + * Use is subject to license terms. Sun, Sun Microsystems, the Sun logo, Java and Solaris are trademarks or + * registered trademarks of Sun Microsystems, Inc. in the U.S. and other countries. All SPARC trademarks + * are used under license and are trademarks or registered trademarks of SPARC International, Inc. in the + * U.S. and other countries. + * + * UNIX is a registered trademark in the U.S. and other countries, exclusively licensed through X/Open + * Company, Ltd. + */ + +package com.sun.hotspot.c1x; + +import java.lang.reflect.*; + +import com.sun.c1x.*; +import com.sun.hotspot.c1x.logging.*; + +public class HotSpotOptions { + + public static void setDefaultOptions() { + C1XOptions.setOptimizationLevel(3); + C1XOptions.OptInlineExcept = false; + C1XOptions.OptInlineSynchronized = false; + C1XOptions.DetailedAsserts = false; + C1XOptions.CommentedAssembly = false; + C1XOptions.MethodEndBreakpointGuards = 2; + } + + public static boolean setOption(String option) { + if (option.length() == 0) { + return false; + } + + Object value = null; + String fieldName = null; + String valueString = null; + + System.out.println(option); + + char first = option.charAt(0); + if (first == '+' || first == '-') { + fieldName = option.substring(1); + value = (first == '+'); + } else { + int index = option.indexOf('='); + if (index == -1) { + return false; + } + fieldName = option.substring(0, index); + valueString = option.substring(index + 1); + } + + Field f; + try { + f = C1XOptions.class.getField(fieldName); + + if (value == null) { + if (f.getType() == Float.TYPE) { + value = Float.parseFloat(valueString); + } else if (f.getType() == Double.TYPE) { + value = Double.parseDouble(valueString); + } else if (f.getType() == Integer.TYPE) { + value = Integer.parseInt(valueString); + } else if (f.getType() == Boolean.TYPE) { + value = Boolean.parseBoolean(valueString); + } else if (f.getType() == String.class) { + value = valueString; + } + } + if (value != null) { + f.set(null, value); + Logger.info("Set option " + fieldName + " to " + value); + } else { + Logger.info("Wrong value \"" + valueString + "\" for option " + fieldName); + return false; + } + } catch (SecurityException e) { + Logger.info("Security exception when setting option " + option); + return false; + } catch (NoSuchFieldException e) { + Logger.info("Could not find option " + fieldName); + return false; + } catch (IllegalArgumentException e) { + Logger.info("Illegal value for option " + option); + return false; + } catch (IllegalAccessException e) { + Logger.info("Illegal access exception when setting option " + option); + return false; + } + + return true; + } +} diff -r 160aacf936ad -r 34354e2e40a3 c1x4hotspotsrc/HotSpotVM/src/com/sun/hotspot/c1x/InvocationSocket.java --- a/c1x4hotspotsrc/HotSpotVM/src/com/sun/hotspot/c1x/InvocationSocket.java Tue Apr 12 16:58:56 2011 +0200 +++ b/c1x4hotspotsrc/HotSpotVM/src/com/sun/hotspot/c1x/InvocationSocket.java Wed Apr 13 14:40:13 2011 +0200 @@ -152,6 +152,7 @@ if (forbiddenMethodNames.contains(methodName)) { throw new IllegalAccessException(methodName + " not allowed"); } + Object result = null; try { if (DEBUG) { Logger.startScope("invoking remote " + methodName); @@ -160,7 +161,7 @@ output.writeObject(new Invocation(receiver, methodName, args)); output.flush(); - Object result = waitForResult(); + result = waitForResult(false); // result caching for selected methods if ((args == null || args.length == 0) && cachedMethodNames.contains(methodName)) { @@ -172,7 +173,7 @@ throw t; } finally { if (DEBUG) { - Logger.endScope(""); + Logger.endScope(" = " + result); } } } @@ -182,9 +183,17 @@ * Waits for the result of a remote method invocation. Invocations that should be executed in this VM might arrive * while waiting for the result, and these invocations will be executed before again waiting fort he result. */ - public Object waitForResult() throws IOException, ClassNotFoundException { + public Object waitForResult(boolean eofExpected) throws IOException, ClassNotFoundException { while (true) { - Object in = input.readObject(); + Object in; + try { + in = input.readObject(); + } catch(EOFException e) { + if (eofExpected) { + return null; + } + throw e; + } if (in instanceof Result) { return ((Result) in).result; } else if (in instanceof RuntimeException) { @@ -209,7 +218,7 @@ output.writeObject(e); output.flush(); } else { - Object result; + Object result = null; try { if (invoke.args == null) { if (DEBUG) { @@ -244,7 +253,11 @@ result = e.getCause(); } finally { if (DEBUG) { - Logger.endScope(""); + if (result instanceof Result) { + Logger.endScope(" = " + ((Result)result).result); + } else { + Logger.endScope(" = " + result); + } } } output.writeObject(result); diff -r 160aacf936ad -r 34354e2e40a3 c1x4hotspotsrc/HotSpotVM/src/com/sun/hotspot/c1x/VMExits.java --- a/c1x4hotspotsrc/HotSpotVM/src/com/sun/hotspot/c1x/VMExits.java Tue Apr 12 16:58:56 2011 +0200 +++ b/c1x4hotspotsrc/HotSpotVM/src/com/sun/hotspot/c1x/VMExits.java Wed Apr 13 14:40:13 2011 +0200 @@ -31,8 +31,6 @@ */ public interface VMExits { - boolean setOption(String option); - void compileMethod(long methodVmId, String name, int entryBCI) throws Throwable; RiMethod createRiMethodResolved(long vmId, String name); diff -r 160aacf936ad -r 34354e2e40a3 c1x4hotspotsrc/HotSpotVM/src/com/sun/hotspot/c1x/VMExitsNative.java --- a/c1x4hotspotsrc/HotSpotVM/src/com/sun/hotspot/c1x/VMExitsNative.java Tue Apr 12 16:58:56 2011 +0200 +++ b/c1x4hotspotsrc/HotSpotVM/src/com/sun/hotspot/c1x/VMExitsNative.java Wed Apr 13 14:40:13 2011 +0200 @@ -22,10 +22,8 @@ package com.sun.hotspot.c1x; import java.io.*; -import java.lang.reflect.*; import java.util.*; -import com.sun.c1x.*; import com.sun.c1x.debug.*; import com.sun.cri.ci.*; import com.sun.cri.ri.*; @@ -68,82 +66,6 @@ typeVoid = new HotSpotTypePrimitive(compiler, CiKind.Void); } - /** - * Default option configuration for C1X. - */ - static { - C1XOptions.setOptimizationLevel(3); - C1XOptions.OptInlineExcept = false; - C1XOptions.OptInlineSynchronized = false; - C1XOptions.DetailedAsserts = false; - C1XOptions.CommentedAssembly = false; - C1XOptions.MethodEndBreakpointGuards = 2; - } - - @Override - public boolean setOption(String option) { - if (option.length() == 0) { - return false; - } - - Object value = null; - String fieldName = null; - String valueString = null; - - char first = option.charAt(0); - if (first == '+' || first == '-') { - fieldName = option.substring(1); - value = (first == '+'); - } else { - int index = option.indexOf('='); - if (index == -1) { - return false; - } - fieldName = option.substring(0, index); - valueString = option.substring(index + 1); - } - - Field f; - try { - f = C1XOptions.class.getField(fieldName); - - if (value == null) { - if (f.getType() == Float.TYPE) { - value = Float.parseFloat(valueString); - } else if (f.getType() == Double.TYPE) { - value = Double.parseDouble(valueString); - } else if (f.getType() == Integer.TYPE) { - value = Integer.parseInt(valueString); - } else if (f.getType() == Boolean.TYPE) { - value = Boolean.parseBoolean(valueString); - } else if (f.getType() == String.class) { - value = valueString; - } - } - if (value != null) { - f.set(null, value); - Logger.info("Set option " + fieldName + " to " + value); - } else { - Logger.info("Wrong value \"" + valueString + "\" for option " + fieldName); - return false; - } - } catch (SecurityException e) { - Logger.info("Security exception when setting option " + option); - return false; - } catch (NoSuchFieldException e) { - Logger.info("Could not find option " + fieldName); - return false; - } catch (IllegalArgumentException e) { - Logger.info("Illegal value for option " + option); - return false; - } catch (IllegalAccessException e) { - Logger.info("Illegal access exception when setting option " + option); - return false; - } - - return true; - } - private static Set compiledMethods = new HashSet(); @Override diff -r 160aacf936ad -r 34354e2e40a3 c1x4hotspotsrc/HotSpotVM/src/com/sun/hotspot/c1x/server/CompilationServer.java --- a/c1x4hotspotsrc/HotSpotVM/src/com/sun/hotspot/c1x/server/CompilationServer.java Tue Apr 12 16:58:56 2011 +0200 +++ b/c1x4hotspotsrc/HotSpotVM/src/com/sun/hotspot/c1x/server/CompilationServer.java Wed Apr 13 14:40:13 2011 +0200 @@ -22,6 +22,7 @@ import java.io.*; import java.net.*; +import java.util.*; import javax.net.*; @@ -30,18 +31,53 @@ import com.sun.hotspot.c1x.logging.*; /** - * Server side of the client/server compilation model. + * Server side of the client/server compilation model. The server listens for connections on the hardcoded port 1199. * * @author Lukas Stadler */ -public class CompilationServer { +public class CompilationServer implements Runnable { public static void main(String[] args) throws Exception { - new CompilationServer().run(); + new CompilationServer(false).run(); + } + + public static interface ConnectionObserver { + + public void connectionStarted(Compiler compiler); + + public void connectionFinished(Compiler compiler); } - private void run() throws IOException, ClassNotFoundException { - ServerSocket serverSocket = ServerSocketFactory.getDefault().createServerSocket(1199); + private final boolean multiple; + private final ArrayList observers = new ArrayList(); + + /** + * Creates a new Compilation server. The server is activated by calling {@link #run()} directly or via a new + * {@link Thread}. + * + * @param multiple true if the server should server should serve an infinite amount of consecutive connections, + * false if it should terminate after the first connection ends. + */ + public CompilationServer(boolean multiple) { + this.multiple = multiple; + HotSpotOptions.setDefaultOptions(); + } + + public void addConnectionObserver(ConnectionObserver observer) { + observers.add(observer); + } + + public void removeConnectionObserver(ConnectionObserver observer) { + observers.remove(observer); + } + + public void run() { + final ServerSocket serverSocket; + try { + serverSocket = ServerSocketFactory.getDefault().createServerSocket(1199); + } catch (IOException e) { + throw new RuntimeException("Couldn't create compilation server", e); + } do { Socket socket = null; try { @@ -51,18 +87,35 @@ ReplacingStreams streams = new ReplacingStreams(socket.getOutputStream(), socket.getInputStream()); - VMEntries entries = (VMEntries) streams.getInvocation().waitForResult(); + // get the VMEntries proxy from the client + VMEntries entries = (VMEntries) streams.getInvocation().waitForResult(false); + + // return the initialized compiler to the client Compiler compiler = CompilerImpl.initializeServer(entries); - + compiler.getCompiler(); streams.getInvocation().sendResult(compiler); - streams.getInvocation().waitForResult(); + for (ConnectionObserver observer : observers) { + observer.connectionStarted(compiler); + } + + streams.getInvocation().waitForResult(true); + + for (ConnectionObserver observer : observers) { + observer.connectionFinished(compiler); + } } catch (IOException e) { e.printStackTrace(); + } catch (ClassNotFoundException e) { + throw new RuntimeException(e); + } finally { if (socket != null) { - socket.close(); + try { + socket.close(); + } catch (IOException e) { + } } } - } while (false); + } while (multiple); } } diff -r 160aacf936ad -r 34354e2e40a3 src/share/vm/c1x/c1x_Compiler.cpp --- a/src/share/vm/c1x/c1x_Compiler.cpp Tue Apr 12 16:58:56 2011 +0200 +++ b/src/share/vm/c1x/c1x_Compiler.cpp Wed Apr 13 14:40:13 2011 +0200 @@ -67,12 +67,15 @@ { VM_ENTRY_MARK; HandleMark hm; + VMExits::setDefaultOptions(); for (int i = 0; i < Arguments::num_c1x_args(); ++i) { const char* arg = Arguments::c1x_args_array()[i]; Handle option = java_lang_String::create_from_str(arg, THREAD); jboolean result = VMExits::setOption(option); if (!result) fatal("Invalid option for C1X!"); } + + VMExits::initializeCompiler(); } } diff -r 160aacf936ad -r 34354e2e40a3 src/share/vm/c1x/c1x_VMExits.cpp --- a/src/share/vm/c1x/c1x_VMExits.cpp Tue Apr 12 16:58:56 2011 +0200 +++ b/src/share/vm/c1x/c1x_VMExits.cpp Wed Apr 13 14:40:13 2011 +0200 @@ -67,18 +67,37 @@ return Handle(JNIHandles::resolve_non_null(_vmExitsPermObject)); } +void VMExits::initializeCompiler() { + KlassHandle compilerImplKlass = SystemDictionary::resolve_or_null(vmSymbols::com_sun_hotspot_c1x_CompilerImpl(), SystemDictionary::java_system_loader(), NULL, Thread::current()); + check_not_null(compilerImplKlass(), "Couldn't find class com.sun.hotspot.c1x.CompilerImpl"); + + JavaValue result(T_VOID); + JavaCalls::call_static(&result, compilerImplKlass, vmSymbols::initialize_name(), vmSymbols::void_method_signature(), Thread::current()); + check_pending_exception("Couldn't initialize compiler"); +} + jboolean VMExits::setOption(Handle option) { assert(!option.is_null(), ""); + KlassHandle compilerKlass = SystemDictionary::resolve_or_null(vmSymbols::com_sun_hotspot_c1x_HotSpotOptions(), SystemDictionary::java_system_loader(), NULL, Thread::current()); + check_not_null(compilerKlass(), "Couldn't find class com.sun.hotspot.c1x.HotSpotOptions"); + Thread* THREAD = Thread::current(); JavaValue result(T_BOOLEAN); - JavaCallArguments args; - args.push_oop(instance()); - args.push_oop(option); - JavaCalls::call_interface(&result, vmExitsKlass(), vmSymbols::setOption_name(), vmSymbols::setOption_signature(), &args, THREAD); + JavaCalls::call_static(&result, compilerKlass, vmSymbols::setOption_name(), vmSymbols::setOption_signature(), option, THREAD); check_pending_exception("Error while calling setOption"); return result.get_jboolean(); } +void VMExits::setDefaultOptions() { + KlassHandle compilerKlass = SystemDictionary::resolve_or_null(vmSymbols::com_sun_hotspot_c1x_HotSpotOptions(), SystemDictionary::java_system_loader(), NULL, Thread::current()); + check_not_null(compilerKlass(), "Couldn't find class com.sun.hotspot.c1x.HotSpotOptions"); + + Thread* THREAD = Thread::current(); + JavaValue result(T_VOID); + JavaCalls::call_static(&result, compilerKlass, vmSymbols::setDefaultOptions_name(), vmSymbols::void_method_signature(), THREAD); + check_pending_exception("Error while calling setDefaultOptions"); +} + void VMExits::compileMethod(jlong methodVmId, Handle name, int entry_bci) { assert(!name.is_null(), "just checking"); Thread* THREAD = Thread::current(); diff -r 160aacf936ad -r 34354e2e40a3 src/share/vm/c1x/c1x_VMExits.hpp --- a/src/share/vm/c1x/c1x_VMExits.hpp Tue Apr 12 16:58:56 2011 +0200 +++ b/src/share/vm/c1x/c1x_VMExits.hpp Wed Apr 13 14:40:13 2011 +0200 @@ -33,11 +33,16 @@ static Handle instance(); public: + static void initializeCompiler(); + static Handle compilerInstance(); - // public abstract boolean setOption(String option); + // public static boolean HotSpotOptions.setOption(String option); static jboolean setOption(Handle option); + // public static void HotSpotOptions.setDefaultOptions(); + static void setDefaultOptions(); + // public abstract void compileMethod(long vmId, String name, int entry_bci); static void compileMethod(jlong vmId, Handle name, int entry_bci); diff -r 160aacf936ad -r 34354e2e40a3 src/share/vm/classfile/vmSymbols.hpp --- a/src/share/vm/classfile/vmSymbols.hpp Tue Apr 12 16:58:56 2011 +0200 +++ b/src/share/vm/classfile/vmSymbols.hpp Wed Apr 13 14:40:13 2011 +0200 @@ -265,6 +265,7 @@ template(com_sun_hotspot_c1x_HotSpotTargetMethod, "com/sun/hotspot/c1x/HotSpotTargetMethod") \ template(com_sun_hotspot_c1x_HotSpotField, "com/sun/hotspot/c1x/HotSpotField") \ template(com_sun_c1x_C1XOptions, "com/sun/c1x/C1XOptions") \ + template(com_sun_hotspot_c1x_HotSpotOptions, "com/sun/hotspot/c1x/HotSpotOptions") \ template(com_sun_hotspot_c1x_HotSpotTypeResolved, "com/sun/hotspot/c1x/HotSpotTypeResolvedImpl") \ template(com_sun_hotspot_c1x_HotSpotType, "com/sun/hotspot/c1x/HotSpotType") \ template(com_sun_hotspot_c1x_HotSpotExceptionHandler,"com/sun/hotspot/c1x/HotSpotExceptionHandler") \ @@ -300,6 +301,7 @@ template(compileMethod_name, "compileMethod") \ template(compileMethod_signature, "(JLjava/lang/String;I)V") \ template(setOption_name, "setOption") \ + template(setDefaultOptions_name, "setDefaultOptions") \ template(setOption_signature, "(Ljava/lang/String;)Z") \ template(createRiMethodResolved_name, "createRiMethodResolved") \ template(createRiMethodResolved_signature, "(JLjava/lang/String;)Lcom/sun/cri/ri/RiMethod;") \ @@ -328,6 +330,7 @@ template(getVMExits_name, "getVMExits") \ template(getVMExits_signature, "()Lcom/sun/hotspot/c1x/VMExits;") \ template(getInstance_name, "getInstance") \ + template(initialize_name, "initialize") \ template(getInstance_signature, "()Lcom/sun/hotspot/c1x/Compiler;") \ template(forObject_name, "forObject") \ \