diff --git a/src/hotspot/share/ci/ciMethod.cpp b/src/hotspot/share/ci/ciMethod.cpp index 862824c5b72..b2d9e14208d 100644 --- a/src/hotspot/share/ci/ciMethod.cpp +++ b/src/hotspot/share/ci/ciMethod.cpp @@ -117,9 +117,11 @@ ciMethod::ciMethod(const methodHandle& h_m, ciInstanceKlass* holder) : if (h_m->method_holder()->is_linked()) { _can_be_statically_bound = h_m->can_be_statically_bound(); + _can_omit_stack_trace = h_m->can_omit_stack_trace(); } else { // Have to use a conservative value in this case. _can_be_statically_bound = false; + _can_omit_stack_trace = true; } // Adjust the definition of this condition to be more useful: @@ -176,6 +178,7 @@ ciMethod::ciMethod(ciInstanceKlass* holder, _intrinsic_id( vmIntrinsics::_none), _instructions_size(-1), _can_be_statically_bound(false), + _can_omit_stack_trace(true), _liveness( NULL) #if defined(COMPILER2) , @@ -766,6 +769,20 @@ bool ciMethod::can_be_statically_bound(ciInstanceKlass* context) const { return (holder() == context) && can_be_statically_bound(); } +// ------------------------------------------------------------------ +// ciMethod::can_omit_stack_trace +// +// Tries to determine whether a method can omit stack trace in throw in compiled code. +bool ciMethod::can_omit_stack_trace() const { + if (!StackTraceInThrowable) { + return true; // stack trace is switched off. + } + if (!OmitStackTraceInFastThrow) { + return false; // Have to provide stack trace. + } + return _can_omit_stack_trace; +} + // ------------------------------------------------------------------ // ciMethod::resolve_invoke // diff --git a/src/hotspot/share/ci/ciMethod.hpp b/src/hotspot/share/ci/ciMethod.hpp index 926badd2f38..5e0732dfeb7 100644 --- a/src/hotspot/share/ci/ciMethod.hpp +++ b/src/hotspot/share/ci/ciMethod.hpp @@ -92,6 +92,7 @@ class ciMethod : public ciMetadata { bool _is_c2_compilable; bool _can_be_parsed; bool _can_be_statically_bound; + bool _can_omit_stack_trace; bool _has_reserved_stack_access; bool _is_overpass; @@ -364,6 +365,8 @@ class ciMethod : public ciMetadata { bool can_be_statically_bound(ciInstanceKlass* context) const; + bool can_omit_stack_trace() const; + // Replay data methods static void dump_name_as_ascii(outputStream* st, Method* method); void dump_name_as_ascii(outputStream* st); diff --git a/src/hotspot/share/classfile/vmSymbols.hpp b/src/hotspot/share/classfile/vmSymbols.hpp index d8dfcc418cc..7980e99d3ca 100644 --- a/src/hotspot/share/classfile/vmSymbols.hpp +++ b/src/hotspot/share/classfile/vmSymbols.hpp @@ -142,6 +142,7 @@ template(java_util_Iterator, "java/util/Iterator") \ template(java_lang_Record, "java/lang/Record") \ template(sun_instrument_InstrumentationImpl, "sun/instrument/InstrumentationImpl") \ + template(sun_invoke_util_ValueConversions, "sun/invoke/util/ValueConversions") \ \ template(jdk_internal_loader_NativeLibraries, "jdk/internal/loader/NativeLibraries") \ template(jdk_internal_loader_BuiltinClassLoader, "jdk/internal/loader/BuiltinClassLoader") \ @@ -485,6 +486,7 @@ template(data_cache_line_flush_size_name, "DATA_CACHE_LINE_FLUSH_SIZE") \ template(during_unsafe_access_name, "during_unsafe_access") \ template(checkIndex_name, "checkIndex") \ + template(requireNonNull_name, "requireNonNull") \ \ /* name symbols needed by intrinsics */ \ VM_INTRINSICS_DO(VM_INTRINSIC_IGNORE, VM_SYMBOL_IGNORE, template, VM_SYMBOL_IGNORE, VM_ALIAS_IGNORE) \ diff --git a/src/hotspot/share/oops/method.cpp b/src/hotspot/share/oops/method.cpp index 830b539997b..54646ce3cad 100644 --- a/src/hotspot/share/oops/method.cpp +++ b/src/hotspot/share/oops/method.cpp @@ -818,6 +818,32 @@ bool Method::can_be_statically_bound(InstanceKlass* context) const { return (method_holder() == context) && can_be_statically_bound(); } +/** + * Returns false if this is one of specially treated methods for + * which we have to provide stack trace in throw in compiled code. + * Returns true otherwise. + */ +bool Method::can_omit_stack_trace() { + InstanceKlass* ik = method_holder(); + ClassLoaderData* loader_data = ik->class_loader_data(); + if (loader_data->is_boot_class_loader_data()) { + if (intrinsic_id() == vmIntrinsics::_Class_cast) { + return false; // java.lang.Class::cast() + } + Symbol* klass_name = ik->name(); + if (klass_name == vmSymbols::sun_invoke_util_ValueConversions()) { + return false; // All methods in sun.invoke.util.ValueConversions + } + if ((klass_name == vmSymbols::java_util_Objects()) && + (name() == vmSymbols::requireNonNull_name())) { + // No signature check to cover all requireNonNull methods + // with different signatures. + return false; // java.util.Objects::requireNonNull() + } + } + return true; +} + bool Method::is_accessor() const { return is_getter() || is_setter(); } diff --git a/src/hotspot/share/oops/method.hpp b/src/hotspot/share/oops/method.hpp index 33ac08e5fe4..9f31bbbea65 100644 --- a/src/hotspot/share/oops/method.hpp +++ b/src/hotspot/share/oops/method.hpp @@ -600,6 +600,9 @@ public: bool can_be_statically_bound(InstanceKlass* context) const; bool can_be_statically_bound(AccessFlags class_access_flags) const; + // true if method can omit stack trace in throw in compiled code. + bool can_omit_stack_trace(); + // returns true if the method has any backward branches. bool has_loops() { return access_flags().loops_flag_init() ? access_flags().has_loops() : compute_has_loops_flag(); diff --git a/src/hotspot/share/opto/graphKit.cpp b/src/hotspot/share/opto/graphKit.cpp index 10939bcee63..28066fc4d0e 100644 --- a/src/hotspot/share/opto/graphKit.cpp +++ b/src/hotspot/share/opto/graphKit.cpp @@ -560,8 +560,7 @@ void GraphKit::builtin_throw(Deoptimization::DeoptReason reason, Node* arg) { // let us handle the throw inline, with a preconstructed instance. // Note: If the deopt count has blown up, the uncommon trap // runtime is going to flush this nmethod, not matter what. - if (treat_throw_as_hot - && (!StackTraceInThrowable || OmitStackTraceInFastThrow)) { + if (treat_throw_as_hot && method()->can_omit_stack_trace()) { // If the throw is local, we use a pre-existing instance and // punt on the backtrace. This would lead to a missing backtrace // (a repeat of 4292742) if the backtrace object is ever asked