changeset 15262:cd51b1253c4c

replaced the link between a HotSpotResolvedJavaMethod and a SpeculationLog with a ClassValue based mechanism (GRAAL-727)
author Doug Simon <doug.simon@oracle.com>
date Tue, 22 Apr 2014 15:46:06 +0200
parents 882f4cb7cfcf
children 0b25b81414c9
files graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaMethod.java
diffstat 1 files changed, 26 insertions(+), 4 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaMethod.java	Tue Apr 22 11:51:34 2014 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaMethod.java	Tue Apr 22 15:46:06 2014 +0200
@@ -28,6 +28,7 @@
 
 import java.lang.annotation.*;
 import java.lang.reflect.*;
+import java.util.*;
 
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
@@ -55,7 +56,6 @@
     private final HotSpotSignature signature;
     private HotSpotMethodData methodData;
     private byte[] code;
-    private SpeculationLog speculationLog;
 
     /**
      * Gets the holder of a HotSpot metaspace method native object.
@@ -623,11 +623,33 @@
         return result;
     }
 
+    /**
+     * The {@link SpeculationLog} for methods compiled by Graal hang off this per-declaring-type
+     * {@link ClassValue}. The raw Method* value is safe to use as a key in the map as a) it is
+     * never moves and b) we never read from it.
+     * <p>
+     * One implication is that we will preserve {@link SpeculationLog}s for methods that have been
+     * redefined via class redefinition. It's tempting to periodically flush such logs but we cannot
+     * read the JVM_ACC_IS_OBSOLETE bit (or anything else) via the raw pointer as obsoleted methods
+     * are subject to clean up and deletion (see InstanceKlass::purge_previous_versions_internal).
+     */
+    private static final ClassValue<Map<Long, SpeculationLog>> SpeculationLogs = new ClassValue<Map<Long, SpeculationLog>>() {
+        @Override
+        protected Map<Long, SpeculationLog> computeValue(java.lang.Class<?> type) {
+            return new HashMap<>(4);
+        }
+    };
+
     public SpeculationLog getSpeculationLog() {
-        if (speculationLog == null) {
-            speculationLog = new HotSpotSpeculationLog();
+        Map<Long, SpeculationLog> map = SpeculationLogs.get(holder.mirror());
+        synchronized (map) {
+            SpeculationLog log = map.get(this.metaspaceMethod);
+            if (log == null) {
+                log = new HotSpotSpeculationLog();
+                map.put(metaspaceMethod, log);
+            }
+            return log;
         }
-        return speculationLog;
     }
 
     public int intrinsicId() {