< prev index next >

src/hotspot/share/prims/jni.cpp

Print this page




3758 
3759     jni_GetObjectRefType,
3760 
3761     // Module features
3762 
3763     jni_GetModule
3764 };
3765 
3766 
3767 // For jvmti use to modify jni function table.
3768 // Java threads in native contiues to run until it is transitioned
3769 // to VM at safepoint. Before the transition or before it is blocked
3770 // for safepoint it may access jni function table. VM could crash if
3771 // any java thread access the jni function table in the middle of memcpy.
3772 // To avoid this each function pointers are copied automically.
3773 void copy_jni_function_table(const struct JNINativeInterface_ *new_jni_NativeInterface) {
3774   assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint");
3775   intptr_t *a = (intptr_t *) jni_functions();
3776   intptr_t *b = (intptr_t *) new_jni_NativeInterface;
3777   for (uint i=0; i <  sizeof(struct JNINativeInterface_)/sizeof(void *); i++) {
3778     Atomic::store_ptr(*b++, a++);
3779   }
3780 }
3781 
3782 void quicken_jni_functions() {
3783   // Replace Get<Primitive>Field with fast versions
3784   if (UseFastJNIAccessors && !JvmtiExport::can_post_field_access()
3785       && !VerifyJNIFields && !CountJNICalls && !CheckJNICalls
3786 #if defined(_WINDOWS) && defined(IA32) && defined(COMPILER2)
3787       // windows x86 currently needs SEH wrapper and the gain of the fast
3788       // versions currently isn't certain for server vm on uniprocessor.
3789       && os::is_MP()
3790 #endif
3791   ) {
3792     address func;
3793     func = JNI_FastGetField::generate_fast_get_boolean_field();
3794     if (func != (address)-1) {
3795       jni_NativeInterface.GetBooleanField = (GetBooleanField_t)func;
3796     }
3797     func = JNI_FastGetField::generate_fast_get_byte_field();
3798     if (func != (address)-1) {


3881 }
3882 
3883 DT_RETURN_MARK_DECL(CreateJavaVM, jint
3884                     , HOTSPOT_JNI_CREATEJAVAVM_RETURN(_ret_ref));
3885 
3886 static jint JNI_CreateJavaVM_inner(JavaVM **vm, void **penv, void *args) {
3887   HOTSPOT_JNI_CREATEJAVAVM_ENTRY((void **) vm, penv, args);
3888 
3889   jint result = JNI_ERR;
3890   DT_RETURN_MARK(CreateJavaVM, jint, (const jint&)result);
3891 
3892   // We're about to use Atomic::xchg for synchronization.  Some Zero
3893   // platforms use the GCC builtin __sync_lock_test_and_set for this,
3894   // but __sync_lock_test_and_set is not guaranteed to do what we want
3895   // on all architectures.  So we check it works before relying on it.
3896 #if defined(ZERO) && defined(ASSERT)
3897   {
3898     jint a = 0xcafebabe;
3899     jint b = Atomic::xchg(0xdeadbeef, &a);
3900     void *c = &a;
3901     void *d = Atomic::xchg_ptr(&b, &c);
3902     assert(a == (jint) 0xdeadbeef && b == (jint) 0xcafebabe, "Atomic::xchg() works");
3903     assert(c == &b && d == &a, "Atomic::xchg_ptr() works");
3904   }
3905 #endif // ZERO && ASSERT
3906 
3907   // At the moment it's only possible to have one Java VM,
3908   // since some of the runtime state is in global variables.
3909 
3910   // We cannot use our mutex locks here, since they only work on
3911   // Threads. We do an atomic compare and exchange to ensure only
3912   // one thread can call this method at a time
3913 
3914   // We use Atomic::xchg rather than Atomic::add/dec since on some platforms
3915   // the add/dec implementations are dependent on whether we are running
3916   // on a multiprocessor, and at this stage of initialization the os::is_MP
3917   // function used to determine this will always return false. Atomic::xchg
3918   // does not have this problem.
3919   if (Atomic::xchg(1, &vm_created) == 1) {
3920     return JNI_EEXIST;   // already created, or create attempt in progress
3921   }
3922   if (Atomic::xchg(0, &safe_to_recreate_vm) == 0) {
3923     return JNI_ERR;  // someone tried and failed and retry not allowed.




3758 
3759     jni_GetObjectRefType,
3760 
3761     // Module features
3762 
3763     jni_GetModule
3764 };
3765 
3766 
3767 // For jvmti use to modify jni function table.
3768 // Java threads in native contiues to run until it is transitioned
3769 // to VM at safepoint. Before the transition or before it is blocked
3770 // for safepoint it may access jni function table. VM could crash if
3771 // any java thread access the jni function table in the middle of memcpy.
3772 // To avoid this each function pointers are copied automically.
3773 void copy_jni_function_table(const struct JNINativeInterface_ *new_jni_NativeInterface) {
3774   assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint");
3775   intptr_t *a = (intptr_t *) jni_functions();
3776   intptr_t *b = (intptr_t *) new_jni_NativeInterface;
3777   for (uint i=0; i <  sizeof(struct JNINativeInterface_)/sizeof(void *); i++) {
3778     Atomic::store(*b++, a++);
3779   }
3780 }
3781 
3782 void quicken_jni_functions() {
3783   // Replace Get<Primitive>Field with fast versions
3784   if (UseFastJNIAccessors && !JvmtiExport::can_post_field_access()
3785       && !VerifyJNIFields && !CountJNICalls && !CheckJNICalls
3786 #if defined(_WINDOWS) && defined(IA32) && defined(COMPILER2)
3787       // windows x86 currently needs SEH wrapper and the gain of the fast
3788       // versions currently isn't certain for server vm on uniprocessor.
3789       && os::is_MP()
3790 #endif
3791   ) {
3792     address func;
3793     func = JNI_FastGetField::generate_fast_get_boolean_field();
3794     if (func != (address)-1) {
3795       jni_NativeInterface.GetBooleanField = (GetBooleanField_t)func;
3796     }
3797     func = JNI_FastGetField::generate_fast_get_byte_field();
3798     if (func != (address)-1) {


3881 }
3882 
3883 DT_RETURN_MARK_DECL(CreateJavaVM, jint
3884                     , HOTSPOT_JNI_CREATEJAVAVM_RETURN(_ret_ref));
3885 
3886 static jint JNI_CreateJavaVM_inner(JavaVM **vm, void **penv, void *args) {
3887   HOTSPOT_JNI_CREATEJAVAVM_ENTRY((void **) vm, penv, args);
3888 
3889   jint result = JNI_ERR;
3890   DT_RETURN_MARK(CreateJavaVM, jint, (const jint&)result);
3891 
3892   // We're about to use Atomic::xchg for synchronization.  Some Zero
3893   // platforms use the GCC builtin __sync_lock_test_and_set for this,
3894   // but __sync_lock_test_and_set is not guaranteed to do what we want
3895   // on all architectures.  So we check it works before relying on it.
3896 #if defined(ZERO) && defined(ASSERT)
3897   {
3898     jint a = 0xcafebabe;
3899     jint b = Atomic::xchg(0xdeadbeef, &a);
3900     void *c = &a;
3901     void *d = Atomic::xchg(&b, &c);
3902     assert(a == (jint) 0xdeadbeef && b == (jint) 0xcafebabe, "Atomic::xchg() works");
3903     assert(c == &b && d == &a, "Atomic::xchg() works");
3904   }
3905 #endif // ZERO && ASSERT
3906 
3907   // At the moment it's only possible to have one Java VM,
3908   // since some of the runtime state is in global variables.
3909 
3910   // We cannot use our mutex locks here, since they only work on
3911   // Threads. We do an atomic compare and exchange to ensure only
3912   // one thread can call this method at a time
3913 
3914   // We use Atomic::xchg rather than Atomic::add/dec since on some platforms
3915   // the add/dec implementations are dependent on whether we are running
3916   // on a multiprocessor, and at this stage of initialization the os::is_MP
3917   // function used to determine this will always return false. Atomic::xchg
3918   // does not have this problem.
3919   if (Atomic::xchg(1, &vm_created) == 1) {
3920     return JNI_EEXIST;   // already created, or create attempt in progress
3921   }
3922   if (Atomic::xchg(0, &safe_to_recreate_vm) == 0) {
3923     return JNI_ERR;  // someone tried and failed and retry not allowed.


< prev index next >