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;
|