# HG changeset patch # User Doug Simon # Date 1398174366 -7200 # Node ID cd51b1253c4ce5f161c3608f96ca083ba65d6935 # Parent 882f4cb7cfcfe2b4070bde72f91390c452ed5855 replaced the link between a HotSpotResolvedJavaMethod and a SpeculationLog with a ClassValue based mechanism (GRAAL-727) diff -r 882f4cb7cfcf -r cd51b1253c4c graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotResolvedJavaMethod.java --- 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. + *

+ * 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> SpeculationLogs = new ClassValue>() { + @Override + protected Map computeValue(java.lang.Class type) { + return new HashMap<>(4); + } + }; + public SpeculationLog getSpeculationLog() { - if (speculationLog == null) { - speculationLog = new HotSpotSpeculationLog(); + Map 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() {