hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotGraalRuntime.java
changeset 46371 0337d0617e7b
parent 46344 694c102fd8ed
child 46459 7d4e637d3f21
--- a/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotGraalRuntime.java	Wed Apr 05 22:48:35 2017 +0000
+++ b/hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotGraalRuntime.java	Thu Apr 06 14:31:32 2017 -0700
@@ -34,8 +34,22 @@
 import static org.graalvm.compiler.debug.GraalDebugConfig.Options.MethodFilter;
 import static org.graalvm.compiler.debug.GraalDebugConfig.Options.Verify;
 
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.lang.management.ManagementFactory;
+import java.nio.file.FileVisitResult;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.nio.file.SimpleFileVisitor;
+import java.nio.file.attribute.BasicFileAttributes;
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.List;
+import java.util.zip.Deflater;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipOutputStream;
 
 import org.graalvm.compiler.api.replacements.SnippetReflectionProvider;
 import org.graalvm.compiler.api.runtime.GraalRuntime;
@@ -278,6 +292,7 @@
     }
 
     private long runtimeStartTime;
+    private boolean shutdown;
 
     /**
      * Take action related to entering a new execution phase.
@@ -291,6 +306,7 @@
     }
 
     void shutdown() {
+        shutdown = true;
         if (debugValuesPrinter != null) {
             debugValuesPrinter.printDebugValues(options);
         }
@@ -302,6 +318,8 @@
             }
         }
         BenchmarkCounters.shutdown(runtime(), options, runtimeStartTime);
+
+        archiveAndDeleteOutputDirectory();
     }
 
     void clearMeters() {
@@ -321,4 +339,95 @@
     public boolean isBootstrapping() {
         return bootstrapJVMCI && !bootstrapFinished;
     }
+
+    @Override
+    public boolean isShutdown() {
+        return shutdown;
+    }
+
+    /**
+     * Gets a unique identifier for this execution such as a process ID.
+     */
+    private static String getExecutionID() {
+        String runtimeName = ManagementFactory.getRuntimeMXBean().getName();
+        try {
+            int index = runtimeName.indexOf('@');
+            if (index != -1) {
+                long pid = Long.parseLong(runtimeName.substring(0, index));
+                return Long.toString(pid);
+            }
+        } catch (NumberFormatException e) {
+        }
+        return runtimeName;
+    }
+
+    private String outputDirectory;
+
+    @Override
+    public String getOutputDirectory() {
+        if (outputDirectory == null) {
+            outputDirectory = "graal_output_" + getExecutionID();
+            File dir = new File(outputDirectory).getAbsoluteFile();
+            if (!dir.exists()) {
+                dir.mkdirs();
+                if (!dir.exists()) {
+                    TTY.println("Warning: could not create Graal diagnostic directory " + dir);
+                    return null;
+                }
+            }
+        }
+        return outputDirectory;
+    }
+
+    /**
+     * Archives and deletes the {@linkplain #getOutputDirectory() output directory} if it exists.
+     */
+    private void archiveAndDeleteOutputDirectory() {
+        if (outputDirectory != null) {
+            Path dir = Paths.get(outputDirectory);
+            if (dir.toFile().exists()) {
+                try {
+                    // Give compiler threads a chance to finishing dumping
+                    Thread.sleep(1000);
+                } catch (InterruptedException e1) {
+                }
+                File zip = new File(outputDirectory + ".zip").getAbsoluteFile();
+                List<Path> toDelete = new ArrayList<>();
+                try (ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(zip))) {
+                    zos.setLevel(Deflater.BEST_COMPRESSION);
+                    Files.walkFileTree(dir, Collections.emptySet(), Integer.MAX_VALUE, new SimpleFileVisitor<Path>() {
+                        @Override
+                        public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
+                            if (attrs.isRegularFile()) {
+                                ZipEntry ze = new ZipEntry(file.toString());
+                                zos.putNextEntry(ze);
+                                zos.write(Files.readAllBytes(file));
+                                zos.closeEntry();
+                            }
+                            toDelete.add(file);
+                            return FileVisitResult.CONTINUE;
+                        }
+
+                        @Override
+                        public FileVisitResult postVisitDirectory(Path d, IOException exc) throws IOException {
+                            toDelete.add(d);
+                            return FileVisitResult.CONTINUE;
+                        }
+                    });
+                    TTY.println("Graal diagnostic output saved in %s", zip);
+                } catch (IOException e) {
+                    TTY.printf("IO error archiving %s:%n", dir);
+                    e.printStackTrace(TTY.out);
+                }
+                for (Path p : toDelete) {
+                    try {
+                        Files.delete(p);
+                    } catch (IOException e) {
+                        TTY.printf("IO error deleting %s:%n", p);
+                        e.printStackTrace(TTY.out);
+                    }
+                }
+            }
+        }
+    }
 }