8042727: nsk/jdb/unwatch/unwatch001 crash in InstanceKlass::methods_do(void (*)(Method*))
Summary: Only walk methods in instanceklass if the class is loaded
Reviewed-by: dholmes, fparain
--- a/hotspot/src/share/vm/classfile/classLoaderData.cpp Tue May 20 20:35:39 2014 +0200
+++ b/hotspot/src/share/vm/classfile/classLoaderData.cpp Wed May 21 14:36:18 2014 -0400
@@ -274,6 +274,8 @@
MutexLockerEx ml(metaspace_lock(), Mutex::_no_safepoint_check_flag);
Klass* old_value = _klasses;
k->set_next_link(old_value);
+ // Make sure linked class is stable, since the class list is walked without a lock
+ OrderAccess::storestore();
// link the new item into the list
_klasses = k;
--- a/hotspot/src/share/vm/compiler/compilerOracle.cpp Tue May 20 20:35:39 2014 +0200
+++ b/hotspot/src/share/vm/compiler/compilerOracle.cpp Wed May 21 14:36:18 2014 -0400
@@ -307,6 +307,9 @@
return (check_predicate(PrintCommand, method));
}
+bool CompilerOracle::should_print_methods() {
+ return lists[PrintCommand] != NULL;
+}
bool CompilerOracle::should_log(methodHandle method) {
if (!LogCompilation) return false;
--- a/hotspot/src/share/vm/compiler/compilerOracle.hpp Tue May 20 20:35:39 2014 +0200
+++ b/hotspot/src/share/vm/compiler/compilerOracle.hpp Wed May 21 14:36:18 2014 -0400
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -73,6 +73,9 @@
// For updating the oracle file
static void append_comment_to_file(const char* message);
static void append_exclude_to_file(methodHandle method);
+
+ // Tells whether there are any methods to print for print_method_statistics()
+ static bool should_print_methods();
};
#endif // SHARE_VM_COMPILER_COMPILERORACLE_HPP
--- a/hotspot/src/share/vm/oops/instanceKlass.cpp Tue May 20 20:35:39 2014 +0200
+++ b/hotspot/src/share/vm/oops/instanceKlass.cpp Wed May 21 14:36:18 2014 -0400
@@ -1273,6 +1273,12 @@
void InstanceKlass::methods_do(void f(Method* method)) {
+ // Methods aren't stable until they are loaded. This can be read outside
+ // a lock through the ClassLoaderData for profiling
+ if (!is_loaded()) {
+ return;
+ }
+
int len = methods()->length();
for (int index = 0; index < len; index++) {
Method* m = methods()->at(index);
--- a/hotspot/src/share/vm/runtime/java.cpp Tue May 20 20:35:39 2014 +0200
+++ b/hotspot/src/share/vm/runtime/java.cpp Wed May 21 14:36:18 2014 -0400
@@ -120,7 +120,8 @@
}
void print_method_profiling_data() {
- if (ProfileInterpreter COMPILER1_PRESENT(|| C1UpdateMethodData)) {
+ if (ProfileInterpreter COMPILER1_PRESENT(|| C1UpdateMethodData) &&
+ (PrintMethodData || CompilerOracle::should_print_methods())) {
ResourceMark rm;
HandleMark hm;
collected_profiled_methods = new GrowableArray<Method*>(1024);