changeset 29332:c2364e06aa8d

Merge
author jwilhelm
date Thu, 05 Mar 2015 17:27:16 +0100
parents b788134d664a 1f646019dc45
children ae2aef8d8ab9
files hotspot/src/share/vm/runtime/thread.cpp hotspot/src/share/vm/runtime/thread.hpp
diffstat 24 files changed, 361 insertions(+), 196 deletions(-) [+]
line wrap: on
line diff
--- a/hotspot/src/os/windows/vm/attachListener_windows.cpp	Wed Mar 04 02:23:38 2015 +0100
+++ b/hotspot/src/os/windows/vm/attachListener_windows.cpp	Thu Mar 05 17:27:16 2015 +0100
@@ -62,7 +62,7 @@
 class Win32AttachListener: AllStatic {
  private:
   enum {
-    preallocate_count = 4                   // number of preallocated operations
+    max_enqueued_operations = 4
   };
 
   // protects the preallocated list and the operation list
@@ -83,9 +83,12 @@
   static void set_tail(Win32AttachOperation* tail)          { _tail = tail; }
 
 
-  // used to wakeup the listener
-  static HANDLE _wakeup;
-  static HANDLE wakeup()                                    { return _wakeup; }
+  // A semaphore is used for communication about enqueued operations.
+  // The maximum count for the semaphore object will be set to "max_enqueued_operations".
+  // The state of a semaphore is signaled when its count is greater than
+  // zero (there are operations enqueued), and nonsignaled when it is zero.
+  static HANDLE _enqueued_ops_semaphore;
+  static HANDLE enqueued_ops_semaphore() { return _enqueued_ops_semaphore; }
 
  public:
   enum {
@@ -110,7 +113,7 @@
 
 // statics
 HANDLE Win32AttachListener::_mutex;
-HANDLE Win32AttachListener::_wakeup;
+HANDLE Win32AttachListener::_enqueued_ops_semaphore;
 Win32AttachOperation* Win32AttachListener::_avail;
 Win32AttachOperation* Win32AttachListener::_head;
 Win32AttachOperation* Win32AttachListener::_tail;
@@ -155,20 +158,19 @@
 };
 
 
-// preallocate the required number of operations
+// Preallocate the maximum number of operations that can be enqueued.
 int Win32AttachListener::init() {
   _mutex = (void*)::CreateMutex(NULL, FALSE, NULL);
   guarantee(_mutex != (HANDLE)NULL, "mutex creation failed");
 
-  _wakeup = ::CreateSemaphore(NULL, 0, 1, NULL);
-  guarantee(_wakeup != (HANDLE)NULL, "semaphore creation failed");
+  _enqueued_ops_semaphore = ::CreateSemaphore(NULL, 0, max_enqueued_operations, NULL);
+  guarantee(_enqueued_ops_semaphore != (HANDLE)NULL, "semaphore creation failed");
 
   set_head(NULL);
   set_tail(NULL);
+  set_available(NULL);
 
-  // preallocate a few operations
-  set_available(NULL);
-  for (int i=0; i<preallocate_count; i++) {
+  for (int i=0; i<max_enqueued_operations; i++) {
     Win32AttachOperation* op = new Win32AttachOperation();
     op->set_next(available());
     set_available(op);
@@ -221,8 +223,12 @@
     op->set_arg(2, arg2);
     op->set_pipe(pipename);
 
-    // wakeup the thread waiting for operations
-    ::ReleaseSemaphore(wakeup(), 1, NULL);
+    // Increment number of enqueued operations.
+    // Side effect: Semaphore will be signaled and will release
+    // any blocking waiters (i.e. the AttachListener thread).
+    BOOL not_exceeding_semaphore_maximum_count =
+      ::ReleaseSemaphore(enqueued_ops_semaphore(), 1, NULL);
+    guarantee(not_exceeding_semaphore_maximum_count, "invariant");
   }
   ::ReleaseMutex(mutex());
 
@@ -230,10 +236,12 @@
 }
 
 
-// dequeue the operation from the head of the operation list. If
+// dequeue the operation from the head of the operation list.
 Win32AttachOperation* Win32AttachListener::dequeue() {
   for (;;) {
-    DWORD res = ::WaitForSingleObject(wakeup(), INFINITE);
+    DWORD res = ::WaitForSingleObject(enqueued_ops_semaphore(), INFINITE);
+    // returning from WaitForSingleObject will have decreased
+    // the current count of the semaphore by 1.
     guarantee(res == WAIT_OBJECT_0, "wait failed");
 
     res = ::WaitForSingleObject(mutex(), INFINITE);
--- a/hotspot/src/share/vm/classfile/defaultMethods.cpp	Wed Mar 04 02:23:38 2015 +0100
+++ b/hotspot/src/share/vm/classfile/defaultMethods.cpp	Thu Mar 05 17:27:16 2015 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2015, 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
@@ -1091,6 +1091,7 @@
     }
     // update idnum for new location
     merged_methods->at(i)->set_method_idnum(i);
+    merged_methods->at(i)->set_orig_method_idnum(i);
   }
 
   // Verify correct order
--- a/hotspot/src/share/vm/oops/constMethod.hpp	Wed Mar 04 02:23:38 2015 +0100
+++ b/hotspot/src/share/vm/oops/constMethod.hpp	Thu Mar 05 17:27:16 2015 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2015, 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
@@ -215,6 +215,7 @@
   u2                _max_stack;                  // Maximum number of entries on the expression stack
   u2                _max_locals;                 // Number of local variables used by this method
   u2                _size_of_parameters;         // size of the parameter block (receiver + arguments) in words
+  u2                _orig_method_idnum;          // Original unique identification number for the method
 
   // Constructor
   ConstMethod(int byte_code_size,
@@ -473,6 +474,9 @@
   u2 method_idnum() const                        { return _method_idnum; }
   void set_method_idnum(u2 idnum)                { _method_idnum = idnum; }
 
+  u2 orig_method_idnum() const                   { return _orig_method_idnum; }
+  void set_orig_method_idnum(u2 idnum)           { _orig_method_idnum = idnum; }
+
   // max stack
   int  max_stack() const                         { return _max_stack; }
   void set_max_stack(int size)                   { _max_stack = size; }
--- a/hotspot/src/share/vm/oops/cpCache.cpp	Wed Mar 04 02:23:38 2015 +0100
+++ b/hotspot/src/share/vm/oops/cpCache.cpp	Thu Mar 05 17:27:16 2015 +0100
@@ -454,7 +454,6 @@
           new_method->name()->as_C_string(),
           new_method->signature()->as_C_string()));
       }
-
       return true;
     }
 
@@ -482,7 +481,6 @@
         new_method->name()->as_C_string(),
         new_method->signature()->as_C_string()));
     }
-
     return true;
   }
 
@@ -509,36 +507,33 @@
           (!f1_as_method()->is_old() && !f1_as_method()->is_obsolete())));
 }
 
-bool ConstantPoolCacheEntry::is_interesting_method_entry(Klass* k) {
+Method* ConstantPoolCacheEntry::get_interesting_method_entry(Klass* k) {
   if (!is_method_entry()) {
     // not a method entry so not interesting by default
-    return false;
+    return NULL;
   }
-
   Method* m = NULL;
   if (is_vfinal()) {
     // virtual and final so _f2 contains method ptr instead of vtable index
     m = f2_as_vfinal_method();
   } else if (is_f1_null()) {
     // NULL _f1 means this is a virtual entry so also not interesting
-    return false;
+    return NULL;
   } else {
     if (!(_f1->is_method())) {
       // _f1 can also contain a Klass* for an interface
-      return false;
+      return NULL;
     }
     m = f1_as_method();
   }
-
   assert(m != NULL && m->is_method(), "sanity check");
   if (m == NULL || !m->is_method() || (k != NULL && m->method_holder() != k)) {
     // robustness for above sanity checks or method is not in
     // the interesting class
-    return false;
+    return NULL;
   }
-
   // the method is in the interesting class so the entry is interesting
-  return true;
+  return m;
 }
 #endif // INCLUDE_JVMTI
 
@@ -615,7 +610,7 @@
 // If any entry of this ConstantPoolCache points to any of
 // old_methods, replace it with the corresponding new_method.
 void ConstantPoolCache::adjust_method_entries(Method** old_methods, Method** new_methods,
-                                                     int methods_length, bool * trace_name_printed) {
+                                              int methods_length, bool * trace_name_printed) {
 
   if (methods_length == 0) {
     // nothing to do if there are no methods
@@ -626,7 +621,7 @@
   Klass* old_holder = old_methods[0]->method_holder();
 
   for (int i = 0; i < length(); i++) {
-    if (!entry_at(i)->is_interesting_method_entry(old_holder)) {
+    if (entry_at(i)->get_interesting_method_entry(old_holder) == NULL) {
       // skip uninteresting methods
       continue;
     }
@@ -650,10 +645,33 @@
   }
 }
 
+// If any entry of this ConstantPoolCache points to any of
+// old_methods, replace it with the corresponding new_method.
+void ConstantPoolCache::adjust_method_entries(InstanceKlass* holder, bool * trace_name_printed) {
+  for (int i = 0; i < length(); i++) {
+    ConstantPoolCacheEntry* entry = entry_at(i);
+    Method* old_method = entry->get_interesting_method_entry(holder);
+    if (old_method == NULL || !old_method->is_old()) {
+      continue; // skip uninteresting entries
+    }
+    if (old_method->is_deleted()) {
+      // clean up entries with deleted methods
+      entry->initialize_entry(entry->constant_pool_index());
+      continue;
+    }
+    Method* new_method = holder->method_with_idnum(old_method->orig_method_idnum());
+
+    assert(new_method != NULL, "method_with_idnum() should not be NULL");
+    assert(old_method != new_method, "sanity check");
+
+    entry_at(i)->adjust_method_entry(old_method, new_method, trace_name_printed);
+  }
+}
+
 // the constant pool cache should never contain old or obsolete methods
 bool ConstantPoolCache::check_no_old_or_obsolete_entries() {
   for (int i = 1; i < length(); i++) {
-    if (entry_at(i)->is_interesting_method_entry(NULL) &&
+    if (entry_at(i)->get_interesting_method_entry(NULL) != NULL &&
         !entry_at(i)->check_no_old_or_obsolete_entries()) {
       return false;
     }
@@ -663,7 +681,7 @@
 
 void ConstantPoolCache::dump_cache() {
   for (int i = 1; i < length(); i++) {
-    if (entry_at(i)->is_interesting_method_entry(NULL)) {
+    if (entry_at(i)->get_interesting_method_entry(NULL) != NULL) {
       entry_at(i)->print(tty, i);
     }
   }
--- a/hotspot/src/share/vm/oops/cpCache.hpp	Wed Mar 04 02:23:38 2015 +0100
+++ b/hotspot/src/share/vm/oops/cpCache.hpp	Thu Mar 05 17:27:16 2015 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2015, 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
@@ -379,9 +379,9 @@
   // printed the klass name so that other routines in the adjust_*
   // group don't print the klass name.
   bool adjust_method_entry(Method* old_method, Method* new_method,
-         bool * trace_name_printed);
+         bool* trace_name_printed);
   bool check_no_old_or_obsolete_entries();
-  bool is_interesting_method_entry(Klass* k);
+  Method* get_interesting_method_entry(Klass* k);
 #endif // INCLUDE_JVMTI
 
   // Debugging & Printing
@@ -478,7 +478,8 @@
   // printed the klass name so that other routines in the adjust_*
   // group don't print the klass name.
   void adjust_method_entries(Method** old_methods, Method** new_methods,
-                             int methods_length, bool * trace_name_printed);
+                             int methods_length, bool* trace_name_printed);
+  void adjust_method_entries(InstanceKlass* holder, bool* trace_name_printed);
   bool check_no_old_or_obsolete_entries();
   void dump_cache();
 #endif // INCLUDE_JVMTI
--- a/hotspot/src/share/vm/oops/instanceKlass.cpp	Wed Mar 04 02:23:38 2015 +0100
+++ b/hotspot/src/share/vm/oops/instanceKlass.cpp	Thu Mar 05 17:27:16 2015 +0100
@@ -2793,30 +2793,33 @@
 // not yet in the vtable due to concurrent subclass define and superinterface
 // redefinition
 // Note: those in the vtable, should have been updated via adjust_method_entries
-void InstanceKlass::adjust_default_methods(Method** old_methods, Method** new_methods,
-                                           int methods_length, bool* trace_name_printed) {
+void InstanceKlass::adjust_default_methods(InstanceKlass* holder, bool* trace_name_printed) {
   // search the default_methods for uses of either obsolete or EMCP methods
   if (default_methods() != NULL) {
-    for (int j = 0; j < methods_length; j++) {
-      Method* old_method = old_methods[j];
-      Method* new_method = new_methods[j];
-
-      for (int index = 0; index < default_methods()->length(); index ++) {
-        if (default_methods()->at(index) == old_method) {
-          default_methods()->at_put(index, new_method);
-          if (RC_TRACE_IN_RANGE(0x00100000, 0x00400000)) {
-            if (!(*trace_name_printed)) {
-              // RC_TRACE_MESG macro has an embedded ResourceMark
-              RC_TRACE_MESG(("adjust: klassname=%s default methods from name=%s",
-                             external_name(),
-                             old_method->method_holder()->external_name()));
-              *trace_name_printed = true;
-            }
-            RC_TRACE(0x00100000, ("default method update: %s(%s) ",
-                                  new_method->name()->as_C_string(),
-                                  new_method->signature()->as_C_string()));
-          }
+    for (int index = 0; index < default_methods()->length(); index ++) {
+      Method* old_method = default_methods()->at(index);
+      if (old_method == NULL || old_method->method_holder() != holder || !old_method->is_old()) {
+        continue; // skip uninteresting entries
+      }
+      assert(!old_method->is_deleted(), "default methods may not be deleted");
+
+      Method* new_method = holder->method_with_idnum(old_method->orig_method_idnum());
+
+      assert(new_method != NULL, "method_with_idnum() should not be NULL");
+      assert(old_method != new_method, "sanity check");
+
+      default_methods()->at_put(index, new_method);
+      if (RC_TRACE_IN_RANGE(0x00100000, 0x00400000)) {
+        if (!(*trace_name_printed)) {
+          // RC_TRACE_MESG macro has an embedded ResourceMark
+          RC_TRACE_MESG(("adjust: klassname=%s default methods from name=%s",
+                         external_name(),
+                         old_method->method_holder()->external_name()));
+          *trace_name_printed = true;
         }
+        RC_TRACE(0x00100000, ("default method update: %s(%s) ",
+                              new_method->name()->as_C_string(),
+                              new_method->signature()->as_C_string()));
       }
     }
   }
--- a/hotspot/src/share/vm/oops/instanceKlass.hpp	Wed Mar 04 02:23:38 2015 +0100
+++ b/hotspot/src/share/vm/oops/instanceKlass.hpp	Thu Mar 05 17:27:16 2015 +0100
@@ -937,8 +937,7 @@
   Method* method_at_itable(Klass* holder, int index, TRAPS);
 
 #if INCLUDE_JVMTI
-  void adjust_default_methods(Method** old_methods, Method** new_methods,
-                              int methods_length, bool* trace_name_printed);
+  void adjust_default_methods(InstanceKlass* holder, bool* trace_name_printed);
 #endif // INCLUDE_JVMTI
 
   // Garbage collection
--- a/hotspot/src/share/vm/oops/klassVtable.cpp	Wed Mar 04 02:23:38 2015 +0100
+++ b/hotspot/src/share/vm/oops/klassVtable.cpp	Thu Mar 05 17:27:16 2015 +0100
@@ -863,44 +863,43 @@
   }
   return updated;
 }
-void klassVtable::adjust_method_entries(Method** old_methods, Method** new_methods,
-                                        int methods_length, bool * trace_name_printed) {
-  // search the vtable for uses of either obsolete or EMCP methods
-  for (int j = 0; j < methods_length; j++) {
-    Method* old_method = old_methods[j];
-    Method* new_method = new_methods[j];
 
-    // In the vast majority of cases we could get the vtable index
-    // by using:  old_method->vtable_index()
-    // However, there are rare cases, eg. sun.awt.X11.XDecoratedPeer.getX()
-    // in sun.awt.X11.XFramePeer where methods occur more than once in the
-    // vtable, so, alas, we must do an exhaustive search.
-    for (int index = 0; index < length(); index++) {
-      if (unchecked_method_at(index) == old_method) {
-        put_method_at(new_method, index);
-          // For default methods, need to update the _default_methods array
-          // which can only have one method entry for a given signature
-          bool updated_default = false;
-          if (old_method->is_default_method()) {
-            updated_default = adjust_default_method(index, old_method, new_method);
-          }
+// search the vtable for uses of either obsolete or EMCP methods
+void klassVtable::adjust_method_entries(InstanceKlass* holder, bool * trace_name_printed) {
+  int prn_enabled = 0;
+  for (int index = 0; index < length(); index++) {
+    Method* old_method = unchecked_method_at(index);
+    if (old_method == NULL || old_method->method_holder() != holder || !old_method->is_old()) {
+      continue; // skip uninteresting entries
+    }
+    assert(!old_method->is_deleted(), "vtable methods may not be deleted");
 
-        if (RC_TRACE_IN_RANGE(0x00100000, 0x00400000)) {
-          if (!(*trace_name_printed)) {
-            // RC_TRACE_MESG macro has an embedded ResourceMark
-            RC_TRACE_MESG(("adjust: klassname=%s for methods from name=%s",
-                           klass()->external_name(),
-                           old_method->method_holder()->external_name()));
-            *trace_name_printed = true;
-          }
-          // RC_TRACE macro has an embedded ResourceMark
-          RC_TRACE(0x00100000, ("vtable method update: %s(%s), updated default = %s",
-                                new_method->name()->as_C_string(),
-                                new_method->signature()->as_C_string(),
-                                updated_default ? "true" : "false"));
-        }
-        // cannot 'break' here; see for-loop comment above.
+    Method* new_method = holder->method_with_idnum(old_method->orig_method_idnum());
+
+    assert(new_method != NULL, "method_with_idnum() should not be NULL");
+    assert(old_method != new_method, "sanity check");
+
+    put_method_at(new_method, index);
+    // For default methods, need to update the _default_methods array
+    // which can only have one method entry for a given signature
+    bool updated_default = false;
+    if (old_method->is_default_method()) {
+      updated_default = adjust_default_method(index, old_method, new_method);
+    }
+
+    if (RC_TRACE_IN_RANGE(0x00100000, 0x00400000)) {
+      if (!(*trace_name_printed)) {
+        // RC_TRACE_MESG macro has an embedded ResourceMark
+        RC_TRACE_MESG(("adjust: klassname=%s for methods from name=%s",
+                       klass()->external_name(),
+                       old_method->method_holder()->external_name()));
+        *trace_name_printed = true;
       }
+      // RC_TRACE macro has an embedded ResourceMark
+      RC_TRACE(0x00100000, ("vtable method update: %s(%s), updated default = %s",
+                            new_method->name()->as_C_string(),
+                            new_method->signature()->as_C_string(),
+                            updated_default ? "true" : "false"));
     }
   }
 }
@@ -1193,37 +1192,35 @@
 }
 
 #if INCLUDE_JVMTI
-void klassItable::adjust_method_entries(Method** old_methods, Method** new_methods,
-                                        int methods_length, bool * trace_name_printed) {
-  // search the itable for uses of either obsolete or EMCP methods
-  for (int j = 0; j < methods_length; j++) {
-    Method* old_method = old_methods[j];
-    Method* new_method = new_methods[j];
-    itableMethodEntry* ime = method_entry(0);
+// search the itable for uses of either obsolete or EMCP methods
+void klassItable::adjust_method_entries(InstanceKlass* holder, bool * trace_name_printed) {
 
-    // The itable can describe more than one interface and the same
-    // method signature can be specified by more than one interface.
-    // This means we have to do an exhaustive search to find all the
-    // old_method references.
-    for (int i = 0; i < _size_method_table; i++) {
-      if (ime->method() == old_method) {
-        ime->initialize(new_method);
+  itableMethodEntry* ime = method_entry(0);
+  for (int i = 0; i < _size_method_table; i++, ime++) {
+    Method* old_method = ime->method();
+    if (old_method == NULL || old_method->method_holder() != holder || !old_method->is_old()) {
+      continue; // skip uninteresting entries
+    }
+    assert(!old_method->is_deleted(), "itable methods may not be deleted");
 
-        if (RC_TRACE_IN_RANGE(0x00100000, 0x00400000)) {
-          if (!(*trace_name_printed)) {
-            // RC_TRACE_MESG macro has an embedded ResourceMark
-            RC_TRACE_MESG(("adjust: name=%s",
-              old_method->method_holder()->external_name()));
-            *trace_name_printed = true;
-          }
-          // RC_TRACE macro has an embedded ResourceMark
-          RC_TRACE(0x00200000, ("itable method update: %s(%s)",
-            new_method->name()->as_C_string(),
-            new_method->signature()->as_C_string()));
-        }
-        // cannot 'break' here; see for-loop comment above.
+    Method* new_method = holder->method_with_idnum(old_method->orig_method_idnum());
+
+    assert(new_method != NULL, "method_with_idnum() should not be NULL");
+    assert(old_method != new_method, "sanity check");
+
+    ime->initialize(new_method);
+
+    if (RC_TRACE_IN_RANGE(0x00100000, 0x00400000)) {
+      if (!(*trace_name_printed)) {
+        // RC_TRACE_MESG macro has an embedded ResourceMark
+        RC_TRACE_MESG(("adjust: name=%s",
+          old_method->method_holder()->external_name()));
+        *trace_name_printed = true;
       }
-      ime++;
+      // RC_TRACE macro has an embedded ResourceMark
+      RC_TRACE(0x00200000, ("itable method update: %s(%s)",
+        new_method->name()->as_C_string(),
+        new_method->signature()->as_C_string()));
     }
   }
 }
--- a/hotspot/src/share/vm/oops/klassVtable.hpp	Wed Mar 04 02:23:38 2015 +0100
+++ b/hotspot/src/share/vm/oops/klassVtable.hpp	Thu Mar 05 17:27:16 2015 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2015, 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
@@ -98,8 +98,7 @@
   // printed the klass name so that other routines in the adjust_*
   // group don't print the klass name.
   bool adjust_default_method(int vtable_index, Method* old_method, Method* new_method);
-  void adjust_method_entries(Method** old_methods, Method** new_methods,
-                             int methods_length, bool * trace_name_printed);
+  void adjust_method_entries(InstanceKlass* holder, bool * trace_name_printed);
   bool check_no_old_or_obsolete_entries();
   void dump_vtable();
 #endif // INCLUDE_JVMTI
@@ -288,8 +287,7 @@
   // trace_name_printed is set to true if the current call has
   // printed the klass name so that other routines in the adjust_*
   // group don't print the klass name.
-  void adjust_method_entries(Method** old_methods, Method** new_methods,
-                             int methods_length, bool * trace_name_printed);
+  void adjust_method_entries(InstanceKlass* holder, bool * trace_name_printed);
   bool check_no_old_or_obsolete_entries();
   void dump_itable();
 #endif // INCLUDE_JVMTI
--- a/hotspot/src/share/vm/oops/method.cpp	Wed Mar 04 02:23:38 2015 +0100
+++ b/hotspot/src/share/vm/oops/method.cpp	Thu Mar 05 17:27:16 2015 +0100
@@ -1450,6 +1450,7 @@
       for (int i = 0; i < length; i++) {
         Method* m = methods->at(i);
         m->set_method_idnum(i);
+        m->set_orig_method_idnum(i);
       }
     }
   }
--- a/hotspot/src/share/vm/oops/method.hpp	Wed Mar 04 02:23:38 2015 +0100
+++ b/hotspot/src/share/vm/oops/method.hpp	Thu Mar 05 17:27:16 2015 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2015, 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
@@ -233,6 +233,9 @@
   u2 method_idnum() const           { return constMethod()->method_idnum(); }
   void set_method_idnum(u2 idnum)   { constMethod()->set_method_idnum(idnum); }
 
+  u2 orig_method_idnum() const           { return constMethod()->orig_method_idnum(); }
+  void set_orig_method_idnum(u2 idnum)   { constMethod()->set_orig_method_idnum(idnum); }
+
   // code size
   int code_size() const                  { return constMethod()->code_size(); }
 
--- a/hotspot/src/share/vm/prims/jvmtiRedefineClasses.cpp	Wed Mar 04 02:23:38 2015 +0100
+++ b/hotspot/src/share/vm/prims/jvmtiRedefineClasses.cpp	Thu Mar 05 17:27:16 2015 +0100
@@ -782,9 +782,13 @@
           Method* idnum_owner = scratch_class->method_with_idnum(old_num);
           if (idnum_owner != NULL) {
             // There is already a method assigned this idnum -- switch them
+            // Take current and original idnum from the new_method
             idnum_owner->set_method_idnum(new_num);
+            idnum_owner->set_orig_method_idnum(k_new_method->orig_method_idnum());
           }
+          // Take current and original idnum from the old_method
           k_new_method->set_method_idnum(old_num);
+          k_new_method->set_orig_method_idnum(k_old_method->orig_method_idnum());
           if (thread->has_pending_exception()) {
             return JVMTI_ERROR_OUT_OF_MEMORY;
           }
@@ -817,9 +821,12 @@
         Method* idnum_owner = scratch_class->method_with_idnum(num);
         if (idnum_owner != NULL) {
           // There is already a method assigned this idnum -- switch them
+          // Take current and original idnum from the new_method
           idnum_owner->set_method_idnum(new_num);
+          idnum_owner->set_orig_method_idnum(k_new_method->orig_method_idnum());
         }
         k_new_method->set_method_idnum(num);
+        k_new_method->set_orig_method_idnum(num);
         if (thread->has_pending_exception()) {
           return JVMTI_ERROR_OUT_OF_MEMORY;
         }
@@ -3327,6 +3334,7 @@
   // This is a very busy routine. We don't want too much tracing
   // printed out.
   bool trace_name_printed = false;
+  InstanceKlass *the_class = InstanceKlass::cast(_the_class_oop);
 
   // Very noisy: only enable this call if you are trying to determine
   // that a specific class gets found by this routine.
@@ -3338,10 +3346,8 @@
   // If the class being redefined is java.lang.Object, we need to fix all
   // array class vtables also
   if (k->oop_is_array() && _the_class_oop == SystemDictionary::Object_klass()) {
-    k->vtable()->adjust_method_entries(_matching_old_methods,
-                                       _matching_new_methods,
-                                       _matching_methods_length,
-                                       &trace_name_printed);
+    k->vtable()->adjust_method_entries(the_class, &trace_name_printed);
+
   } else if (k->oop_is_instance()) {
     HandleMark hm(_thread);
     InstanceKlass *ik = InstanceKlass::cast(k);
@@ -3383,14 +3389,9 @@
         || ik->is_subtype_of(_the_class_oop))) {
       // ik->vtable() creates a wrapper object; rm cleans it up
       ResourceMark rm(_thread);
-      ik->vtable()->adjust_method_entries(_matching_old_methods,
-                                          _matching_new_methods,
-                                          _matching_methods_length,
-                                          &trace_name_printed);
-      ik->adjust_default_methods(_matching_old_methods,
-                                 _matching_new_methods,
-                                 _matching_methods_length,
-                                 &trace_name_printed);
+
+      ik->vtable()->adjust_method_entries(the_class, &trace_name_printed);
+      ik->adjust_default_methods(the_class, &trace_name_printed);
     }
 
     // If the current class has an itable and we are either redefining an
@@ -3405,10 +3406,8 @@
         || ik->is_subclass_of(_the_class_oop))) {
       // ik->itable() creates a wrapper object; rm cleans it up
       ResourceMark rm(_thread);
-      ik->itable()->adjust_method_entries(_matching_old_methods,
-                                          _matching_new_methods,
-                                          _matching_methods_length,
-                                          &trace_name_printed);
+
+      ik->itable()->adjust_method_entries(the_class, &trace_name_printed);
     }
 
     // The constant pools in other classes (other_cp) can refer to
@@ -3432,10 +3431,7 @@
       other_cp = constantPoolHandle(ik->constants());
       cp_cache = other_cp->cache();
       if (cp_cache != NULL) {
-        cp_cache->adjust_method_entries(_matching_old_methods,
-                                        _matching_new_methods,
-                                        _matching_methods_length,
-                                        &trace_name_printed);
+        cp_cache->adjust_method_entries(the_class, &trace_name_printed);
       }
     }
 
@@ -3578,6 +3574,7 @@
 
       // obsolete methods need a unique idnum so they become new entries in
       // the jmethodID cache in InstanceKlass
+      assert(old_method->method_idnum() == new_method->method_idnum(), "must match");
       u2 num = InstanceKlass::cast(_the_class_oop)->next_method_idnum();
       if (num != ConstMethod::UNSET_IDNUM) {
         old_method->set_method_idnum(num);
--- a/hotspot/src/share/vm/runtime/java.cpp	Wed Mar 04 02:23:38 2015 +0100
+++ b/hotspot/src/share/vm/runtime/java.cpp	Thu Mar 05 17:27:16 2015 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2015, 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
@@ -421,9 +421,11 @@
     os::infinite_sleep();
   }
 
-  // Terminate watcher thread - must before disenrolling any periodic task
-  if (PeriodicTask::num_tasks() > 0)
+  // Stop the WatcherThread. We do this before disenrolling various
+  // PeriodicTasks to reduce the likelihood of races.
+  if (PeriodicTask::num_tasks() > 0) {
     WatcherThread::stop();
+  }
 
   // Print statistics gathered (profiling ...)
   if (Arguments::has_profile()) {
--- a/hotspot/src/share/vm/runtime/task.cpp	Wed Mar 04 02:23:38 2015 +0100
+++ b/hotspot/src/share/vm/runtime/task.cpp	Thu Mar 05 17:27:16 2015 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2015, 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
@@ -47,6 +47,8 @@
 #endif
 
 void PeriodicTask::real_time_tick(int delay_time) {
+  assert(Thread::current()->is_Watcher_thread(), "must be WatcherThread");
+
 #ifndef PRODUCT
   if (ProfilerCheckIntervals) {
     _ticks++;
@@ -60,6 +62,8 @@
 #endif
 
   {
+    // The WatcherThread does not participate in the safepoint protocol
+    // for the PeriodicTask_lock because it is not a JavaThread.
     MutexLockerEx ml(PeriodicTask_lock, Mutex::_no_safepoint_check_flag);
     int orig_num_tasks = _num_tasks;
 
@@ -74,8 +78,7 @@
 }
 
 int PeriodicTask::time_to_wait() {
-  MutexLockerEx ml(PeriodicTask_lock->owned_by_self() ?
-                     NULL : PeriodicTask_lock, Mutex::_no_safepoint_check_flag);
+  assert(PeriodicTask_lock->owned_by_self(), "PeriodicTask_lock required");
 
   if (_num_tasks == 0) {
     return 0; // sleep until shutdown or a task is enrolled
@@ -98,14 +101,19 @@
 }
 
 PeriodicTask::~PeriodicTask() {
+  // This PeriodicTask may have already been disenrolled by a call
+  // to disenroll() before the PeriodicTask was deleted.
   disenroll();
 }
 
-/* enroll could be called from a JavaThread, so we have to check for
- * safepoint when taking the lock to avoid deadlocking */
+// enroll the current PeriodicTask
 void PeriodicTask::enroll() {
-  MutexLockerEx ml(PeriodicTask_lock->owned_by_self() ?
-                     NULL : PeriodicTask_lock);
+  // Follow normal safepoint aware lock enter protocol if the caller does
+  // not already own the PeriodicTask_lock. Otherwise, we don't try to
+  // enter it again because VM internal Mutexes do not support recursion.
+  //
+  MutexLockerEx ml(PeriodicTask_lock->owned_by_self() ? NULL
+                                                      : PeriodicTask_lock);
 
   if (_num_tasks == PeriodicTask::max_tasks) {
     fatal("Overflow in PeriodicTask table");
@@ -113,18 +121,21 @@
   _tasks[_num_tasks++] = this;
 
   WatcherThread* thread = WatcherThread::watcher_thread();
-  if (thread) {
+  if (thread != NULL) {
     thread->unpark();
   } else {
     WatcherThread::start();
   }
 }
 
-/* disenroll could be called from a JavaThread, so we have to check for
- * safepoint when taking the lock to avoid deadlocking */
+// disenroll the current PeriodicTask
 void PeriodicTask::disenroll() {
-  MutexLockerEx ml(PeriodicTask_lock->owned_by_self() ?
-                     NULL : PeriodicTask_lock);
+  // Follow normal safepoint aware lock enter protocol if the caller does
+  // not already own the PeriodicTask_lock. Otherwise, we don't try to
+  // enter it again because VM internal Mutexes do not support recursion.
+  //
+  MutexLockerEx ml(PeriodicTask_lock->owned_by_self() ? NULL
+                                                      : PeriodicTask_lock);
 
   int index;
   for(index = 0; index < _num_tasks && _tasks[index] != this; index++)
--- a/hotspot/src/share/vm/runtime/task.hpp	Wed Mar 04 02:23:38 2015 +0100
+++ b/hotspot/src/share/vm/runtime/task.hpp	Thu Mar 05 17:27:16 2015 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2015, 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
@@ -54,6 +54,7 @@
 
   static int _num_tasks;
   static PeriodicTask* _tasks[PeriodicTask::max_tasks];
+  // Can only be called by the WatcherThread
   static void real_time_tick(int delay_time);
 
 #ifndef PRODUCT
@@ -98,6 +99,7 @@
 
   // Calculate when the next periodic task will fire.
   // Called by the WatcherThread's run method.
+  // Requires the PeriodicTask_lock.
   static int time_to_wait();
 
   // The task to perform at each period
--- a/hotspot/src/share/vm/runtime/thread.cpp	Wed Mar 04 02:23:38 2015 +0100
+++ b/hotspot/src/share/vm/runtime/thread.cpp	Thu Mar 05 17:27:16 2015 +0100
@@ -1201,8 +1201,15 @@
 }
 
 int WatcherThread::sleep() const {
+  // The WatcherThread does not participate in the safepoint protocol
+  // for the PeriodicTask_lock because it is not a JavaThread.
   MutexLockerEx ml(PeriodicTask_lock, Mutex::_no_safepoint_check_flag);
 
+  if (_should_terminate) {
+    // check for termination before we do any housekeeping or wait
+    return 0;  // we did not sleep.
+  }
+
   // remaining will be zero if there are no tasks,
   // causing the WatcherThread to sleep until a task is
   // enrolled
@@ -1215,8 +1222,9 @@
 
   jlong time_before_loop = os::javaTimeNanos();
 
-  for (;;) {
-    bool timedout = PeriodicTask_lock->wait(Mutex::_no_safepoint_check_flag, remaining);
+  while (true) {
+    bool timedout = PeriodicTask_lock->wait(Mutex::_no_safepoint_check_flag,
+                                            remaining);
     jlong now = os::javaTimeNanos();
 
     if (remaining == 0) {
@@ -1257,7 +1265,7 @@
   this->initialize_thread_local_storage();
   this->set_native_thread_name(this->name());
   this->set_active_handles(JNIHandleBlock::allocate_block());
-  while (!_should_terminate) {
+  while (true) {
     assert(watcher_thread() == Thread::current(), "thread consistency check");
     assert(watcher_thread() == this, "thread consistency check");
 
@@ -1293,6 +1301,11 @@
       }
     }
 
+    if (_should_terminate) {
+      // check for termination before posting the next tick
+      break;
+    }
+
     PeriodicTask::real_time_tick(time_waited);
   }
 
@@ -1323,27 +1336,19 @@
 }
 
 void WatcherThread::stop() {
-  // Get the PeriodicTask_lock if we can. If we cannot, then the
-  // WatcherThread is using it and we don't want to block on that lock
-  // here because that might cause a safepoint deadlock depending on
-  // what the current WatcherThread tasks are doing.
-  bool have_lock = PeriodicTask_lock->try_lock();
-
-  _should_terminate = true;
-  OrderAccess::fence();  // ensure WatcherThread sees update in main loop
-
-  if (have_lock) {
+  {
+    // Follow normal safepoint aware lock enter protocol since the
+    // WatcherThread is stopped by another JavaThread.
+    MutexLocker ml(PeriodicTask_lock);
+    _should_terminate = true;
+
     WatcherThread* watcher = watcher_thread();
     if (watcher != NULL) {
-      // If we managed to get the lock, then we should unpark the
-      // WatcherThread so that it can see we want it to stop.
+      // unpark the WatcherThread so it can see that it should terminate
       watcher->unpark();
     }
-
-    PeriodicTask_lock->unlock();
   }
 
-  // it is ok to take late safepoints here, if needed
   MutexLocker mu(Terminator_lock);
 
   while (watcher_thread() != NULL) {
@@ -1363,9 +1368,7 @@
 }
 
 void WatcherThread::unpark() {
-  MutexLockerEx ml(PeriodicTask_lock->owned_by_self()
-                   ? NULL
-                   : PeriodicTask_lock, Mutex::_no_safepoint_check_flag);
+  assert(PeriodicTask_lock->owned_by_self(), "PeriodicTask_lock required");
   PeriodicTask_lock->notify();
 }
 
@@ -3562,8 +3565,8 @@
   }
 
   {
-    MutexLockerEx ml(PeriodicTask_lock, Mutex::_no_safepoint_check_flag);
-    // Make sure the watcher thread can be started by WatcherThread::start()
+    MutexLocker ml(PeriodicTask_lock);
+    // Make sure the WatcherThread can be started by WatcherThread::start()
     // or by dynamic enrollment.
     WatcherThread::make_startable();
     // Start up the WatcherThread if there are any periodic tasks
--- a/hotspot/src/share/vm/runtime/thread.hpp	Wed Mar 04 02:23:38 2015 +0100
+++ b/hotspot/src/share/vm/runtime/thread.hpp	Thu Mar 05 17:27:16 2015 +0100
@@ -702,7 +702,8 @@
   static WatcherThread* _watcher_thread;
 
   static bool _startable;
-  volatile static bool _should_terminate; // updated without holding lock
+  // volatile due to at least one lock-free read
+  volatile static bool _should_terminate;
 
   os::WatcherThreadCrashProtection* _crash_protection;
  public:
--- a/hotspot/test/runtime/Safepoint/AssertSafepointCheckConsistency1.java	Wed Mar 04 02:23:38 2015 +0100
+++ b/hotspot/test/runtime/Safepoint/AssertSafepointCheckConsistency1.java	Thu Mar 05 17:27:16 2015 +0100
@@ -47,6 +47,7 @@
                   "-XX:+UnlockDiagnosticVMOptions",
                   "-XX:+WhiteBoxAPI",
                   "-XX:-TransmitErrorReport",
+                  "-XX:-CreateMinidumpOnCrash",
                   "-Xmx32m",
                   "AssertSafepointCheckConsistency1",
                   "test");
@@ -55,5 +56,3 @@
         }
     }
 }
-
-
--- a/hotspot/test/runtime/Safepoint/AssertSafepointCheckConsistency2.java	Wed Mar 04 02:23:38 2015 +0100
+++ b/hotspot/test/runtime/Safepoint/AssertSafepointCheckConsistency2.java	Thu Mar 05 17:27:16 2015 +0100
@@ -47,6 +47,7 @@
                   "-XX:+UnlockDiagnosticVMOptions",
                   "-XX:+WhiteBoxAPI",
                   "-XX:-TransmitErrorReport",
+                  "-XX:-CreateMinidumpOnCrash",
                   "-Xmx32m",
                   "AssertSafepointCheckConsistency2",
                   "test");
--- a/hotspot/test/runtime/Safepoint/AssertSafepointCheckConsistency3.java	Wed Mar 04 02:23:38 2015 +0100
+++ b/hotspot/test/runtime/Safepoint/AssertSafepointCheckConsistency3.java	Thu Mar 05 17:27:16 2015 +0100
@@ -47,6 +47,7 @@
                   "-XX:+UnlockDiagnosticVMOptions",
                   "-XX:+WhiteBoxAPI",
                   "-XX:-TransmitErrorReport",
+                  "-XX:-CreateMinidumpOnCrash",
                   "-Xmx32m",
                   "AssertSafepointCheckConsistency3",
                   "test");
--- a/hotspot/test/runtime/Safepoint/AssertSafepointCheckConsistency4.java	Wed Mar 04 02:23:38 2015 +0100
+++ b/hotspot/test/runtime/Safepoint/AssertSafepointCheckConsistency4.java	Thu Mar 05 17:27:16 2015 +0100
@@ -47,6 +47,7 @@
                "-XX:+UnlockDiagnosticVMOptions",
                "-XX:+WhiteBoxAPI",
                "-XX:-TransmitErrorReport",
+               "-XX:-CreateMinidumpOnCrash",
                "-Xmx32m",
                "AssertSafepointCheckConsistency4",
                "test");
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/Thread/Fibonacci.java	Thu Mar 05 17:27:16 2015 +0100
@@ -0,0 +1,114 @@
+/*
+ * Copyright (c) 2015, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * @test
+ * @summary Calculates Fibonacci numbers "recursively" via threads and compares
+ *     the result with the classical calculation.
+ *     This test is skipped on 32-bit Windows: limited virtual space on Win-32
+ *     make this test inherently unstable on Windows with 32-bit VM data model.
+ * @requires !(os.family == "windows" & sun.arch.data.model == "32")
+ * @library /testlibrary
+ * @run main Fibonacci 15
+ */
+
+import com.oracle.java.testlibrary.Asserts;
+
+public class Fibonacci extends Thread {
+    private int index;
+    private int value;
+    private Fibonacci left;
+    private Fibonacci right;
+
+    public Fibonacci(int i) {
+        index = i;
+    }
+
+    private int getValue() {
+        return value;
+    }
+
+    @Override
+    public void run() {
+        if (index == 0 || index == 1) {
+            // base cases, 0 Fibonacci number = 0, 1 Fibonacci number = 1
+            value = index;
+        } else {
+            // inductive cases
+            left = new Fibonacci(index - 2);
+            right = new Fibonacci(index - 1);
+            left.start();
+            right.start();
+            try {
+                left.join();
+                right.join();
+            } catch (InterruptedException e) {
+                throw new Error("InterruptedException for index " + index, e);
+            }
+            // compute and terminate
+            value = left.getValue() + right.getValue();
+        }
+    }
+
+    public static int traditionalFibonacci(int n) {
+        int n1 = 0, n2 = 1, nn = 0;
+
+        if (n == 0 || n == 1) {
+           nn = n;
+        }
+
+        for (int i = 1; i < n; ++i) {
+            nn = n2 + n1;
+            n1 = n2;
+            n2 = nn;
+        }
+        return nn;
+    }
+
+    public static void main(String[] args) throws Error,AssertionError {
+        int expected;
+        int number;
+        Fibonacci recursiveFibonacci;
+
+        if (args.length != 1) {
+            throw new Error("Error: args.length must be 1");
+        }
+
+        number = Integer.parseInt(args[0]);
+        recursiveFibonacci = new Fibonacci(number);
+
+        recursiveFibonacci.start();
+        try {
+            recursiveFibonacci.join();
+        } catch (InterruptedException e) {
+            throw new Error("InterruptedException in main thread", e);
+        }
+
+        expected = traditionalFibonacci(number);
+
+        System.out.println("Fibonacci[" + number + "] = " + expected);
+
+        Asserts.assertEQ(recursiveFibonacci.getValue(), expected,
+                          "Unexpected calculated value: " + recursiveFibonacci.getValue() + " expected " + expected );
+    }
+}
--- a/hotspot/test/testlibrary/ctw/src/sun/hotspot/tools/ctw/CompileTheWorld.java	Wed Mar 04 02:23:38 2015 +0100
+++ b/hotspot/test/testlibrary/ctw/src/sun/hotspot/tools/ctw/CompileTheWorld.java	Thu Mar 05 17:27:16 2015 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2015, 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
@@ -23,7 +23,7 @@
 
 package sun.hotspot.tools.ctw;
 
-import sun.management.ManagementFactoryHelper;
+import java.lang.management.ManagementFactory;
 
 import java.io.*;
 import java.nio.file.Files;
@@ -55,7 +55,7 @@
 
         try {
             try {
-                if (ManagementFactoryHelper.getCompilationMXBean() == null) {
+                if (ManagementFactory.getCompilationMXBean() == null) {
                     throw new RuntimeException(
                             "CTW can not work in interpreted mode");
                 }
--- a/hotspot/test/testlibrary/ctw/src/sun/hotspot/tools/ctw/Utils.java	Wed Mar 04 02:23:38 2015 +0100
+++ b/hotspot/test/testlibrary/ctw/src/sun/hotspot/tools/ctw/Utils.java	Thu Mar 05 17:27:16 2015 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2015, 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
@@ -24,7 +24,7 @@
 package sun.hotspot.tools.ctw;
 
 import com.sun.management.HotSpotDiagnosticMXBean;
-import sun.management.ManagementFactoryHelper;
+import java.lang.management.ManagementFactory;
 
 import java.io.File;
 import java.util.regex.Pattern;
@@ -160,7 +160,7 @@
     public static String getVMOption(String name) {
         String result;
         HotSpotDiagnosticMXBean diagnostic
-                = ManagementFactoryHelper.getDiagnosticMXBean();
+                = ManagementFactory.getPlatformMXBean(HotSpotDiagnosticMXBean.class);
         result = diagnostic.getVMOption(name).getValue();
         return result;
     }