changeset 17288:db0ee78b1ad5

prevent deadlock in HotSpotGraalRuntime.shutdown() by loading DebugValuesPrinter class eagerly
author Doug Simon <doug.simon@oracle.com>
date Wed, 01 Oct 2014 10:33:24 +0200
parents 0f8b1fb632df
children 4372344cf3d8
files graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/DebugValuesPrinter.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotGraalRuntime.java
diffstat 2 files changed, 70 insertions(+), 64 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/DebugValuesPrinter.java	Tue Sep 30 18:56:28 2014 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/DebugValuesPrinter.java	Wed Oct 01 10:33:24 2014 +0200
@@ -38,75 +38,73 @@
 public class DebugValuesPrinter {
 
     public void printDebugValues(String phase, boolean reset) throws GraalInternalError {
-        if (Debug.areUnconditionalMetricsEnabled() || Debug.areUnconditionalTimersEnabled() || (Debug.isEnabled() && areMetricsOrTimersEnabled())) {
-            TTY.println();
-            if (phase != null) {
-                TTY.println("<DebugValues:" + phase + ">");
-            } else {
-                TTY.println("<DebugValues>");
-            }
-            List<DebugValueMap> topLevelMaps = DebugValueMap.getTopLevelMaps();
-            List<DebugValue> debugValues = KeyRegistry.getDebugValues();
-            if (debugValues.size() > 0) {
-                try {
-                    ArrayList<DebugValue> sortedValues = new ArrayList<>(debugValues);
-                    Collections.sort(sortedValues);
+        TTY.println();
+        if (phase != null) {
+            TTY.println("<DebugValues:" + phase + ">");
+        } else {
+            TTY.println("<DebugValues>");
+        }
+        List<DebugValueMap> topLevelMaps = DebugValueMap.getTopLevelMaps();
+        List<DebugValue> debugValues = KeyRegistry.getDebugValues();
+        if (debugValues.size() > 0) {
+            try {
+                ArrayList<DebugValue> sortedValues = new ArrayList<>(debugValues);
+                Collections.sort(sortedValues);
 
-                    String summary = DebugValueSummary.getValue();
-                    if (summary == null) {
-                        summary = "Complete";
-                    }
-                    switch (summary) {
-                        case "Name":
-                            printSummary(topLevelMaps, sortedValues);
-                            break;
-                        case "Partial": {
-                            DebugValueMap globalMap = new DebugValueMap("Global");
-                            for (DebugValueMap map : topLevelMaps) {
-                                flattenChildren(map, globalMap);
-                            }
-                            globalMap.normalize();
-                            printMap(new DebugValueScope(null, globalMap), sortedValues);
-                            break;
+                String summary = DebugValueSummary.getValue();
+                if (summary == null) {
+                    summary = "Complete";
+                }
+                switch (summary) {
+                    case "Name":
+                        printSummary(topLevelMaps, sortedValues);
+                        break;
+                    case "Partial": {
+                        DebugValueMap globalMap = new DebugValueMap("Global");
+                        for (DebugValueMap map : topLevelMaps) {
+                            flattenChildren(map, globalMap);
                         }
-                        case "Complete": {
-                            DebugValueMap globalMap = new DebugValueMap("Global");
-                            for (DebugValueMap map : topLevelMaps) {
-                                globalMap.addChild(map);
-                            }
-                            globalMap.group();
-                            globalMap.normalize();
-                            printMap(new DebugValueScope(null, globalMap), sortedValues);
-                            break;
+                        globalMap.normalize();
+                        printMap(new DebugValueScope(null, globalMap), sortedValues);
+                        break;
+                    }
+                    case "Complete": {
+                        DebugValueMap globalMap = new DebugValueMap("Global");
+                        for (DebugValueMap map : topLevelMaps) {
+                            globalMap.addChild(map);
+                        }
+                        globalMap.group();
+                        globalMap.normalize();
+                        printMap(new DebugValueScope(null, globalMap), sortedValues);
+                        break;
+                    }
+                    case "Thread":
+                        for (DebugValueMap map : topLevelMaps) {
+                            TTY.println("Showing the results for thread: " + map.getName());
+                            map.group();
+                            map.normalize();
+                            printMap(new DebugValueScope(null, map), sortedValues);
                         }
-                        case "Thread":
-                            for (DebugValueMap map : topLevelMaps) {
-                                TTY.println("Showing the results for thread: " + map.getName());
-                                map.group();
-                                map.normalize();
-                                printMap(new DebugValueScope(null, map), sortedValues);
-                            }
-                            break;
-                        default:
-                            throw new GraalInternalError("Unknown summary type: %s", summary);
+                        break;
+                    default:
+                        throw new GraalInternalError("Unknown summary type: %s", summary);
+                }
+                if (reset) {
+                    for (DebugValueMap topLevelMap : topLevelMaps) {
+                        topLevelMap.reset();
                     }
-                    if (reset) {
-                        for (DebugValueMap topLevelMap : topLevelMaps) {
-                            topLevelMap.reset();
-                        }
-                    }
-                } catch (Throwable e) {
-                    // Don't want this to change the exit status of the VM
-                    PrintStream err = System.err;
-                    err.println("Error while printing debug values:");
-                    e.printStackTrace();
                 }
+            } catch (Throwable e) {
+                // Don't want this to change the exit status of the VM
+                PrintStream err = System.err;
+                err.println("Error while printing debug values:");
+                e.printStackTrace();
             }
-            if (phase != null) {
-                TTY.println("</DebugValues:" + phase + ">");
-            } else {
-                TTY.println("</DebugValues>");
-            }
+        }
+        if (phase != null) {
+            TTY.println("</DebugValues:" + phase + ">");
+        } else {
+            TTY.println("</DebugValues>");
         }
     }
 
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotGraalRuntime.java	Tue Sep 30 18:56:28 2014 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotGraalRuntime.java	Wed Oct 01 10:33:24 2014 +0200
@@ -132,6 +132,11 @@
                         throw new GraalInternalError("Unsupported value for DebugSummaryValue: %s", summary);
                 }
             }
+            if (Debug.areUnconditionalMetricsEnabled() || Debug.areUnconditionalTimersEnabled() || (Debug.isEnabled() && areMetricsOrTimersEnabled())) {
+                // This must be created here to avoid loading the DebugValuesPrinter class
+                // during shutdown() which in turn can cause a deadlock
+                debugValuesPrinter = new DebugValuesPrinter();
+            }
         }
 
         // Complete initialization of backends
@@ -247,6 +252,7 @@
 
     protected final HotSpotVMConfig config;
     private final HotSpotBackend hostBackend;
+    private DebugValuesPrinter debugValuesPrinter;
 
     /**
      * Graal mirrors are stored as a {@link ClassValue} associated with the {@link Class} of the
@@ -581,7 +587,9 @@
      */
     @SuppressWarnings("unused")
     private void shutdown() throws Exception {
-        new DebugValuesPrinter().printDebugValues(ResetDebugValuesAfterBootstrap.getValue() ? "application" : null, false);
+        if (debugValuesPrinter != null) {
+            debugValuesPrinter.printDebugValues(ResetDebugValuesAfterBootstrap.getValue() ? "application" : null, false);
+        }
         phaseTransition("final");
 
         SnippetCounter.printGroups(TTY.out().out());