# HG changeset patch # User Christian Wimmer # Date 1445443572 25200 # Node ID ea58bbafd5b9672e004f4d987d6f2400e57fccac # Parent 37505a836aaf0e765e7ef614351012c3a2e4582d Move SpeculationLog implementation to HotSpotSpeculationLog, because it is not useful for other VMs diff -r 37505a836aaf -r ea58bbafd5b9 jvmci/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/CompilerToVM.java --- 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. diff -r 37505a836aaf -r ea58bbafd5b9 jvmci/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotCodeCacheProvider.java --- 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) { diff -r 37505a836aaf -r ea58bbafd5b9 jvmci/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotSpeculationLog.java --- 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 failedSpeculations; + + /** Strong references to all reasons embededded in the current nmethod. */ + private volatile Collection 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); } } diff -r 37505a836aaf -r ea58bbafd5b9 jvmci/jdk.vm.ci.meta/src/jdk/vm/ci/meta/SpeculationLog.java --- 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 speculations; - private Set 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); } diff -r 37505a836aaf -r ea58bbafd5b9 src/share/vm/jvmci/jvmciCompilerToVM.cpp --- 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)}, diff -r 37505a836aaf -r ea58bbafd5b9 src/share/vm/jvmci/jvmciJavaClasses.hpp --- 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;") \ diff -r 37505a836aaf -r ea58bbafd5b9 src/share/vm/jvmci/systemDictionary_jvmci.hpp --- 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) \ diff -r 37505a836aaf -r ea58bbafd5b9 src/share/vm/jvmci/vmSymbols_jvmci.hpp --- 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") \ diff -r 37505a836aaf -r ea58bbafd5b9 src/share/vm/runtime/deoptimization.cpp --- 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");