src/share/vm/prims/jvmtiImpl.cpp
Index Unified diffs Context diffs Sdiffs Wdiffs Patch New Old Previous File Next File 6766644 Sdiff src/share/vm/prims

src/share/vm/prims/jvmtiImpl.cpp

Print this page
rev 2029 : 6766644: Redefinition of compiled method fails with assertion "Can not load classes with the Compiler thread"
Summary: Defer posting events from the compiler thread: use service thread
Reviewed-by:
* * *
   1 /*
   2  * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  *
  23  */
  24 
  25 #include "precompiled.hpp"
  26 #include "classfile/systemDictionary.hpp"
  27 #include "interpreter/interpreter.hpp"
  28 #include "jvmtifiles/jvmtiEnv.hpp"
  29 #include "memory/resourceArea.hpp"
  30 #include "oops/instanceKlass.hpp"
  31 #include "prims/jvmtiAgentThread.hpp"
  32 #include "prims/jvmtiEventController.inline.hpp"
  33 #include "prims/jvmtiImpl.hpp"
  34 #include "prims/jvmtiRedefineClasses.hpp"

  35 #include "runtime/deoptimization.hpp"
  36 #include "runtime/handles.hpp"
  37 #include "runtime/handles.inline.hpp"
  38 #include "runtime/interfaceSupport.hpp"
  39 #include "runtime/javaCalls.hpp"
  40 #include "runtime/signature.hpp"
  41 #include "runtime/vframe.hpp"
  42 #include "runtime/vframe_hp.hpp"
  43 #include "runtime/vm_operations.hpp"
  44 #include "utilities/exceptions.hpp"
  45 #ifdef TARGET_OS_FAMILY_linux
  46 # include "thread_linux.inline.hpp"
  47 #endif
  48 #ifdef TARGET_OS_FAMILY_solaris
  49 # include "thread_solaris.inline.hpp"
  50 #endif
  51 #ifdef TARGET_OS_FAMILY_windows
  52 # include "thread_windows.inline.hpp"
  53 #endif
  54 


 893 #ifndef PRODUCT
 894   MutexLocker mu(Threads_lock);
 895   ResourceMark rm;
 896 
 897   tty->print("Suspended Threads: [");
 898   for (JavaThread *thread = Threads::first(); thread != NULL; thread = thread->next()) {
 899 #if JVMTI_TRACE
 900     const char *name   = JvmtiTrace::safe_get_thread_name(thread);
 901 #else
 902     const char *name   = "";
 903 #endif /*JVMTI_TRACE */
 904     tty->print("%s(%c ", name, thread->is_being_ext_suspended() ? 'S' : '_');
 905     if (!thread->has_last_Java_frame()) {
 906       tty->print("no stack");
 907     }
 908     tty->print(") ");
 909   }
 910   tty->print_cr("]");
 911 #endif
 912 }
















































































































































































   1 /*
   2  * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  *
  23  */
  24 
  25 #include "precompiled.hpp"
  26 #include "classfile/systemDictionary.hpp"
  27 #include "interpreter/interpreter.hpp"
  28 #include "jvmtifiles/jvmtiEnv.hpp"
  29 #include "memory/resourceArea.hpp"
  30 #include "oops/instanceKlass.hpp"
  31 #include "prims/jvmtiAgentThread.hpp"
  32 #include "prims/jvmtiEventController.inline.hpp"
  33 #include "prims/jvmtiImpl.hpp"
  34 #include "prims/jvmtiRedefineClasses.hpp"
  35 #include "runtime/atomic.hpp"
  36 #include "runtime/deoptimization.hpp"
  37 #include "runtime/handles.hpp"
  38 #include "runtime/handles.inline.hpp"
  39 #include "runtime/interfaceSupport.hpp"
  40 #include "runtime/javaCalls.hpp"
  41 #include "runtime/signature.hpp"
  42 #include "runtime/vframe.hpp"
  43 #include "runtime/vframe_hp.hpp"
  44 #include "runtime/vm_operations.hpp"
  45 #include "utilities/exceptions.hpp"
  46 #ifdef TARGET_OS_FAMILY_linux
  47 # include "thread_linux.inline.hpp"
  48 #endif
  49 #ifdef TARGET_OS_FAMILY_solaris
  50 # include "thread_solaris.inline.hpp"
  51 #endif
  52 #ifdef TARGET_OS_FAMILY_windows
  53 # include "thread_windows.inline.hpp"
  54 #endif
  55 


 894 #ifndef PRODUCT
 895   MutexLocker mu(Threads_lock);
 896   ResourceMark rm;
 897 
 898   tty->print("Suspended Threads: [");
 899   for (JavaThread *thread = Threads::first(); thread != NULL; thread = thread->next()) {
 900 #if JVMTI_TRACE
 901     const char *name   = JvmtiTrace::safe_get_thread_name(thread);
 902 #else
 903     const char *name   = "";
 904 #endif /*JVMTI_TRACE */
 905     tty->print("%s(%c ", name, thread->is_being_ext_suspended() ? 'S' : '_');
 906     if (!thread->has_last_Java_frame()) {
 907       tty->print("no stack");
 908     }
 909     tty->print(") ");
 910   }
 911   tty->print_cr("]");
 912 #endif
 913 }
 914 
 915 #ifndef KERNEL
 916 
 917 JvmtiDeferredEvent JvmtiDeferredEvent::compiled_method_loaded_event(
 918     nmethod* nm) {
 919   JvmtiDeferredEvent event = JvmtiDeferredEvent(TYPE_COMPILED_METHOD_LOADED);
 920   event.set_compiled_method_loaded(nm);
 921   nmethodLocker::lock_nmethod(nm); // will be unlocked when posted
 922   return event;
 923 }
 924 
 925 JvmtiDeferredEvent JvmtiDeferredEvent::compiled_method_unloaded_event(
 926     jmethodID id, const void* code) {
 927   JvmtiDeferredEvent event =
 928     JvmtiDeferredEvent(TYPE_COMPILED_METHOD_UNLOADED);
 929   event.set_compiled_method_unloaded(id, code);
 930   return event;
 931 }
 932 
 933 void JvmtiDeferredEvent::post() {
 934   switch(_type) {
 935     case TYPE_COMPILED_METHOD_LOADED:
 936       JvmtiExport::post_compiled_method_load(compiled_method_loaded());
 937       nmethodLocker::unlock_nmethod(compiled_method_loaded());
 938       break;
 939     case TYPE_COMPILED_METHOD_UNLOADED:
 940       JvmtiExport::post_compiled_method_unload(
 941         compiled_method_unloaded_method_id(),
 942         compiled_method_unloaded_code_begin());
 943       break;
 944     default:
 945       ShouldNotReachHere();
 946   }
 947 }
 948 
 949 JvmtiDeferredEventQueue::QueueNode* JvmtiDeferredEventQueue::_queue_tail = NULL;
 950 JvmtiDeferredEventQueue::QueueNode* JvmtiDeferredEventQueue::_queue_head = NULL;
 951 
 952 volatile JvmtiDeferredEventQueue::QueueNode*
 953     JvmtiDeferredEventQueue::_pending_list = NULL;
 954 
 955 bool JvmtiDeferredEventQueue::has_events() {
 956   assert(Service_lock->owned_by_self(), "Must own Service_lock");
 957   process_pending_events();
 958   return _queue_head != NULL;
 959 }
 960 
 961 void JvmtiDeferredEventQueue::enqueue(const JvmtiDeferredEvent& event) {
 962   assert(Service_lock->owned_by_self(), "Must own Service_lock");
 963 
 964   process_pending_events();
 965 
 966   // Events get added to the beginning of the queue
 967   QueueNode* node = new QueueNode(event);
 968   if (_queue_tail == NULL) {
 969     _queue_tail = _queue_head = node;
 970   } else {
 971     assert(_queue_tail->next() == NULL, "Must be the last element in the list");
 972     _queue_tail->set_next(node);
 973     _queue_tail = node;
 974   }
 975 
 976   Service_lock->notify_all();
 977   assert((_queue_head == NULL) == (_queue_tail == NULL),
 978          "Inconsistent queue markers");
 979 }
 980 
 981 JvmtiDeferredEvent JvmtiDeferredEventQueue::dequeue() {
 982   assert(Service_lock->owned_by_self(), "Must own Service_lock");
 983 
 984   process_pending_events();
 985 
 986   assert(_queue_head != NULL, "Nothing to dequeue");
 987 
 988   if (_queue_head == NULL) {
 989     // Just in case this happens in product; it shouldn't be let's not crash
 990     return JvmtiDeferredEvent();
 991   }
 992 
 993   QueueNode* node = _queue_head;
 994   _queue_head = _queue_head->next();
 995   if (_queue_head == NULL) {
 996     _queue_tail = NULL;
 997   }
 998 
 999   assert((_queue_head == NULL) == (_queue_tail == NULL),
1000          "Inconsistent queue markers");
1001 
1002   JvmtiDeferredEvent event = node->event();
1003   delete node;
1004   return event;
1005 }
1006 
1007 void JvmtiDeferredEventQueue::add_pending_event(
1008     const JvmtiDeferredEvent& event) {
1009 
1010   QueueNode* node = new QueueNode(event);
1011 
1012   while (true) {
1013     node->set_next((QueueNode*)_pending_list);
1014     QueueNode* old_value = (QueueNode*)Atomic::cmpxchg_ptr(
1015       (void*)node, (volatile void*)&_pending_list, node->next());
1016     if (old_value == node->next()) {
1017       break;
1018     }
1019   }
1020 }
1021 
1022 // This method transfers any events that were added by someone NOT holding
1023 // the lock into the mainline queue.
1024 void JvmtiDeferredEventQueue::process_pending_events() {
1025   assert(Service_lock->owned_by_self(), "Must own Service_lock");
1026 
1027   if (_pending_list != NULL) {
1028     QueueNode* head;
1029     while (true) {
1030       head = (QueueNode*)_pending_list;
1031       QueueNode* old_value = (QueueNode*)Atomic::cmpxchg_ptr(
1032         NULL, (volatile void*)&_pending_list, (void*)head);
1033       if (old_value == head) {
1034         break;
1035       }
1036     }
1037 
1038     assert((_queue_head == NULL) == (_queue_tail == NULL),
1039            "Inconsistent queue markers");
1040 
1041     if (head != NULL) {
1042       // Since we've treated the pending list as a stack (with newer
1043       // events at the beginning), we need to join the bottom of the stack
1044       // with the 'tail' of the queue in order to get the events in the
1045       // right order.  We do this by reversing the pending list and appending
1046       // it to the queue.
1047 
1048       QueueNode* new_tail = head;
1049       QueueNode* new_head = NULL;
1050 
1051       // This reverses the list
1052       QueueNode* prev = new_tail;
1053       QueueNode* node = new_tail->next();
1054       new_tail->set_next(NULL);
1055       while (node != NULL) {
1056         QueueNode* next = node->next();
1057         node->set_next(prev);
1058         prev = node;
1059         node = next;
1060       }
1061       new_head = prev;
1062 
1063       // Now append the new list to the queue
1064       if (_queue_tail != NULL) {
1065         _queue_tail->set_next(new_head);
1066       } else { // _queue_head == NULL
1067         _queue_head = new_head;
1068       }
1069       _queue_tail = new_tail;
1070 
1071       Service_lock->notify_all();
1072     }
1073   }
1074 }
1075 
1076 void JvmtiDeferredEventQueue::wait_for_empty_queue() {
1077   MutexLockerEx ml(Service_lock, Mutex::_no_safepoint_check_flag);
1078   while (has_events()) {
1079     Service_lock->notify_all();
1080     Service_lock->wait(Mutex::_no_safepoint_check_flag);
1081   }
1082 }
1083 
1084 void JvmtiDeferredEventQueue::notify_empty_queue() {
1085   assert(Service_lock->owned_by_self(), "Must own Service_lock");
1086   Service_lock->notify_all();
1087 }
1088 
1089 #endif // ndef KERNEL
src/share/vm/prims/jvmtiImpl.cpp
Index Unified diffs Context diffs Sdiffs Wdiffs Patch New Old Previous File Next File