# HG changeset patch # User Doug Simon # Date 1424180945 -3600 # Node ID dd8989d5547f02f5ac542c19584dc140c58b70a9 # Parent b6d8deed3fd5b926a73c6209e1ecce1f81e1d3b0 provide more detail when Graal code installation fails due to a failed dependency check diff -r b6d8deed3fd5 -r dd8989d5547f 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 Tue Feb 17 14:07:13 2015 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotCompiledNmethod.java Tue Feb 17 14:49:05 2015 +0100 @@ -25,6 +25,8 @@ import com.oracle.graal.api.code.*; import com.oracle.graal.hotspot.meta.*; +import edu.umd.cs.findbugs.annotations.*; + /** * {@link HotSpotCompiledCode} destined for installation as an nmethod. */ @@ -36,6 +38,12 @@ public final int id; public final long graalEnv; + /** + * May be set by VM if code installation fails. It will describe in more detail why installation + * failed (e.g., exactly which dependency failed). + */ + @SuppressFBWarnings("UWF_UNWRITTEN_FIELD") private String installationFailureMessage; + public HotSpotCompiledNmethod(HotSpotResolvedJavaMethod method, CompilationResult compResult) { this(method, compResult, 0L); } @@ -52,4 +60,8 @@ public String toString() { return getClass().getSimpleName() + "[" + id + ":" + method.format("%H.%n(%p)%r@") + entryBCI + "]"; } + + public String getInstallationFailureMessage() { + return installationFailureMessage; + } } diff -r b6d8deed3fd5 -r dd8989d5547f 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 Tue Feb 17 14:07:13 2015 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotCodeCacheProvider.java Tue Feb 17 14:49:05 2015 +0100 @@ -259,8 +259,13 @@ HotSpotInstalledCode code = new HotSpotNmethod(hotspotMethod, compResult.getName(), false); installedCode = code; } - CodeInstallResult result = runtime.getCompilerToVM().installCode(new HotSpotCompiledNmethod(hotspotMethod, compResult), installedCode, log); + HotSpotCompiledNmethod compiledCode = new HotSpotCompiledNmethod(hotspotMethod, compResult); + CodeInstallResult result = runtime.getCompilerToVM().installCode(compiledCode, installedCode, log); if (result != CodeInstallResult.OK) { + String msg = compiledCode.getInstallationFailureMessage(); + if (msg != null) { + throw new BailoutException(result != CodeInstallResult.DEPENDENCIES_FAILED, "Code installation failed: %s%n%s", result, msg); + } throw new BailoutException(result != CodeInstallResult.DEPENDENCIES_FAILED, "Code installation failed: %s", result); } return logOrDump(installedCode, compResult); diff -r b6d8deed3fd5 -r dd8989d5547f src/share/vm/code/dependencies.cpp --- a/src/share/vm/code/dependencies.cpp Tue Feb 17 14:07:13 2015 +0100 +++ b/src/share/vm/code/dependencies.cpp Tue Feb 17 14:49:05 2015 +0100 @@ -737,10 +737,10 @@ } void Dependencies::print_dependency(DepType dept, int nargs, DepArgument args[], - Klass* witness) { + Klass* witness, outputStream* st) { ResourceMark rm; ttyLocker ttyl; // keep the following output all in one block - tty->print_cr("%s of type %s", + st->print_cr("%s of type %s", (witness == NULL)? "Dependency": "Failed dependency", dep_name(dept)); // print arguments @@ -762,18 +762,18 @@ } else { what = "object "; } - tty->print(" %s = %s", what, (put_star? "*": "")); + st->print(" %s = %s", what, (put_star? "*": "")); if (arg.is_klass()) - tty->print("%s", ((Klass*)arg.metadata_value())->external_name()); + st->print("%s", ((Klass*)arg.metadata_value())->external_name()); else if (arg.is_method()) - ((Method*)arg.metadata_value())->print_value(); + ((Method*)arg.metadata_value())->print_value_on(st); else ShouldNotReachHere(); // Provide impl for this type. - tty->cr(); + st->cr(); } if (witness != NULL) { bool put_star = !Dependencies::is_concrete_klass(witness); - tty->print_cr(" witness = %s%s", + st->print_cr(" witness = %s%s", (put_star? "*": ""), witness->external_name()); } @@ -806,18 +806,18 @@ } } -void Dependencies::DepStream::print_dependency(Klass* witness, bool verbose) { +void Dependencies::DepStream::print_dependency(Klass* witness, bool verbose, outputStream* st) { int nargs = argument_count(); DepArgument args[max_arg_count]; for (int j = 0; j < nargs; j++) { args[j] = argument(j); } - Dependencies::print_dependency(type(), nargs, args, witness); + Dependencies::print_dependency(type(), nargs, args, witness, st); if (verbose) { if (_code != NULL) { - tty->print(" code: "); - _code->print_value_on(tty); - tty->cr(); + st->print(" code: "); + _code->print_value_on(st); + st->cr(); } } } diff -r b6d8deed3fd5 -r dd8989d5547f src/share/vm/code/dependencies.hpp --- a/src/share/vm/code/dependencies.hpp Tue Feb 17 14:07:13 2015 +0100 +++ b/src/share/vm/code/dependencies.hpp Tue Feb 17 14:49:05 2015 +0100 @@ -508,7 +508,7 @@ Klass* witness = NULL); static void print_dependency(DepType dept, int nargs, DepArgument args[], - Klass* witness = NULL); + Klass* witness = NULL, outputStream* st = tty); private: // helper for encoding common context types as zero: @@ -605,7 +605,7 @@ void log_dependency(Klass* witness = NULL); // Print the current dependency to tty. - void print_dependency(Klass* witness = NULL, bool verbose = false); + void print_dependency(Klass* witness = NULL, bool verbose = false, outputStream* st = tty); }; friend class Dependencies::DepStream; diff -r b6d8deed3fd5 -r dd8989d5547f src/share/vm/graal/graalCodeInstaller.cpp --- a/src/share/vm/graal/graalCodeInstaller.cpp Tue Feb 17 14:07:13 2015 +0100 +++ b/src/share/vm/graal/graalCodeInstaller.cpp Tue Feb 17 14:49:05 2015 +0100 @@ -468,7 +468,7 @@ 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, env, id, false, installed_code, speculation_log); + GraalCompiler::instance(), _debug_recorder, _dependencies, env, id, false, installed_code, compiled_code, speculation_log); cb = nm; } diff -r b6d8deed3fd5 -r dd8989d5547f src/share/vm/graal/graalEnv.cpp --- a/src/share/vm/graal/graalEnv.cpp Tue Feb 17 14:07:13 2015 +0100 +++ b/src/share/vm/graal/graalEnv.cpp Tue Feb 17 14:49:05 2015 +0100 @@ -421,11 +421,12 @@ // ------------------------------------------------------------------ // Check for changes to the system dictionary during compilation // class loads, evolution, breakpoints -bool GraalEnv::check_for_system_dictionary_modification(Dependencies* dependencies, GraalEnv* env) { +bool GraalEnv::check_for_system_dictionary_modification(Dependencies* dependencies, Handle compiled_code, GraalEnv* env, TRAPS) { // 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 + Handle message = java_lang_String::create_from_str("Hotswapping or breakpointing was enabled during compilation", THREAD); + HotSpotCompiledNmethod::set_installationFailureMessage(compiled_code, message()); return false; } } @@ -440,8 +441,13 @@ } for (Dependencies::DepStream deps(dependencies); deps.next(); ) { - Klass* witness = deps.check_dependency(); + Klass* witness = deps.check_dependency(); if (witness != NULL) { + ResourceMark rm; + stringStream st; + deps.print_dependency(witness, true, &st); + Handle message = java_lang_String::create_from_str(st.as_string(), THREAD); + HotSpotCompiledNmethod::set_installationFailureMessage(compiled_code, message()); return false; } if (LogCompilation) { @@ -470,6 +476,7 @@ int compile_id, bool has_unsafe_access, Handle installed_code, + Handle compiled_code, Handle speculation_log) { GRAAL_EXCEPTION_CONTEXT; NMethodSweeper::possibly_sweep(); @@ -487,7 +494,7 @@ dependencies->encode_content_bytes(); // Check for {class loads, evolution, breakpoints} during compilation - if (!check_for_system_dictionary_modification(dependencies, env)) { + if (!check_for_system_dictionary_modification(dependencies, compiled_code, env, THREAD)) { // While not a true deoptimization, it is a preemptive decompile. MethodData* mdp = method()->method_data(); if (mdp != NULL) { diff -r b6d8deed3fd5 -r dd8989d5547f src/share/vm/graal/graalEnv.hpp --- a/src/share/vm/graal/graalEnv.hpp Tue Feb 17 14:07:13 2015 +0100 +++ b/src/share/vm/graal/graalEnv.hpp Tue Feb 17 14:49:05 2015 +0100 @@ -133,7 +133,7 @@ // Helper routine for determining the validity of a compilation // with respect to concurrent class loading. - static bool check_for_system_dictionary_modification(Dependencies* target, GraalEnv* env); + static bool check_for_system_dictionary_modification(Dependencies* target, Handle compiled_code, GraalEnv* env, TRAPS); public: CompileTask* task() { return _task; } @@ -156,6 +156,7 @@ int compile_id, bool has_unsafe_access, Handle installed_code, + Handle compiled_code, Handle speculation_log); // converts the Klass* representing the holder of a method into a diff -r b6d8deed3fd5 -r dd8989d5547f src/share/vm/graal/graalJavaAccess.hpp --- a/src/share/vm/graal/graalJavaAccess.hpp Tue Feb 17 14:07:13 2015 +0100 +++ b/src/share/vm/graal/graalJavaAccess.hpp Tue Feb 17 14:49:05 2015 +0100 @@ -82,6 +82,7 @@ end_class \ start_class(HotSpotCompiledNmethod) \ oop_field(HotSpotCompiledNmethod, method, "Lcom/oracle/graal/hotspot/meta/HotSpotResolvedJavaMethod;") \ + oop_field(HotSpotCompiledNmethod, installationFailureMessage, "Ljava/lang/String;") \ int_field(HotSpotCompiledNmethod, entryBCI) \ int_field(HotSpotCompiledNmethod, id) \ long_field(HotSpotCompiledNmethod, graalEnv) \