< prev index next >

src/hotspot/share/prims/jni.cpp

Print this page




3794   }
3795   return ret;
3796 }
3797 
3798 DT_RETURN_MARK_DECL(CreateJavaVM, jint
3799                     , HOTSPOT_JNI_CREATEJAVAVM_RETURN(_ret_ref));
3800 
3801 static jint JNI_CreateJavaVM_inner(JavaVM **vm, void **penv, void *args) {
3802   HOTSPOT_JNI_CREATEJAVAVM_ENTRY((void **) vm, penv, args);
3803 
3804   jint result = JNI_ERR;
3805   DT_RETURN_MARK(CreateJavaVM, jint, (const jint&)result);
3806 
3807   // We're about to use Atomic::xchg for synchronization.  Some Zero
3808   // platforms use the GCC builtin __sync_lock_test_and_set for this,
3809   // but __sync_lock_test_and_set is not guaranteed to do what we want
3810   // on all architectures.  So we check it works before relying on it.
3811 #if defined(ZERO) && defined(ASSERT)
3812   {
3813     jint a = 0xcafebabe;
3814     jint b = Atomic::xchg((jint) 0xdeadbeef, &a);
3815     void *c = &a;
3816     void *d = Atomic::xchg(&b, &c);
3817     assert(a == (jint) 0xdeadbeef && b == (jint) 0xcafebabe, "Atomic::xchg() works");
3818     assert(c == &b && d == &a, "Atomic::xchg() works");
3819   }
3820 #endif // ZERO && ASSERT
3821 
3822   // At the moment it's only possible to have one Java VM,
3823   // since some of the runtime state is in global variables.
3824 
3825   // We cannot use our mutex locks here, since they only work on
3826   // Threads. We do an atomic compare and exchange to ensure only
3827   // one thread can call this method at a time
3828 
3829   // We use Atomic::xchg rather than Atomic::add/dec since on some platforms
3830   // the add/dec implementations are dependent on whether we are running
3831   // on a multiprocessor Atomic::xchg does not have this problem.
3832   if (Atomic::xchg(1, &vm_created) == 1) {
3833     return JNI_EEXIST;   // already created, or create attempt in progress
3834   }
3835   if (Atomic::xchg(0, &safe_to_recreate_vm) == 0) {
3836     return JNI_ERR;  // someone tried and failed and retry not allowed.
3837   }
3838 
3839   assert(vm_created == 1, "vm_created is true during the creation");
3840 
3841   /**
3842    * Certain errors during initialization are recoverable and do not
3843    * prevent this method from being called again at a later time
3844    * (perhaps with different arguments).  However, at a certain
3845    * point during initialization if an error occurs we cannot allow
3846    * this function to be called again (or it will crash).  In those
3847    * situations, the 'canTryAgain' flag is set to false, which atomically
3848    * sets safe_to_recreate_vm to 1, such that any new call to
3849    * JNI_CreateJavaVM will immediately fail using the above logic.
3850    */
3851   bool can_try_again = true;
3852 
3853   result = Threads::create_vm((JavaVMInitArgs*) args, &can_try_again);
3854   if (result == JNI_OK) {
3855     JavaThread *thread = JavaThread::current();




3794   }
3795   return ret;
3796 }
3797 
3798 DT_RETURN_MARK_DECL(CreateJavaVM, jint
3799                     , HOTSPOT_JNI_CREATEJAVAVM_RETURN(_ret_ref));
3800 
3801 static jint JNI_CreateJavaVM_inner(JavaVM **vm, void **penv, void *args) {
3802   HOTSPOT_JNI_CREATEJAVAVM_ENTRY((void **) vm, penv, args);
3803 
3804   jint result = JNI_ERR;
3805   DT_RETURN_MARK(CreateJavaVM, jint, (const jint&)result);
3806 
3807   // We're about to use Atomic::xchg for synchronization.  Some Zero
3808   // platforms use the GCC builtin __sync_lock_test_and_set for this,
3809   // but __sync_lock_test_and_set is not guaranteed to do what we want
3810   // on all architectures.  So we check it works before relying on it.
3811 #if defined(ZERO) && defined(ASSERT)
3812   {
3813     jint a = 0xcafebabe;
3814     jint b = Atomic::xchg(&a, (jint) 0xdeadbeef);
3815     void *c = &a;
3816     void *d = Atomic::xchg(&c, &b);
3817     assert(a == (jint) 0xdeadbeef && b == (jint) 0xcafebabe, "Atomic::xchg() works");
3818     assert(c == &b && d == &a, "Atomic::xchg() works");
3819   }
3820 #endif // ZERO && ASSERT
3821 
3822   // At the moment it's only possible to have one Java VM,
3823   // since some of the runtime state is in global variables.
3824 
3825   // We cannot use our mutex locks here, since they only work on
3826   // Threads. We do an atomic compare and exchange to ensure only
3827   // one thread can call this method at a time
3828 
3829   // We use Atomic::xchg rather than Atomic::add/dec since on some platforms
3830   // the add/dec implementations are dependent on whether we are running
3831   // on a multiprocessor Atomic::xchg does not have this problem.
3832   if (Atomic::xchg(&vm_created, 1) == 1) {
3833     return JNI_EEXIST;   // already created, or create attempt in progress
3834   }
3835   if (Atomic::xchg(&safe_to_recreate_vm, 0) == 0) {
3836     return JNI_ERR;  // someone tried and failed and retry not allowed.
3837   }
3838 
3839   assert(vm_created == 1, "vm_created is true during the creation");
3840 
3841   /**
3842    * Certain errors during initialization are recoverable and do not
3843    * prevent this method from being called again at a later time
3844    * (perhaps with different arguments).  However, at a certain
3845    * point during initialization if an error occurs we cannot allow
3846    * this function to be called again (or it will crash).  In those
3847    * situations, the 'canTryAgain' flag is set to false, which atomically
3848    * sets safe_to_recreate_vm to 1, such that any new call to
3849    * JNI_CreateJavaVM will immediately fail using the above logic.
3850    */
3851   bool can_try_again = true;
3852 
3853   result = Threads::create_vm((JavaVMInitArgs*) args, &can_try_again);
3854   if (result == JNI_OK) {
3855     JavaThread *thread = JavaThread::current();


< prev index next >