# HG changeset patch # User Doug Simon # Date 1423756452 -3600 # Node ID 98592ae4b1fa82af723303950a886d0218d5efbb # Parent 49605c649beb474e6855c98ed45eb763cab7f88e only record method dependencies if JVMTI hotswapping or breakpointing is enabled don't verify dependencies if the SystemDictionary was not updated during compilation diff -r 49605c649beb -r 98592ae4b1fa graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/MemoryUsageBenchmark.java --- a/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/MemoryUsageBenchmark.java Thu Feb 12 15:20:14 2015 +0100 +++ b/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/MemoryUsageBenchmark.java Thu Feb 12 16:54:12 2015 +0100 @@ -135,10 +135,10 @@ method.reprofile(); int id = method.allocateCompileId(INVOCATION_ENTRY_BCI); - long ctask = 0L; + long graalEnv = 0L; try (MemoryUsageCloseable c = label == null ? null : new MemoryUsageCloseable(label)) { - CompilationTask task = new CompilationTask(backend, method, INVOCATION_ENTRY_BCI, ctask, id, false); + CompilationTask task = new CompilationTask(backend, method, INVOCATION_ENTRY_BCI, graalEnv, id, false); task.runCompilation(); } } @@ -152,9 +152,9 @@ method.reprofile(); int id = method.allocateCompileId(INVOCATION_ENTRY_BCI); - long ctask = 0L; + long graalEnv = 0L; try (AllocSpy as = AllocSpy.open(methodName)) { - CompilationTask task = new CompilationTask(backend, method, INVOCATION_ENTRY_BCI, ctask, id, false); + CompilationTask task = new CompilationTask(backend, method, INVOCATION_ENTRY_BCI, graalEnv, id, false); task.runCompilation(); } } diff -r 49605c649beb -r 98592ae4b1fa graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompilationTask.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompilationTask.java Thu Feb 12 15:20:14 2015 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompilationTask.java Thu Feb 12 16:54:12 2015 +0100 @@ -97,17 +97,16 @@ private static final com.sun.management.ThreadMXBean threadMXBean = (com.sun.management.ThreadMXBean) ManagementFactory.getThreadMXBean(); /** - * The address of the native CompileTask associated with this compilation or 0L if no such - * association exists. + * The address of the GraalEnv associated with this compilation or 0L if no such object exists. */ - private final long ctask; + private final long graalEnv; - public CompilationTask(HotSpotBackend backend, HotSpotResolvedJavaMethod method, int entryBCI, long ctask, int id, boolean installAsDefault) { + public CompilationTask(HotSpotBackend backend, HotSpotResolvedJavaMethod method, int entryBCI, long graalEnv, int id, boolean installAsDefault) { this.backend = backend; this.method = method; this.entryBCI = entryBCI; this.id = id; - this.ctask = ctask; + this.graalEnv = graalEnv; this.installAsDefault = installAsDefault; } @@ -209,14 +208,19 @@ graphCache = new HashMap<>(); } + boolean recordEvolMethodDeps = graalEnv == 0 || unsafe.getByte(graalEnv + config.graalEnvJvmtiCanHotswapOrPostBreakpointOffset) != 0; + HotSpotProviders providers = backend.getProviders(); Replacements replacements = providers.getReplacements(); graph = replacements.getMethodSubstitution(method); if (graph == null || entryBCI != INVOCATION_ENTRY_BCI) { graph = new StructuredGraph(method, entryBCI, AllowAssumptions.from(OptAssumptions.getValue())); + if (!recordEvolMethodDeps) { + graph.disableMethodRecording(); + } } else { // Compiling method substitution - must clone the graph - graph = graph.copy(graph.name, method, AllowAssumptions.from(OptAssumptions.getValue())); + graph = graph.copy(graph.name, method, AllowAssumptions.from(OptAssumptions.getValue()), recordEvolMethodDeps); } InlinedBytecodes.add(method.getCodeSize()); CallingConvention cc = getCallingConvention(providers.getCodeCache(), Type.JavaCallee, graph.method(), false); @@ -313,7 +317,9 @@ compilationEvent.commit(); } - if (ctask != 0) { + if (graalEnv != 0) { + long ctask = unsafe.getAddress(graalEnv + config.graalEnvTaskOffset); + assert ctask != 0L; unsafe.putInt(ctask + config.compileTaskNumInlinedBytecodesOffset, processedBytes); } if ((config.ciTime || config.ciTimeEach) && installedCode != null) { @@ -335,7 +341,7 @@ final HotSpotCodeCacheProvider codeCache = backend.getProviders().getCodeCache(); InstalledCode installedCode = null; try (Scope s = Debug.scope("CodeInstall", new DebugDumpScope(String.valueOf(id), true), codeCache, method)) { - installedCode = codeCache.installMethod(method, compResult, ctask, installAsDefault); + installedCode = codeCache.installMethod(method, compResult, graalEnv, installAsDefault); } catch (Throwable e) { throw Debug.handle(e); } @@ -354,11 +360,11 @@ * * @param metaspaceMethod * @param entryBCI - * @param ctask address of native CompileTask object + * @param graalEnv address of native GraalEnv object * @param id CompileTask::_compile_id */ @SuppressWarnings("unused") - private static void compileMetaspaceMethod(long metaspaceMethod, int entryBCI, long ctask, int id) { + private static void compileMetaspaceMethod(long metaspaceMethod, int entryBCI, long graalEnv, int id) { // Ensure a Graal runtime is initialized prior to Debug being initialized as the former // may include processing command line options used by the latter. Graal.getRuntime(); @@ -369,15 +375,15 @@ } HotSpotResolvedJavaMethod method = HotSpotResolvedJavaMethodImpl.fromMetaspace(metaspaceMethod); - compileMethod(method, entryBCI, ctask, id); + compileMethod(method, entryBCI, graalEnv, id); } /** * Compiles a method to machine code. */ - static void compileMethod(HotSpotResolvedJavaMethod method, int entryBCI, long ctask, int id) { + static void compileMethod(HotSpotResolvedJavaMethod method, int entryBCI, long graalEnv, int id) { HotSpotBackend backend = runtime().getHostBackend(); - CompilationTask task = new CompilationTask(backend, method, entryBCI, ctask, id, true); + CompilationTask task = new CompilationTask(backend, method, entryBCI, graalEnv, id, true); try (DebugConfigScope dcs = setConfig(new TopLevelDebugConfig())) { task.runCompilation(); } diff -r 49605c649beb -r 98592ae4b1fa graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotCompiledNmethod.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotCompiledNmethod.java Thu Feb 12 15:20:14 2015 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotCompiledNmethod.java Thu Feb 12 16:54:12 2015 +0100 @@ -34,18 +34,18 @@ public final HotSpotResolvedJavaMethod method; public final int entryBCI; public final int id; - public final long ctask; + public final long graalEnv; public HotSpotCompiledNmethod(HotSpotResolvedJavaMethod method, CompilationResult compResult) { this(method, compResult, 0L); } - public HotSpotCompiledNmethod(HotSpotResolvedJavaMethod method, CompilationResult compResult, long ctask) { + public HotSpotCompiledNmethod(HotSpotResolvedJavaMethod method, CompilationResult compResult, long graalEnv) { super(compResult); this.method = method; this.entryBCI = compResult.getEntryBCI(); this.id = compResult.getId(); - this.ctask = ctask; + this.graalEnv = graalEnv; } @Override diff -r 49605c649beb -r 98592ae4b1fa graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotVMConfig.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotVMConfig.java Thu Feb 12 15:20:14 2015 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotVMConfig.java Thu Feb 12 16:54:12 2015 +0100 @@ -1082,6 +1082,8 @@ @HotSpotVMConstant(name = "JVM_ACC_MONITOR_MATCH") @Stable public int jvmAccMonitorMatch; @HotSpotVMConstant(name = "JVM_ACC_HAS_MONITOR_BYTECODES") @Stable public int jvmAccHasMonitorBytecodes; + @HotSpotVMField(name = "GraalEnv::_task", type = "CompileTask*", get = HotSpotVMField.Type.OFFSET) @Stable public int graalEnvTaskOffset; + @HotSpotVMField(name = "GraalEnv::_jvmti_can_hotswap_or_post_breakpoint", type = "bool", get = HotSpotVMField.Type.OFFSET) @Stable public int graalEnvJvmtiCanHotswapOrPostBreakpointOffset; @HotSpotVMField(name = "CompileTask::_num_inlined_bytecodes", type = "int", get = HotSpotVMField.Type.OFFSET) @Stable public int compileTaskNumInlinedBytecodesOffset; /** diff -r 49605c649beb -r 98592ae4b1fa graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotCodeCacheProvider.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotCodeCacheProvider.java Thu Feb 12 15:20:14 2015 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotCodeCacheProvider.java Thu Feb 12 16:54:12 2015 +0100 @@ -239,12 +239,12 @@ return installedCode; } - public InstalledCode installMethod(HotSpotResolvedJavaMethod method, CompilationResult compResult, long ctask, boolean isDefault) { + public InstalledCode installMethod(HotSpotResolvedJavaMethod method, CompilationResult compResult, long graalEnv, boolean isDefault) { if (compResult.getId() == -1) { compResult.setId(method.allocateCompileId(compResult.getEntryBCI())); } HotSpotInstalledCode installedCode = new HotSpotNmethod(method, compResult.getName(), isDefault); - runtime.getCompilerToVM().installCode(new HotSpotCompiledNmethod(method, compResult, ctask), installedCode, method.getSpeculationLog()); + runtime.getCompilerToVM().installCode(new HotSpotCompiledNmethod(method, compResult, graalEnv), installedCode, method.getSpeculationLog()); return logOrDump(installedCode, compResult); } diff -r 49605c649beb -r 98592ae4b1fa graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/StructuredGraph.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/StructuredGraph.java Thu Feb 12 15:20:14 2015 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/StructuredGraph.java Thu Feb 12 16:54:12 2015 +0100 @@ -220,15 +220,15 @@ } public StructuredGraph copy(String newName, ResolvedJavaMethod newMethod) { - return copy(newName, newMethod, AllowAssumptions.from(assumptions != null)); + return copy(newName, newMethod, AllowAssumptions.from(assumptions != null), isMethodRecordingEnabled()); } - public StructuredGraph copy(String newName, ResolvedJavaMethod newMethod, AllowAssumptions allowAssumptions) { + public StructuredGraph copy(String newName, ResolvedJavaMethod newMethod, AllowAssumptions allowAssumptions, boolean enableMethodRecording) { StructuredGraph copy = new StructuredGraph(newName, newMethod, graphId, entryBCI, allowAssumptions); if (allowAssumptions == AllowAssumptions.YES && assumptions != null) { copy.assumptions.record(assumptions); } - if (!isMethodRecordingEnabled()) { + if (!enableMethodRecording) { copy.disableMethodRecording(); } copy.setGuardsStage(getGuardsStage()); diff -r 49605c649beb -r 98592ae4b1fa src/share/vm/compiler/compileBroker.cpp --- a/src/share/vm/compiler/compileBroker.cpp Thu Feb 12 15:20:14 2015 +0100 +++ b/src/share/vm/compiler/compileBroker.cpp Thu Feb 12 16:54:12 2015 +0100 @@ -1987,6 +1987,11 @@ int compilable = ciEnv::MethodCompilable; AbstractCompiler *comp = compiler(task_level); + int system_dictionary_modification_counter; + { + MutexLocker locker(Compile_lock, thread); + system_dictionary_modification_counter = SystemDictionary::number_of_modifications(); + } #ifdef COMPILERGRAAL if (comp != NULL && comp->is_graal()) { GraalCompiler* graal = (GraalCompiler*) comp; @@ -1994,17 +1999,13 @@ TraceTime t1("compilation", &time); EventCompilation event; - graal->compile_method(target_handle, osr_bci, task); + GraalEnv env(task, system_dictionary_modification_counter); + graal->compile_method(target_handle, osr_bci, &env); post_compile(thread, task, event, task->code() != NULL, NULL); } else #endif // COMPILERGRAAL { - int system_dictionary_modification_counter; - { - MutexLocker locker(Compile_lock, thread); - system_dictionary_modification_counter = SystemDictionary::number_of_modifications(); - } NoHandleMark nhm; ThreadToNativeFromVM ttn(thread); diff -r 49605c649beb -r 98592ae4b1fa src/share/vm/graal/graalCodeInstaller.cpp --- a/src/share/vm/graal/graalCodeInstaller.cpp Thu Feb 12 15:20:14 2015 +0100 +++ b/src/share/vm/graal/graalCodeInstaller.cpp Thu Feb 12 16:54:12 2015 +0100 @@ -462,13 +462,13 @@ methodHandle method = getMethodFromHotSpotMethod(HotSpotCompiledNmethod::method(compiled_code)); jint entry_bci = HotSpotCompiledNmethod::entryBCI(compiled_code); jint id = HotSpotCompiledNmethod::id(compiled_code); - CompileTask* task = (CompileTask*) (address) HotSpotCompiledNmethod::ctask(compiled_code); + GraalEnv* env = (GraalEnv*) (address) HotSpotCompiledNmethod::graalEnv(compiled_code); if (id == -1) { // Make sure a valid compile_id is associated with every compile id = CompileBroker::assign_compile_id_unlocked(Thread::current(), method, entry_bci); } result = GraalEnv::register_method(method, nm, entry_bci, &_offsets, _custom_stack_area_offset, &buffer, stack_slots, _debug_recorder->_oopmaps, &_exception_handler_table, - GraalCompiler::instance(), _debug_recorder, _dependencies, task, id, false, installed_code, speculation_log); + GraalCompiler::instance(), _debug_recorder, _dependencies, env, id, false, installed_code, speculation_log); cb = nm; } diff -r 49605c649beb -r 98592ae4b1fa src/share/vm/graal/graalCompiler.cpp --- a/src/share/vm/graal/graalCompiler.cpp Thu Feb 12 15:20:14 2015 +0100 +++ b/src/share/vm/graal/graalCompiler.cpp Thu Feb 12 16:54:12 2015 +0100 @@ -105,7 +105,7 @@ _bootstrapping = false; } -void GraalCompiler::compile_method(methodHandle method, int entry_bci, CompileTask* task) { +void GraalCompiler::compile_method(methodHandle method, int entry_bci, GraalEnv* env) { GRAAL_EXCEPTION_CONTEXT bool is_osr = entry_bci != InvocationEntryBci; @@ -122,8 +122,8 @@ JavaCallArguments args; args.push_long((jlong) (address) method()); args.push_int(entry_bci); - args.push_long((jlong) (address) task); - args.push_int(task->compile_id()); + args.push_long((jlong) (address) env); + args.push_int(env->task()->compile_id()); JavaCalls::call_static(&result, SystemDictionary::CompilationTask_klass(), vmSymbols::compileMetaspaceMethod_name(), vmSymbols::compileMetaspaceMethod_signature(), &args, CHECK_ABORT); _methodsCompiled++; diff -r 49605c649beb -r 98592ae4b1fa src/share/vm/graal/graalCompiler.hpp --- a/src/share/vm/graal/graalCompiler.hpp Thu Feb 12 15:20:14 2015 +0100 +++ b/src/share/vm/graal/graalCompiler.hpp Thu Feb 12 16:54:12 2015 +0100 @@ -25,6 +25,7 @@ #define SHARE_VM_GRAAL_GRAAL_COMPILER_HPP #include "compiler/abstractCompiler.hpp" +#include "graal/graalEnv.hpp" class GraalCompiler : public AbstractCompiler { @@ -72,7 +73,7 @@ // Compilation entry point for methods virtual void compile_method(ciEnv* env, ciMethod* target, int entry_bci); - void compile_method(methodHandle target, int entry_bci, CompileTask* task); + void compile_method(methodHandle target, int entry_bci, GraalEnv* env); // Print compilation timers and statistics virtual void print_timers(); diff -r 49605c649beb -r 98592ae4b1fa src/share/vm/graal/graalEnv.cpp --- a/src/share/vm/graal/graalEnv.cpp Thu Feb 12 15:20:14 2015 +0100 +++ b/src/share/vm/graal/graalEnv.cpp Thu Feb 12 16:54:12 2015 +0100 @@ -45,6 +45,18 @@ #include "graal/graalRuntime.hpp" #include "graal/graalJavaAccess.hpp" +GraalEnv::GraalEnv(CompileTask* task, int system_dictionary_modification_counter) { + _task = task; + _system_dictionary_modification_counter = system_dictionary_modification_counter; + { + // Get Jvmti capabilities under lock to get consistent values. + MutexLocker mu(JvmtiThreadState_lock); + _jvmti_can_hotswap_or_post_breakpoint = JvmtiExport::can_hotswap_or_post_breakpoint(); + _jvmti_can_access_local_variables = JvmtiExport::can_access_local_variables(); + _jvmti_can_post_on_exceptions = JvmtiExport::can_post_on_exceptions(); + } +} + // ------------------------------------------------------------------ // Note: the logic of this method should mirror the logic of // constantPoolOopDesc::verify_constant_pool_resolve. @@ -409,19 +421,23 @@ // ------------------------------------------------------------------ // Check for changes to the system dictionary during compilation // class loads, evolution, breakpoints -bool GraalEnv::check_for_system_dictionary_modification(Dependencies* dependencies) { - // Dependencies must be checked when the system dictionary changes. - // If logging is enabled all violated dependences will be recorded in - // the log. In debug mode check dependencies even if the system - // dictionary hasn't changed to verify that no invalid dependencies - // were inserted. Any violated dependences in this case are dumped to - // the tty. +bool GraalEnv::check_for_system_dictionary_modification(Dependencies* dependencies, GraalEnv* env) { + // If JVMTI capabilities were enabled during compile, the compilation is invalidated. + if (env != NULL) { + if (!env->_jvmti_can_hotswap_or_post_breakpoint && JvmtiExport::can_hotswap_or_post_breakpoint()) { + // Hotswapping or breakpointing was enabled during compilation + return false; + } + } - // TODO (thomaswue): Always check dependency for now. - //bool counter_changed = system_dictionary_modification_counter_changed(); - //bool test_deps = counter_changed; - //DEBUG_ONLY(test_deps = true); - //if (!test_deps) return; + // Dependencies must be checked when the system dictionary changes + // or if we don't know whether it has changed (i.e., env == NULL). + // In debug mode, always check dependencies. + bool counter_changed = env != NULL && env->_system_dictionary_modification_counter != SystemDictionary::number_of_modifications(); + bool verify_deps = env == NULL || trueInDebug; + if (!counter_changed && !verify_deps) { + return true; + } for (Dependencies::DepStream deps(dependencies); deps.next(); ) { Klass* witness = deps.check_dependency(); @@ -450,7 +466,7 @@ AbstractCompiler* compiler, DebugInformationRecorder* debug_info, Dependencies* dependencies, - CompileTask* task, + GraalEnv* env, int compile_id, bool has_unsafe_access, Handle installed_code, @@ -471,7 +487,7 @@ dependencies->encode_content_bytes(); // Check for {class loads, evolution, breakpoints} during compilation - if (!check_for_system_dictionary_modification(dependencies)) { + if (!check_for_system_dictionary_modification(dependencies, env)) { // While not a true deoptimization, it is a preemptive decompile. MethodData* mdp = method()->method_data(); if (mdp != NULL) { @@ -516,6 +532,7 @@ // Record successful registration. // (Put nm into the task handle *before* publishing to the Java heap.) + CompileTask* task = env == NULL ? NULL : env->task(); if (task != NULL) task->set_code(nm); if (installed_code->is_a(HotSpotNmethod::klass()) && HotSpotNmethod::isDefault(installed_code())) { diff -r 49605c649beb -r 98592ae4b1fa src/share/vm/graal/graalEnv.hpp --- a/src/share/vm/graal/graalEnv.hpp Thu Feb 12 15:20:14 2015 +0100 +++ b/src/share/vm/graal/graalEnv.hpp Thu Feb 12 16:54:12 2015 +0100 @@ -50,7 +50,7 @@ // // This class is the top level broker for requests from the compiler // to the VM. -class GraalEnv : AllStatic { +class GraalEnv : StackObj { CI_PACKAGE_ACCESS_TO friend class CompileBroker; @@ -92,7 +92,16 @@ int method_index, Bytecodes::Code bc, instanceKlassHandle& loading_klass); + GraalEnv(CompileTask* task, int system_dictionary_modification_counter); + private: + CompileTask* _task; + int _system_dictionary_modification_counter; + + // Cache JVMTI state + bool _jvmti_can_hotswap_or_post_breakpoint; + bool _jvmti_can_access_local_variables; + bool _jvmti_can_post_on_exceptions; // Implementation methods for loading and constant pool access. static KlassHandle get_klass_by_name_impl(KlassHandle& accessing_klass, @@ -124,9 +133,11 @@ // Helper routine for determining the validity of a compilation // with respect to concurrent class loading. - static bool check_for_system_dictionary_modification(Dependencies* target); + static bool check_for_system_dictionary_modification(Dependencies* target, GraalEnv* env); public: + CompileTask* task() { return _task; } + // Register the result of a compilation. static GraalEnv::CodeInstallResult register_method( methodHandle& target, @@ -141,7 +152,7 @@ AbstractCompiler* compiler, DebugInformationRecorder* debug_info, Dependencies* dependencies, - CompileTask* task, + GraalEnv* env, int compile_id, bool has_unsafe_access, Handle installed_code, diff -r 49605c649beb -r 98592ae4b1fa src/share/vm/graal/graalJavaAccess.hpp --- a/src/share/vm/graal/graalJavaAccess.hpp Thu Feb 12 15:20:14 2015 +0100 +++ b/src/share/vm/graal/graalJavaAccess.hpp Thu Feb 12 16:54:12 2015 +0100 @@ -84,7 +84,7 @@ oop_field(HotSpotCompiledNmethod, method, "Lcom/oracle/graal/hotspot/meta/HotSpotResolvedJavaMethod;") \ int_field(HotSpotCompiledNmethod, entryBCI) \ int_field(HotSpotCompiledNmethod, id) \ - long_field(HotSpotCompiledNmethod, ctask) \ + long_field(HotSpotCompiledNmethod, graalEnv) \ end_class \ start_class(HotSpotCompiledRuntimeStub) \ oop_field(HotSpotCompiledRuntimeStub, stubName, "Ljava/lang/String;") \ diff -r 49605c649beb -r 98592ae4b1fa src/share/vm/graal/vmStructs_graal.hpp --- a/src/share/vm/graal/vmStructs_graal.hpp Thu Feb 12 15:20:14 2015 +0100 +++ b/src/share/vm/graal/vmStructs_graal.hpp Thu Feb 12 16:54:12 2015 +0100 @@ -36,6 +36,8 @@ nonstatic_field(ThreadShadow, _pending_failed_speculation, oop) \ nonstatic_field(ThreadShadow, _pending_transfer_to_interpreter, bool) \ nonstatic_field(MethodData, _graal_node_count, int) \ + nonstatic_field(GraalEnv, _task, CompileTask*) \ + nonstatic_field(GraalEnv, _jvmti_can_hotswap_or_post_breakpoint, bool) \ #define VM_TYPES_GRAAL(declare_type, declare_toplevel_type) \