8214896: JFR Tool left files behind
authoregahlin
Wed, 05 Dec 2018 18:08:50 +0100
changeset 52855 dffc52d799f1
parent 52854 eb4f89bce401
child 52856 5f3b9b633731
8214896: JFR Tool left files behind Reviewed-by: mgronlun
src/jdk.jfr/share/classes/jdk/jfr/internal/cmd/Command.java
src/jdk.jfr/share/classes/jdk/jfr/internal/cmd/Execute.java
src/jdk.jfr/share/classes/jdk/jfr/internal/cmd/HelpCommand.java
src/jdk.jfr/share/classes/jdk/jfr/internal/cmd/JSONWriter.java
src/jdk.jfr/share/classes/jdk/jfr/internal/cmd/PrettyWriter.java
src/jdk.jfr/share/classes/jdk/jfr/internal/cmd/PrintCommand.java
src/jdk.jfr/share/classes/jdk/jfr/internal/cmd/ReconstructCommand.java
src/jdk.jfr/share/classes/jdk/jfr/internal/cmd/SplitCommand.java
src/jdk.jfr/share/classes/jdk/jfr/internal/cmd/StructuredWriter.java
src/jdk.jfr/share/classes/jdk/jfr/internal/cmd/SummaryCommand.java
src/jdk.jfr/share/classes/jdk/jfr/internal/cmd/XMLWriter.java
test/jdk/jdk/jfr/cmd/ExecuteHelper.java
test/jdk/jdk/jfr/cmd/TestHelp.java
test/jdk/jdk/jfr/cmd/TestPrint.java
test/jdk/jdk/jfr/cmd/TestPrintDefault.java
test/jdk/jdk/jfr/cmd/TestPrintJSON.java
test/jdk/jdk/jfr/cmd/TestPrintXML.java
test/jdk/jdk/jfr/cmd/TestReconstruct.java
test/jdk/jdk/jfr/cmd/TestSplit.java
test/jdk/jdk/jfr/cmd/TestSummary.java
--- a/src/jdk.jfr/share/classes/jdk/jfr/internal/cmd/Command.java	Wed Dec 05 17:11:22 2018 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,150 +0,0 @@
-/*
- * Copyright (c) 2016, 2018, 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 jdk.jfr.internal.cmd;
-
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Deque;
-import java.util.List;
-
-abstract class Command {
-
-    private final static Command HELP = new HelpCommand();
-    private final static List<Command> COMMANDS = createCommands();
-
-    static void displayHelp() {
-        System.out.println("Usage: java " + Execute.class.getName() + " <command> [<options>]");
-        System.out.println();
-        displayAvailableCommands();
-    }
-
-    static void displayAvailableCommands() {
-        System.out.println("Available commands are:");
-        System.out.println();
-        boolean first = true;
-        for (Command c : Command.COMMANDS) {
-            if (!first) {
-                System.out.println();
-            }
-            System.out.println("  " + c.getName() + " " + c.getOptionSyntax());
-            System.out.println("    " + c.getDescription());
-            first = false;
-        }
-    }
-
-    public static List<Command> getCommands() {
-        return COMMANDS;
-    }
-
-    public static Command valueOf(String commandName) {
-        for (Command command : COMMANDS) {
-            if (command.getName().equals(commandName)) {
-                return command;
-            }
-        }
-        return null;
-    }
-
-    abstract public String getOptionSyntax();
-
-    abstract public String getName();
-
-    abstract public String getDescription();
-
-    abstract public void displayOptionUsage();
-
-    abstract public void execute(Deque<String> options);
-
-    final protected void userFailed(String message) {
-        println();
-        println(message);
-        displayUsage();
-        throw new IllegalArgumentException(message);
-    }
-
-    final protected void ensureMaxArgumentCount(Deque<String> options, int maxCount) {
-        if (options.size() > maxCount) {
-            userFailed("Too many arguments");
-        }
-    }
-
-    final protected void ensureMinArgumentCount(Deque<String> options, int minCount) {
-        if (options.size() < minCount) {
-            userFailed("Too few arguments");
-        }
-    }
-
-    final protected void ensureFileExist(Path file) {
-        if (!Files.exists(file)) {
-            userFailed("Could not find file " + file);
-        }
-    }
-
-    final protected Path ensureFileDoesNotExist(Path file) {
-        if (Files.exists(file)) {
-            userFailed("File " + file + " already exists");
-        }
-        return file;
-    }
-
-    final protected void ensureJFRFile(Path path) {
-        if (!path.toString().endsWith(".jfr")) {
-            userFailed("Filename must end with .jfr");
-        }
-    }
-
-    final protected void displayUsage() {
-        String javaText = "java " + Execute.class.getName();
-        println();
-        println("Usage: " + javaText + " " + getName() + " " + getOptionSyntax());
-        println();
-        displayOptionUsage();
-    }
-
-    final protected void println() {
-        System.out.println();
-    }
-
-    final protected void print(String text) {
-        System.out.print(text);
-    }
-
-    final protected void println(String text) {
-        System.out.println(text);
-    }
-
-    private static List<Command> createCommands() {
-        List<Command> commands = new ArrayList<>();
-        commands.add(new PrintCommand());
-        commands.add(new SummaryCommand());
-        commands.add(new ReconstructCommand());
-        commands.add(new SplitCommand());
-        commands.add(HELP);
-        return Collections.unmodifiableList(commands);
-    }
-}
--- a/src/jdk.jfr/share/classes/jdk/jfr/internal/cmd/Execute.java	Wed Dec 05 17:11:22 2018 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,65 +0,0 @@
-/*
- * Copyright (c) 2016, 2018, 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 jdk.jfr.internal.cmd;
-
-import java.util.Arrays;
-import java.util.Deque;
-import java.util.LinkedList;
-
-/**
- * Launcher class for JFR tools
- *
- */
-public final class Execute {
-
-    public static void main(String... args) {
-        Deque<String> argList = new LinkedList<>(Arrays.asList(args));
-        if (argList.isEmpty()) {
-            System.out.println();
-            Command.displayHelp();
-            return;
-        }
-        String command = argList.remove();
-        for (Command c : Command.getCommands()) {
-            if (c.getName().equals(command)) {
-                try {
-                    c.execute(argList);
-                } catch (IllegalArgumentException iae) {
-                    return; // already handled by command
-                } catch (Throwable e) {
-                    System.out.println();
-                    System.out.println(e.getMessage());
-                    System.out.println();
-                }
-                return;
-            }
-        }
-        System.out.println();
-        System.out.println("Unknown command " + command + ".");
-        System.out.println();
-        Command.displayHelp();
-    }
-}
--- a/src/jdk.jfr/share/classes/jdk/jfr/internal/cmd/HelpCommand.java	Wed Dec 05 17:11:22 2018 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,68 +0,0 @@
-/*
- * Copyright (c) 2016, 2018, 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 jdk.jfr.internal.cmd;
-
-import java.util.Deque;
-
-final class HelpCommand extends Command {
-
-    @Override
-    public String getOptionSyntax() {
-        return "[<command>]";
-    }
-
-    @Override
-    public void displayOptionUsage() {
-        println("  <command>   The name of the command to get help for");
-        println();
-        Command.displayAvailableCommands();
-    }
-
-    @Override
-    public String getName() {
-        return "help";
-    }
-
-    @Override
-    public String getDescription() {
-        return "Display help about a command";
-    }
-
-    @Override
-    public void execute(Deque<String> options) {
-        if (options.isEmpty()) {
-            displayUsage();
-        } else {
-            ensureMaxArgumentCount(options, 1);
-            String commandName = options.remove();
-            Command c = Command.valueOf(commandName);
-            if (c == null) {
-                userFailed("Unknown command " + commandName);
-            }
-            c.displayUsage();
-        }
-    }
-}
--- a/src/jdk.jfr/share/classes/jdk/jfr/internal/cmd/JSONWriter.java	Wed Dec 05 17:11:22 2018 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,258 +0,0 @@
-/*
- * Copyright (c) 2016, 2018, 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 jdk.jfr.internal.cmd;
-
-import java.io.IOException;
-import java.io.PrintWriter;
-import java.nio.file.Path;
-
-import jdk.jfr.EventType;
-import jdk.jfr.ValueDescriptor;
-import jdk.jfr.consumer.RecordedEvent;
-import jdk.jfr.consumer.RecordedObject;
-import jdk.jfr.consumer.RecordingFile;
-
-final class JSONWriter extends StructuredWriter {
-
-    public JSONWriter(PrintWriter writer) {
-        super(writer);
-    }
-
-    public void print(Path source) throws IOException {
-        try (RecordingFile es = new RecordingFile(source)) {
-            printObjectBegin();
-            printRecording(es);
-            printObjectEnd();
-            flush();
-        }
-    }
-
-    private void printRecording(RecordingFile es) throws IOException {
-        printDataStructureName("recording");
-        printObjectBegin();
-        printEvents(es);
-        printObjectEnd();
-    }
-
-    private void printEvents(RecordingFile es) throws IOException {
-        printDataStructureName("events");
-        printArrayBegin();
-        boolean first = true;
-        while (es.hasMoreEvents()) {
-            RecordedEvent e = es.readEvent();
-            printNewDataStructure(first, true, null);
-            printEvent(e);
-            flush();
-            first = false;
-        }
-        printArrayEnd();
-    }
-
-    private void printEvent(RecordedEvent e) {
-        printObjectBegin();
-        EventType type = e.getEventType();
-        printValue(true, false, "name", type.getName());
-        printValue(false, false, "typeId", type.getId());
-        printValue(false, false, "startTime", e.getStartTime());
-        printValue(false, false, "duration", e.getDuration());
-        printNewDataStructure(false, false, "values");
-        printObject(e);
-        printObjectEnd();
-    }
-
-    void printValue(boolean first, boolean arrayElement, String name, Object value) {
-        printNewDataStructure(first, arrayElement, name);
-        if (!printIfNull(value)) {
-            if (value instanceof Boolean) {
-                printAsString(value);
-                return;
-            }
-            if (value instanceof Double) {
-                Double dValue = (Double) value;
-                if (Double.isNaN(dValue) || Double.isInfinite(dValue)) {
-                    printNull();
-                    return;
-                }
-                printAsString(value);
-                return;
-            }
-            if (value instanceof Float) {
-                Float fValue = (Float) value;
-                if (Float.isNaN(fValue) || Float.isInfinite(fValue)) {
-                    printNull();
-                    return;
-                }
-                printAsString(value);
-                return;
-            }
-            if (value instanceof Number) {
-                printAsString(value);
-                return;
-            }
-            print("\"");
-            printEscaped(String.valueOf(value));
-            print("\"");
-        }
-    }
-
-    public void printObject(RecordedObject object) {
-        printObjectBegin();
-        boolean first = true;
-        for (ValueDescriptor v : object.getFields()) {
-            printValueDescriptor(first, false, v, object.getValue(v.getName()));
-            first = false;
-        }
-        printObjectEnd();
-    }
-
-    private void printArray(ValueDescriptor v, Object[] array) {
-        printArrayBegin();
-        boolean first = true;
-        for (Object arrayElement : array) {
-            printValueDescriptor(first, true, v, arrayElement);
-            first = false;
-        }
-        printArrayEnd();
-    }
-
-    private void printValueDescriptor(boolean first, boolean arrayElement, ValueDescriptor vd, Object value) {
-        if (vd.isArray() && !arrayElement) {
-            printNewDataStructure(first, arrayElement, vd.getName());
-            if (!printIfNull(value)) {
-                printArray(vd, (Object[]) value);
-            }
-            return;
-        }
-        if (!vd.getFields().isEmpty()) {
-            printNewDataStructure(first, arrayElement, vd.getName());
-            if (!printIfNull(value)) {
-                printObject((RecordedObject) value);
-            }
-            return;
-        }
-        printValue(first, arrayElement, vd.getName(), value);
-    }
-
-    private void printNewDataStructure(boolean first, boolean arrayElement, String name) {
-        if (!first) {
-            print(", ");
-            if (!arrayElement) {
-                println();
-            }
-        }
-        if (!arrayElement) {
-            printDataStructureName(name);
-        }
-    }
-
-    private boolean printIfNull(Object value) {
-        if (value == null) {
-            printNull();
-            return true;
-        }
-        return false;
-    }
-
-    private void printNull() {
-        print("null");
-    }
-
-    private void printDataStructureName(String text) {
-        printIndent();
-        print("\"");
-        print(text);
-        print("\": ");
-    }
-
-    private void printObjectEnd() {
-        retract();
-        println();
-        printIndent();
-        print("}");
-    }
-
-    private void printObjectBegin() {
-        println("{");
-        indent();
-    }
-
-    private void printArrayEnd() {
-        print("]");
-    }
-
-    private void printArrayBegin() {
-        print("[");
-    }
-
-    private void printEscaped(String text) {
-        for (int i = 0; i < text.length(); i++) {
-            printEscaped(text.charAt(i));
-        }
-    }
-
-    private void printEscaped(char c) {
-        if (c == '\b') {
-            print("\\b");
-            return;
-        }
-        if (c == '\n') {
-            print("\\n");
-            return;
-        }
-        if (c == '\t') {
-            print("\\t");
-            return;
-        }
-        if (c == '\f') {
-            print("\\f");
-            return;
-        }
-        if (c == '\r') {
-            print("\\r");
-            return;
-        }
-        if (c == '\"') {
-            print("\\\"");
-            return;
-        }
-        if (c == '\\') {
-            print("\\\\");
-            return;
-        }
-        if (c == '/') {
-            print("\\/");
-            return;
-        }
-        if (c > 0x7F || c < 32) {
-            print("\\u");
-            // 0x10000 will pad with zeros.
-            print(Integer.toHexString(0x10000 + (int) c).substring(1));
-            return;
-        }
-        print(c);
-    }
-
-}
--- a/src/jdk.jfr/share/classes/jdk/jfr/internal/cmd/PrettyWriter.java	Wed Dec 05 17:11:22 2018 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,236 +0,0 @@
-/*
- * Copyright (c) 2016, 2018, 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 jdk.jfr.internal.cmd;
-
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.io.PrintWriter;
-import java.nio.file.Path;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.List;
-import java.util.StringJoiner;
-
-import jdk.jfr.AnnotationElement;
-import jdk.jfr.ValueDescriptor;
-import jdk.jfr.consumer.RecordedEvent;
-import jdk.jfr.consumer.RecordedObject;
-import jdk.jfr.consumer.RecordingFile;
-import jdk.jfr.internal.PrivateAccess;
-import jdk.jfr.internal.Type;
-import jdk.jfr.internal.consumer.ChunkHeader;
-import jdk.jfr.internal.consumer.RecordingInput;
-
-public final class PrettyWriter extends StructuredWriter {
-
-    public PrettyWriter(PrintWriter destination) {
-        super(destination);
-    }
-
-    void print(Path source) throws FileNotFoundException, IOException {
-        try (RecordingInput input = new RecordingInput(source.toFile())) {
-            HashSet<Type> typeSet = new HashSet<>();
-            for (ChunkHeader ch = new ChunkHeader(input); !ch.isLastChunk(); ch = ch.nextHeader()) {
-                typeSet.addAll(ch.readMetadata().getTypes());
-            }
-            List<Type> types = new ArrayList<>(typeSet);
-            Collections.sort(types, (c1, c2) -> Long.compare(c1.getId(), c2.getId()));
-            for (Type t : types) {
-                printType(t);
-            }
-            flush();
-        }
-
-        try (RecordingFile es = new RecordingFile(source)) {
-            while (es.hasMoreEvents()) {
-                print(es.readEvent());
-                flush();
-            }
-        }
-        flush();
-    }
-
-    public void printType(Type t) throws IOException {
-        print("// id: ");
-        println(String.valueOf(t.getId()));
-        int commentIndex = t.getName().length() + 10;
-        String typeName = t.getName();
-        int index = typeName.lastIndexOf(".");
-        if (index != -1) {
-            println("package " + typeName.substring(0, index) + ";");
-        }
-        printAnnotations(commentIndex, t.getAnnotationElements());
-        print("class " + typeName.substring(index + 1));
-        String superType = t.getSuperType();
-        if (superType != null) {
-            print(" extends " + superType);
-        }
-        println(" {");
-        indent();
-        for (ValueDescriptor v : t.getFields()) {
-            printField(commentIndex, v);
-        }
-        retract();
-        println("}");
-        println();
-    }
-
-    private void printField(int commentIndex, ValueDescriptor v) throws IOException {
-        println();
-        printAnnotations(commentIndex, v.getAnnotationElements());
-        printIndent();
-        Type vType = PrivateAccess.getInstance().getType(v);
-        if (Type.SUPER_TYPE_SETTING.equals(vType.getSuperType())) {
-            print("static ");
-        }
-        print(makeSimpleType(v.getTypeName()));
-        if (v.isArray()) {
-            print("[]");
-        }
-        print(" ");
-        print(v.getName());
-        print(";");
-        printCommentRef(commentIndex, v.getTypeId());
-    }
-
-    private void printCommentRef(int commentIndex, long typeId) throws IOException {
-        int column = getColumn();
-        if (column > commentIndex) {
-            print("  ");
-        } else {
-            while (column < commentIndex) {
-                print(" ");
-                column++;
-            }
-        }
-        println(" // id=" + typeId);
-    }
-
-    private void printAnnotations(int commentIndex, List<AnnotationElement> annotations) throws IOException {
-        for (AnnotationElement a : annotations) {
-            printIndent();
-            print("@");
-            print(makeSimpleType(a.getTypeName()));
-            List<ValueDescriptor> vs = a.getValueDescriptors();
-            if (!vs.isEmpty()) {
-                printAnnotation(a);
-                printCommentRef(commentIndex, a.getTypeId());
-            } else {
-                println();
-            }
-        }
-    }
-
-    private void printAnnotation(AnnotationElement a) throws IOException {
-        StringJoiner sj = new StringJoiner(", ", "(", ")");
-        List<ValueDescriptor> vs = a.getValueDescriptors();
-        for (ValueDescriptor v : vs) {
-            Object o = a.getValue(v.getName());
-            if (vs.size() == 1 && v.getName().equals("value")) {
-                sj.add(textify(o));
-            } else {
-                sj.add(v.getName() + "=" + textify(o));
-            }
-        }
-        print(sj.toString());
-    }
-
-    private String textify(Object o) {
-        if (o.getClass().isArray()) {
-            Object[] array = (Object[]) o;
-            if (array.length == 1) {
-                return quoteIfNeeded(array[0]);
-            }
-            StringJoiner s = new StringJoiner(", ", "{", "}") ;
-            for (Object ob : array) {
-                s.add(quoteIfNeeded(ob));
-            }
-            return s.toString();
-        } else {
-            return quoteIfNeeded(o);
-        }
-    }
-
-    private String quoteIfNeeded(Object o) {
-        if (o instanceof String) {
-            return "\"" + o + "\"";
-        } else {
-            return String.valueOf(o);
-        }
-    }
-
-    private String makeSimpleType(String typeName) {
-        int index = typeName.lastIndexOf(".");
-        return typeName.substring(index + 1);
-    }
-
-    public void print(RecordedEvent event) throws IOException {
-        print(makeSimpleType(event.getEventType().getName()), " ");
-        print((RecordedObject) event, "");
-    }
-
-    public void print(RecordedObject struct, String postFix) throws IOException {
-        println("{");
-        indent();
-        for (ValueDescriptor v : struct.getFields()) {
-            printIndent();
-            print(v.getName(), " = ");
-            printValue(struct.getValue(v.getName()), "");
-        }
-        retract();
-        printIndent();
-        println("}" + postFix);
-    }
-
-    private void printArray(Object[] array) throws IOException {
-        println("[");
-        indent();
-        for (int i = 0; i < array.length; i++) {
-            printIndent();
-            printValue(array[i], i + 1 < array.length ? ", " : "");
-        }
-        retract();
-        printIndent();
-        println("]");
-    }
-
-    private void printValue(Object value, String postFix) throws IOException {
-        if (value == null) {
-            println("null" + postFix);
-        } else if (value instanceof RecordedObject) {
-            print((RecordedObject) value, postFix);
-        } else if (value.getClass().isArray()) {
-            printArray((Object[]) value);
-        } else {
-            String text = String.valueOf(value);
-            if (value instanceof String) {
-                text = "\"" + text + "\"";
-            }
-            println(text);
-        }
-    }
-}
--- a/src/jdk.jfr/share/classes/jdk/jfr/internal/cmd/PrintCommand.java	Wed Dec 05 17:11:22 2018 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,100 +0,0 @@
-/*
- * Copyright (c) 2016, 2018, 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 jdk.jfr.internal.cmd;
-
-import java.io.IOException;
-import java.io.PrintWriter;
-import java.nio.file.Path;
-import java.nio.file.Paths;
-import java.util.Deque;
-
-final class PrintCommand extends Command {
-    @Override
-    public String getName() {
-        return "print";
-    }
-
-    @Override
-    public String getOptionSyntax() {
-        return "[--xml|--json] <file>";
-    }
-
-    @Override
-    public String getDescription() {
-        return "Print contents of a recording file (.jfr)";
-    }
-
-    @Override
-    public void displayOptionUsage() {
-        println("  --xml    Print a recording in XML format");
-        println();
-        println("  --json   Print a recording in JSON format");
-        println();
-        println("  <file>   Location of the recording file (.jfr) to print");
-    }
-
-    @Override
-    public void execute(Deque<String> options) {
-        if (options.isEmpty()) {
-            userFailed("Missing file");
-        }
-        ensureMaxArgumentCount(options, 2);
-
-        Path file = Paths.get(options.removeLast());
-
-        ensureFileExist(file);
-        ensureJFRFile(file);
-        ensureMaxArgumentCount(options, 1);
-
-        String format = "--pretty";
-        if (!options.isEmpty()) {
-            format = options.remove();
-        }
-        try (PrintWriter pw = new PrintWriter(System.out)) {
-            try {
-                switch (format) {
-                case "--pretty":
-                    PrettyWriter prettyWriter = new PrettyWriter(pw);
-                    prettyWriter.print(file);
-                    break;
-                case "--xml":
-                    XMLWriter xmlPrinter = new XMLWriter(pw);
-                    xmlPrinter.print(file);
-                    break;
-                case "--json":
-                    JSONWriter jsonWriter = new JSONWriter(pw);
-                    jsonWriter.print(file);
-                    break;
-                default:
-                    userFailed("Unknown option " + format);
-                    break;
-                }
-            } catch (IOException ioe) {
-                userFailed("Could not read recording at " + file.toAbsolutePath() + ". " + ioe.getMessage());
-            }
-        }
-    }
-}
--- a/src/jdk.jfr/share/classes/jdk/jfr/internal/cmd/ReconstructCommand.java	Wed Dec 05 17:11:22 2018 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,131 +0,0 @@
-/*
- * Copyright (c) 2016, 2018, 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 jdk.jfr.internal.cmd;
-
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.nio.channels.FileChannel;
-import java.nio.file.DirectoryStream;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.nio.file.Paths;
-import java.util.ArrayList;
-import java.util.Deque;
-import java.util.List;
-
-final class ReconstructCommand extends Command {
-
-    @Override
-    public String getOptionSyntax() {
-        return "<repository> <file>";
-    }
-
-    @Override
-    public String getName() {
-        return "reconstruct";
-    }
-
-    @Override
-    public String getDescription() {
-        return "Assemble leftover chunks, from a disk repository, into a recording file (.jfr)";
-    }
-
-    @Override
-    public void displayOptionUsage() {
-        println("  <repository>   Directory where the repository is located");
-        println();
-        println("  <file>         Name of the recording file (.jfr) to create");
-    }
-
-    @Override
-    public void execute(Deque<String> options) {
-        ensureMinArgumentCount(options, 2);
-        ensureMaxArgumentCount(options, 2);
-
-        Path repository = Paths.get(options.pop()).toAbsolutePath();
-        if (!Files.exists(repository)) {
-            userFailed("Could not find disk repository at " + repository);
-        }
-        if (!Files.isDirectory(repository)) {
-            userFailed("Must specify a directory as disk repository");
-        }
-        Path output = Paths.get(options.pop());
-        ensureFileDoesNotExist(output);
-        ensureJFRFile(output);
-
-        try (FileOutputStream fos = new FileOutputStream(output.toFile())) {
-            List<Path> files = listJFRFiles(repository);
-            if (files.isEmpty()) {
-                throw new IllegalStateException("No *.jfr files found at " + repository);
-            }
-            println();
-            println("Combining files... ");
-            println();
-            transferTo(files, output, fos.getChannel());
-            println();
-            println("Reconstruction complete.");
-        } catch (IOException e) {
-            userFailed("Could not open destination file " + output + ". " + e.getMessage());
-        }
-    }
-
-    private List<Path> listJFRFiles(Path path) throws IOException {
-        try {
-            List<Path> files = new ArrayList<>();
-            if (Files.isDirectory(path)) {
-                try (DirectoryStream<Path> stream = Files.newDirectoryStream(path, "*.jfr")) {
-                    for (Path p : stream) {
-                        if (!Files.isDirectory(p) && Files.isReadable(p)) {
-                            files.add(p);
-                        }
-                    }
-                }
-            }
-            files.sort((u, v) -> u.getFileName().compareTo(v.getFileName()));
-            return files;
-        } catch (IOException ioe) {
-            throw new IllegalStateException("Could not list *.jfr for directory " + path + ". " + ioe.getMessage());
-        }
-    }
-
-    private void transferTo(List<Path> sourceFiles, Path output, FileChannel out) {
-        long pos = 0;
-        for (Path p : sourceFiles) {
-            println(" " + p.toString());
-            try (FileChannel sourceChannel = FileChannel.open(p)) {
-                long rem = Files.size(p);
-                while (rem > 0) {
-                    long n = Math.min(rem, 1024 * 1024);
-                    long w = out.transferFrom(sourceChannel, pos, n);
-                    pos += w;
-                    rem -= w;
-                }
-            } catch (IOException ioe) {
-                throw new IllegalStateException("Could not copy recording chunk " + p + " to new file. " + ioe.getMessage());
-            }
-        }
-    }
-}
--- a/src/jdk.jfr/share/classes/jdk/jfr/internal/cmd/SplitCommand.java	Wed Dec 05 17:11:22 2018 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,195 +0,0 @@
-/*
- * Copyright (c) 2016, 2018, 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 jdk.jfr.internal.cmd;
-
-import java.io.BufferedInputStream;
-import java.io.DataInputStream;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.nio.file.Paths;
-import java.util.ArrayList;
-import java.util.Deque;
-import java.util.List;
-
-import jdk.jfr.internal.consumer.ChunkHeader;
-import jdk.jfr.internal.consumer.RecordingInput;
-
-final class SplitCommand extends Command {
-
-    @Override
-    public String getOptionSyntax() {
-        return "[--maxchunks <chunks>] <file>";
-    }
-
-    @Override
-    public void displayOptionUsage() {
-        println("  --maxchunks <chunks>   Maximum number of chunks per splitted file (default 5).");
-        println("                         The chunk size varies, but is typically around 15 MB.");
-        println();
-        println("  <file>                 Location of recording file (.jfr) to split");
-    }
-
-    @Override
-    public String getName() {
-        return "split";
-    }
-
-    @Override
-    public String getDescription() {
-        return "Splits a recording file into smaller files";
-    }
-
-    @Override
-    public void execute(Deque<String> options) {
-        if (options.isEmpty()) {
-            userFailed("Missing file");
-        }
-        ensureMaxArgumentCount(options, 3);
-        Path file = Paths.get(options.removeLast());
-        ensureFileExist(file);
-        ensureJFRFile(file);
-        int maxchunks = 5;
-        if (!options.isEmpty()) {
-            String option = options.pop();
-            if (!"--maxchunks".equals(option)) {
-                userFailed("Unknown option " + option);
-            }
-            if (options.isEmpty()) {
-                userFailed("Missing value for --maxChunks");
-            }
-            String value = options.pop();
-            try {
-                maxchunks = Integer.parseInt(value);
-                if (maxchunks < 1) {
-                    userFailed("Must be at least one chunk per file.");
-                }
-            } catch (NumberFormatException nfe) {
-                userFailed("Not a valid value for --maxchunks.");
-            }
-        }
-        ensureMaxArgumentCount(options, 0);
-        println();
-        println("Examining recording " + file + " ...");
-        List<Long> sizes;
-
-        try {
-            sizes = findChunkSizes(file);
-        } catch (IOException e) {
-            throw new IllegalStateException("Unexpected error. " + e.getMessage());
-        }
-        if (sizes.size() <= maxchunks) {
-            throw new IllegalStateException("Number of chunks in recording (" + sizes.size() + ") doesn't exceed max chunks (" + maxchunks + ")");
-        }
-        println();
-
-        println();
-        if (sizes.size() > 0) {
-            print("File consists of " + sizes.size() + " chunks. The recording will be split into ");
-            sizes = combineChunkSizes(sizes, maxchunks);
-            println(sizes.size() + " files with at most " + maxchunks + " chunks per file.");
-            println();
-
-            try {
-                splitFile(file, sizes);
-            } catch (IOException e) {
-                throw new IllegalStateException("Unexpected error. " + e.getMessage());
-            }
-        } else {
-            println("No JFR chunks found in file. ");
-        }
-    }
-
-    private List<Long> findChunkSizes(Path p) throws IOException {
-        try (RecordingInput input = new RecordingInput(p.toFile())) {
-            List<Long> sizes = new ArrayList<>();
-            ChunkHeader ch = new ChunkHeader(input);
-            sizes.add(ch.getSize());
-            while (!ch.isLastChunk()) {
-                ch = ch.nextHeader();
-                sizes.add(ch.getSize());
-            }
-            return sizes;
-        }
-    }
-
-    private List<Long> combineChunkSizes(List<Long> sizes, int chunksPerFile) {
-        List<Long> reduced = new ArrayList<Long>();
-        long size = sizes.get(0);
-        for (int n = 1; n < sizes.size(); n++) {
-            if (n % chunksPerFile == 0) {
-                reduced.add(size);
-                size = 0;
-            }
-            size += sizes.get(n);
-        }
-        reduced.add(size);
-        return reduced;
-    }
-
-    private void splitFile(Path file, List<Long> splitPositions) throws IOException {
-
-        int padAmountZeros = String.valueOf(splitPositions.size() - 1).length();
-        String fileName = file.toString();
-        String fileFormatter = fileName.subSequence(0, fileName.length() - 4) + "_%0" + padAmountZeros + "d.jfr";
-        for (int i = 0; i < splitPositions.size(); i++) {
-            Path p = Paths.get(String.format(fileFormatter, i));
-            if (Files.exists(p)) {
-                throw new IllegalStateException("Can't create split file " + p + ", a file with that name already exist");
-            }
-        }
-        DataInputStream stream = new DataInputStream(new BufferedInputStream(new FileInputStream(file.toFile())));
-
-        for (int i = 0; i < splitPositions.size(); i++) {
-            Long l = splitPositions.get(i);
-            byte[] bytes = readBytes(stream, l.intValue());
-            Path p = Paths.get(String.format(fileFormatter, i));
-            File splittedFile = p.toFile();
-            println("Writing " + splittedFile + " ...");
-            FileOutputStream fos = new FileOutputStream(splittedFile);
-            fos.write(bytes);
-            fos.close();
-        }
-        stream.close();
-    }
-
-    private byte[] readBytes(InputStream stream, int count) throws IOException {
-        byte[] data = new byte[count];
-        int totalRead = 0;
-        while (totalRead < data.length) {
-            int read = stream.read(data, totalRead, data.length - totalRead);
-            if (read == -1) {
-                throw new IOException("Unexpected end of data.");
-            }
-            totalRead += read;
-        }
-        return data;
-    }
-}
--- a/src/jdk.jfr/share/classes/jdk/jfr/internal/cmd/StructuredWriter.java	Wed Dec 05 17:11:22 2018 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,111 +0,0 @@
-/*
- * Copyright (c) 2016, 2018, 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 jdk.jfr.internal.cmd;
-
-import java.io.PrintWriter;
-
-abstract class StructuredWriter {
-    private final static String LINE_SEPARATOR = String.format("%n");
-
-    private final PrintWriter out;
-    private final StringBuilder builder = new StringBuilder(4000);
-
-    private char[] indentionArray = new char[0];
-    private int indent = 0;
-    private int column;
-
-    StructuredWriter(PrintWriter p) {
-        out = p;
-    }
-
-    final protected int getColumn() {
-        return column;
-    }
-
-    // Flush to print writer
-    public final void flush() {
-        out.print(builder.toString());
-        builder.setLength(0);
-    }
-
-    final public void printIndent() {
-        builder.append(indentionArray, 0, indent);
-        column += indent;
-    }
-
-    final public void println() {
-        builder.append(LINE_SEPARATOR);
-        column = 0;
-    }
-
-    final public void print(String... texts) {
-        for (String text : texts) {
-            print(text);
-        }
-    }
-
-    final public void printAsString(Object o) {
-        print(String.valueOf(o));
-    }
-
-    final public void print(String text) {
-        builder.append(text);
-        column += text.length();
-    }
-
-    final public void print(char c) {
-        builder.append(c);
-        column++;
-    }
-
-    final public void print(int value) {
-        print(String.valueOf(value));
-    }
-
-    final public void indent() {
-        indent += 2;
-        updateIndent();
-    }
-
-    final public void retract() {
-        indent -= 2;
-        updateIndent();
-    }
-
-    final public void println(String text) {
-        print(text);
-        println();
-    }
-
-    private void updateIndent() {
-        if (indent > indentionArray.length) {
-            indentionArray = new char[indent];
-            for (int i = 0; i < indentionArray.length; i++) {
-                indentionArray[i] = ' ';
-            }
-        }
-    }
-}
--- a/src/jdk.jfr/share/classes/jdk/jfr/internal/cmd/SummaryCommand.java	Wed Dec 05 17:11:22 2018 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,173 +0,0 @@
-/*
- * Copyright (c) 2016, 2018, 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 jdk.jfr.internal.cmd;
-
-import java.io.IOException;
-import java.nio.file.Path;
-import java.nio.file.Paths;
-import java.time.Duration;
-import java.time.Instant;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Deque;
-import java.util.HashMap;
-import java.util.List;
-
-import jdk.jfr.EventType;
-import jdk.jfr.internal.MetadataDescriptor;
-import jdk.jfr.internal.Type;
-import jdk.jfr.internal.consumer.ChunkHeader;
-import jdk.jfr.internal.consumer.RecordingInput;
-
-final class SummaryCommand extends Command {
-
-    private static class Statistics {
-        Statistics(String name) {
-            this.name = name;
-        }
-
-        String name;
-        long count;
-        long size;
-    }
-
-    @Override
-    public String getOptionSyntax() {
-        return "<file>";
-    }
-
-    @Override
-    public void displayOptionUsage() {
-        println("  <file>   Location of the recording file (.jfr) to display information about");
-    }
-
-    @Override
-    public String getName() {
-        return "summary";
-    }
-
-    @Override
-    public String getDescription() {
-        return "Display general information about a recording file (.jfr)";
-    }
-
-    @Override
-    public void execute(Deque<String> options) {
-        if (options.isEmpty()) {
-            userFailed("Missing file");
-        }
-        ensureMaxArgumentCount(options, 1);
-        Path p = Paths.get(options.remove());
-        ensureFileExist(p);
-        ensureJFRFile(p);
-        try {
-            printInformation(p);
-        } catch (IOException e) {
-            throw new IllegalStateException("Unexpected error. " + e.getMessage());
-        }
-    }
-
-    private void printInformation(Path p) throws IOException {
-        long totalSize = 0;
-        long totalDuration = 0;
-        long chunks = 0;
-
-        try (RecordingInput input = new RecordingInput(p.toFile())) {
-            ChunkHeader first = new ChunkHeader(input);
-            ChunkHeader ch = first;
-            String eventPrefix = Type.EVENT_NAME_PREFIX;
-            if (first.getMajor() == 1) {
-                eventPrefix = "com.oracle.jdk.";
-            }
-            HashMap<Long, Statistics> stats = new HashMap<>();
-            stats.put(0L, new Statistics(eventPrefix + "Metadata"));
-            stats.put(1L, new Statistics(eventPrefix + "CheckPoint"));
-            int minWidth = 0;
-            while (true) {
-                long chunkEnd = ch.getEnd();
-                MetadataDescriptor md = ch.readMetadata();
-
-                for (EventType eventType : md.getEventTypes()) {
-                    stats.computeIfAbsent(eventType.getId(), (e) -> new Statistics(eventType.getName()));
-                    minWidth = Math.max(minWidth, eventType.getName().length());
-                }
-
-                totalSize += ch.getSize();
-                totalDuration += ch.getDuration();
-                chunks++;
-                input.position(ch.getEventStart());
-                while (input.position() < chunkEnd) {
-
-                    long pos = input.position();
-                    int size = input.readInt();
-                    long eventTypeId = input.readLong();
-                    Statistics s = stats.get(eventTypeId);
-
-                    if (s != null) {
-                        s.count++;
-                        s.size += size;
-                    }
-                    input.position(pos + size);
-                }
-                if (ch.isLastChunk()) {
-                    break;
-                }
-                ch = ch.nextHeader();
-            }
-            println();
-            long epochSeconds = first.getStartNanos() / 1_000_000_000L;
-            long adjustNanos = first.getStartNanos() - epochSeconds * 1_000_000_000L;
-            println(" Version: " + first.getMajor() + "." + first.getMinor());
-            println(" Chunks: " + chunks);
-            println(" Size: " + totalSize + " bytes");
-            println(" Start: " + Instant.ofEpochSecond(epochSeconds, adjustNanos));
-            println(" Duration: " + Duration.ofNanos(totalDuration));
-            println();
-            println(" Start Ticks: " + first.getStartTicks());
-            println(" Ticks / Second: " + first.getTicksPerSecond());
-
-            List<Statistics> statsList = new ArrayList<>(stats.values());
-            Collections.sort(statsList, (u, v) -> Long.compare(v.count, u.count));
-            println();
-            String header = "      Count  Size (bytes) ";
-            String typeHeader = " Event Type";
-            minWidth = Math.max(minWidth, typeHeader.length());
-            println(typeHeader + pad(minWidth - typeHeader.length(), ' ') + header);
-            println(pad(minWidth + header.length(), '='));
-            for (Statistics s : statsList) {
-                System.out.printf(" %-" + minWidth + "s%10d  %12d\n", s.name, s.count, s.size);
-            }
-        }
-    }
-
-    private String pad(int count, char c) {
-        StringBuilder sb = new StringBuilder();
-        for (int i = 0; i < count; i++) {
-            sb.append(c);
-        }
-        return sb.toString();
-    }
-}
--- a/src/jdk.jfr/share/classes/jdk/jfr/internal/cmd/XMLWriter.java	Wed Dec 05 17:11:22 2018 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,191 +0,0 @@
-/*
- * Copyright (c) 2016, 2018, 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 jdk.jfr.internal.cmd;
-
-import java.io.IOException;
-import java.io.PrintWriter;
-import java.nio.file.Path;
-
-import jdk.jfr.EventType;
-import jdk.jfr.ValueDescriptor;
-import jdk.jfr.consumer.RecordedEvent;
-import jdk.jfr.consumer.RecordedObject;
-import jdk.jfr.consumer.RecordingFile;
-
-final class XMLWriter extends StructuredWriter {
-
-    public XMLWriter(PrintWriter destination) {
-        super(destination);
-    }
-
-    public void print(Path source) throws IOException {
-        try (RecordingFile es = new RecordingFile(source)) {
-            println("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
-            println("<recording>");
-            indent();
-            printIndent();
-            println("<events>");
-            indent();
-            while (es.hasMoreEvents()) {
-                printEvent(es.readEvent());
-                flush();
-            }
-            retract();
-            printIndent();
-            println("</events>");
-            retract();
-            println("</recording>");
-            flush();
-        }
-    }
-
-    private void printEvent(RecordedEvent e) throws IOException {
-        EventType type = e.getEventType();
-        printIndent();
-        print("<event");
-        printAttribute("typeId", String.valueOf(type.getId()));
-        printAttribute("name", type.getName());
-        printAttribute("startTime",e.getStartTime().toString());
-        printAttribute("duration", e.getDuration().toString());
-        print(">");
-        printObject(e);
-        printIndent();
-        println("</event>");
-        println();
-    }
-
-    private void printAttribute(String name, String value) {
-        print(" ", name, "=\"", value, "\"");
-    }
-
-    public void printObject(RecordedObject struct) {
-        println();
-        indent();
-        for (ValueDescriptor v : struct.getFields()) {
-            printValueDescriptor(v, struct.getValue(v.getName()), -1);
-        }
-        retract();
-    }
-
-    private void printArray(ValueDescriptor v, Object[] array) {
-        println();
-        indent();
-        for (int index = 0; index < array.length; index++) {
-            printValueDescriptor(v, array[index], index);
-        }
-        retract();
-    }
-
-    private void printValueDescriptor(ValueDescriptor vd, Object value, int index) {
-        boolean arrayElement = index != -1;
-        String name = arrayElement ? null : vd.getName();
-        if (vd.isArray() && !arrayElement) {
-            if (printBeginElement("array", name, value, index)) {
-                printArray(vd, (Object[]) value);
-                printIndent();
-                printEndElement("array");
-            }
-            return;
-        }
-        if (!vd.getFields().isEmpty()) {
-            if (printBeginElement("struct", name, value, index)) {
-                printObject((RecordedObject) value);
-                printIndent();
-                printEndElement("struct");
-            }
-            return;
-        }
-        if (printBeginElement("value", name, value, index)) {
-            printEscaped(String.valueOf(value));
-            printEndElement("value");
-        }
-    }
-
-    private boolean printBeginElement(String elementName, String name, Object value, int index) {
-        printIndent();
-        print("<", elementName);
-        if (name != null) {
-            printAttribute("name", name);
-        }
-        if (index != -1) {
-            printAttribute("index", Integer.toString(index));
-        }
-        if (value == null) {
-            print("><null/></");
-            print(elementName);
-            println(">");
-            return false;
-        }
-        if (value.getClass().isArray()) {
-            Object[] array = (Object[]) value;
-            printAttribute("size", Integer.toString(array.length));
-        }
-        print(">");
-        return true;
-    }
-
-    private void printEndElement(String elementName) {
-        print("</");
-        print(elementName);
-        println(">");
-    }
-
-    private void printEscaped(String text) {
-        for (int i = 0; i < text.length(); i++) {
-            printEscaped(text.charAt(i));
-        }
-    }
-
-    private void printEscaped(char c) {
-        if (c == 34) {
-            print("&quot;");
-            return;
-        }
-        if (c == 38) {
-            print("&amp;");
-            return;
-        }
-        if (c == 39) {
-            print("&apos;");
-            return;
-        }
-        if (c == 60) {
-            print("&lt;");
-            return;
-        }
-        if (c == 62) {
-            print("&gt;");
-            return;
-        }
-        if (c > 0x7F) {
-            print("&#");
-            print((int) c);
-            print(';');
-            return;
-        }
-        print(c);
-    }
-}
--- a/test/jdk/jdk/jfr/cmd/ExecuteHelper.java	Wed Dec 05 17:11:22 2018 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,140 +0,0 @@
-/*
- * Copyright (c) 2016, 2018, 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 jdk.jfr.cmd;
-
-import java.nio.file.Path;
-import java.util.Arrays;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import jdk.jfr.Configuration;
-import jdk.jfr.Event;
-import jdk.jfr.Recording;
-import jdk.test.lib.Utils;
-import jdk.test.lib.process.OutputAnalyzer;
-import jdk.test.lib.process.ProcessTools;;
-
-final class ExecuteHelper {
-
-    public static Object[] array;
-
-    static class CustomEvent extends Event {
-        int intValue;
-        long longValue;
-        double doubliValue;
-        float floatValue;
-        String stringValue;
-        Short shortValue;
-        boolean booleanValue;
-        char charValue;
-        double trickyDouble;
-    }
-
-    public static OutputAnalyzer run(String... args) {
-        String[] array = new String[args.length + 1];
-        System.arraycopy(args, 0, array, 1, args.length);
-        array[0] = "jdk.jfr.internal.cmd.Execute";
-        try {
-            return ProcessTools.executeTestJava(array);
-        } catch (Exception e) {
-            String message = String.format("Caught exception while executing '%s'", Arrays.asList(array));
-            throw new RuntimeException(message, e);
-        }
-    }
-
-    public static void emitCustomEvents() {
-        // Custom events with potentially tricky values
-        CustomEvent event1 = new CustomEvent();
-        event1.trickyDouble = Double.NaN;
-        event1.intValue = Integer.MIN_VALUE;
-        event1.longValue = Long.MIN_VALUE;
-        event1.doubliValue = Double.MIN_VALUE;
-        event1.floatValue = Float.MIN_VALUE;
-        StringBuilder sb = new StringBuilder();
-        for (int i = 0; i < 512; i++) {
-            sb.append((char) i);
-        }
-        sb.append("\u2324");
-        event1.stringValue = sb.toString();
-        event1.shortValue = Short.MIN_VALUE;
-        event1.booleanValue = true;
-        event1.booleanValue = false;
-        event1.charValue = '\b';
-        event1.commit();
-
-        CustomEvent event2 = new CustomEvent();
-        event2.trickyDouble = Double.NEGATIVE_INFINITY;
-        event2.intValue = Integer.MAX_VALUE;
-        event2.longValue = Long.MAX_VALUE;
-        event2.doubliValue = Double.MAX_VALUE;
-        event2.floatValue = Float.MAX_VALUE;
-        event2.stringValue = null;
-        event2.shortValue = Short.MAX_VALUE;
-        event2.booleanValue = false;
-        event2.charValue = 0;
-        event2.commit();
-    }
-
-    public static Path createProfilingRecording() throws Exception {
-        Path file = Utils.createTempFile("profiling-recording", ".jfr");
-        // Create a recording with some data
-        try (Recording r = new Recording(Configuration.getConfiguration("profile"))) {
-            r.start();
-
-            // Allocation event
-            array = new Object[1000000];
-            array = null;
-
-            // Class loading event etc
-            provokeClassLoading();
-
-            // GC events
-            System.gc();
-
-            // ExecutionSample
-            long t = System.currentTimeMillis();
-            while (System.currentTimeMillis() - t < 50) {
-                // do nothing
-            }
-
-            // Other periodic events, i.e CPU load
-            Thread.sleep(1000);
-
-            r.stop();
-            r.dump(file);
-        }
-
-        return file;
-    }
-
-    private static void provokeClassLoading() {
-       // Matching a string with regexp
-       // is expected to load some classes and generate some VM events
-       Pattern p = Pattern.compile("a*b");
-       Matcher m = p.matcher("aaaaab");
-       m.matches();
-    }
-}
--- a/test/jdk/jdk/jfr/cmd/TestHelp.java	Wed Dec 05 17:11:22 2018 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,57 +0,0 @@
-/*
- * Copyright (c) 2016, 2018, 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 jdk.jfr.cmd;
-
-import jdk.test.lib.process.OutputAnalyzer;
-
-/**
- * @test
- * @summary Test help
- * @key jfr
- * @requires vm.hasJFR
- * @library /test/lib /test/jdk
- * @run main/othervm jdk.jfr.cmd.TestHelp
- */
-public class TestHelp {
-
-    public static void main(String[] args) throws Exception {
-        OutputAnalyzer output = ExecuteHelper.run("help");
-        output.shouldContain("Available commands are:");
-        output.shouldContain("print");
-        output.shouldContain("reconstruct");
-        output.shouldContain("summary");
-        output.shouldContain("help");
-
-        output = ExecuteHelper.run("help", "help");
-        output.shouldContain("Available commands are:");
-
-        output = ExecuteHelper.run("help", "wrongcommand");
-        output.shouldContain("Unknown command");
-
-        output = ExecuteHelper.run("help", "wrongcommand", "wrongarguments");
-        output.shouldContain("Too many arguments");
-    }
-}
--- a/test/jdk/jdk/jfr/cmd/TestPrint.java	Wed Dec 05 17:11:22 2018 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,66 +0,0 @@
-/*
- * Copyright (c) 2016, 2018, 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 jdk.jfr.cmd;
-
-import java.io.FileWriter;
-import java.nio.file.Files;
-import java.nio.file.Path;
-
-import jdk.test.lib.Utils;
-import jdk.test.lib.process.OutputAnalyzer;
-
-/**
- * @test
- * @summary Test jfr print
- * @key jfr
- * @requires vm.hasJFR
- * @library /test/lib /test/jdk
- * @run main/othervm jdk.jfr.cmd.TestPrint
- */
-public class TestPrint {
-
-    public static void main(String[] args) throws Exception {
-
-        OutputAnalyzer output = ExecuteHelper.run("print");
-        output.shouldContain("Missing file");
-
-        output = ExecuteHelper.run("print", "missing.jfr");
-        output.shouldContain("Could not find file ");
-
-        output = ExecuteHelper.run("print", "missing.jfr", "option1", "option2");
-        output.shouldContain("Too many arguments");
-
-        Path file = Utils.createTempFile("faked-print-file",  ".jfr");
-        FileWriter fw = new FileWriter(file.toFile());
-        fw.write('d');
-        fw.close();
-        output = ExecuteHelper.run("print", "--wrongOption", file.toAbsolutePath().toString());
-        output.shouldContain("Unknown option");
-        Files.delete(file);
-
-        // Also see TestPrintJSON, TestPrintXML and TestPrintDefault.
-    }
-}
--- a/test/jdk/jdk/jfr/cmd/TestPrintDefault.java	Wed Dec 05 17:11:22 2018 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,53 +0,0 @@
-/*
- * Copyright (c) 2016, 2018, 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 jdk.jfr.cmd;
-
-import java.nio.file.Path;
-
-import jdk.test.lib.process.OutputAnalyzer;
-
-/**
- * @test
- * @key jfr
- * @summary Tests print --json
- * @requires vm.hasJFR
- *
- * @library /test/lib /test/jdk
- * @modules java.scripting
- *          jdk.jfr
- *
- * @run main/othervm jdk.jfr.cmd.TestPrintDefault
- */
-public class TestPrintDefault {
-
-    public static void main(String... args) throws Exception {
-
-        Path recordingFile = ExecuteHelper.createProfilingRecording().toAbsolutePath();
-
-        OutputAnalyzer output = ExecuteHelper.run("print", recordingFile.toString());
-        output.shouldContain("JVMInformation");
-    }
-}
--- a/test/jdk/jdk/jfr/cmd/TestPrintJSON.java	Wed Dec 05 17:11:22 2018 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,149 +0,0 @@
-/*
- * Copyright (c) 2016, 2018, 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 jdk.jfr.cmd;
-
-import java.nio.file.Path;
-
-import javax.script.ScriptEngine;
-import javax.script.ScriptEngineManager;
-
-import jdk.jfr.ValueDescriptor;
-import jdk.jfr.consumer.RecordedEvent;
-import jdk.jfr.consumer.RecordedObject;
-import jdk.jfr.consumer.RecordingFile;
-import jdk.nashorn.api.scripting.JSObject;
-import jdk.test.lib.Asserts;
-import jdk.test.lib.process.OutputAnalyzer;
-
-/**
- * @test
- * @key jfr
- * @summary Tests print --json
- * @requires vm.hasJFR
- *
- * @library /test/lib /test/jdk
- * @modules jdk.scripting.nashorn
- *          jdk.jfr
- *
- * @run main/othervm jdk.jfr.cmd.TestPrintJSON
- */
-public class TestPrintJSON {
-
-    public static void main(String... args) throws Exception {
-
-        Path recordingFile = ExecuteHelper.createProfilingRecording().toAbsolutePath();
-
-        OutputAnalyzer output = ExecuteHelper.run("print", "--json", recordingFile.toString());
-        String json = output.getStdout();
-
-        // Parse JSON using Nashorn
-        String statement = "var jsonObject = " + json;
-        ScriptEngineManager factory = new ScriptEngineManager();
-        ScriptEngine engine = factory.getEngineByName("nashorn");
-        engine.eval(statement);
-        JSObject o = (JSObject) engine.get("jsonObject");
-        JSObject recording = (JSObject) o.getMember("recording");
-        JSObject events = (JSObject) recording.getMember("events");
-
-        // Verify events are equal
-        try (RecordingFile rf = new RecordingFile(recordingFile)) {
-            for (Object jsonEvent : events.values()) {
-                RecordedEvent recordedEvent = rf.readEvent();
-                double typeId = recordedEvent.getEventType().getId();
-                String startTime = recordedEvent.getStartTime().toString();
-                String duration = recordedEvent.getDuration().toString();
-                Asserts.assertEquals(typeId, ((Number) ((JSObject) jsonEvent).getMember("typeId")).doubleValue());
-                Asserts.assertEquals(startTime, ((JSObject) jsonEvent).getMember("startTime"));
-                Asserts.assertEquals(duration, ((JSObject) jsonEvent).getMember("duration"));
-                assertEquals(jsonEvent, recordedEvent);
-            }
-            Asserts.assertFalse(rf.hasMoreEvents(), "Incorrect number of events");
-        }
-    }
-
-    private static void assertEquals(Object jsonObject, Object jfrObject) throws Exception {
-        // Check object
-        if (jfrObject instanceof RecordedObject) {
-            JSObject values = (JSObject) ((JSObject) jsonObject).getMember("values");
-            RecordedObject recObject = (RecordedObject) jfrObject;
-            Asserts.assertEquals(values.values().size(), recObject.getFields().size());
-            for (ValueDescriptor v : recObject.getFields()) {
-                String name = v.getName();
-                assertEquals(values.getMember(name), recObject.getValue(name));
-                return;
-            }
-        }
-        // Check array
-        if (jfrObject != null && jfrObject.getClass().isArray()) {
-            Object[] jfrArray = (Object[]) jfrObject;
-            JSObject jsArray = (JSObject) jsonObject;
-            for (int i = 0; i < jfrArray.length; i++) {
-                assertEquals(jsArray.getSlot(i), jfrArray[i]);
-            }
-            return;
-        }
-        String jsonText = String.valueOf(jsonObject);
-        // Double.NaN / Double.Inifinity is not supported by JSON format,
-        // use null
-        if (jfrObject instanceof Double) {
-            double expected = ((Double) jfrObject);
-            if (Double.isInfinite(expected) || Double.isNaN(expected)) {
-                Asserts.assertEquals("null", jsonText);
-                return;
-            }
-            double value = Double.parseDouble(jsonText);
-            Asserts.assertEquals(expected, value);
-            return;
-        }
-        // Float.NaN / Float.Inifinity is not supported by JSON format,
-        // use null
-        if (jfrObject instanceof Float) {
-            float expected = ((Float) jfrObject);
-            if (Float.isInfinite(expected) || Float.isNaN(expected)) {
-                Asserts.assertEquals("null", jsonText);
-                return;
-            }
-            float value = Float.parseFloat(jsonText);
-            Asserts.assertEquals(expected, value);
-            return;
-        }
-        if (jfrObject instanceof Integer) {
-            Integer expected = ((Integer) jfrObject);
-            double value = Double.parseDouble(jsonText);
-            Asserts.assertEquals(expected.doubleValue(), value);
-            return;
-        }
-        if (jfrObject instanceof Long) {
-            Long expected = ((Long) jfrObject);
-            double value = Double.parseDouble(jsonText);
-            Asserts.assertEquals(expected.doubleValue(), value);
-            return;
-        }
-
-        String jfrText = String.valueOf(jfrObject);
-        Asserts.assertEquals(jfrText, jsonText, "Primitive values don't match. JSON = " + jsonText);
-    }
-}
--- a/test/jdk/jdk/jfr/cmd/TestPrintXML.java	Wed Dec 05 17:11:22 2018 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,222 +0,0 @@
-/*
- * Copyright (c) 2016, 2018, 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 jdk.jfr.cmd;
-
-import java.io.StringReader;
-import java.nio.file.Path;
-import java.time.Duration;
-import java.time.Instant;
-import java.util.AbstractMap.SimpleEntry;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Stack;
-
-import javax.xml.parsers.SAXParser;
-import javax.xml.parsers.SAXParserFactory;
-
-import jdk.jfr.ValueDescriptor;
-import jdk.jfr.consumer.RecordedEvent;
-import jdk.jfr.consumer.RecordedObject;
-import jdk.jfr.consumer.RecordingFile;
-import jdk.test.lib.process.OutputAnalyzer;
-
-import org.xml.sax.Attributes;
-import org.xml.sax.InputSource;
-import org.xml.sax.SAXException;
-import org.xml.sax.XMLReader;
-import org.xml.sax.helpers.DefaultHandler;
-
-/**
- * @test
- * @key jfr
- * @summary Tests print --xml
- * @requires vm.hasJFR
- *
- * @library /test/lib /test/jdk
- * @modules java.scripting
- *          java.xml
- *          jdk.jfr
- *
- * @run main/othervm jdk.jfr.cmd.TestPrintXML
- */
-public class TestPrintXML {
-
-    public static void main(String... args) throws Exception {
-
-        Path recordingFile = ExecuteHelper.createProfilingRecording().toAbsolutePath();
-
-        OutputAnalyzer output = ExecuteHelper.run("print", "--xml", recordingFile.toString());
-        String xml = output.getStdout();
-        System.out.println(xml);
-        // Parse XML string
-        SAXParserFactory factory = SAXParserFactory.newInstance();
-        SAXParser sp = factory.newSAXParser();
-        XMLReader xr = sp.getXMLReader();
-        RecordingHandler handler = new RecordingHandler();
-        xr.setContentHandler(handler);
-        xr.parse(new InputSource(new StringReader(xml)));
-
-        // Verify that all data was written correctly
-        Iterator<RecordedEvent> it = RecordingFile.readAllEvents(recordingFile).iterator();
-        for (XMLEvent xmlEvent : handler.events) {
-            RecordedEvent re = it.next();
-            if (!compare(re, xmlEvent.values)) {
-                System.out.println(re);
-                System.out.println(xmlEvent.values.toString());
-                throw new Exception("Event doesn't match");
-            }
-        }
-
-    }
-
-    @SuppressWarnings("unchecked")
-    static boolean compare(Object eventObject, Object xmlObject) {
-        if (eventObject == null) {
-            return xmlObject == null;
-        }
-        if (eventObject instanceof RecordedObject) {
-            RecordedObject re = (RecordedObject) eventObject;
-            Map<String, Object> xmlMap = (Map<String, Object>) xmlObject;
-            List<ValueDescriptor> fields = re.getFields();
-            if (fields.size() != xmlMap.size()) {
-                return false;
-            }
-            for (ValueDescriptor v : fields) {
-                String name = v.getName();
-                if (!compare(re.getValue(name), xmlMap.get(name))) {
-                    return false;
-                }
-            }
-            return true;
-        }
-        if (eventObject.getClass().isArray()) {
-            Object[] array = (Object[]) eventObject;
-            Object[] xmlArray = (Object[]) xmlObject;
-            if (array.length != xmlArray.length) {
-                return false;
-            }
-            for (int i = 0; i < array.length; i++) {
-                if (!compare(array[i], xmlArray[i])) {
-                    return false;
-                }
-            }
-            return true;
-        }
-        String s1 = String.valueOf(eventObject);
-        String s2 = (String) xmlObject;
-        return s1.equals(s2);
-    }
-
-    static class XMLEvent {
-        String name;
-        Instant startTime;
-        Duration duration;
-        Map<String, Object> values = new HashMap<>();
-
-        XMLEvent(String name, Instant startTime, Duration duration) {
-            this.name = name;
-            this.startTime = startTime;
-            this.duration = duration;
-        }
-    }
-
-    public static final class RecordingHandler extends DefaultHandler {
-
-        private Stack<Object> objects = new Stack<>();
-        private Stack<SimpleEntry<String, String>> elements = new Stack<>();
-        private List<XMLEvent> events = new ArrayList<>();
-
-        @Override
-        public void startElement(String uri, String localName, String qName, Attributes attrs) throws SAXException {
-            elements.push(new SimpleEntry<>(attrs.getValue("name"), attrs.getValue("index")));
-            switch (qName) {
-            case "null":
-                objects.pop();
-                objects.push(null);
-                break;
-            case "event":
-                Instant startTime = Instant.parse(attrs.getValue("startTime"));
-                Duration duration = Duration.parse(attrs.getValue("duration"));
-                objects.push(new XMLEvent(attrs.getValue("name"), startTime, duration));
-                break;
-            case "struct":
-                objects.push(new HashMap<String, Object>());
-                break;
-            case "array":
-                objects.push(new Object[Integer.parseInt(attrs.getValue("size"))]);
-                break;
-            case "value":
-                objects.push(new StringBuilder());
-                break;
-            }
-        }
-
-        @Override
-        public void characters(char[] ch, int start, int length) throws SAXException {
-            if (!objects.isEmpty()) {
-                Object o = objects.peek();
-                if (o instanceof StringBuilder) {
-                    ((StringBuilder) o).append(ch, start, length);
-                }
-            }
-        }
-
-        @SuppressWarnings("unchecked")
-        @Override
-        public void endElement(String uri, String localName, String qName) {
-            SimpleEntry<String, String> element = elements.pop();
-            switch (qName) {
-            case "event":
-            case "struct":
-            case "array":
-            case "value":
-                String name = element.getKey();
-                Object value = objects.pop();
-                if (objects.isEmpty()) {
-                    events.add((XMLEvent) value);
-                    return;
-                }
-                if (value instanceof StringBuilder) {
-                    value = ((StringBuilder) value).toString();
-                }
-                Object parent = objects.peek();
-                if (parent instanceof XMLEvent) {
-                    ((XMLEvent) parent).values.put(name, value);
-                }
-                if (parent instanceof Map) {
-                    ((Map<String, Object>) parent).put(name, value);
-                }
-                if (parent != null && parent.getClass().isArray()) {
-                    int index = Integer.parseInt(element.getValue());
-                    ((Object[]) parent)[index] = value;
-                }
-            }
-        }
-    }
-}
--- a/test/jdk/jdk/jfr/cmd/TestReconstruct.java	Wed Dec 05 17:11:22 2018 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,146 +0,0 @@
-/*
- * Copyright (c) 2016, 2018, 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 jdk.jfr.cmd;
-
-import java.io.FileWriter;
-import java.io.IOException;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.nio.file.Paths;
-
-import jdk.jfr.Event;
-import jdk.jfr.Name;
-import jdk.jfr.Recording;
-import jdk.jfr.consumer.RecordedEvent;
-import jdk.jfr.consumer.RecordingFile;
-import jdk.jfr.internal.Repository;
-import jdk.jfr.internal.SecuritySupport.SafePath;
-import jdk.test.lib.Asserts;
-import jdk.test.lib.process.OutputAnalyzer;
-
-/**
- * @test
- * @summary Test jfr reconstruct
- * @key jfr
- * @requires vm.hasJFR
- * @library /test/lib /test/jdk
- * @modules jdk.jfr/jdk.jfr.internal
- * @run main/othervm jdk.jfr.cmd.TestReconstruct
- */
-public class TestReconstruct {
-
-    @Name("Correlation")
-    static class CorrelationEvent extends Event {
-        int id;
-    }
-    private static int RECORDING_COUNT = 5;
-
-    @SuppressWarnings("resource")
-    public static void main(String[] args) throws Exception {
-        // Create some disk recordings
-        Recording[] recordings = new Recording[5];
-        for (int i = 0; i < RECORDING_COUNT; i++) {
-            Recording r = new Recording();
-            r.setToDisk(true);
-            r.start();
-            CorrelationEvent ce = new CorrelationEvent();
-            ce.id = i;
-            ce.commit();
-            r.stop();
-            recordings[i] = r;
-        }
-        Path dir = Paths.get("reconstruction-parts");
-        Files.createDirectories(dir);
-
-        long expectedCount = 0;
-        for (int i = 0; i < RECORDING_COUNT; i++) {
-            Path tmp = dir.resolve("chunk-part-" + i + ".jfr");
-            recordings[i].dump(tmp);
-            expectedCount += countEventInRecording(tmp);
-        }
-
-        SafePath repository = Repository.getRepository().getRepositoryPath();
-        Path destinationPath = Paths.get("reconstructed.jfr");
-
-        String directory = repository.toString();
-        String destination = destinationPath.toAbsolutePath().toString();
-
-        // Test failure
-        OutputAnalyzer output = ExecuteHelper.run("reconstruct");
-
-        output.shouldContain("Too few arguments");
-
-        output = ExecuteHelper.run("reconstruct", directory);
-        output.shouldContain("Too few arguments");
-
-        output = ExecuteHelper.run("reconstruct", "not-a-directory", destination);
-        output.shouldContain("Could not find disk repository at");
-
-        output = ExecuteHelper.run("reconstruct", directory, "not-a-destination");
-        output.shouldContain("Filename must end with .jfr");
-
-        output = ExecuteHelper.run("reconstruct", "--wrongOption", directory, destination);
-        output.shouldContain("Too many arguments");
-
-        FileWriter fw = new FileWriter(destination);
-        fw.write('d');
-        fw.close();
-        output = ExecuteHelper.run("reconstruct", directory, destination);
-        output.shouldContain("already exists");
-        Files.delete(destinationPath);
-
-        // test success
-        output = ExecuteHelper.run("reconstruct", directory, destination);
-        System.out.println(output.getOutput());
-        output.shouldContain("Reconstruction complete");
-
-        long reconstructedCount = countEventInRecording(destinationPath);
-        Asserts.assertEquals(expectedCount, reconstructedCount);
-        // Cleanup
-        for (int i = 0; i < RECORDING_COUNT; i++) {
-            recordings[i].close();
-        }
-    }
-
-    private static long countEventInRecording(Path file) throws IOException {
-        Integer lastId = -1;
-        try (RecordingFile rf = new RecordingFile(file)) {
-            long count = 0;
-            while (rf.hasMoreEvents()) {
-                RecordedEvent re = rf.readEvent();
-                if (re.getEventType().getName().equals("Correlation")) {
-                    Integer id = re.getValue("id");
-                    if (id < lastId) {
-                        Asserts.fail("Expected chunk number to increase");
-                    }
-                    lastId = id;
-                }
-                count++;
-            }
-            return count;
-        }
-    }
-}
--- a/test/jdk/jdk/jfr/cmd/TestSplit.java	Wed Dec 05 17:11:22 2018 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,121 +0,0 @@
-/*
- * Copyright (c) 2016, 2018, 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 jdk.jfr.cmd;
-
-import java.io.IOException;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.nio.file.Paths;
-import java.text.ParseException;
-import java.text.SimpleDateFormat;
-import java.util.Date;
-
-import jdk.jfr.Configuration;
-import jdk.jfr.Recording;
-import jdk.jfr.consumer.RecordingFile;
-import jdk.test.lib.process.OutputAnalyzer;
-
-/**
- * @test
- * @summary Test jfr split
- * @key jfr
- * @requires vm.hasJFR
- * @library /test/lib /test/jdk
- * @run main/othervm jdk.jfr.cmd.TestSplit
- */
-public class TestSplit {
-
-    public static void main(String[] args) throws Exception {
-        SimpleDateFormat formatter = new SimpleDateFormat("yyyy_MM_dd_HH_mm_ss");
-        String dateText = formatter.format(new Date());
-
-        Path recordingFileA = Paths.get("many-chunks-A-" + dateText + ".jfr");
-        Path recordingFileB = Paths.get("many-chunks-B-" + dateText + ".jfr");
-        makeRecordingWithChunks(6, recordingFileA);
-        Files.copy(recordingFileA, recordingFileB);
-
-        String fileAText = recordingFileA.toAbsolutePath().toString();
-        String fileBText = recordingFileB.toAbsolutePath().toString();
-
-        OutputAnalyzer output = ExecuteHelper.run("split");
-        output.shouldContain("Missing file");
-
-        output = ExecuteHelper.run("split", "--wrongOption1", "..wrongOption2", "..wrongOption3", fileAText);
-        output.shouldContain("Too many arguments");
-
-        output = ExecuteHelper.run("split", "--wrongOption", fileAText);
-        output.shouldContain("Unknown option");
-
-        output = ExecuteHelper.run("split", "--wrongOption", "1", fileAText);
-        output.shouldContain("Unknown option");
-
-        output = ExecuteHelper.run("split", "--maxchunks", "-3", fileAText);
-        output.shouldContain("Must be at least one chunk per file");
-
-        output = ExecuteHelper.run("split", "--maxchunks", "1000", fileAText);
-        output.shouldContain("Number of chunks in recording");
-        output.shouldContain("doesn't exceed max chunks");
-        output = ExecuteHelper.run("split", fileAText); // maxchunks is 5 by
-                                                        // default
-        System.out.println(output.getOutput());
-        System.out.println(fileAText);
-        verifyRecording(fileAText.substring(0, fileAText.length() - 4) + "_1.jfr");
-        verifyRecording(fileAText.substring(0, fileAText.length() - 4) + "_2.jfr");
-
-        output = ExecuteHelper.run("split", "--maxchunks", "2", fileBText);
-
-        verifyRecording(fileBText.substring(0, fileBText.length() - 4) + "_1.jfr");
-        verifyRecording(fileBText.substring(0, fileBText.length() - 4) + "_2.jfr");
-        verifyRecording(fileBText.substring(0, fileBText.length() - 4) + "_3.jfr");
-
-        output = ExecuteHelper.run("split", "--maxchunks", "2", fileBText);
-        output.shouldContain("file with that name already exist");
-    }
-
-    private static void verifyRecording(String name) throws IOException {
-        System.out.println("split name " + name);
-        try (RecordingFile rf = new RecordingFile(Paths.get(name))) {
-            rf.readEvent();
-        }
-    }
-
-    // Will create at least 2 * count + 1 chunks.
-    private static void makeRecordingWithChunks(int count, Path file) throws IOException, ParseException {
-        Recording main = new Recording(Configuration.getConfiguration("default"));
-        main.setToDisk(true);
-        main.start();
-        for (int i = 0; i < count; i++) {
-            Recording r = new Recording();
-            r.setToDisk(true);
-            r.start();
-            r.stop();
-            r.close();
-        }
-        main.stop();
-        main.dump(file);
-        main.close();
-    }
-}
--- a/test/jdk/jdk/jfr/cmd/TestSummary.java	Wed Dec 05 17:11:22 2018 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,62 +0,0 @@
-/*
- * Copyright (c) 2016, 2018, 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 jdk.jfr.cmd;
-
-import java.nio.file.Path;
-
-import jdk.jfr.EventType;
-import jdk.jfr.consumer.RecordingFile;
-import jdk.test.lib.process.OutputAnalyzer;
-
-/**
- * @test
- * @summary Test jfr info
- * @key jfr
- * @requires vm.hasJFR
- * @library /test/lib /test/jdk
- * @run main/othervm jdk.jfr.cmd.TestSummary
- */
-public class TestSummary {
-
-    public static void main(String[] args) throws Exception {
-        Path f = ExecuteHelper.createProfilingRecording().toAbsolutePath();
-        String file = f.toAbsolutePath().toString();
-
-        OutputAnalyzer output = ExecuteHelper.run("summary");
-        output.shouldContain("Missing file");
-
-        output = ExecuteHelper.run("summary", "--wrongOption", file);
-        output.shouldContain("Too many arguments");
-
-        output = ExecuteHelper.run("summary", file);
-        try (RecordingFile rf = new RecordingFile(f)) {
-            for (EventType t : rf.readEventTypes()) {
-                output.shouldContain(t.getName());
-            }
-        }
-        output.shouldContain("Version");
-    }
-}