changeset 22699:ea58bbafd5b9

Move SpeculationLog implementation to HotSpotSpeculationLog, because it is not useful for other VMs
author Christian Wimmer <christian.wimmer@oracle.com>
date Wed, 21 Oct 2015 09:06:12 -0700
parents 37505a836aaf
children 1ecbf6cc9ab0
files jvmci/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/CompilerToVM.java jvmci/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotCodeCacheProvider.java jvmci/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotSpeculationLog.java jvmci/jdk.vm.ci.meta/src/jdk/vm/ci/meta/SpeculationLog.java src/share/vm/jvmci/jvmciCompilerToVM.cpp src/share/vm/jvmci/jvmciJavaClasses.hpp src/share/vm/jvmci/systemDictionary_jvmci.hpp src/share/vm/jvmci/vmSymbols_jvmci.hpp src/share/vm/runtime/deoptimization.cpp
diffstat 9 files changed, 88 insertions(+), 51 deletions(-) [+]
line wrap: on
line diff
--- a/jvmci/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/CompilerToVM.java	Wed Oct 21 15:05:59 2015 +0200
+++ b/jvmci/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/CompilerToVM.java	Wed Oct 21 09:06:12 2015 -0700
@@ -37,7 +37,6 @@
 import jdk.vm.ci.meta.JavaType;
 import jdk.vm.ci.meta.ResolvedJavaMethod;
 import jdk.vm.ci.meta.ResolvedJavaType;
-import jdk.vm.ci.meta.SpeculationLog;
 import sun.misc.Unsafe;
 
 /**
@@ -310,7 +309,7 @@
      *         {@link HotSpotVMConfig#codeInstallResultDependenciesFailed} or
      *         {@link HotSpotVMConfig#codeInstallResultDependenciesInvalid}.
      */
-    native int installCode(TargetDescription target, HotSpotCompiledCode compiledCode, InstalledCode code, SpeculationLog speculationLog);
+    native int installCode(TargetDescription target, HotSpotCompiledCode compiledCode, InstalledCode code, HotSpotSpeculationLog speculationLog);
 
     /**
      * Notifies the VM of statistics for a completed compilation.
--- a/jvmci/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotCodeCacheProvider.java	Wed Oct 21 15:05:59 2015 +0200
+++ b/jvmci/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotCodeCacheProvider.java	Wed Oct 21 09:06:12 2015 -0700
@@ -147,7 +147,7 @@
         } else {
             compiledCode = new HotSpotCompiledCode(compResult);
         }
-        int result = runtime.getCompilerToVM().installCode(target, compiledCode, resultInstalledCode, log);
+        int result = runtime.getCompilerToVM().installCode(target, compiledCode, resultInstalledCode, (HotSpotSpeculationLog) log);
         if (result != config.codeInstallResultOk) {
             String resultDesc = config.getCodeInstallResultDescription(result);
             if (compiledCode instanceof HotSpotCompiledNmethod) {
--- a/jvmci/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotSpeculationLog.java	Wed Oct 21 15:05:59 2015 +0200
+++ b/jvmci/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotSpeculationLog.java	Wed Oct 21 09:06:12 2015 -0700
@@ -22,14 +22,63 @@
  */
 package jdk.vm.ci.hotspot;
 
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Set;
+import java.util.concurrent.ConcurrentLinkedQueue;
+
 import jdk.vm.ci.meta.JavaConstant;
 import jdk.vm.ci.meta.SpeculationLog;
 
-public class HotSpotSpeculationLog extends SpeculationLog {
+public class HotSpotSpeculationLog implements SpeculationLog {
+
+    /** Written by the C++ code that performs deoptimization. */
+    private volatile Object lastFailed;
+
+    /** All speculations that have been a deoptimization reason. */
+    private Set<SpeculationReason> failedSpeculations;
+
+    /** Strong references to all reasons embededded in the current nmethod. */
+    private volatile Collection<SpeculationReason> speculations;
+
+    @Override
+    public synchronized void collectFailedSpeculations() {
+        if (lastFailed != null) {
+            if (failedSpeculations == null) {
+                failedSpeculations = new HashSet<>(2);
+            }
+            failedSpeculations.add((SpeculationReason) lastFailed);
+            lastFailed = null;
+            speculations = null;
+        }
+    }
 
     @Override
-    public JavaConstant speculate(Object reason) {
-        addSpeculation(reason);
+    public boolean maySpeculate(SpeculationReason reason) {
+        if (failedSpeculations != null && failedSpeculations.contains(reason)) {
+            return false;
+        }
+        return true;
+    }
+
+    @Override
+    public JavaConstant speculate(SpeculationReason reason) {
+        assert maySpeculate(reason);
+
+        /*
+         * Objects referenced from nmethods are weak references. We need a strong reference to the
+         * reason objects that are embedded in nmethods, so we add them to the speculations
+         * collection.
+         */
+        if (speculations == null) {
+            synchronized (this) {
+                if (speculations == null) {
+                    speculations = new ConcurrentLinkedQueue<>();
+                }
+            }
+        }
+        speculations.add(reason);
+
         return HotSpotObjectConstantImpl.forObject(reason);
     }
 }
--- a/jvmci/jdk.vm.ci.meta/src/jdk/vm/ci/meta/SpeculationLog.java	Wed Oct 21 15:05:59 2015 +0200
+++ b/jvmci/jdk.vm.ci.meta/src/jdk/vm/ci/meta/SpeculationLog.java	Wed Oct 21 09:06:12 2015 -0700
@@ -22,49 +22,38 @@
  */
 package jdk.vm.ci.meta;
 
-import java.util.Collection;
-import java.util.HashSet;
-import java.util.Set;
-import java.util.concurrent.ConcurrentLinkedQueue;
-
 /**
- * Manages a list of unique deoptimization reasons.
+ * Manages unique deoptimization reasons. Reasons are embedded in compiled code and can be
+ * invalidated at run time. Subsequent compilations then should not speculate again on such
+ * invalidated reasons to avoid repeated deoptimization.
  *
+ * All methods of this interface are called by the compiler. There is no need for API to register
+ * failed speculations during deoptimization, since every VM has different needs there.
  */
-public abstract class SpeculationLog {
-    private volatile Object lastFailed;
-    private volatile Collection<Object> speculations;
-    private Set<Object> failedSpeculations;
+public interface SpeculationLog {
 
-    public synchronized void collectFailedSpeculations() {
-        if (lastFailed != null) {
-            if (failedSpeculations == null) {
-                failedSpeculations = new HashSet<>(2);
-            }
-            failedSpeculations.add(lastFailed);
-            lastFailed = null;
-            speculations = null;
-        }
+    /**
+     * Marker interface for speculation objects that can be added to the speculation log.
+     */
+    public interface SpeculationReason {
     }
 
-    public boolean maySpeculate(Object reason) {
-        if (failedSpeculations != null && failedSpeculations.contains(reason)) {
-            return false;
-        }
-        return true;
-    }
+    /**
+     * Must be called before compilation, i.e., before a compiler calls {@link #maySpeculate}.
+     */
+    void collectFailedSpeculations();
 
-    protected void addSpeculation(Object reason) {
-        assert maySpeculate(reason);
-        if (speculations == null) {
-            synchronized (this) {
-                if (speculations == null) {
-                    speculations = new ConcurrentLinkedQueue<>();
-                }
-            }
-        }
-        speculations.add(reason);
-    }
+    /**
+     * If this method returns true, the compiler is allowed to {@link #speculate} with the given
+     * reason.
+     */
+    boolean maySpeculate(SpeculationReason reason);
 
-    public abstract JavaConstant speculate(Object reason);
+    /**
+     * Registers a speculation that was performed by the compiler.
+     *
+     * @return A compiler constant encapsulating the provided reason. It is usually passed as an
+     *         argument to the deoptimization function.
+     */
+    JavaConstant speculate(SpeculationReason reason);
 }
--- a/src/share/vm/jvmci/jvmciCompilerToVM.cpp	Wed Oct 21 15:05:59 2015 +0200
+++ b/src/share/vm/jvmci/jvmciCompilerToVM.cpp	Wed Oct 21 09:06:12 2015 -0700
@@ -1196,7 +1196,6 @@
 #define CC (char*)  /*cast a literal from (const char*)*/
 #define FN_PTR(f) CAST_FROM_FN_PTR(void*, &(c2v_ ## f))
 
-#define SPECULATION_LOG       "Ljdk/vm/ci/meta/SpeculationLog;"
 #define STRING                "Ljava/lang/String;"
 #define OBJECT                "Ljava/lang/Object;"
 #define CLASS                 "Ljava/lang/Class;"
@@ -1210,6 +1209,7 @@
 #define HS_COMPILED_CODE      "Ljdk/vm/ci/hotspot/HotSpotCompiledCode;"
 #define HS_CONFIG             "Ljdk/vm/ci/hotspot/HotSpotVMConfig;"
 #define HS_STACK_FRAME_REF    "Ljdk/vm/ci/hotspot/HotSpotStackFrameReference;"
+#define HS_SPECULATION_LOG    "Ljdk/vm/ci/hotspot/HotSpotSpeculationLog;"
 #define METASPACE_METHOD_DATA "J"
 
 JNINativeMethod CompilerToVM::methods[] = {
@@ -1248,7 +1248,7 @@
   {CC"getConstantPool",                              CC"(Ljava/lang/Object;J)"HS_CONSTANT_POOL,                                        FN_PTR(getConstantPool)},
   {CC"getResolvedJavaType",                          CC"(Ljava/lang/Object;JZ)"HS_RESOLVED_KLASS,                                      FN_PTR(getResolvedJavaType)},
   {CC"initializeConfiguration",                      CC"("HS_CONFIG")V",                                                               FN_PTR(initializeConfiguration)},
-  {CC"installCode",                                  CC"("TARGET_DESCRIPTION HS_COMPILED_CODE INSTALLED_CODE SPECULATION_LOG")I",      FN_PTR(installCode)},
+  {CC"installCode",                                  CC"("TARGET_DESCRIPTION HS_COMPILED_CODE INSTALLED_CODE HS_SPECULATION_LOG")I",   FN_PTR(installCode)},
   {CC"notifyCompilationStatistics",                  CC"(I"HS_RESOLVED_METHOD"ZIJJ"INSTALLED_CODE")V",                                 FN_PTR(notifyCompilationStatistics)},
   {CC"resetCompilationStatistics",                   CC"()V",                                                                          FN_PTR(resetCompilationStatistics)},
   {CC"disassembleCodeBlob",                          CC"("INSTALLED_CODE")"STRING,                                                     FN_PTR(disassembleCodeBlob)},
--- a/src/share/vm/jvmci/jvmciJavaClasses.hpp	Wed Oct 21 15:05:59 2015 +0200
+++ b/src/share/vm/jvmci/jvmciJavaClasses.hpp	Wed Oct 21 09:06:12 2015 -0700
@@ -257,8 +257,8 @@
     oop_field(StackLockValue, slot, "Ljdk/vm/ci/meta/AllocatableValue;")                                                                                       \
     boolean_field(StackLockValue, eliminated)                                                                                                                  \
   end_class                                                                                                                                                    \
-  start_class(SpeculationLog)                                                                                                                                  \
-    oop_field(SpeculationLog, lastFailed, "Ljava/lang/Object;")                                                                                                \
+  start_class(HotSpotSpeculationLog)                                                                                                                           \
+    oop_field(HotSpotSpeculationLog, lastFailed, "Ljava/lang/Object;")                                                                                         \
   end_class                                                                                                                                                    \
   start_class(HotSpotStackFrameReference)                                                                                                                      \
     oop_field(HotSpotStackFrameReference, compilerToVM, "Ljdk/vm/ci/hotspot/CompilerToVM;")                                                                    \
--- a/src/share/vm/jvmci/systemDictionary_jvmci.hpp	Wed Oct 21 15:05:59 2015 +0200
+++ b/src/share/vm/jvmci/systemDictionary_jvmci.hpp	Wed Oct 21 09:06:12 2015 -0700
@@ -45,6 +45,7 @@
   do_klass(HotSpotConstantPool_klass,                    jdk_vm_ci_hotspot_HotSpotConstantPool,                 Jvmci) \
   do_klass(HotSpotJVMCIMetaAccessContext_klass,          jdk_vm_ci_hotspot_HotSpotJVMCIMetaAccessContext,       Jvmci) \
   do_klass(HotSpotJVMCIRuntime_klass,                    jdk_vm_ci_hotspot_HotSpotJVMCIRuntime,                 Jvmci) \
+  do_klass(HotSpotSpeculationLog_klass,                  jdk_vm_ci_hotspot_HotSpotSpeculationLog,               Jvmci) \
   do_klass(Assumptions_ConcreteMethod_klass,             jdk_vm_ci_meta_Assumptions_ConcreteMethod,             Jvmci) \
   do_klass(Assumptions_NoFinalizableSubclass_klass,      jdk_vm_ci_meta_Assumptions_NoFinalizableSubclass,      Jvmci) \
   do_klass(Assumptions_ConcreteSubtype_klass,            jdk_vm_ci_meta_Assumptions_ConcreteSubtype,            Jvmci) \
@@ -72,7 +73,6 @@
   do_klass(StackSlot_klass,                              jdk_vm_ci_code_StackSlot,                              Jvmci) \
   do_klass(StackLockValue_klass,                         jdk_vm_ci_code_StackLockValue,                         Jvmci) \
   do_klass(VirtualObject_klass,                          jdk_vm_ci_code_VirtualObject,                          Jvmci) \
-  do_klass(SpeculationLog_klass,                         jdk_vm_ci_meta_SpeculationLog,                         Jvmci) \
   do_klass(JavaConstant_klass,                           jdk_vm_ci_meta_JavaConstant,                           Jvmci) \
   do_klass(PrimitiveConstant_klass,                      jdk_vm_ci_meta_PrimitiveConstant,                      Jvmci) \
   do_klass(RawConstant_klass,                            jdk_vm_ci_meta_RawConstant,                            Jvmci) \
--- a/src/share/vm/jvmci/vmSymbols_jvmci.hpp	Wed Oct 21 15:05:59 2015 +0200
+++ b/src/share/vm/jvmci/vmSymbols_jvmci.hpp	Wed Oct 21 09:06:12 2015 -0700
@@ -46,6 +46,7 @@
   template(jdk_vm_ci_hotspot_HotSpotConstantPool,                 "jdk/vm/ci/hotspot/HotSpotConstantPool")                                \
   template(jdk_vm_ci_hotspot_HotSpotJVMCIMetaAccessContext,       "jdk/vm/ci/hotspot/HotSpotJVMCIMetaAccessContext")                      \
   template(jdk_vm_ci_hotspot_HotSpotJVMCIRuntime,                 "jdk/vm/ci/hotspot/HotSpotJVMCIRuntime")                                \
+  template(jdk_vm_ci_hotspot_HotSpotSpeculationLog,               "jdk/vm/ci/hotspot/HotSpotSpeculationLog")                              \
   template(jdk_vm_ci_meta_JavaConstant,                           "jdk/vm/ci/meta/JavaConstant")                                          \
   template(jdk_vm_ci_meta_PrimitiveConstant,                      "jdk/vm/ci/meta/PrimitiveConstant")                                     \
   template(jdk_vm_ci_meta_RawConstant,                            "jdk/vm/ci/meta/RawConstant")                                           \
@@ -59,7 +60,6 @@
   template(jdk_vm_ci_meta_Assumptions_NoFinalizableSubclass,      "jdk/vm/ci/meta/Assumptions$NoFinalizableSubclass")                     \
   template(jdk_vm_ci_meta_Assumptions_ConcreteMethod,             "jdk/vm/ci/meta/Assumptions$ConcreteMethod")                            \
   template(jdk_vm_ci_meta_Assumptions_CallSiteTargetValue,        "jdk/vm/ci/meta/Assumptions$CallSiteTargetValue")                       \
-  template(jdk_vm_ci_meta_SpeculationLog,                         "jdk/vm/ci/meta/SpeculationLog")                                        \
   template(jdk_vm_ci_code_Architecture,                           "jdk/vm/ci/code/Architecture")                                          \
   template(jdk_vm_ci_code_TargetDescription,                      "jdk/vm/ci/code/TargetDescription")                                     \
   template(jdk_vm_ci_code_CompilationResult_Call,                 "jdk/vm/ci/code/CompilationResult$Call")                                \
--- a/src/share/vm/runtime/deoptimization.cpp	Wed Oct 21 15:05:59 2015 +0200
+++ b/src/share/vm/runtime/deoptimization.cpp	Wed Oct 21 09:06:12 2015 -0700
@@ -1479,14 +1479,14 @@
         oop speculation_log = nm->speculation_log();
         if (speculation_log != NULL) {
           if (TraceDeoptimization || TraceUncollectedSpeculations) {
-            if (SpeculationLog::lastFailed(speculation_log) != NULL) {
+            if (HotSpotSpeculationLog::lastFailed(speculation_log) != NULL) {
               tty->print_cr("A speculation that was not collected by the compiler is being overwritten");
             }
           }
           if (TraceDeoptimization) {
             tty->print_cr("Saving speculation to speculation log");
           }
-          SpeculationLog::set_lastFailed(speculation_log, speculation);
+          HotSpotSpeculationLog::set_lastFailed(speculation_log, speculation);
         } else {
           if (TraceDeoptimization) {
             tty->print_cr("Speculation present but no speculation log");