8209950: SIGBUS in CodeHeapState::print_names()
Reviewed-by: thartmann, kvn
This commit is contained in:
parent
05b8f66dff
commit
af1ce0a659
@ -2168,9 +2168,8 @@ void CodeHeapState::print_names(outputStream* out, CodeHeap* heap) {
|
||||
|
||||
// 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();
|
||||
|
@ -619,3 +619,18 @@ void CompiledMethod::do_unloading_parallel_postponed() {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 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());
|
||||
}
|
||||
|
@ -238,6 +238,8 @@ public:
|
||||
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(); }
|
||||
|
@ -2135,16 +2135,14 @@ class MethodArityHistogram {
|
||||
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);
|
||||
|
Loading…
Reference in New Issue
Block a user