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