< prev index next >

src/hotspot/share/prims/jni.cpp

Print this page




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


3901 #if defined(ZERO) && defined(ASSERT)
3902   {
3903     jint a = 0xcafebabe;
3904     jint b = Atomic::xchg((jint) 0xdeadbeef, &a);
3905     void *c = &a;
3906     void *d = Atomic::xchg(&b, &c);
3907     assert(a == (jint) 0xdeadbeef && b == (jint) 0xcafebabe, "Atomic::xchg() works");
3908     assert(c == &b && d == &a, "Atomic::xchg() works");
3909   }
3910 #endif // ZERO && ASSERT
3911 
3912   // At the moment it's only possible to have one Java VM,
3913   // since some of the runtime state is in global variables.
3914 
3915   // We cannot use our mutex locks here, since they only work on
3916   // Threads. We do an atomic compare and exchange to ensure only
3917   // one thread can call this method at a time
3918 
3919   // We use Atomic::xchg rather than Atomic::add/dec since on some platforms
3920   // the add/dec implementations are dependent on whether we are running
3921   // on a multiprocessor, and at this stage of initialization the os::is_MP
3922   // function used to determine this will always return false. Atomic::xchg
3923   // does not have this problem.
3924   if (Atomic::xchg(1, &vm_created) == 1) {
3925     return JNI_EEXIST;   // already created, or create attempt in progress
3926   }
3927   if (Atomic::xchg(0, &safe_to_recreate_vm) == 0) {
3928     return JNI_ERR;  // someone tried and failed and retry not allowed.
3929   }
3930 
3931   assert(vm_created == 1, "vm_created is true during the creation");
3932 
3933   /**
3934    * Certain errors during initialization are recoverable and do not
3935    * prevent this method from being called again at a later time
3936    * (perhaps with different arguments).  However, at a certain
3937    * point during initialization if an error occurs we cannot allow
3938    * this function to be called again (or it will crash).  In those
3939    * situations, the 'canTryAgain' flag is set to false, which atomically
3940    * sets safe_to_recreate_vm to 1, such that any new call to
3941    * JNI_CreateJavaVM will immediately fail using the above logic.
3942    */
3943   bool can_try_again = true;




3762 
3763 
3764 // For jvmti use to modify jni function table.
3765 // Java threads in native contiues to run until it is transitioned
3766 // to VM at safepoint. Before the transition or before it is blocked
3767 // for safepoint it may access jni function table. VM could crash if
3768 // any java thread access the jni function table in the middle of memcpy.
3769 // To avoid this each function pointers are copied automically.
3770 void copy_jni_function_table(const struct JNINativeInterface_ *new_jni_NativeInterface) {
3771   assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint");
3772   intptr_t *a = (intptr_t *) jni_functions();
3773   intptr_t *b = (intptr_t *) new_jni_NativeInterface;
3774   for (uint i=0; i <  sizeof(struct JNINativeInterface_)/sizeof(void *); i++) {
3775     Atomic::store(*b++, a++);
3776   }
3777 }
3778 
3779 void quicken_jni_functions() {
3780   // Replace Get<Primitive>Field with fast versions
3781   if (UseFastJNIAccessors && !JvmtiExport::can_post_field_access()
3782       && !VerifyJNIFields && !CountJNICalls && !CheckJNICalls) {






3783     address func;
3784     func = JNI_FastGetField::generate_fast_get_boolean_field();
3785     if (func != (address)-1) {
3786       jni_NativeInterface.GetBooleanField = (GetBooleanField_t)func;
3787     }
3788     func = JNI_FastGetField::generate_fast_get_byte_field();
3789     if (func != (address)-1) {
3790       jni_NativeInterface.GetByteField = (GetByteField_t)func;
3791     }
3792     func = JNI_FastGetField::generate_fast_get_char_field();
3793     if (func != (address)-1) {
3794       jni_NativeInterface.GetCharField = (GetCharField_t)func;
3795     }
3796     func = JNI_FastGetField::generate_fast_get_short_field();
3797     if (func != (address)-1) {
3798       jni_NativeInterface.GetShortField = (GetShortField_t)func;
3799     }
3800     func = JNI_FastGetField::generate_fast_get_int_field();
3801     if (func != (address)-1) {
3802       jni_NativeInterface.GetIntField = (GetIntField_t)func;


3895 #if defined(ZERO) && defined(ASSERT)
3896   {
3897     jint a = 0xcafebabe;
3898     jint b = Atomic::xchg((jint) 0xdeadbeef, &a);
3899     void *c = &a;
3900     void *d = Atomic::xchg(&b, &c);
3901     assert(a == (jint) 0xdeadbeef && b == (jint) 0xcafebabe, "Atomic::xchg() works");
3902     assert(c == &b && d == &a, "Atomic::xchg() works");
3903   }
3904 #endif // ZERO && ASSERT
3905 
3906   // At the moment it's only possible to have one Java VM,
3907   // since some of the runtime state is in global variables.
3908 
3909   // We cannot use our mutex locks here, since they only work on
3910   // Threads. We do an atomic compare and exchange to ensure only
3911   // one thread can call this method at a time
3912 
3913   // We use Atomic::xchg rather than Atomic::add/dec since on some platforms
3914   // the add/dec implementations are dependent on whether we are running
3915   // on a multiprocessor Atomic::xchg does not have this problem.


3916   if (Atomic::xchg(1, &vm_created) == 1) {
3917     return JNI_EEXIST;   // already created, or create attempt in progress
3918   }
3919   if (Atomic::xchg(0, &safe_to_recreate_vm) == 0) {
3920     return JNI_ERR;  // someone tried and failed and retry not allowed.
3921   }
3922 
3923   assert(vm_created == 1, "vm_created is true during the creation");
3924 
3925   /**
3926    * Certain errors during initialization are recoverable and do not
3927    * prevent this method from being called again at a later time
3928    * (perhaps with different arguments).  However, at a certain
3929    * point during initialization if an error occurs we cannot allow
3930    * this function to be called again (or it will crash).  In those
3931    * situations, the 'canTryAgain' flag is set to false, which atomically
3932    * sets safe_to_recreate_vm to 1, such that any new call to
3933    * JNI_CreateJavaVM will immediately fail using the above logic.
3934    */
3935   bool can_try_again = true;


< prev index next >