src/share/vm/prims/jni.cpp
Index Unified diffs Context diffs Sdiffs Wdiffs Patch New Old Previous File Next File hotspot-npg Sdiff src/share/vm/prims

src/share/vm/prims/jni.cpp

Print this page




2986 
2987   // A jfieldID for a static field is a JNIid specifying the field holder and the offset within the Klass*
2988   JNIid* id = InstanceKlass::cast(fd.field_holder())->jni_id_for(fd.offset());
2989   debug_only(id->set_is_static_field_id();)
2990 
2991   debug_only(id->verify(fd.field_holder()));
2992 
2993   ret = jfieldIDWorkaround::to_static_jfieldID(id);
2994   return ret;
2995 JNI_END
2996 
2997 
2998 JNI_ENTRY(jobject, jni_GetStaticObjectField(JNIEnv *env, jclass clazz, jfieldID fieldID))
2999   JNIWrapper("GetStaticObjectField");
3000 #ifndef USDT2
3001   DTRACE_PROBE3(hotspot_jni, GetStaticObjectField__entry, env, clazz, fieldID);
3002 #else /* USDT2 */
3003   HOTSPOT_JNI_GETSTATICOBJECTFIELD_ENTRY(
3004                                          env, clazz, (uintptr_t) fieldID);
3005 #endif /* USDT2 */
3006 #ifndef JNICHECK_KERNEL
3007   DEBUG_ONLY(Klass* param_k = jniCheck::validate_class(thread, clazz);)
3008 #endif // JNICHECK_KERNEL
3009   JNIid* id = jfieldIDWorkaround::from_static_jfieldID(fieldID);
3010   assert(id->is_static_field_id(), "invalid static field id");
3011   // Keep JVMTI addition small and only check enabled flag here.
3012   // jni_GetField_probe() assumes that is okay to create handles.
3013   if (JvmtiExport::should_post_field_access()) {
3014     JvmtiExport::jni_GetField_probe(thread, NULL, NULL, id->holder(), fieldID, true);
3015   }
3016   jobject ret = JNIHandles::make_local(id->holder()->java_mirror()->obj_field(id->offset()));
3017 #ifndef USDT2
3018   DTRACE_PROBE1(hotspot_jni, GetStaticObjectField__return, ret);
3019 #else /* USDT2 */
3020   HOTSPOT_JNI_GETSTATICOBJECTFIELD_RETURN(
3021                                           ret);
3022 #endif /* USDT2 */
3023   return ret;
3024 JNI_END
3025 
3026 #ifndef USDT2
3027 #define DEFINE_GETSTATICFIELD(Return,Fieldname,Result) \
3028 \


3934                             HOTSPOT_JNI_SETLONGARRAYREGION_RETURN())
3935 DEFINE_SETSCALARARRAYREGION(T_FLOAT,   jfloat,   Float,   float
3936                             , HOTSPOT_JNI_SETFLOATARRAYREGION_ENTRY(env, array, start, len, (float *) buf),
3937                             HOTSPOT_JNI_SETFLOATARRAYREGION_RETURN())
3938 DEFINE_SETSCALARARRAYREGION(T_DOUBLE,  jdouble,  Double,  double
3939                             , HOTSPOT_JNI_SETDOUBLEARRAYREGION_ENTRY(env, array, start, len, (double *) buf),
3940                             HOTSPOT_JNI_SETDOUBLEARRAYREGION_RETURN())
3941 #endif /* USDT2 */
3942 
3943 
3944 //
3945 // Interception of natives
3946 //
3947 
3948 // The RegisterNatives call being attempted tried to register with a method that
3949 // is not native.  Ask JVM TI what prefixes have been specified.  Then check
3950 // to see if the native method is now wrapped with the prefixes.  See the
3951 // SetNativeMethodPrefix(es) functions in the JVM TI Spec for details.
3952 static Method* find_prefixed_native(KlassHandle k,
3953                                       Symbol* name, Symbol* signature, TRAPS) {

3954   ResourceMark rm(THREAD);
3955   Method* method;
3956   int name_len = name->utf8_length();
3957   char* name_str = name->as_utf8();
3958   int prefix_count;
3959   char** prefixes = JvmtiExport::get_all_native_method_prefixes(&prefix_count);
3960   for (int i = 0; i < prefix_count; i++) {
3961     char* prefix = prefixes[i];
3962     int prefix_len = (int)strlen(prefix);
3963 
3964     // try adding this prefix to the method name and see if it matches another method name
3965     int trial_len = name_len + prefix_len;
3966     char* trial_name_str = NEW_RESOURCE_ARRAY(char, trial_len + 1);
3967     strcpy(trial_name_str, prefix);
3968     strcat(trial_name_str, name_str);
3969     TempNewSymbol trial_name = SymbolTable::probe(trial_name_str, trial_len);
3970     if (trial_name == NULL) {
3971       continue; // no such symbol, so this prefix wasn't used, try the next prefix
3972     }
3973     method = Klass::cast(k())->lookup_method(trial_name, signature);
3974     if (method == NULL) {
3975       continue; // signature doesn't match, try the next prefix
3976     }
3977     if (method->is_native()) {
3978       method->set_is_prefixed_native();
3979       return method; // wahoo, we found a prefixed version of the method, return it
3980     }
3981     // found as non-native, so prefix is good, add it, probably just need more prefixes
3982     name_len = trial_len;
3983     name_str = trial_name_str;
3984   }

3985   return NULL; // not found
3986 }
3987 
3988 static bool register_native(KlassHandle k, Symbol* name, Symbol* signature, address entry, TRAPS) {
3989   Method* method = Klass::cast(k())->lookup_method(name, signature);
3990   if (method == NULL) {
3991     ResourceMark rm;
3992     stringStream st;
3993     st.print("Method %s name or signature does not match",
3994              Method::name_and_sig_as_C_string(Klass::cast(k()), name, signature));
3995     THROW_MSG_(vmSymbols::java_lang_NoSuchMethodError(), st.as_string(), false);
3996   }
3997   if (!method->is_native()) {
3998     // trying to register to a non-native method, see if a JVM TI agent has added prefix(es)
3999     method = find_prefixed_native(k, name, signature, THREAD);
4000     if (method == NULL) {
4001       ResourceMark rm;
4002       stringStream st;
4003       st.print("Method %s is not declared as native",
4004                Method::name_and_sig_as_C_string(Klass::cast(k()), name, signature));


4958     if (func != (address)-1) {
4959       jni_NativeInterface.GetIntField = (GetIntField_t)func;
4960     }
4961     func = JNI_FastGetField::generate_fast_get_long_field();
4962     if (func != (address)-1) {
4963       jni_NativeInterface.GetLongField = (GetLongField_t)func;
4964     }
4965     func = JNI_FastGetField::generate_fast_get_float_field();
4966     if (func != (address)-1) {
4967       jni_NativeInterface.GetFloatField = (GetFloatField_t)func;
4968     }
4969     func = JNI_FastGetField::generate_fast_get_double_field();
4970     if (func != (address)-1) {
4971       jni_NativeInterface.GetDoubleField = (GetDoubleField_t)func;
4972     }
4973   }
4974 }
4975 
4976 // Returns the function structure
4977 struct JNINativeInterface_* jni_functions() {
4978 #ifndef JNICHECK_KERNEL
4979   if (CheckJNICalls) return jni_functions_check();
4980 #else  // JNICHECK_KERNEL
4981   if (CheckJNICalls) warning("-Xcheck:jni is not supported in kernel vm.");
4982 #endif // JNICHECK_KERNEL
4983   return &jni_NativeInterface;
4984 }
4985 
4986 // Returns the function structure
4987 struct JNINativeInterface_* jni_functions_nocheck() {
4988   return &jni_NativeInterface;
4989 }
4990 
4991 
4992 // Invocation API
4993 
4994 
4995 // Forward declaration
4996 extern const struct JNIInvokeInterface_ jni_InvokeInterface;
4997 
4998 // Global invocation API vars
4999 volatile jint vm_created = 0;
5000 // Indicate whether it is safe to recreate VM
5001 volatile jint safe_to_recreate_vm = 1;
5002 struct JavaVM_ main_vm = {&jni_InvokeInterface};




2986 
2987   // A jfieldID for a static field is a JNIid specifying the field holder and the offset within the Klass*
2988   JNIid* id = InstanceKlass::cast(fd.field_holder())->jni_id_for(fd.offset());
2989   debug_only(id->set_is_static_field_id();)
2990 
2991   debug_only(id->verify(fd.field_holder()));
2992 
2993   ret = jfieldIDWorkaround::to_static_jfieldID(id);
2994   return ret;
2995 JNI_END
2996 
2997 
2998 JNI_ENTRY(jobject, jni_GetStaticObjectField(JNIEnv *env, jclass clazz, jfieldID fieldID))
2999   JNIWrapper("GetStaticObjectField");
3000 #ifndef USDT2
3001   DTRACE_PROBE3(hotspot_jni, GetStaticObjectField__entry, env, clazz, fieldID);
3002 #else /* USDT2 */
3003   HOTSPOT_JNI_GETSTATICOBJECTFIELD_ENTRY(
3004                                          env, clazz, (uintptr_t) fieldID);
3005 #endif /* USDT2 */
3006 #if INCLUDE_JNI_CHECK
3007   DEBUG_ONLY(Klass* param_k = jniCheck::validate_class(thread, clazz);)
3008 #endif // INCLUDE_JNI_CHECK
3009   JNIid* id = jfieldIDWorkaround::from_static_jfieldID(fieldID);
3010   assert(id->is_static_field_id(), "invalid static field id");
3011   // Keep JVMTI addition small and only check enabled flag here.
3012   // jni_GetField_probe() assumes that is okay to create handles.
3013   if (JvmtiExport::should_post_field_access()) {
3014     JvmtiExport::jni_GetField_probe(thread, NULL, NULL, id->holder(), fieldID, true);
3015   }
3016   jobject ret = JNIHandles::make_local(id->holder()->java_mirror()->obj_field(id->offset()));
3017 #ifndef USDT2
3018   DTRACE_PROBE1(hotspot_jni, GetStaticObjectField__return, ret);
3019 #else /* USDT2 */
3020   HOTSPOT_JNI_GETSTATICOBJECTFIELD_RETURN(
3021                                           ret);
3022 #endif /* USDT2 */
3023   return ret;
3024 JNI_END
3025 
3026 #ifndef USDT2
3027 #define DEFINE_GETSTATICFIELD(Return,Fieldname,Result) \
3028 \


3934                             HOTSPOT_JNI_SETLONGARRAYREGION_RETURN())
3935 DEFINE_SETSCALARARRAYREGION(T_FLOAT,   jfloat,   Float,   float
3936                             , HOTSPOT_JNI_SETFLOATARRAYREGION_ENTRY(env, array, start, len, (float *) buf),
3937                             HOTSPOT_JNI_SETFLOATARRAYREGION_RETURN())
3938 DEFINE_SETSCALARARRAYREGION(T_DOUBLE,  jdouble,  Double,  double
3939                             , HOTSPOT_JNI_SETDOUBLEARRAYREGION_ENTRY(env, array, start, len, (double *) buf),
3940                             HOTSPOT_JNI_SETDOUBLEARRAYREGION_RETURN())
3941 #endif /* USDT2 */
3942 
3943 
3944 //
3945 // Interception of natives
3946 //
3947 
3948 // The RegisterNatives call being attempted tried to register with a method that
3949 // is not native.  Ask JVM TI what prefixes have been specified.  Then check
3950 // to see if the native method is now wrapped with the prefixes.  See the
3951 // SetNativeMethodPrefix(es) functions in the JVM TI Spec for details.
3952 static Method* find_prefixed_native(KlassHandle k,
3953                                       Symbol* name, Symbol* signature, TRAPS) {
3954 #if INCLUDE_JVMTI
3955   ResourceMark rm(THREAD);
3956   Method* method;
3957   int name_len = name->utf8_length();
3958   char* name_str = name->as_utf8();
3959   int prefix_count;
3960   char** prefixes = JvmtiExport::get_all_native_method_prefixes(&prefix_count);
3961   for (int i = 0; i < prefix_count; i++) {
3962     char* prefix = prefixes[i];
3963     int prefix_len = (int)strlen(prefix);
3964 
3965     // try adding this prefix to the method name and see if it matches another method name
3966     int trial_len = name_len + prefix_len;
3967     char* trial_name_str = NEW_RESOURCE_ARRAY(char, trial_len + 1);
3968     strcpy(trial_name_str, prefix);
3969     strcat(trial_name_str, name_str);
3970     TempNewSymbol trial_name = SymbolTable::probe(trial_name_str, trial_len);
3971     if (trial_name == NULL) {
3972       continue; // no such symbol, so this prefix wasn't used, try the next prefix
3973     }
3974     method = Klass::cast(k())->lookup_method(trial_name, signature);
3975     if (method == NULL) {
3976       continue; // signature doesn't match, try the next prefix
3977     }
3978     if (method->is_native()) {
3979       method->set_is_prefixed_native();
3980       return method; // wahoo, we found a prefixed version of the method, return it
3981     }
3982     // found as non-native, so prefix is good, add it, probably just need more prefixes
3983     name_len = trial_len;
3984     name_str = trial_name_str;
3985   }
3986 #endif // INCLUDE_JVMTI
3987   return NULL; // not found
3988 }
3989 
3990 static bool register_native(KlassHandle k, Symbol* name, Symbol* signature, address entry, TRAPS) {
3991   Method* method = Klass::cast(k())->lookup_method(name, signature);
3992   if (method == NULL) {
3993     ResourceMark rm;
3994     stringStream st;
3995     st.print("Method %s name or signature does not match",
3996              Method::name_and_sig_as_C_string(Klass::cast(k()), name, signature));
3997     THROW_MSG_(vmSymbols::java_lang_NoSuchMethodError(), st.as_string(), false);
3998   }
3999   if (!method->is_native()) {
4000     // trying to register to a non-native method, see if a JVM TI agent has added prefix(es)
4001     method = find_prefixed_native(k, name, signature, THREAD);
4002     if (method == NULL) {
4003       ResourceMark rm;
4004       stringStream st;
4005       st.print("Method %s is not declared as native",
4006                Method::name_and_sig_as_C_string(Klass::cast(k()), name, signature));


4960     if (func != (address)-1) {
4961       jni_NativeInterface.GetIntField = (GetIntField_t)func;
4962     }
4963     func = JNI_FastGetField::generate_fast_get_long_field();
4964     if (func != (address)-1) {
4965       jni_NativeInterface.GetLongField = (GetLongField_t)func;
4966     }
4967     func = JNI_FastGetField::generate_fast_get_float_field();
4968     if (func != (address)-1) {
4969       jni_NativeInterface.GetFloatField = (GetFloatField_t)func;
4970     }
4971     func = JNI_FastGetField::generate_fast_get_double_field();
4972     if (func != (address)-1) {
4973       jni_NativeInterface.GetDoubleField = (GetDoubleField_t)func;
4974     }
4975   }
4976 }
4977 
4978 // Returns the function structure
4979 struct JNINativeInterface_* jni_functions() {
4980 #if INCLUDE_JNI_CHECK
4981   if (CheckJNICalls) return jni_functions_check();
4982 #endif // INCLUDE_JNI_CHECK


4983   return &jni_NativeInterface;
4984 }
4985 
4986 // Returns the function structure
4987 struct JNINativeInterface_* jni_functions_nocheck() {
4988   return &jni_NativeInterface;
4989 }
4990 
4991 
4992 // Invocation API
4993 
4994 
4995 // Forward declaration
4996 extern const struct JNIInvokeInterface_ jni_InvokeInterface;
4997 
4998 // Global invocation API vars
4999 volatile jint vm_created = 0;
5000 // Indicate whether it is safe to recreate VM
5001 volatile jint safe_to_recreate_vm = 1;
5002 struct JavaVM_ main_vm = {&jni_InvokeInterface};


src/share/vm/prims/jni.cpp
Index Unified diffs Context diffs Sdiffs Wdiffs Patch New Old Previous File Next File