@@ -3527,7 +3527,15 @@ static void post_thread_start_event(const JavaThread* jt) {
35273527extern const struct JNIInvokeInterface_ jni_InvokeInterface;
35283528
35293529// Global invocation API vars
3530- volatile int vm_created = 0 ;
3530+ enum VM_Creation_State {
3531+ NOT_CREATED = 0 ,
3532+ IN_PROGRESS, // Most JNI operations are permitted during this phase to
3533+ // allow for initialization actions by libraries and agents.
3534+ COMPLETE
3535+ };
3536+
3537+ volatile VM_Creation_State vm_created = NOT_CREATED;
3538+
35313539// Indicate whether it is safe to recreate VM. Recreation is only
35323540// possible after a failed initial creation attempt in some cases.
35333541volatile int safe_to_recreate_vm = 1 ;
@@ -3596,7 +3604,7 @@ static jint JNI_CreateJavaVM_inner(JavaVM **vm, void **penv, void *args) {
35963604 // We use Atomic::xchg rather than Atomic::add/dec since on some platforms
35973605 // the add/dec implementations are dependent on whether we are running
35983606 // on a multiprocessor Atomic::xchg does not have this problem.
3599- if (Atomic::xchg (&vm_created, 1 ) == 1 ) {
3607+ if (Atomic::xchg (&vm_created, IN_PROGRESS) != NOT_CREATED ) {
36003608 return JNI_EEXIST; // already created, or create attempt in progress
36013609 }
36023610
@@ -3609,8 +3617,6 @@ static jint JNI_CreateJavaVM_inner(JavaVM **vm, void **penv, void *args) {
36093617 return JNI_ERR;
36103618 }
36113619
3612- assert (vm_created == 1 , " vm_created is true during the creation" );
3613-
36143620 /* *
36153621 * Certain errors during initialization are recoverable and do not
36163622 * prevent this method from being called again at a later time
@@ -3627,9 +3633,11 @@ static jint JNI_CreateJavaVM_inner(JavaVM **vm, void **penv, void *args) {
36273633 if (result == JNI_OK) {
36283634 JavaThread *thread = JavaThread::current ();
36293635 assert (!thread->has_pending_exception (), " should have returned not OK" );
3630- /* thread is thread_in_vm here */
3636+ // thread is thread_in_vm here
36313637 *vm = (JavaVM *)(&main_vm);
36323638 *(JNIEnv**)penv = thread->jni_environment ();
3639+ // mark creation complete for other JNI ops
3640+ Atomic::release_store (&vm_created, COMPLETE);
36333641
36343642#if INCLUDE_JVMCI
36353643 if (EnableJVMCI) {
@@ -3694,7 +3702,8 @@ static jint JNI_CreateJavaVM_inner(JavaVM **vm, void **penv, void *args) {
36943702 *(JNIEnv**)penv = 0 ;
36953703 // reset vm_created last to avoid race condition. Use OrderAccess to
36963704 // control both compiler and architectural-based reordering.
3697- Atomic::release_store (&vm_created, 0 );
3705+ assert (vm_created == IN_PROGRESS, " must be" );
3706+ Atomic::release_store (&vm_created, NOT_CREATED);
36983707 }
36993708
37003709 // Flush stdout and stderr before exit.
@@ -3723,7 +3732,7 @@ _JNI_IMPORT_OR_EXPORT_ jint JNICALL JNI_CreateJavaVM(JavaVM **vm, void **penv, v
37233732_JNI_IMPORT_OR_EXPORT_ jint JNICALL JNI_GetCreatedJavaVMs (JavaVM **vm_buf, jsize bufLen, jsize *numVMs) {
37243733 HOTSPOT_JNI_GETCREATEDJAVAVMS_ENTRY ((void **) vm_buf, bufLen, (uintptr_t *) numVMs);
37253734
3726- if (vm_created == 1 ) {
3735+ if (vm_created == COMPLETE ) {
37273736 if (numVMs != NULL ) *numVMs = 1 ;
37283737 if (bufLen > 0 ) *vm_buf = (JavaVM *)(&main_vm);
37293738 } else {
@@ -3743,7 +3752,7 @@ static jint JNICALL jni_DestroyJavaVM_inner(JavaVM *vm) {
37433752 jint res = JNI_ERR;
37443753 DT_RETURN_MARK (DestroyJavaVM, jint, (const jint&)res);
37453754
3746- if (vm_created == 0 ) {
3755+ if (vm_created == NOT_CREATED ) {
37473756 res = JNI_ERR;
37483757 return res;
37493758 }
@@ -3767,7 +3776,7 @@ static jint JNICALL jni_DestroyJavaVM_inner(JavaVM *vm) {
37673776 ThreadStateTransition::transition_from_native (thread, _thread_in_vm);
37683777 Threads::destroy_vm ();
37693778 // Don't bother restoring thread state, VM is gone.
3770- vm_created = 0 ;
3779+ vm_created = NOT_CREATED ;
37713780 return JNI_OK;
37723781}
37733782
@@ -3904,7 +3913,8 @@ static jint attach_current_thread(JavaVM *vm, void **penv, void *_args, bool dae
39043913
39053914jint JNICALL jni_AttachCurrentThread (JavaVM *vm, void **penv, void *_args) {
39063915 HOTSPOT_JNI_ATTACHCURRENTTHREAD_ENTRY (vm, penv, _args);
3907- if (vm_created == 0 ) {
3916+ if (vm_created == NOT_CREATED) {
3917+ // Not sure how we could possibly get here.
39083918 HOTSPOT_JNI_ATTACHCURRENTTHREAD_RETURN ((uint32_t ) JNI_ERR);
39093919 return JNI_ERR;
39103920 }
@@ -3917,7 +3927,8 @@ jint JNICALL jni_AttachCurrentThread(JavaVM *vm, void **penv, void *_args) {
39173927
39183928jint JNICALL jni_DetachCurrentThread (JavaVM *vm) {
39193929 HOTSPOT_JNI_DETACHCURRENTTHREAD_ENTRY (vm);
3920- if (vm_created == 0 ) {
3930+ if (vm_created == NOT_CREATED) {
3931+ // Not sure how we could possibly get here.
39213932 HOTSPOT_JNI_DETACHCURRENTTHREAD_RETURN (JNI_ERR);
39223933 return JNI_ERR;
39233934 }
@@ -3980,7 +3991,7 @@ jint JNICALL jni_GetEnv(JavaVM *vm, void **penv, jint version) {
39803991 jint ret = JNI_ERR;
39813992 DT_RETURN_MARK (GetEnv, jint, (const jint&)ret);
39823993
3983- if (vm_created == 0 ) {
3994+ if (vm_created == NOT_CREATED ) {
39843995 *penv = NULL ;
39853996 ret = JNI_EDETACHED;
39863997 return ret;
@@ -4031,8 +4042,9 @@ jint JNICALL jni_GetEnv(JavaVM *vm, void **penv, jint version) {
40314042
40324043jint JNICALL jni_AttachCurrentThreadAsDaemon (JavaVM *vm, void **penv, void *_args) {
40334044 HOTSPOT_JNI_ATTACHCURRENTTHREADASDAEMON_ENTRY (vm, penv, _args);
4034- if (vm_created == 0 ) {
4035- HOTSPOT_JNI_ATTACHCURRENTTHREADASDAEMON_RETURN ((uint32_t ) JNI_ERR);
4045+ if (vm_created == NOT_CREATED) {
4046+ // Not sure how we could possibly get here.
4047+ HOTSPOT_JNI_ATTACHCURRENTTHREADASDAEMON_RETURN ((uint32_t ) JNI_ERR);
40364048 return JNI_ERR;
40374049 }
40384050
0 commit comments