OpenJDK / jdk / jdk
changeset 51591:9183040e34d8
8209950: SIGBUS in CodeHeapState::print_names()
Reviewed-by: thartmann, kvn
author | lucy |
---|---|
date | Thu, 30 Aug 2018 09:34:10 +0200 |
parents | 3aaf039a3636 |
children | 1ddd1ec04431 |
files | src/hotspot/share/code/codeHeapState.cpp src/hotspot/share/code/compiledMethod.cpp src/hotspot/share/code/compiledMethod.hpp src/hotspot/share/runtime/sharedRuntime.cpp |
diffstat | 4 files changed, 25 insertions(+), 11 deletions(-) [+] |
line wrap: on
line diff
--- a/src/hotspot/share/code/codeHeapState.cpp Thu Aug 30 09:25:38 2018 +0200 +++ b/src/hotspot/share/code/codeHeapState.cpp Thu Aug 30 09:34:10 2018 +0200 @@ -2168,9 +2168,8 @@ // this_blob->as_nmethod_or_null() is safe. Inlined, maybe invisible on stack. nmethod* nm = this_blob->as_nmethod_or_null(); - Method* method = (nm == NULL) ? NULL : nm->method(); // may be uninitialized, i.e. != NULL, but invalid - if ((nm != NULL) && (method != NULL) && (cbType != nMethod_dead) && (cbType != nMethod_inconstruction) && - os::is_readable_pointer(method) && os::is_readable_pointer(method->constants())) { + if (CompiledMethod::nmethod_access_is_safe(nm)) { + Method* method = nm->method(); ResourceMark rm; //---< collect all data to locals as quickly as possible >--- unsigned int total_size = nm->total_size();
--- a/src/hotspot/share/code/compiledMethod.cpp Thu Aug 30 09:25:38 2018 +0200 +++ b/src/hotspot/share/code/compiledMethod.cpp Thu Aug 30 09:34:10 2018 +0200 @@ -619,3 +619,18 @@ } } } + +// Iterating over all nmethods, e.g. with the help of CodeCache::nmethods_do(fun) was found +// to not be inherently safe. There is a chance that fields are seen which are not properly +// initialized. This happens despite the fact that nmethods_do() asserts the CodeCache_lock +// to be held. +// To bundle knowledge about necessary checks in one place, this function was introduced. +// It is not claimed that these checks are sufficient, but they were found to be necessary. +bool CompiledMethod::nmethod_access_is_safe(nmethod* nm) { + Method* method = (nm == NULL) ? NULL : nm->method(); // nm->method() may be uninitialized, i.e. != NULL, but invalid + return (nm != NULL) && (method != NULL) && (method->signature() != NULL) && + !nm->is_zombie() && !nm->is_not_installed() && + os::is_readable_pointer(method) && + os::is_readable_pointer(method->constants()) && + os::is_readable_pointer(method->signature()); +}
--- a/src/hotspot/share/code/compiledMethod.hpp Thu Aug 30 09:25:38 2018 +0200 +++ b/src/hotspot/share/code/compiledMethod.hpp Thu Aug 30 09:34:10 2018 +0200 @@ -238,6 +238,8 @@ return _mark_for_deoptimization_status != deoptimize_noupdate; } + static bool nmethod_access_is_safe(nmethod* nm); + // tells whether frames described by this nmethod can be deoptimized // note: native wrappers cannot be deoptimized. bool can_be_deoptimized() const { return is_java_method(); }
--- a/src/hotspot/share/runtime/sharedRuntime.cpp Thu Aug 30 09:25:38 2018 +0200 +++ b/src/hotspot/share/runtime/sharedRuntime.cpp Thu Aug 30 09:34:10 2018 +0200 @@ -2135,16 +2135,14 @@ static int _max_size; // max. arg size seen static void add_method_to_histogram(nmethod* nm) { - // These checks are taken from CodeHeapState::print_names() - Method* m = (nm == NULL) ? NULL : nm->method(); // nm->method() may be uninitialized, i.e. != NULL, but invalid - if ((nm != NULL) && (m != NULL) && !nm->is_zombie() && !nm->is_not_installed() && - os::is_readable_pointer(m) && os::is_readable_pointer(m->constants())) { - ArgumentCount args(m->signature()); - int arity = args.size() + (m->is_static() ? 0 : 1); - int argsize = m->size_of_parameters(); + if (CompiledMethod::nmethod_access_is_safe(nm)) { + Method* method = nm->method(); + ArgumentCount args(method->signature()); + int arity = args.size() + (method->is_static() ? 0 : 1); + int argsize = method->size_of_parameters(); arity = MIN2(arity, MAX_ARITY-1); argsize = MIN2(argsize, MAX_ARITY-1); - int count = nm->method()->compiled_invocation_count(); + int count = method->compiled_invocation_count(); _arity_histogram[arity] += count; _size_histogram[argsize] += count; _max_arity = MAX2(_max_arity, arity);