changeset 151:81c3deb0f69f

Cleanup binary link.
author shade
date Tue, 27 Aug 2013 17:59:27 +0400
parents a3aef9af97ce
children 9b7bbf28d685
files jmh-core/src/main/java/org/openjdk/jmh/ForkedMain.java jmh-core/src/main/java/org/openjdk/jmh/link/BinaryLinkClient.java jmh-core/src/main/java/org/openjdk/jmh/link/BinaryLinkServer.java jmh-core/src/main/java/org/openjdk/jmh/link/CallInfo.java jmh-core/src/main/java/org/openjdk/jmh/link/InfraRequest.java jmh-core/src/main/java/org/openjdk/jmh/link/OptionsReply.java jmh-core/src/main/java/org/openjdk/jmh/link/frames/FinishingFrame.java jmh-core/src/main/java/org/openjdk/jmh/link/frames/InfraFrame.java jmh-core/src/main/java/org/openjdk/jmh/link/frames/OptionsFrame.java jmh-core/src/main/java/org/openjdk/jmh/link/frames/OutputFormatFrame.java jmh-core/src/main/java/org/openjdk/jmh/output/OutputFormatFactory.java jmh-core/src/main/java/org/openjdk/jmh/runner/Runner.java
diffstat 12 files changed, 250 insertions(+), 188 deletions(-) [+]
line wrap: on
line diff
--- a/jmh-core/src/main/java/org/openjdk/jmh/ForkedMain.java	Tue Aug 27 17:43:33 2013 +0400
+++ b/jmh-core/src/main/java/org/openjdk/jmh/ForkedMain.java	Tue Aug 27 17:59:27 2013 +0400
@@ -47,19 +47,35 @@
         if (argv.length == 0) {
             throw new IllegalArgumentException("Empty arguments for forked VM");
         } else {
+            BinaryLinkClient link = null;
             try {
-                String hostname = argv[0];
+                // This assumes the exact order of arguments:
+                //   1) host name to back-connect
+                //   2) host port to back-connect
+                //   3) benchmark to execute (saves benchmark lookup via Options)
+                String hostName = argv[0];
                 int hostPort = Integer.valueOf(argv[1]);
                 BenchmarkRecord benchmark = new BenchmarkRecord(argv[2]);
 
-                BinaryLinkClient link = new BinaryLinkClient(hostname, hostPort);
+                // establish the link to host VM and pull the options
+                link = new BinaryLinkClient(hostName, hostPort);
                 Options options = link.requestOptions();
+
+                // run!
                 ForkedRunner runner = new ForkedRunner(options, link);
                 runner.run(benchmark);
             } catch (IOException ex) {
                 throw new IllegalArgumentException(ex.getMessage());
             } catch (ClassNotFoundException ex) {
                 throw new IllegalArgumentException(ex.getMessage());
+            } finally {
+                if (link != null) {
+                    try {
+                        link.close();
+                    } catch (IOException e) {
+                        // swallow
+                    }
+                }
             }
         }
     }
--- a/jmh-core/src/main/java/org/openjdk/jmh/link/BinaryLinkClient.java	Tue Aug 27 17:43:33 2013 +0400
+++ b/jmh-core/src/main/java/org/openjdk/jmh/link/BinaryLinkClient.java	Tue Aug 27 17:59:27 2013 +0400
@@ -24,6 +24,10 @@
  */
 package org.openjdk.jmh.link;
 
+import org.openjdk.jmh.link.frames.FinishingFrame;
+import org.openjdk.jmh.link.frames.InfraFrame;
+import org.openjdk.jmh.link.frames.OptionsFrame;
+import org.openjdk.jmh.link.frames.OutputFormatFrame;
 import org.openjdk.jmh.runner.options.Options;
 
 import java.io.IOException;
@@ -33,7 +37,7 @@
 import java.lang.reflect.Method;
 import java.net.Socket;
 
-public final class BinaryLinkClient implements InvocationHandler {
+public final class BinaryLinkClient {
 
     private final Socket clientSocket;
 
@@ -47,26 +51,30 @@
     }
 
     public Options requestOptions() throws IOException, ClassNotFoundException {
-        oos.writeObject(new InfraRequest(InfraRequest.Type.OPTIONS_REQUEST));
+        oos.writeObject(new InfraFrame(InfraFrame.Type.OPTIONS_REQUEST));
         Object reply = ois.readObject();
-        if (reply instanceof OptionsReply) {
-            return (((OptionsReply) reply).getOpts());
+        if (reply instanceof OptionsFrame) {
+            return (((OptionsFrame) reply).getOpts());
         } else {
             throw new IllegalStateException("Got the erroneous reply: " + reply);
         }
     }
 
-    @Override
-    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
-        oos.writeObject(new CallInfo(ClassConventions.getMethodName(method), args));
+    public InvocationHandler getOutputFormatHandler() {
+        return new InvocationHandler() {
+            @Override
+            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
+                oos.writeObject(new OutputFormatFrame(ClassConventions.getMethodName(method), args));
+                oos.flush();
+                return null; // expect null
+            }
+        };
+    }
+
+    public void close() throws IOException {
+        oos.writeObject(new FinishingFrame());
         oos.flush();
-
-        if (method.getName().equals("close")) {
-            // other side is notified, close ourselves
-            oos.close();
-            clientSocket.close();
-        }
-
-        return null; // expect null
+        oos.close();
+        clientSocket.close();
     }
 }
--- a/jmh-core/src/main/java/org/openjdk/jmh/link/BinaryLinkServer.java	Tue Aug 27 17:43:33 2013 +0400
+++ b/jmh-core/src/main/java/org/openjdk/jmh/link/BinaryLinkServer.java	Tue Aug 27 17:59:27 2013 +0400
@@ -24,6 +24,10 @@
  */
 package org.openjdk.jmh.link;
 
+import org.openjdk.jmh.link.frames.FinishingFrame;
+import org.openjdk.jmh.link.frames.InfraFrame;
+import org.openjdk.jmh.link.frames.OptionsFrame;
+import org.openjdk.jmh.link.frames.OutputFormatFrame;
 import org.openjdk.jmh.output.format.OutputFormat;
 import org.openjdk.jmh.runner.options.Options;
 
@@ -59,7 +63,6 @@
     private final OutputFormat out;
     private final Map<String, Method> methods;
     private final Set<String> forbidden;
-    private final Set<String> finishing;
     private final Acceptor acceptor;
     private final List<Handler> registeredHandlers;
 
@@ -68,7 +71,6 @@
         this.out = out;
         this.methods = new HashMap<String, Method>();
         this.forbidden = new HashSet<String>();
-        this.finishing = new HashSet<String>();
 
         // enumerate methods
         for (Method m : out.getClass().getMethods()) {
@@ -77,9 +79,6 @@
             if (m.getName().equals("startRun")) { forbidden.add(ClassConventions.getMethodName(m)); }
             if (m.getName().equals("endRun"))   { forbidden.add(ClassConventions.getMethodName(m)); }
 
-            // receiving close has a special meaning
-            if (m.getName().equals("close"))    { finishing.add(ClassConventions.getMethodName(m)); }
-
             Method prev = methods.put(ClassConventions.getMethodName(m), m);
             if (prev != null) {
                 out.println("WARNING: Duplicate methods: " + m + " vs. " + prev);
@@ -199,36 +198,15 @@
 
                 Object obj;
                 while ((obj = ois.readObject()) != null) {
-                    if (obj instanceof CallInfo) {
-                        CallInfo frame = (CallInfo) obj;
-
-                        Method m = methods.get(frame.method);
-
-                        if (finishing.contains(frame.method)) {
-                            break;
-                        }
-
-                        if (forbidden.contains(frame.method)) {
-                            continue;
-                        }
-
-                        if (m == null) {
-                            out.println("WARNING: Unknown method to forward: " + frame.method);
-                            continue;
-                        }
-
-                        m.invoke(out, frame.args);
+                    if (obj instanceof OutputFormatFrame) {
+                        handleOutputFormat((OutputFormatFrame) obj);
                     }
-
-                    if (obj instanceof InfraRequest) {
-                        switch (((InfraRequest) obj).getType()) {
-                            case OPTIONS_REQUEST:
-                                oos.writeObject(new OptionsReply(opts));
-                                oos.flush();
-                                break;
-                            default:
-                                throw new IllegalStateException("Unknown infrastructure request: " + obj);
-                        }
+                    if (obj instanceof InfraFrame) {
+                        handleInfra((InfraFrame) obj);
+                    }
+                    if (obj instanceof FinishingFrame) {
+                        // close the streams
+                        break;
                     }
                 }
             } catch (ObjectStreamException e) {
@@ -248,6 +226,33 @@
             }
         }
 
+        private void handleInfra(InfraFrame req) throws IOException {
+            switch (req.getType()) {
+                case OPTIONS_REQUEST:
+                    oos.writeObject(new OptionsFrame(opts));
+                    oos.flush();
+                    break;
+                default:
+                    throw new IllegalStateException("Unknown infrastructure request: " + req);
+            }
+        }
+
+        private boolean handleOutputFormat(OutputFormatFrame frame) throws IllegalAccessException, InvocationTargetException {
+            Method m = methods.get(frame.method);
+
+            if (m == null) {
+                out.println("WARNING: Unknown method to forward: " + frame.method);
+                return true;
+            }
+
+            if (forbidden.contains(frame.method)) {
+                return true;
+            }
+
+            m.invoke(out, frame.args);
+            return false;
+        }
+
         public void close() {
             try {
                 socket.close();
--- a/jmh-core/src/main/java/org/openjdk/jmh/link/CallInfo.java	Tue Aug 27 17:43:33 2013 +0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,43 +0,0 @@
-/*
- * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code 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 General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package org.openjdk.jmh.link;
-
-import java.io.Serializable;
-
-/**
- * Call info:
- *   - method name
- *   - arguments (assumed to be serializable)
- */
-public class CallInfo implements Serializable {
-    private static final long serialVersionUID = -7151852354574635295L;
-    public final String method;
-    public final Object[] args;
-
-    public CallInfo(String method, Object[] args) {
-        this.method = method;
-        this.args = args;
-    }
-}
--- a/jmh-core/src/main/java/org/openjdk/jmh/link/InfraRequest.java	Tue Aug 27 17:43:33 2013 +0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,45 +0,0 @@
-/*
- * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code 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 General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package org.openjdk.jmh.link;
-
-import java.io.Serializable;
-
-public class InfraRequest implements Serializable {
-
-    private final Type type;
-
-    public InfraRequest(Type type) {
-        this.type = type;
-    }
-
-    public Type getType() {
-        return type;
-    }
-
-    public enum Type {
-        OPTIONS_REQUEST,
-    }
-
-}
--- a/jmh-core/src/main/java/org/openjdk/jmh/link/OptionsReply.java	Tue Aug 27 17:43:33 2013 +0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,42 +0,0 @@
-/*
- * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code 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 General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package org.openjdk.jmh.link;
-
-import org.openjdk.jmh.runner.options.Options;
-
-import java.io.Serializable;
-
-public class OptionsReply implements Serializable {
-
-    private final Options opts;
-
-    public OptionsReply(Options opts) {
-        this.opts = opts;
-    }
-
-    public Options getOpts() {
-        return opts;
-    }
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jmh-core/src/main/java/org/openjdk/jmh/link/frames/FinishingFrame.java	Tue Aug 27 17:59:27 2013 +0400
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code 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 General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.jmh.link.frames;
+
+import java.io.Serializable;
+
+public class FinishingFrame implements Serializable {
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jmh-core/src/main/java/org/openjdk/jmh/link/frames/InfraFrame.java	Tue Aug 27 17:59:27 2013 +0400
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code 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 General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.jmh.link.frames;
+
+import java.io.Serializable;
+
+public class InfraFrame implements Serializable {
+
+    private final Type type;
+
+    public InfraFrame(Type type) {
+        this.type = type;
+    }
+
+    public Type getType() {
+        return type;
+    }
+
+    public enum Type {
+        OPTIONS_REQUEST,
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jmh-core/src/main/java/org/openjdk/jmh/link/frames/OptionsFrame.java	Tue Aug 27 17:59:27 2013 +0400
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code 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 General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.jmh.link.frames;
+
+import org.openjdk.jmh.runner.options.Options;
+
+import java.io.Serializable;
+
+public class OptionsFrame implements Serializable {
+
+    private final Options opts;
+
+    public OptionsFrame(Options opts) {
+        this.opts = opts;
+    }
+
+    public Options getOpts() {
+        return opts;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jmh-core/src/main/java/org/openjdk/jmh/link/frames/OutputFormatFrame.java	Tue Aug 27 17:59:27 2013 +0400
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code 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 General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.jmh.link.frames;
+
+import java.io.Serializable;
+
+/**
+ * Encapsulates the OutputFormat call
+ *   - method name
+ *   - arguments (assumed to be serializable)
+ */
+public class OutputFormatFrame implements Serializable {
+    private static final long serialVersionUID = -7151852354574635295L;
+    public final String method;
+    public final Object[] args;
+
+    public OutputFormatFrame(String method, Object[] args) {
+        this.method = method;
+        this.args = args;
+    }
+}
--- a/jmh-core/src/main/java/org/openjdk/jmh/output/OutputFormatFactory.java	Tue Aug 27 17:43:33 2013 +0400
+++ b/jmh-core/src/main/java/org/openjdk/jmh/output/OutputFormatFactory.java	Tue Aug 27 17:59:27 2013 +0400
@@ -68,7 +68,7 @@
         return (OutputFormat) Proxy.newProxyInstance(
                 Thread.currentThread().getContextClassLoader(),
                 new Class[]{OutputFormat.class},
-                link
+                link.getOutputFormatHandler()
         );
     }
 
--- a/jmh-core/src/main/java/org/openjdk/jmh/runner/Runner.java	Tue Aug 27 17:43:33 2013 +0400
+++ b/jmh-core/src/main/java/org/openjdk/jmh/runner/Runner.java	Tue Aug 27 17:59:27 2013 +0400
@@ -245,17 +245,17 @@
     }
 
     private void runSeparate(Set<BenchmarkRecord> benchmarksToFork) {
-        BinaryLinkServer reader = null;
+        BinaryLinkServer server = null;
         try {
-            reader = new BinaryLinkServer(options, out);
+            server = new BinaryLinkServer(options, out);
             for (BenchmarkRecord benchmark : benchmarksToFork) {
-                runSeparateMicroBenchmark(reader, benchmark, reader.getHost(), reader.getPort());
+                runSeparateMicroBenchmark(server, benchmark, server.getHost(), server.getPort());
             }
         } catch (IOException e) {
             throw new IllegalStateException(e);
         } finally {
-            if (reader != null) {
-                reader.terminate();
+            if (server != null) {
+                server.terminate();
             }
         }
     }
@@ -437,9 +437,12 @@
         command.add(classPath);
         command.add(ForkedMain.class.getName());
 
+        // Forked VM assumes the exact order of arguments:
+        //   1) host name to back-connect
+        //   2) host port to back-connect
+        //   3) benchmark to execute (saves benchmark lookup via Options)
         command.add(host);
         command.add(String.valueOf(port));
-
         command.add(benchmark.toLine());
 
         return command.toArray(new String[command.size()]);