8042727: nsk/jdb/unwatch/unwatch001 crash in InstanceKlass::methods_do(void (*)(Method*))
authorcoleenp
Wed, 21 May 2014 14:36:18 -0400
changeset 24658 e41df2fc6e87
parent 24462 0676642e6560
child 24659 a1482c33e323
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
hotspot/src/share/vm/classfile/classLoaderData.cpp
hotspot/src/share/vm/compiler/compilerOracle.cpp
hotspot/src/share/vm/compiler/compilerOracle.hpp
hotspot/src/share/vm/oops/instanceKlass.cpp
hotspot/src/share/vm/runtime/java.cpp
--- 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);