Mercurial > hg > graal-compiler
comparison src/share/vm/prims/jvm.cpp @ 2162:ccfcb502af3f
6566340: Restore use of stillborn flag to signify a thread that was stopped before it started
Summary: Restore use of stillborn flag
Reviewed-by: acorn, alanb
author | dholmes |
---|---|
date | Tue, 25 Jan 2011 00:14:21 -0500 |
parents | 828eafbd85cc |
children | 3582bf76420e |
comparison
equal
deleted
inserted
replaced
2157:d535bf4c1235 | 2162:ccfcb502af3f |
---|---|
1 /* | 1 /* |
2 * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved. | 2 * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved. |
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 * | 4 * |
5 * This code is free software; you can redistribute it and/or modify it | 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 | 6 * under the terms of the GNU General Public License version 2 only, as |
7 * published by the Free Software Foundation. | 7 * published by the Free Software Foundation. |
2649 { | 2649 { |
2650 // Ensure that the C++ Thread and OSThread structures aren't freed before | 2650 // Ensure that the C++ Thread and OSThread structures aren't freed before |
2651 // we operate. | 2651 // we operate. |
2652 MutexLocker mu(Threads_lock); | 2652 MutexLocker mu(Threads_lock); |
2653 | 2653 |
2654 // Check to see if we're running a thread that's already exited or was | 2654 // Since JDK 5 the java.lang.Thread threadStatus is used to prevent |
2655 // stopped (is_stillborn) or is still active (thread is not NULL). | 2655 // re-starting an already started thread, so we should usually find |
2656 if (java_lang_Thread::is_stillborn(JNIHandles::resolve_non_null(jthread)) || | 2656 // that the JavaThread is null. However for a JNI attached thread |
2657 java_lang_Thread::thread(JNIHandles::resolve_non_null(jthread)) != NULL) { | 2657 // there is a small window between the Thread object being created |
2658 throw_illegal_thread_state = true; | 2658 // (with its JavaThread set) and the update to its threadStatus, so we |
2659 // have to check for this | |
2660 if (java_lang_Thread::thread(JNIHandles::resolve_non_null(jthread)) != NULL) { | |
2661 throw_illegal_thread_state = true; | |
2659 } else { | 2662 } else { |
2663 // We could also check the stillborn flag to see if this thread was already stopped, but | |
2664 // for historical reasons we let the thread detect that itself when it starts running | |
2665 | |
2660 jlong size = | 2666 jlong size = |
2661 java_lang_Thread::stackSize(JNIHandles::resolve_non_null(jthread)); | 2667 java_lang_Thread::stackSize(JNIHandles::resolve_non_null(jthread)); |
2662 // Allocate the C++ Thread structure and create the native thread. The | 2668 // Allocate the C++ Thread structure and create the native thread. The |
2663 // stack size retrieved from java is signed, but the constructor takes | 2669 // stack size retrieved from java is signed, but the constructor takes |
2664 // size_t (an unsigned type), so avoid passing negative values which would | 2670 // size_t (an unsigned type), so avoid passing negative values which would |
2702 JVM_END | 2708 JVM_END |
2703 | 2709 |
2704 // JVM_Stop is implemented using a VM_Operation, so threads are forced to safepoints | 2710 // JVM_Stop is implemented using a VM_Operation, so threads are forced to safepoints |
2705 // before the quasi-asynchronous exception is delivered. This is a little obtrusive, | 2711 // before the quasi-asynchronous exception is delivered. This is a little obtrusive, |
2706 // but is thought to be reliable and simple. In the case, where the receiver is the | 2712 // but is thought to be reliable and simple. In the case, where the receiver is the |
2707 // save thread as the sender, no safepoint is needed. | 2713 // same thread as the sender, no safepoint is needed. |
2708 JVM_ENTRY(void, JVM_StopThread(JNIEnv* env, jobject jthread, jobject throwable)) | 2714 JVM_ENTRY(void, JVM_StopThread(JNIEnv* env, jobject jthread, jobject throwable)) |
2709 JVMWrapper("JVM_StopThread"); | 2715 JVMWrapper("JVM_StopThread"); |
2710 | 2716 |
2711 oop java_throwable = JNIHandles::resolve(throwable); | 2717 oop java_throwable = JNIHandles::resolve(throwable); |
2712 if (java_throwable == NULL) { | 2718 if (java_throwable == NULL) { |
2713 THROW(vmSymbols::java_lang_NullPointerException()); | 2719 THROW(vmSymbols::java_lang_NullPointerException()); |
2714 } | 2720 } |
2715 oop java_thread = JNIHandles::resolve_non_null(jthread); | 2721 oop java_thread = JNIHandles::resolve_non_null(jthread); |
2716 JavaThread* receiver = java_lang_Thread::thread(java_thread); | 2722 JavaThread* receiver = java_lang_Thread::thread(java_thread); |
2717 Events::log("JVM_StopThread thread JavaThread " INTPTR_FORMAT " as oop " INTPTR_FORMAT " [exception " INTPTR_FORMAT "]", receiver, (address)java_thread, throwable); | 2723 Events::log("JVM_StopThread thread JavaThread " INTPTR_FORMAT " as oop " INTPTR_FORMAT " [exception " INTPTR_FORMAT "]", receiver, (address)java_thread, throwable); |
2718 // First check if thread already exited | 2724 // First check if thread is alive |
2719 if (receiver != NULL) { | 2725 if (receiver != NULL) { |
2720 // Check if exception is getting thrown at self (use oop equality, since the | 2726 // Check if exception is getting thrown at self (use oop equality, since the |
2721 // target object might exit) | 2727 // target object might exit) |
2722 if (java_thread == thread->threadObj()) { | 2728 if (java_thread == thread->threadObj()) { |
2723 // This is a change from JDK 1.1, but JDK 1.2 will also do it: | |
2724 // NOTE (from JDK 1.2): this is done solely to prevent stopped | |
2725 // threads from being restarted. | |
2726 // Fix for 4314342, 4145910, perhaps others: it now doesn't have | |
2727 // any effect on the "liveness" of a thread; see | |
2728 // JVM_IsThreadAlive, below. | |
2729 if (java_throwable->is_a(SystemDictionary::ThreadDeath_klass())) { | |
2730 java_lang_Thread::set_stillborn(java_thread); | |
2731 } | |
2732 THROW_OOP(java_throwable); | 2729 THROW_OOP(java_throwable); |
2733 } else { | 2730 } else { |
2734 // Enques a VM_Operation to stop all threads and then deliver the exception... | 2731 // Enques a VM_Operation to stop all threads and then deliver the exception... |
2735 Thread::send_async_exception(java_thread, JNIHandles::resolve(throwable)); | 2732 Thread::send_async_exception(java_thread, JNIHandles::resolve(throwable)); |
2736 } | 2733 } |
2734 } | |
2735 else { | |
2736 // Either: | |
2737 // - target thread has not been started before being stopped, or | |
2738 // - target thread already terminated | |
2739 // We could read the threadStatus to determine which case it is | |
2740 // but that is overkill as it doesn't matter. We must set the | |
2741 // stillborn flag for the first case, and if the thread has already | |
2742 // exited setting this flag has no affect | |
2743 java_lang_Thread::set_stillborn(java_thread); | |
2737 } | 2744 } |
2738 JVM_END | 2745 JVM_END |
2739 | 2746 |
2740 | 2747 |
2741 JVM_ENTRY(jboolean, JVM_IsThreadAlive(JNIEnv* env, jobject jthread)) | 2748 JVM_ENTRY(jboolean, JVM_IsThreadAlive(JNIEnv* env, jobject jthread)) |