146 if (UseBiasedLocking) { |
146 if (UseBiasedLocking) { |
147 const int alignment = markOopDesc::biased_lock_alignment; |
147 const int alignment = markOopDesc::biased_lock_alignment; |
148 size_t aligned_size = size + (alignment - sizeof(intptr_t)); |
148 size_t aligned_size = size + (alignment - sizeof(intptr_t)); |
149 void* real_malloc_addr = throw_excpt? AllocateHeap(aligned_size, flags, CURRENT_PC) |
149 void* real_malloc_addr = throw_excpt? AllocateHeap(aligned_size, flags, CURRENT_PC) |
150 : AllocateHeap(aligned_size, flags, CURRENT_PC, |
150 : AllocateHeap(aligned_size, flags, CURRENT_PC, |
151 AllocFailStrategy::RETURN_NULL); |
151 AllocFailStrategy::RETURN_NULL); |
152 void* aligned_addr = (void*) align_size_up((intptr_t) real_malloc_addr, alignment); |
152 void* aligned_addr = (void*) align_size_up((intptr_t) real_malloc_addr, alignment); |
153 assert(((uintptr_t) aligned_addr + (uintptr_t) size) <= |
153 assert(((uintptr_t) aligned_addr + (uintptr_t) size) <= |
154 ((uintptr_t) real_malloc_addr + (uintptr_t) aligned_size), |
154 ((uintptr_t) real_malloc_addr + (uintptr_t) aligned_size), |
155 "JavaThread alignment code overflowed allocated storage"); |
155 "JavaThread alignment code overflowed allocated storage"); |
156 if (TraceBiasedLocking) { |
156 if (TraceBiasedLocking) { |
515 if (bits != NULL && (*bits & DEBUG_FALSE_BITS) != 0) { |
515 if (bits != NULL && (*bits & DEBUG_FALSE_BITS) != 0) { |
516 MutexLocker ml(Threads_lock); // needed for get_thread_name() |
516 MutexLocker ml(Threads_lock); // needed for get_thread_name() |
517 ResourceMark rm; |
517 ResourceMark rm; |
518 |
518 |
519 tty->print_cr( |
519 tty->print_cr( |
520 "Failed wait_for_ext_suspend_completion(thread=%s, debug_bits=%x)", |
520 "Failed wait_for_ext_suspend_completion(thread=%s, debug_bits=%x)", |
521 jt->get_thread_name(), *bits); |
521 jt->get_thread_name(), *bits); |
522 |
522 |
523 guarantee(!AssertOnSuspendWaitFailure, "external suspend wait failed"); |
523 guarantee(!AssertOnSuspendWaitFailure, "external suspend wait failed"); |
524 } |
524 } |
525 } |
525 } |
526 } |
526 } |
652 // |
652 // |
653 // Wait for an external suspend request to complete (or be cancelled). |
653 // Wait for an external suspend request to complete (or be cancelled). |
654 // Returns true if the thread is externally suspended and false otherwise. |
654 // Returns true if the thread is externally suspended and false otherwise. |
655 // |
655 // |
656 bool JavaThread::wait_for_ext_suspend_completion(int retries, int delay, |
656 bool JavaThread::wait_for_ext_suspend_completion(int retries, int delay, |
657 uint32_t *bits) { |
657 uint32_t *bits) { |
658 TraceSuspendDebugBits tsdb(this, true /* is_wait */, |
658 TraceSuspendDebugBits tsdb(this, true /* is_wait */, |
659 false /* !called_by_wait */, bits); |
659 false /* !called_by_wait */, bits); |
660 |
660 |
661 // local flag copies to minimize SR_lock hold time |
661 // local flag copies to minimize SR_lock hold time |
662 bool is_suspended; |
662 bool is_suspended; |
757 // The assertion for that is currently too complex to put here: |
757 // The assertion for that is currently too complex to put here: |
758 bool JavaThread::profile_last_Java_frame(frame* _fr) { |
758 bool JavaThread::profile_last_Java_frame(frame* _fr) { |
759 bool gotframe = false; |
759 bool gotframe = false; |
760 // self suspension saves needed state. |
760 // self suspension saves needed state. |
761 if (has_last_Java_frame() && _anchor.walkable()) { |
761 if (has_last_Java_frame() && _anchor.walkable()) { |
762 *_fr = pd_last_frame(); |
762 *_fr = pd_last_frame(); |
763 gotframe = true; |
763 gotframe = true; |
764 } |
764 } |
765 return gotframe; |
765 return gotframe; |
766 } |
766 } |
767 |
767 |
768 void Thread::interrupt(Thread* thread) { |
768 void Thread::interrupt(Thread* thread) { |
788 if (res == thread_parity) { |
788 if (res == thread_parity) { |
789 return true; |
789 return true; |
790 } else { |
790 } else { |
791 guarantee(res == strong_roots_parity, "Or else what?"); |
791 guarantee(res == strong_roots_parity, "Or else what?"); |
792 assert(SharedHeap::heap()->workers()->active_workers() > 0, |
792 assert(SharedHeap::heap()->workers()->active_workers() > 0, |
793 "Should only fail when parallel."); |
793 "Should only fail when parallel."); |
794 return false; |
794 return false; |
795 } |
795 } |
796 } |
796 } |
797 assert(SharedHeap::heap()->workers()->active_workers() > 0, |
797 assert(SharedHeap::heap()->workers()->active_workers() > 0, |
798 "Should only fail when parallel."); |
798 "Should only fail when parallel."); |
880 |
880 |
881 // The flag: potential_vm_operation notifies if this particular safepoint state could potential |
881 // The flag: potential_vm_operation notifies if this particular safepoint state could potential |
882 // invoke the vm-thread (i.e., and oop allocation). In that case, we also have to make sure that |
882 // invoke the vm-thread (i.e., and oop allocation). In that case, we also have to make sure that |
883 // no threads which allow_vm_block's are held |
883 // no threads which allow_vm_block's are held |
884 void Thread::check_for_valid_safepoint_state(bool potential_vm_operation) { |
884 void Thread::check_for_valid_safepoint_state(bool potential_vm_operation) { |
885 // Check if current thread is allowed to block at a safepoint |
885 // Check if current thread is allowed to block at a safepoint |
886 if (!(_allow_safepoint_count == 0)) |
886 if (!(_allow_safepoint_count == 0)) |
887 fatal("Possible safepoint reached by thread that does not allow it"); |
887 fatal("Possible safepoint reached by thread that does not allow it"); |
888 if (is_Java_thread() && ((JavaThread*)this)->thread_state() != _thread_in_vm) { |
888 if (is_Java_thread() && ((JavaThread*)this)->thread_state() != _thread_in_vm) { |
889 fatal("LEAF method calling lock?"); |
889 fatal("LEAF method calling lock?"); |
890 } |
890 } |
891 |
891 |
892 #ifdef ASSERT |
892 #ifdef ASSERT |
893 if (potential_vm_operation && is_Java_thread() |
893 if (potential_vm_operation && is_Java_thread() |
894 && !Universe::is_bootstrapping()) { |
894 && !Universe::is_bootstrapping()) { |
895 // Make sure we do not hold any locks that the VM thread also uses. |
895 // Make sure we do not hold any locks that the VM thread also uses. |
896 // This could potentially lead to deadlocks |
896 // This could potentially lead to deadlocks |
897 for (Monitor *cur = _owned_locks; cur; cur = cur->next()) { |
897 for (Monitor *cur = _owned_locks; cur; cur = cur->next()) { |
898 // Threads_lock is special, since the safepoint synchronization will not start before this is |
898 // Threads_lock is special, since the safepoint synchronization will not start before this is |
899 // acquired. Hence, a JavaThread cannot be holding it at a safepoint. So is VMOperationRequest_lock, |
899 // acquired. Hence, a JavaThread cannot be holding it at a safepoint. So is VMOperationRequest_lock, |
900 // since it is used to transfer control between JavaThreads and the VMThread |
900 // since it is used to transfer control between JavaThreads and the VMThread |
901 // Do not *exclude* any locks unless you are absolutely sure it is correct. Ask someone else first! |
901 // Do not *exclude* any locks unless you are absolutely sure it is correct. Ask someone else first! |
902 if ((cur->allow_vm_block() && |
902 if ((cur->allow_vm_block() && |
903 cur != Threads_lock && |
903 cur != Threads_lock && |
904 cur != Compile_lock && // Temporary: should not be necessary when we get separate compilation |
904 cur != Compile_lock && // Temporary: should not be necessary when we get separate compilation |
905 cur != VMOperationRequest_lock && |
905 cur != VMOperationRequest_lock && |
906 cur != VMOperationQueue_lock) || |
906 cur != VMOperationQueue_lock) || |
907 cur->rank() == Mutex::special) { |
907 cur->rank() == Mutex::special) { |
908 fatal(err_msg("Thread holding lock at safepoint that vm can block on: %s", cur->name())); |
908 fatal(err_msg("Thread holding lock at safepoint that vm can block on: %s", cur->name())); |
909 } |
|
910 } |
909 } |
911 } |
910 } |
912 |
911 } |
913 if (GCALotAtAllSafepoints) { |
912 |
914 // We could enter a safepoint here and thus have a gc |
913 if (GCALotAtAllSafepoints) { |
915 InterfaceSupport::check_gc_alot(); |
914 // We could enter a safepoint here and thus have a gc |
916 } |
915 InterfaceSupport::check_gc_alot(); |
|
916 } |
917 #endif |
917 #endif |
918 } |
918 } |
919 #endif |
919 #endif |
920 |
920 |
921 bool Thread::is_in_stack(address adr) const { |
921 bool Thread::is_in_stack(address adr) const { |
945 bool Thread::is_lock_owned(address adr) const { |
945 bool Thread::is_lock_owned(address adr) const { |
946 return on_local_stack(adr); |
946 return on_local_stack(adr); |
947 } |
947 } |
948 |
948 |
949 bool Thread::set_as_starting_thread() { |
949 bool Thread::set_as_starting_thread() { |
950 // NOTE: this must be called inside the main thread. |
950 // NOTE: this must be called inside the main thread. |
951 return os::create_main_thread((JavaThread*)this); |
951 return os::create_main_thread((JavaThread*)this); |
952 } |
952 } |
953 |
953 |
954 static void initialize_class(Symbol* class_name, TRAPS) { |
954 static void initialize_class(Symbol* class_name, TRAPS) { |
955 Klass* klass = SystemDictionary::resolve_or_fail(class_name, true, CHECK); |
955 Klass* klass = SystemDictionary::resolve_or_fail(class_name, true, CHECK); |
1002 |
1002 |
1003 Handle string = java_lang_String::create_from_str("main", CHECK_NULL); |
1003 Handle string = java_lang_String::create_from_str("main", CHECK_NULL); |
1004 |
1004 |
1005 JavaValue result(T_VOID); |
1005 JavaValue result(T_VOID); |
1006 JavaCalls::call_special(&result, thread_oop, |
1006 JavaCalls::call_special(&result, thread_oop, |
1007 klass, |
1007 klass, |
1008 vmSymbols::object_initializer_name(), |
1008 vmSymbols::object_initializer_name(), |
1009 vmSymbols::threadgroup_string_void_signature(), |
1009 vmSymbols::threadgroup_string_void_signature(), |
1010 thread_group, |
1010 thread_group, |
1011 string, |
1011 string, |
1012 CHECK_NULL); |
1012 CHECK_NULL); |
1013 return thread_oop(); |
1013 return thread_oop(); |
1014 } |
1014 } |
1015 |
1015 |
1016 static void call_initializeSystemClass(TRAPS) { |
1016 static void call_initializeSystemClass(TRAPS) { |
1017 Klass* k = SystemDictionary::resolve_or_fail(vmSymbols::java_lang_System(), true, CHECK); |
1017 Klass* k = SystemDictionary::resolve_or_fail(vmSymbols::java_lang_System(), true, CHECK); |
1018 instanceKlassHandle klass (THREAD, k); |
1018 instanceKlassHandle klass (THREAD, k); |
1019 |
1019 |
1020 JavaValue result(T_VOID); |
1020 JavaValue result(T_VOID); |
1021 JavaCalls::call_static(&result, klass, vmSymbols::initializeSystemClass_name(), |
1021 JavaCalls::call_static(&result, klass, vmSymbols::initializeSystemClass_name(), |
1022 vmSymbols::void_method_signature(), CHECK); |
1022 vmSymbols::void_method_signature(), CHECK); |
1023 } |
1023 } |
1024 |
1024 |
1025 char java_runtime_name[128] = ""; |
1025 char java_runtime_name[128] = ""; |
1026 char java_runtime_version[128] = ""; |
1026 char java_runtime_version[128] = ""; |
1027 |
1027 |
1028 // extract the JRE name from sun.misc.Version.java_runtime_name |
1028 // extract the JRE name from sun.misc.Version.java_runtime_name |
1029 static const char* get_java_runtime_name(TRAPS) { |
1029 static const char* get_java_runtime_name(TRAPS) { |
1030 Klass* k = SystemDictionary::find(vmSymbols::sun_misc_Version(), |
1030 Klass* k = SystemDictionary::find(vmSymbols::sun_misc_Version(), |
1031 Handle(), Handle(), CHECK_AND_CLEAR_NULL); |
1031 Handle(), Handle(), CHECK_AND_CLEAR_NULL); |
1032 fieldDescriptor fd; |
1032 fieldDescriptor fd; |
1033 bool found = k != NULL && |
1033 bool found = k != NULL && |
1034 InstanceKlass::cast(k)->find_local_field(vmSymbols::java_runtime_name_name(), |
1034 InstanceKlass::cast(k)->find_local_field(vmSymbols::java_runtime_name_name(), |
1035 vmSymbols::string_signature(), &fd); |
1035 vmSymbols::string_signature(), &fd); |
1036 if (found) { |
1036 if (found) { |
1047 } |
1047 } |
1048 |
1048 |
1049 // extract the JRE version from sun.misc.Version.java_runtime_version |
1049 // extract the JRE version from sun.misc.Version.java_runtime_version |
1050 static const char* get_java_runtime_version(TRAPS) { |
1050 static const char* get_java_runtime_version(TRAPS) { |
1051 Klass* k = SystemDictionary::find(vmSymbols::sun_misc_Version(), |
1051 Klass* k = SystemDictionary::find(vmSymbols::sun_misc_Version(), |
1052 Handle(), Handle(), CHECK_AND_CLEAR_NULL); |
1052 Handle(), Handle(), CHECK_AND_CLEAR_NULL); |
1053 fieldDescriptor fd; |
1053 fieldDescriptor fd; |
1054 bool found = k != NULL && |
1054 bool found = k != NULL && |
1055 InstanceKlass::cast(k)->find_local_field(vmSymbols::java_runtime_version_name(), |
1055 InstanceKlass::cast(k)->find_local_field(vmSymbols::java_runtime_version_name(), |
1056 vmSymbols::string_signature(), &fd); |
1056 vmSymbols::string_signature(), &fd); |
1057 if (found) { |
1057 if (found) { |
1073 Klass* k = SystemDictionary::resolve_or_null(vmSymbols::sun_misc_PostVMInitHook(), THREAD); |
1073 Klass* k = SystemDictionary::resolve_or_null(vmSymbols::sun_misc_PostVMInitHook(), THREAD); |
1074 instanceKlassHandle klass (THREAD, k); |
1074 instanceKlassHandle klass (THREAD, k); |
1075 if (klass.not_null()) { |
1075 if (klass.not_null()) { |
1076 JavaValue result(T_VOID); |
1076 JavaValue result(T_VOID); |
1077 JavaCalls::call_static(&result, klass, vmSymbols::run_method_name(), |
1077 JavaCalls::call_static(&result, klass, vmSymbols::run_method_name(), |
1078 vmSymbols::void_method_signature(), |
1078 vmSymbols::void_method_signature(), |
1079 CHECK); |
1079 CHECK); |
1080 } |
1080 } |
1081 } |
1081 } |
1082 |
1082 |
1083 static void reset_vm_info_property(TRAPS) { |
1083 static void reset_vm_info_property(TRAPS) { |
1084 // the vm info string |
1084 // the vm info string |
1144 THREAD); |
1144 THREAD); |
1145 } |
1145 } |
1146 |
1146 |
1147 |
1147 |
1148 if (daemon) { |
1148 if (daemon) { |
1149 java_lang_Thread::set_daemon(thread_oop()); |
1149 java_lang_Thread::set_daemon(thread_oop()); |
1150 } |
1150 } |
1151 |
1151 |
1152 if (HAS_PENDING_EXCEPTION) { |
1152 if (HAS_PENDING_EXCEPTION) { |
1153 return; |
1153 return; |
1154 } |
1154 } |
1155 |
1155 |
1156 KlassHandle group(this, SystemDictionary::ThreadGroup_klass()); |
1156 KlassHandle group(this, SystemDictionary::ThreadGroup_klass()); |
1157 Handle threadObj(this, this->threadObj()); |
1157 Handle threadObj(this, this->threadObj()); |
1158 |
1158 |
1159 JavaCalls::call_special(&result, |
1159 JavaCalls::call_special(&result, |
1160 thread_group, |
1160 thread_group, |
1161 group, |
1161 group, |
1162 vmSymbols::add_method_name(), |
1162 vmSymbols::add_method_name(), |
1163 vmSymbols::thread_void_signature(), |
1163 vmSymbols::thread_void_signature(), |
1164 threadObj, // Arg 1 |
1164 threadObj, // Arg 1 |
1165 THREAD); |
1165 THREAD); |
1166 |
1166 |
1167 |
1167 |
1168 } |
1168 } |
1169 |
1169 |
1170 // NamedThread -- non-JavaThread subclasses with multiple |
1170 // NamedThread -- non-JavaThread subclasses with multiple |
1244 for (;;) { |
1244 for (;;) { |
1245 bool timedout = PeriodicTask_lock->wait(Mutex::_no_safepoint_check_flag, remaining); |
1245 bool timedout = PeriodicTask_lock->wait(Mutex::_no_safepoint_check_flag, remaining); |
1246 jlong now = os::javaTimeNanos(); |
1246 jlong now = os::javaTimeNanos(); |
1247 |
1247 |
1248 if (remaining == 0) { |
1248 if (remaining == 0) { |
1249 // if we didn't have any tasks we could have waited for a long time |
1249 // if we didn't have any tasks we could have waited for a long time |
1250 // consider the time_slept zero and reset time_before_loop |
1250 // consider the time_slept zero and reset time_before_loop |
1251 time_slept = 0; |
1251 time_slept = 0; |
1252 time_before_loop = now; |
1252 time_before_loop = now; |
1253 } else { |
1253 } else { |
1254 // need to recalculate since we might have new tasks in _tasks |
1254 // need to recalculate since we might have new tasks in _tasks |
1255 time_slept = (int) ((now - time_before_loop) / 1000000); |
1255 time_slept = (int) ((now - time_before_loop) / 1000000); |
1256 } |
1256 } |
1257 |
1257 |
1258 // Change to task list or spurious wakeup of some kind |
1258 // Change to task list or spurious wakeup of some kind |
1259 if (timedout || _should_terminate) { |
1259 if (timedout || _should_terminate) { |
1260 break; |
1260 break; |
1261 } |
1261 } |
1262 |
1262 |
1263 remaining = PeriodicTask::time_to_wait(); |
1263 remaining = PeriodicTask::time_to_wait(); |
1264 if (remaining == 0) { |
1264 if (remaining == 0) { |
1265 // Last task was just disenrolled so loop around and wait until |
1265 // Last task was just disenrolled so loop around and wait until |
1266 // another task gets enrolled |
1266 // another task gets enrolled |
1267 continue; |
1267 continue; |
1268 } |
1268 } |
1269 |
1269 |
1270 remaining -= time_slept; |
1270 remaining -= time_slept; |
1271 if (remaining <= 0) |
1271 if (remaining <= 0) |
1272 break; |
1272 break; |
1300 // also because the WatcherThread is less likely to crash than other |
1300 // also because the WatcherThread is less likely to crash than other |
1301 // threads. |
1301 // threads. |
1302 |
1302 |
1303 for (;;) { |
1303 for (;;) { |
1304 if (!ShowMessageBoxOnError |
1304 if (!ShowMessageBoxOnError |
1305 && (OnError == NULL || OnError[0] == '\0') |
1305 && (OnError == NULL || OnError[0] == '\0') |
1306 && Arguments::abort_hook() == NULL) { |
1306 && Arguments::abort_hook() == NULL) { |
1307 os::sleep(this, 2 * 60 * 1000, false); |
1307 os::sleep(this, 2 * 60 * 1000, false); |
1308 fdStream err(defaultStream::output_fd()); |
1308 fdStream err(defaultStream::output_fd()); |
1309 err.print_raw_cr("# [ timer expired, abort... ]"); |
1309 err.print_raw_cr("# [ timer expired, abort... ]"); |
1310 // skip atexit/vm_exit/vm_abort hooks |
1310 // skip atexit/vm_exit/vm_abort hooks |
1311 os::die(); |
1311 os::die(); |
1312 } |
1312 } |
1313 |
1313 |
1314 // Wake up 5 seconds later, the fatal handler may reset OnError or |
1314 // Wake up 5 seconds later, the fatal handler may reset OnError or |
1315 // ShowMessageBoxOnError when it is ready to abort. |
1315 // ShowMessageBoxOnError when it is ready to abort. |
1316 os::sleep(this, 5 * 1000, false); |
1316 os::sleep(this, 5 * 1000, false); |
1484 SATBMarkQueueSet JavaThread::_satb_mark_queue_set; |
1484 SATBMarkQueueSet JavaThread::_satb_mark_queue_set; |
1485 DirtyCardQueueSet JavaThread::_dirty_card_queue_set; |
1485 DirtyCardQueueSet JavaThread::_dirty_card_queue_set; |
1486 #endif // INCLUDE_ALL_GCS |
1486 #endif // INCLUDE_ALL_GCS |
1487 |
1487 |
1488 JavaThread::JavaThread(bool is_attaching_via_jni) : |
1488 JavaThread::JavaThread(bool is_attaching_via_jni) : |
1489 Thread() |
1489 Thread() |
1490 #if INCLUDE_ALL_GCS |
1490 #if INCLUDE_ALL_GCS |
1491 , _satb_mark_queue(&_satb_mark_queue_set), |
1491 , _satb_mark_queue(&_satb_mark_queue_set), |
1492 _dirty_card_queue(&_dirty_card_queue_set) |
1492 _dirty_card_queue(&_dirty_card_queue_set) |
1493 #endif // INCLUDE_ALL_GCS |
1493 #endif // INCLUDE_ALL_GCS |
1494 { |
1494 { |
1495 initialize(); |
1495 initialize(); |
1496 if (is_attaching_via_jni) { |
1496 if (is_attaching_via_jni) { |
1497 _jni_attach_state = _attaching_via_jni; |
1497 _jni_attach_state = _attaching_via_jni; |
1541 |
1541 |
1542 // Remove this ifdef when C1 is ported to the compiler interface. |
1542 // Remove this ifdef when C1 is ported to the compiler interface. |
1543 static void compiler_thread_entry(JavaThread* thread, TRAPS); |
1543 static void compiler_thread_entry(JavaThread* thread, TRAPS); |
1544 |
1544 |
1545 JavaThread::JavaThread(ThreadFunction entry_point, size_t stack_sz) : |
1545 JavaThread::JavaThread(ThreadFunction entry_point, size_t stack_sz) : |
1546 Thread() |
1546 Thread() |
1547 #if INCLUDE_ALL_GCS |
1547 #if INCLUDE_ALL_GCS |
1548 , _satb_mark_queue(&_satb_mark_queue_set), |
1548 , _satb_mark_queue(&_satb_mark_queue_set), |
1549 _dirty_card_queue(&_dirty_card_queue_set) |
1549 _dirty_card_queue(&_dirty_card_queue_set) |
1550 #endif // INCLUDE_ALL_GCS |
1550 #endif // INCLUDE_ALL_GCS |
1551 { |
1551 { |
1552 if (TraceThreadEvents) { |
1552 if (TraceThreadEvents) { |
1553 tty->print_cr("creating thread %p", this); |
1553 tty->print_cr("creating thread %p", this); |
1554 } |
1554 } |
1647 JvmtiExport::post_thread_start(this); |
1647 JvmtiExport::post_thread_start(this); |
1648 } |
1648 } |
1649 |
1649 |
1650 EventThreadStart event; |
1650 EventThreadStart event; |
1651 if (event.should_commit()) { |
1651 if (event.should_commit()) { |
1652 event.set_javalangthread(java_lang_Thread::thread_id(this->threadObj())); |
1652 event.set_javalangthread(java_lang_Thread::thread_id(this->threadObj())); |
1653 event.commit(); |
1653 event.commit(); |
1654 } |
1654 } |
1655 |
1655 |
1656 // We call another function to do the rest so we are sure that the stack addresses used |
1656 // We call another function to do the rest so we are sure that the stack addresses used |
1657 // from there will be lower than the stack base just computed |
1657 // from there will be lower than the stack base just computed |
1658 thread_main_inner(); |
1658 thread_main_inner(); |
1740 uncaught_exception, |
1740 uncaught_exception, |
1741 THREAD); |
1741 THREAD); |
1742 if (HAS_PENDING_EXCEPTION) { |
1742 if (HAS_PENDING_EXCEPTION) { |
1743 ResourceMark rm(this); |
1743 ResourceMark rm(this); |
1744 jio_fprintf(defaultStream::error_stream(), |
1744 jio_fprintf(defaultStream::error_stream(), |
1745 "\nException: %s thrown from the UncaughtExceptionHandler" |
1745 "\nException: %s thrown from the UncaughtExceptionHandler" |
1746 " in thread \"%s\"\n", |
1746 " in thread \"%s\"\n", |
1747 pending_exception()->klass()->external_name(), |
1747 pending_exception()->klass()->external_name(), |
1748 get_thread_name()); |
1748 get_thread_name()); |
1749 CLEAR_PENDING_EXCEPTION; |
1749 CLEAR_PENDING_EXCEPTION; |
1750 } |
1750 } |
1751 } |
1751 } |
1752 |
1752 |
1753 // Called before the java thread exit since we want to read info |
1753 // Called before the java thread exit since we want to read info |
1754 // from java_lang_Thread object |
1754 // from java_lang_Thread object |
1755 EventThreadEnd event; |
1755 EventThreadEnd event; |
1756 if (event.should_commit()) { |
1756 if (event.should_commit()) { |
1757 event.set_javalangthread(java_lang_Thread::thread_id(this->threadObj())); |
1757 event.set_javalangthread(java_lang_Thread::thread_id(this->threadObj())); |
1758 event.commit(); |
1758 event.commit(); |
1759 } |
1759 } |
1760 |
1760 |
1761 // Call after last event on thread |
1761 // Call after last event on thread |
1762 EVENT_THREAD_EXIT(this); |
1762 EVENT_THREAD_EXIT(this); |
1763 |
1763 |
1769 while (java_lang_Thread::threadGroup(threadObj()) != NULL && (count-- > 0)) { |
1769 while (java_lang_Thread::threadGroup(threadObj()) != NULL && (count-- > 0)) { |
1770 EXCEPTION_MARK; |
1770 EXCEPTION_MARK; |
1771 JavaValue result(T_VOID); |
1771 JavaValue result(T_VOID); |
1772 KlassHandle thread_klass(THREAD, SystemDictionary::Thread_klass()); |
1772 KlassHandle thread_klass(THREAD, SystemDictionary::Thread_klass()); |
1773 JavaCalls::call_virtual(&result, |
1773 JavaCalls::call_virtual(&result, |
1774 threadObj, thread_klass, |
1774 threadObj, thread_klass, |
1775 vmSymbols::exit_method_name(), |
1775 vmSymbols::exit_method_name(), |
1776 vmSymbols::void_method_signature(), |
1776 vmSymbols::void_method_signature(), |
1777 THREAD); |
1777 THREAD); |
1778 CLEAR_PENDING_EXCEPTION; |
1778 CLEAR_PENDING_EXCEPTION; |
1779 } |
1779 } |
1780 } |
1780 } |
1781 // notify JVMTI |
1781 // notify JVMTI |
1782 if (JvmtiExport::should_post_thread_life()) { |
1782 if (JvmtiExport::should_post_thread_life()) { |
2060 if (check_unsafe_error && |
2060 if (check_unsafe_error && |
2061 condition == _async_unsafe_access_error && !has_pending_exception()) { |
2061 condition == _async_unsafe_access_error && !has_pending_exception()) { |
2062 condition = _no_async_condition; // done |
2062 condition = _no_async_condition; // done |
2063 switch (thread_state()) { |
2063 switch (thread_state()) { |
2064 case _thread_in_vm: |
2064 case _thread_in_vm: |
2065 { |
2065 { |
2066 JavaThread* THREAD = this; |
2066 JavaThread* THREAD = this; |
2067 THROW_MSG(vmSymbols::java_lang_InternalError(), "a fault occurred in an unsafe memory access operation"); |
2067 THROW_MSG(vmSymbols::java_lang_InternalError(), "a fault occurred in an unsafe memory access operation"); |
2068 } |
2068 } |
2069 case _thread_in_native: |
2069 case _thread_in_native: |
2070 { |
2070 { |
2071 ThreadInVMfromNative tiv(this); |
2071 ThreadInVMfromNative tiv(this); |
2072 JavaThread* THREAD = this; |
2072 JavaThread* THREAD = this; |
2073 THROW_MSG(vmSymbols::java_lang_InternalError(), "a fault occurred in an unsafe memory access operation"); |
2073 THROW_MSG(vmSymbols::java_lang_InternalError(), "a fault occurred in an unsafe memory access operation"); |
2074 } |
2074 } |
2075 case _thread_in_Java: |
2075 case _thread_in_Java: |
2076 { |
2076 { |
2077 ThreadInVMfromJava tiv(this); |
2077 ThreadInVMfromJava tiv(this); |
2078 JavaThread* THREAD = this; |
2078 JavaThread* THREAD = this; |
2079 THROW_MSG(vmSymbols::java_lang_InternalError(), "a fault occurred in a recent unsafe memory access operation in compiled Java code"); |
2079 THROW_MSG(vmSymbols::java_lang_InternalError(), "a fault occurred in a recent unsafe memory access operation in compiled Java code"); |
2080 } |
2080 } |
2081 default: |
2081 default: |
2082 ShouldNotReachHere(); |
2082 ShouldNotReachHere(); |
2083 } |
2083 } |
2084 } |
2084 } |
2085 |
2085 |
2168 |
2168 |
2169 // Set async. pending exception in thread. |
2169 // Set async. pending exception in thread. |
2170 set_pending_async_exception(java_throwable); |
2170 set_pending_async_exception(java_throwable); |
2171 |
2171 |
2172 if (TraceExceptions) { |
2172 if (TraceExceptions) { |
2173 ResourceMark rm; |
2173 ResourceMark rm; |
2174 tty->print_cr("Pending Async. exception installed of type: %s", InstanceKlass::cast(_pending_async_exception->klass())->external_name()); |
2174 tty->print_cr("Pending Async. exception installed of type: %s", InstanceKlass::cast(_pending_async_exception->klass())->external_name()); |
2175 } |
2175 } |
2176 // for AbortVMOnException flag |
2176 // for AbortVMOnException flag |
2177 NOT_PRODUCT(Exceptions::debug_check_abort(InstanceKlass::cast(_pending_async_exception->klass())->external_name())); |
2177 NOT_PRODUCT(Exceptions::debug_check_abort(InstanceKlass::cast(_pending_async_exception->klass())->external_name())); |
2178 } |
2178 } |
2179 } |
2179 } |
2239 int JavaThread::java_suspend_self() { |
2239 int JavaThread::java_suspend_self() { |
2240 int ret = 0; |
2240 int ret = 0; |
2241 |
2241 |
2242 // we are in the process of exiting so don't suspend |
2242 // we are in the process of exiting so don't suspend |
2243 if (is_exiting()) { |
2243 if (is_exiting()) { |
2244 clear_external_suspend(); |
2244 clear_external_suspend(); |
2245 return ret; |
2245 return ret; |
2246 } |
2246 } |
2247 |
2247 |
2248 assert(_anchor.walkable() || |
2248 assert(_anchor.walkable() || |
2249 (is_Java_thread() && !((JavaThread*)this)->has_last_Java_frame()), |
2249 (is_Java_thread() && !((JavaThread*)this)->has_last_Java_frame()), |
2250 "must have walkable stack"); |
2250 "must have walkable stack"); |
2251 |
2251 |
2252 MutexLockerEx ml(SR_lock(), Mutex::_no_safepoint_check_flag); |
2252 MutexLockerEx ml(SR_lock(), Mutex::_no_safepoint_check_flag); |
2253 |
2253 |
2254 assert(!this->is_ext_suspended(), |
2254 assert(!this->is_ext_suspended(), |
2255 "a thread trying to self-suspend should not already be suspended"); |
2255 "a thread trying to self-suspend should not already be suspended"); |
2256 |
2256 |
2257 if (this->is_suspend_equivalent()) { |
2257 if (this->is_suspend_equivalent()) { |
2258 // If we are self-suspending as a result of the lifting of a |
2258 // If we are self-suspending as a result of the lifting of a |
2259 // suspend equivalent condition, then the suspend_equivalent |
2259 // suspend equivalent condition, then the suspend_equivalent |
2260 // flag is not cleared until we set the ext_suspended flag so |
2260 // flag is not cleared until we set the ext_suspended flag so |
2287 #ifdef ASSERT |
2287 #ifdef ASSERT |
2288 // verify the JavaThread has not yet been published in the Threads::list, and |
2288 // verify the JavaThread has not yet been published in the Threads::list, and |
2289 // hence doesn't need protection from concurrent access at this stage |
2289 // hence doesn't need protection from concurrent access at this stage |
2290 void JavaThread::verify_not_published() { |
2290 void JavaThread::verify_not_published() { |
2291 if (!Threads_lock->owned_by_self()) { |
2291 if (!Threads_lock->owned_by_self()) { |
2292 MutexLockerEx ml(Threads_lock, Mutex::_no_safepoint_check_flag); |
2292 MutexLockerEx ml(Threads_lock, Mutex::_no_safepoint_check_flag); |
2293 assert(!Threads::includes(this), |
2293 assert(!Threads::includes(this), |
2294 "java thread shouldn't have been published yet!"); |
2294 "java thread shouldn't have been published yet!"); |
2295 } |
2295 } |
2296 else { |
2296 else { |
2297 assert(!Threads::includes(this), |
2297 assert(!Threads::includes(this), |
2298 "java thread shouldn't have been published yet!"); |
2298 "java thread shouldn't have been published yet!"); |
2299 } |
2299 } |
2300 } |
2300 } |
2301 #endif |
2301 #endif |
2302 |
2302 |
2638 |
2638 |
2639 // If the caller is a NamedThread, then remember, in the current scope, |
2639 // If the caller is a NamedThread, then remember, in the current scope, |
2640 // the given JavaThread in its _processed_thread field. |
2640 // the given JavaThread in its _processed_thread field. |
2641 class RememberProcessedThread: public StackObj { |
2641 class RememberProcessedThread: public StackObj { |
2642 NamedThread* _cur_thr; |
2642 NamedThread* _cur_thr; |
2643 public: |
2643 public: |
2644 RememberProcessedThread(JavaThread* jthr) { |
2644 RememberProcessedThread(JavaThread* jthr) { |
2645 Thread* thread = Thread::current(); |
2645 Thread* thread = Thread::current(); |
2646 if (thread->is_Named_thread()) { |
2646 if (thread->is_Named_thread()) { |
2647 _cur_thr = (NamedThread *)thread; |
2647 _cur_thr = (NamedThread *)thread; |
2648 _cur_thr->set_processed_thread(jthr); |
2648 _cur_thr->set_processed_thread(jthr); |
2667 |
2667 |
2668 // Traverse the GCHandles |
2668 // Traverse the GCHandles |
2669 Thread::oops_do(f, cld_f, cf); |
2669 Thread::oops_do(f, cld_f, cf); |
2670 |
2670 |
2671 assert((!has_last_Java_frame() && java_call_counter() == 0) || |
2671 assert((!has_last_Java_frame() && java_call_counter() == 0) || |
2672 (has_last_Java_frame() && java_call_counter() > 0), "wrong java_sp info!"); |
2672 (has_last_Java_frame() && java_call_counter() > 0), "wrong java_sp info!"); |
2673 |
2673 |
2674 if (has_last_Java_frame()) { |
2674 if (has_last_Java_frame()) { |
2675 // Record JavaThread to GC thread |
2675 // Record JavaThread to GC thread |
2676 RememberProcessedThread rpt(this); |
2676 RememberProcessedThread rpt(this); |
2677 |
2677 |
2727 |
2727 |
2728 void JavaThread::nmethods_do(CodeBlobClosure* cf) { |
2728 void JavaThread::nmethods_do(CodeBlobClosure* cf) { |
2729 Thread::nmethods_do(cf); // (super method is a no-op) |
2729 Thread::nmethods_do(cf); // (super method is a no-op) |
2730 |
2730 |
2731 assert((!has_last_Java_frame() && java_call_counter() == 0) || |
2731 assert((!has_last_Java_frame() && java_call_counter() == 0) || |
2732 (has_last_Java_frame() && java_call_counter() > 0), "wrong java_sp info!"); |
2732 (has_last_Java_frame() && java_call_counter() > 0), "wrong java_sp info!"); |
2733 |
2733 |
2734 if (has_last_Java_frame()) { |
2734 if (has_last_Java_frame()) { |
2735 // Traverse the execution stack |
2735 // Traverse the execution stack |
2736 for (StackFrameStream fst(this); !fst.is_done(); fst.next()) { |
2736 for (StackFrameStream fst(this); !fst.is_done(); fst.next()) { |
2737 fst.current()->nmethods_do(cf); |
2737 fst.current()->nmethods_do(cf); |
2807 // JavaThread::print() is that we can't grab lock or allocate memory. |
2807 // JavaThread::print() is that we can't grab lock or allocate memory. |
2808 void JavaThread::print_on_error(outputStream* st, char *buf, int buflen) const { |
2808 void JavaThread::print_on_error(outputStream* st, char *buf, int buflen) const { |
2809 st->print("JavaThread \"%s\"", get_thread_name_string(buf, buflen)); |
2809 st->print("JavaThread \"%s\"", get_thread_name_string(buf, buflen)); |
2810 oop thread_obj = threadObj(); |
2810 oop thread_obj = threadObj(); |
2811 if (thread_obj != NULL) { |
2811 if (thread_obj != NULL) { |
2812 if (java_lang_Thread::is_daemon(thread_obj)) st->print(" daemon"); |
2812 if (java_lang_Thread::is_daemon(thread_obj)) st->print(" daemon"); |
2813 } |
2813 } |
2814 st->print(" ["); |
2814 st->print(" ["); |
2815 st->print("%s", _get_thread_state_name(_thread_state)); |
2815 st->print("%s", _get_thread_state_name(_thread_state)); |
2816 if (osthread()) { |
2816 if (osthread()) { |
2817 st->print(", id=%d", osthread()->thread_id()); |
2817 st->print(", id=%d", osthread()->thread_id()); |
2948 // oop representing the java_lang_Thread to the new thread (a JavaThread *). |
2948 // oop representing the java_lang_Thread to the new thread (a JavaThread *). |
2949 |
2949 |
2950 Handle thread_oop(Thread::current(), |
2950 Handle thread_oop(Thread::current(), |
2951 JNIHandles::resolve_non_null(jni_thread)); |
2951 JNIHandles::resolve_non_null(jni_thread)); |
2952 assert(InstanceKlass::cast(thread_oop->klass())->is_linked(), |
2952 assert(InstanceKlass::cast(thread_oop->klass())->is_linked(), |
2953 "must be initialized"); |
2953 "must be initialized"); |
2954 set_threadObj(thread_oop()); |
2954 set_threadObj(thread_oop()); |
2955 java_lang_Thread::set_thread(thread_oop(), this); |
2955 java_lang_Thread::set_thread(thread_oop(), this); |
2956 |
2956 |
2957 if (prio == NoPriority) { |
2957 if (prio == NoPriority) { |
2958 prio = java_lang_Thread::priority(thread_oop()); |
2958 prio = java_lang_Thread::priority(thread_oop()); |
3581 CLEAR_PENDING_EXCEPTION; |
3581 CLEAR_PENDING_EXCEPTION; |
3582 } |
3582 } |
3583 } |
3583 } |
3584 |
3584 |
3585 { |
3585 { |
3586 MutexLockerEx ml(PeriodicTask_lock, Mutex::_no_safepoint_check_flag); |
3586 MutexLockerEx ml(PeriodicTask_lock, Mutex::_no_safepoint_check_flag); |
3587 // Make sure the watcher thread can be started by WatcherThread::start() |
3587 // Make sure the watcher thread can be started by WatcherThread::start() |
3588 // or by dynamic enrollment. |
3588 // or by dynamic enrollment. |
3589 WatcherThread::make_startable(); |
3589 WatcherThread::make_startable(); |
3590 // Start up the WatcherThread if there are any periodic tasks |
3590 // Start up the WatcherThread if there are any periodic tasks |
3591 // NOTE: All PeriodicTasks should be registered by now. If they |
3591 // NOTE: All PeriodicTasks should be registered by now. If they |
3592 // aren't, late joiners might appear to start slowly (we might |
3592 // aren't, late joiners might appear to start slowly (we might |
3593 // take a while to process their first tick). |
3593 // take a while to process their first tick). |
3594 if (PeriodicTask::num_tasks() > 0) { |
3594 if (PeriodicTask::num_tasks() > 0) { |
3595 WatcherThread::start(); |
3595 WatcherThread::start(); |
3596 } |
3596 } |
3597 } |
3597 } |
3598 |
3598 |
3599 // Give os specific code one last chance to start |
3599 // Give os specific code one last chance to start |
3600 os::init_3(); |
3600 os::init_3(); |
3601 |
3601 |
3747 extern struct JavaVM_ main_vm; |
3747 extern struct JavaVM_ main_vm; |
3748 for (AgentLibrary* agent = Arguments::agents(); agent != NULL; agent = agent->next()) { |
3748 for (AgentLibrary* agent = Arguments::agents(); agent != NULL; agent = agent->next()) { |
3749 |
3749 |
3750 // Find the Agent_OnUnload function. |
3750 // Find the Agent_OnUnload function. |
3751 Agent_OnUnload_t unload_entry = CAST_TO_FN_PTR(Agent_OnUnload_t, |
3751 Agent_OnUnload_t unload_entry = CAST_TO_FN_PTR(Agent_OnUnload_t, |
3752 os::find_agent_function(agent, |
3752 os::find_agent_function(agent, |
3753 false, |
3753 false, |
3754 on_unload_symbols, |
3754 on_unload_symbols, |
3755 num_symbol_entries)); |
3755 num_symbol_entries)); |
3756 |
3756 |
3757 // Invoke the Agent_OnUnload function |
3757 // Invoke the Agent_OnUnload function |
3758 if (unload_entry != NULL) { |
3758 if (unload_entry != NULL) { |
3759 JavaThread* thread = JavaThread::current(); |
3759 JavaThread* thread = JavaThread::current(); |
3760 ThreadToNativeFromVM ttn(thread); |
3760 ThreadToNativeFromVM ttn(thread); |
4058 // turn off parallelism in process_roots while active_workers |
4058 // turn off parallelism in process_roots while active_workers |
4059 // is being used for parallelism elsewhere. |
4059 // is being used for parallelism elsewhere. |
4060 bool is_par = sh->n_par_threads() > 0; |
4060 bool is_par = sh->n_par_threads() > 0; |
4061 assert(!is_par || |
4061 assert(!is_par || |
4062 (SharedHeap::heap()->n_par_threads() == |
4062 (SharedHeap::heap()->n_par_threads() == |
4063 SharedHeap::heap()->workers()->active_workers()), "Mismatch"); |
4063 SharedHeap::heap()->workers()->active_workers()), "Mismatch"); |
4064 int cp = SharedHeap::heap()->strong_roots_parity(); |
4064 int cp = SharedHeap::heap()->strong_roots_parity(); |
4065 ALL_JAVA_THREADS(p) { |
4065 ALL_JAVA_THREADS(p) { |
4066 if (p->claim_oops_do(is_par, cp)) { |
4066 if (p->claim_oops_do(is_par, cp)) { |
4067 p->oops_do(f, cld_f, cf); |
4067 p->oops_do(f, cld_f, cf); |
4068 } |
4068 } |
4111 } |
4111 } |
4112 |
4112 |
4113 |
4113 |
4114 // Get count Java threads that are waiting to enter the specified monitor. |
4114 // Get count Java threads that are waiting to enter the specified monitor. |
4115 GrowableArray<JavaThread*>* Threads::get_pending_threads(int count, |
4115 GrowableArray<JavaThread*>* Threads::get_pending_threads(int count, |
4116 address monitor, bool doLock) { |
4116 address monitor, bool doLock) { |
4117 assert(doLock || SafepointSynchronize::is_at_safepoint(), |
4117 assert(doLock || SafepointSynchronize::is_at_safepoint(), |
4118 "must grab Threads_lock or be at safepoint"); |
4118 "must grab Threads_lock or be at safepoint"); |
4119 GrowableArray<JavaThread*>* result = new GrowableArray<JavaThread*>(count); |
4119 GrowableArray<JavaThread*>* result = new GrowableArray<JavaThread*>(count); |
4120 |
4120 |
4121 int i = 0; |
4121 int i = 0; |
4122 { |
4122 { |
4123 MutexLockerEx ml(doLock ? Threads_lock : NULL); |
4123 MutexLockerEx ml(doLock ? Threads_lock : NULL); |
4179 void Threads::print_on(outputStream* st, bool print_stacks, bool internal_format, bool print_concurrent_locks) { |
4179 void Threads::print_on(outputStream* st, bool print_stacks, bool internal_format, bool print_concurrent_locks) { |
4180 char buf[32]; |
4180 char buf[32]; |
4181 st->print_cr("%s", os::local_time_string(buf, sizeof(buf))); |
4181 st->print_cr("%s", os::local_time_string(buf, sizeof(buf))); |
4182 |
4182 |
4183 st->print_cr("Full thread dump %s (%s %s):", |
4183 st->print_cr("Full thread dump %s (%s %s):", |
4184 Abstract_VM_Version::vm_name(), |
4184 Abstract_VM_Version::vm_name(), |
4185 Abstract_VM_Version::vm_release(), |
4185 Abstract_VM_Version::vm_release(), |
4186 Abstract_VM_Version::vm_info_string() |
4186 Abstract_VM_Version::vm_info_string() |
4187 ); |
4187 ); |
4188 st->cr(); |
4188 st->cr(); |
4189 |
4189 |
4190 #if INCLUDE_ALL_GCS |
4190 #if INCLUDE_ALL_GCS |
4191 // Dump concurrent locks |
4191 // Dump concurrent locks |
4192 ConcurrentLocksDump concurrent_locks; |
4192 ConcurrentLocksDump concurrent_locks; |
4301 |
4301 |
4302 typedef volatile int SpinLockT; |
4302 typedef volatile int SpinLockT; |
4303 |
4303 |
4304 void Thread::SpinAcquire (volatile int * adr, const char * LockName) { |
4304 void Thread::SpinAcquire (volatile int * adr, const char * LockName) { |
4305 if (Atomic::cmpxchg (1, adr, 0) == 0) { |
4305 if (Atomic::cmpxchg (1, adr, 0) == 0) { |
4306 return; // normal fast-path return |
4306 return; // normal fast-path return |
4307 } |
4307 } |
4308 |
4308 |
4309 // Slow-path : We've encountered contention -- Spin/Yield/Block strategy. |
4309 // Slow-path : We've encountered contention -- Spin/Yield/Block strategy. |
4310 TEVENT(SpinAcquire - ctx); |
4310 TEVENT(SpinAcquire - ctx); |
4311 int ctr = 0; |
4311 int ctr = 0; |
4312 int Yields = 0; |
4312 int Yields = 0; |
4313 for (;;) { |
4313 for (;;) { |
4314 while (*adr != 0) { |
4314 while (*adr != 0) { |
4315 ++ctr; |
4315 ++ctr; |
4316 if ((ctr & 0xFFF) == 0 || !os::is_MP()) { |
4316 if ((ctr & 0xFFF) == 0 || !os::is_MP()) { |
4317 if (Yields > 5) { |
4317 if (Yields > 5) { |
4318 os::naked_short_sleep(1); |
4318 os::naked_short_sleep(1); |
4319 } else { |
|
4320 os::naked_yield(); |
|
4321 ++Yields; |
|
4322 } |
|
4323 } else { |
4319 } else { |
4324 SpinPause(); |
4320 os::naked_yield(); |
|
4321 ++Yields; |
4325 } |
4322 } |
4326 } |
4323 } else { |
4327 if (Atomic::cmpxchg(1, adr, 0) == 0) return; |
4324 SpinPause(); |
|
4325 } |
|
4326 } |
|
4327 if (Atomic::cmpxchg(1, adr, 0) == 0) return; |
4328 } |
4328 } |
4329 } |
4329 } |
4330 |
4330 |
4331 void Thread::SpinRelease (volatile int * adr) { |
4331 void Thread::SpinRelease (volatile int * adr) { |
4332 assert(*adr != 0, "invariant"); |
4332 assert(*adr != 0, "invariant"); |
4399 |
4399 |
4400 void Thread::muxAcquire (volatile intptr_t * Lock, const char * LockName) { |
4400 void Thread::muxAcquire (volatile intptr_t * Lock, const char * LockName) { |
4401 intptr_t w = Atomic::cmpxchg_ptr(LOCKBIT, Lock, 0); |
4401 intptr_t w = Atomic::cmpxchg_ptr(LOCKBIT, Lock, 0); |
4402 if (w == 0) return; |
4402 if (w == 0) return; |
4403 if ((w & LOCKBIT) == 0 && Atomic::cmpxchg_ptr (w|LOCKBIT, Lock, w) == w) { |
4403 if ((w & LOCKBIT) == 0 && Atomic::cmpxchg_ptr (w|LOCKBIT, Lock, w) == w) { |
4404 return; |
4404 return; |
4405 } |
4405 } |
4406 |
4406 |
4407 TEVENT(muxAcquire - Contention); |
4407 TEVENT(muxAcquire - Contention); |
4408 ParkEvent * const Self = Thread::current()->_MuxEvent; |
4408 ParkEvent * const Self = Thread::current()->_MuxEvent; |
4409 assert((intptr_t(Self) & LOCKBIT) == 0, "invariant"); |
4409 assert((intptr_t(Self) & LOCKBIT) == 0, "invariant"); |
4410 for (;;) { |
4410 for (;;) { |
4411 int its = (os::is_MP() ? 100 : 0) + 1; |
4411 int its = (os::is_MP() ? 100 : 0) + 1; |
4412 |
4412 |
4413 // Optional spin phase: spin-then-park strategy |
4413 // Optional spin phase: spin-then-park strategy |
4414 while (--its >= 0) { |
4414 while (--its >= 0) { |
4415 w = *Lock; |
4415 w = *Lock; |
4416 if ((w & LOCKBIT) == 0 && Atomic::cmpxchg_ptr (w|LOCKBIT, Lock, w) == w) { |
4416 if ((w & LOCKBIT) == 0 && Atomic::cmpxchg_ptr (w|LOCKBIT, Lock, w) == w) { |
|
4417 return; |
|
4418 } |
|
4419 } |
|
4420 |
|
4421 Self->reset(); |
|
4422 Self->OnList = intptr_t(Lock); |
|
4423 // The following fence() isn't _strictly necessary as the subsequent |
|
4424 // CAS() both serializes execution and ratifies the fetched *Lock value. |
|
4425 OrderAccess::fence(); |
|
4426 for (;;) { |
|
4427 w = *Lock; |
|
4428 if ((w & LOCKBIT) == 0) { |
|
4429 if (Atomic::cmpxchg_ptr (w|LOCKBIT, Lock, w) == w) { |
|
4430 Self->OnList = 0; // hygiene - allows stronger asserts |
4417 return; |
4431 return; |
4418 } |
|
4419 } |
|
4420 |
|
4421 Self->reset(); |
|
4422 Self->OnList = intptr_t(Lock); |
|
4423 // The following fence() isn't _strictly necessary as the subsequent |
|
4424 // CAS() both serializes execution and ratifies the fetched *Lock value. |
|
4425 OrderAccess::fence(); |
|
4426 for (;;) { |
|
4427 w = *Lock; |
|
4428 if ((w & LOCKBIT) == 0) { |
|
4429 if (Atomic::cmpxchg_ptr (w|LOCKBIT, Lock, w) == w) { |
|
4430 Self->OnList = 0; // hygiene - allows stronger asserts |
|
4431 return; |
|
4432 } |
|
4433 continue; // Interference -- *Lock changed -- Just retry |
|
4434 } |
4432 } |
4435 assert(w & LOCKBIT, "invariant"); |
4433 continue; // Interference -- *Lock changed -- Just retry |
4436 Self->ListNext = (ParkEvent *) (w & ~LOCKBIT); |
4434 } |
4437 if (Atomic::cmpxchg_ptr(intptr_t(Self)|LOCKBIT, Lock, w) == w) break; |
4435 assert(w & LOCKBIT, "invariant"); |
4438 } |
4436 Self->ListNext = (ParkEvent *) (w & ~LOCKBIT); |
4439 |
4437 if (Atomic::cmpxchg_ptr(intptr_t(Self)|LOCKBIT, Lock, w) == w) break; |
4440 while (Self->OnList != 0) { |
4438 } |
4441 Self->park(); |
4439 |
4442 } |
4440 while (Self->OnList != 0) { |
|
4441 Self->park(); |
|
4442 } |
4443 } |
4443 } |
4444 } |
4444 } |
4445 |
4445 |
4446 void Thread::muxAcquireW (volatile intptr_t * Lock, ParkEvent * ev) { |
4446 void Thread::muxAcquireW (volatile intptr_t * Lock, ParkEvent * ev) { |
4447 intptr_t w = Atomic::cmpxchg_ptr(LOCKBIT, Lock, 0); |
4447 intptr_t w = Atomic::cmpxchg_ptr(LOCKBIT, Lock, 0); |