Mercurial > hg > graal-compiler
comparison src/share/vm/prims/jvmtiImpl.cpp @ 2301:f91db74a6810
7017640: Fix for 6766644 deadlocks on some NSK tests when running with -Xcomp
Summary: Dynamic-code generated events should be deferred and processed by service thread
Reviewed-by: dsamersoff, dcubed
author | kamg |
---|---|
date | Sat, 26 Feb 2011 13:33:23 -0500 |
parents | bf8517f4e4d0 |
children | 46a56fac55c7 |
comparison
equal
deleted
inserted
replaced
2265:162b62460264 | 2301:f91db74a6810 |
---|---|
916 #ifndef KERNEL | 916 #ifndef KERNEL |
917 | 917 |
918 JvmtiDeferredEvent JvmtiDeferredEvent::compiled_method_load_event( | 918 JvmtiDeferredEvent JvmtiDeferredEvent::compiled_method_load_event( |
919 nmethod* nm) { | 919 nmethod* nm) { |
920 JvmtiDeferredEvent event = JvmtiDeferredEvent(TYPE_COMPILED_METHOD_LOAD); | 920 JvmtiDeferredEvent event = JvmtiDeferredEvent(TYPE_COMPILED_METHOD_LOAD); |
921 event.set_compiled_method_load(nm); | 921 event._event_data.compiled_method_load = nm; |
922 nmethodLocker::lock_nmethod(nm); // will be unlocked when posted | 922 nmethodLocker::lock_nmethod(nm); // will be unlocked when posted |
923 return event; | 923 return event; |
924 } | 924 } |
925 | 925 |
926 JvmtiDeferredEvent JvmtiDeferredEvent::compiled_method_unload_event( | 926 JvmtiDeferredEvent JvmtiDeferredEvent::compiled_method_unload_event( |
927 jmethodID id, const void* code) { | 927 jmethodID id, const void* code) { |
928 JvmtiDeferredEvent event = JvmtiDeferredEvent(TYPE_COMPILED_METHOD_UNLOAD); | 928 JvmtiDeferredEvent event = JvmtiDeferredEvent(TYPE_COMPILED_METHOD_UNLOAD); |
929 event.set_compiled_method_unload(id, code); | 929 event._event_data.compiled_method_unload.method_id = id; |
930 event._event_data.compiled_method_unload.code_begin = code; | |
930 return event; | 931 return event; |
931 } | 932 } |
933 JvmtiDeferredEvent JvmtiDeferredEvent::dynamic_code_generated_event( | |
934 const char* name, const void* code_begin, const void* code_end) { | |
935 JvmtiDeferredEvent event = JvmtiDeferredEvent(TYPE_DYNAMIC_CODE_GENERATED); | |
936 event._event_data.dynamic_code_generated.name = name; | |
937 event._event_data.dynamic_code_generated.code_begin = code_begin; | |
938 event._event_data.dynamic_code_generated.code_end = code_end; | |
939 return event; | |
940 } | |
932 | 941 |
933 void JvmtiDeferredEvent::post() { | 942 void JvmtiDeferredEvent::post() { |
943 assert(ServiceThread::is_service_thread(Thread::current()), | |
944 "Service thread must post enqueued events"); | |
934 switch(_type) { | 945 switch(_type) { |
935 case TYPE_COMPILED_METHOD_LOAD: | 946 case TYPE_COMPILED_METHOD_LOAD: { |
936 JvmtiExport::post_compiled_method_load(compiled_method_load()); | 947 nmethod* nm = _event_data.compiled_method_load; |
937 nmethodLocker::unlock_nmethod(compiled_method_load()); | 948 JvmtiExport::post_compiled_method_load(nm); |
949 nmethodLocker::unlock_nmethod(nm); | |
938 break; | 950 break; |
951 } | |
939 case TYPE_COMPILED_METHOD_UNLOAD: | 952 case TYPE_COMPILED_METHOD_UNLOAD: |
940 JvmtiExport::post_compiled_method_unload( | 953 JvmtiExport::post_compiled_method_unload( |
941 compiled_method_unload_method_id(), | 954 _event_data.compiled_method_unload.method_id, |
942 compiled_method_unload_code_begin()); | 955 _event_data.compiled_method_unload.code_begin); |
943 break; | 956 break; |
944 case TYPE_FLUSH: | 957 case TYPE_DYNAMIC_CODE_GENERATED: |
945 JvmtiDeferredEventQueue::flush_complete(flush_state_addr()); | 958 JvmtiExport::post_dynamic_code_generated_internal( |
959 _event_data.dynamic_code_generated.name, | |
960 _event_data.dynamic_code_generated.code_begin, | |
961 _event_data.dynamic_code_generated.code_end); | |
946 break; | 962 break; |
947 default: | 963 default: |
948 ShouldNotReachHere(); | 964 ShouldNotReachHere(); |
949 } | 965 } |
950 } | 966 } |
1063 _queue_tail = new_tail; | 1079 _queue_tail = new_tail; |
1064 } | 1080 } |
1065 } | 1081 } |
1066 } | 1082 } |
1067 | 1083 |
1068 enum { | |
1069 // Random - used for debugging | |
1070 FLUSHING = 0x50403020, | |
1071 FLUSHED = 0x09080706 | |
1072 }; | |
1073 | |
1074 void JvmtiDeferredEventQueue::flush_queue(Thread* thread) { | |
1075 | |
1076 volatile int flush_state = FLUSHING; | |
1077 | |
1078 JvmtiDeferredEvent flush(JvmtiDeferredEvent::TYPE_FLUSH); | |
1079 flush.set_flush_state_addr((int*)&flush_state); | |
1080 | |
1081 if (ServiceThread::is_service_thread(thread)) { | |
1082 // If we are the service thread we have to post all preceding events | |
1083 // Use the flush event as a token to indicate when we can stop | |
1084 JvmtiDeferredEvent event; | |
1085 { | |
1086 MutexLockerEx ml(Service_lock, Mutex::_no_safepoint_check_flag); | |
1087 enqueue(flush); | |
1088 event = dequeue(); | |
1089 } | |
1090 while (!event.is_flush_event() || | |
1091 event.flush_state_addr() != &flush_state) { | |
1092 event.post(); | |
1093 { | |
1094 MutexLockerEx ml(Service_lock, Mutex::_no_safepoint_check_flag); | |
1095 event = dequeue(); | |
1096 } | |
1097 } | |
1098 } else { | |
1099 // Wake up the service thread so it will process events. When it gets | |
1100 // to the flush event it will set 'flush_complete' and notify us. | |
1101 MutexLockerEx ml(Service_lock, Mutex::_no_safepoint_check_flag); | |
1102 enqueue(flush); | |
1103 while (flush_state != FLUSHED) { | |
1104 assert(flush_state == FLUSHING || flush_state == FLUSHED, | |
1105 "only valid values for this"); | |
1106 Service_lock->wait(Mutex::_no_safepoint_check_flag); | |
1107 } | |
1108 } | |
1109 } | |
1110 | |
1111 void JvmtiDeferredEventQueue::flush_complete(int* state_addr) { | |
1112 assert(state_addr != NULL && *state_addr == FLUSHING, "must be"); | |
1113 MutexLockerEx ml(Service_lock, Mutex::_no_safepoint_check_flag); | |
1114 *state_addr = FLUSHED; | |
1115 Service_lock->notify_all(); | |
1116 } | |
1117 | |
1118 #endif // ndef KERNEL | 1084 #endif // ndef KERNEL |