diff graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/ri/HotSpotMethodResolvedImpl.java @ 5346:4c3d953f8131

added mechanism (enabled by -G:PICache and -G:PiFilter) for saving/loading method profiling info to/from disk
author Doug Simon <doug.simon@oracle.com>
date Thu, 03 May 2012 13:39:45 +0200
parents f47c770756e6
children dc71b06d09f8
line wrap: on
line diff
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/ri/HotSpotMethodResolvedImpl.java	Wed May 02 18:23:12 2012 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/ri/HotSpotMethodResolvedImpl.java	Thu May 03 13:39:45 2012 +0200
@@ -22,6 +22,7 @@
  */
 package com.oracle.graal.hotspot.ri;
 
+import java.io.*;
 import java.lang.annotation.*;
 import java.lang.reflect.*;
 import java.util.*;
@@ -226,18 +227,72 @@
         return compilationComplexity;
     }
 
+    private static final MethodFilter profilingInfoFilter = GraalOptions.PIFilter == null ? null : new MethodFilter(GraalOptions.PIFilter);
+
+    /**
+     * Determines if the profiling info cache should be used for this method.
+     */
+    private boolean useProfilingInfoCache() {
+        return GraalOptions.PICache != null && (profilingInfoFilter == null || profilingInfoFilter.matches(this));
+    }
+
+    private RiProfilingInfo loadProfilingInfo() {
+        if (!useProfilingInfoCache()) {
+            return null;
+        }
+        synchronized (this) {
+            File file = new File(GraalOptions.PICache, JniMangle.mangleMethod(holder, name, signature(), false));
+            if (file.exists()) {
+                try {
+                    SnapshotProfilingInfo snapshot = SnapshotProfilingInfo.load(file, compiler.getRuntime());
+                    if (snapshot.codeSize() != codeSize) {
+                        // The class file was probably changed - ignore the saved profile
+                        return null;
+                    }
+                    return snapshot;
+                } catch (Exception e) {
+                    // ignore
+                }
+            }
+            return null;
+        }
+    }
+
+    private void saveProfilingInfo(RiProfilingInfo info) {
+        if (useProfilingInfoCache()) {
+            synchronized (this) {
+                String base = JniMangle.mangleMethod(holder, name, signature(), false);
+                File file = new File(GraalOptions.PICache, base);
+                File txtFile = new File(GraalOptions.PICache, base + ".txt");
+                SnapshotProfilingInfo snapshot = info instanceof SnapshotProfilingInfo ? (SnapshotProfilingInfo) info : new SnapshotProfilingInfo(info);
+                try {
+                    snapshot.save(file, txtFile);
+                } catch (IOException e) {
+                    // ignore
+                }
+            }
+        }
+    }
+
     @Override
     public RiProfilingInfo profilingInfo() {
+        RiProfilingInfo info = loadProfilingInfo();
+        if (info != null) {
+            return info;
+        }
+
         if (GraalOptions.UseProfilingInformation && methodData == null) {
             methodData = compiler.getCompilerToVM().RiMethod_methodData(this);
         }
 
-        if (methodData == null) {
+        if (methodData == null || (!methodData.hasNormalData() && !methodData.hasExtraData())) {
             // Be optimistic and return false for exceptionSeen. A methodDataOop is allocated in case of a deoptimization.
-            return BaseProfilingInfo.get(RiExceptionSeen.FALSE);
+            info = BaseProfilingInfo.get(RiExceptionSeen.FALSE);
         } else {
-            return new HotSpotProfilingInfo(compiler, methodData);
+            info = new HotSpotProfilingInfo(compiler, methodData, codeSize);
+            saveProfilingInfo(info);
         }
+        return info;
     }
 
     @Override