static address lookup_special_native(constchar* jni_name) { int count = sizeof(lookup_special_native_methods) / sizeof(JNINativeMethod); for (int i = 0; i < count; i++) { // NB: To ignore the jni prefix and jni postfix strstr is used matching. if (strstr(jni_name, lookup_special_native_methods[i].name) != NULL) { return CAST_FROM_FN_PTR(address, lookup_special_native_methods[i].fnPtr);
}
} return NULL;
}
// If the loader is null we have a system class, so we attempt a lookup in // the native Java library. This takes care of any bootstrapping problems. // Note: It is critical for bootstrapping that Java_java_lang_ClassLoader_findNative // gets found the first time around - otherwise an infinite loop can occur. This is // another VM/library dependency
Handle loader(THREAD, method->method_holder()->class_loader()); if (loader.is_null()) {
entry = lookup_special_native(jni_name); if (entry == NULL) {
entry = (address) os::dll_lookup(os::native_java_library(), jni_name);
} if (entry != NULL) { return entry;
}
}
// Otherwise call static method findNative in ClassLoader
Klass* klass = vmClasses::ClassLoader_klass();
Handle name_arg = java_lang_String::create_from_str(jni_name, CHECK_NULL);
if (entry == NULL) { // findNative didn't find it, if there are any agent libraries look in them
AgentLibrary* agent; for (agent = Arguments::agents(); agent != NULL; agent = agent->next()) {
entry = (address) os::dll_lookup(agent->os_lib(), jni_name); if (entry != NULL) { return entry;
}
}
}
return entry;
}
constchar* NativeLookup::compute_complete_jni_name(constchar* pure_name, constchar* long_name, int args_size, bool os_style) {
stringStream st; if (os_style) {
os::print_jni_name_prefix_on(&st, args_size);
}
st.print_raw(pure_name);
st.print_raw(long_name); if (os_style) {
os::print_jni_name_suffix_on(&st, args_size);
}
return st.as_string();
}
// Check all the formats of native implementation name to see if there is one // for the specified method.
address NativeLookup::lookup_entry(const methodHandle& method, TRAPS) {
address entry = NULL; // Compute pure name char* pure_name = pure_jni_name(method); if (pure_name == NULL) { // JNI name mapping rejected this method so return // NULL to indicate UnsatisfiedLinkError should be thrown. return NULL;
}
// Compute argument size int args_size = 1// JNIEnv
+ (method->is_static() ? 1 : 0) // class for static methods
+ method->size_of_parameters(); // actual parameters
// 1) Try JNI short style
entry = lookup_style(method, pure_name, "", args_size, true, CHECK_NULL); if (entry != NULL) return entry;
// Compute long name char* long_name = long_jni_name(method); if (long_name == NULL) { // JNI name mapping rejected this method so return // NULL to indicate UnsatisfiedLinkError should be thrown. return NULL;
}
// 2) Try JNI long style
entry = lookup_style(method, pure_name, long_name, args_size, true, CHECK_NULL); if (entry != NULL) return entry;
// 3) Try JNI short style without os prefix/suffix
entry = lookup_style(method, pure_name, "", args_size, false, CHECK_NULL); if (entry != NULL) return entry;
// 4) Try JNI long style without os prefix/suffix
entry = lookup_style(method, pure_name, long_name, args_size, false, CHECK_NULL);
return entry; // NULL indicates not found
}
// Check if there are any JVM TI prefixes which have been applied to the native method name. // If any are found, remove them before attempting the look up of the // native implementation again. // See SetNativeMethodPrefix in the JVM TI Spec for more details.
address NativeLookup::lookup_entry_prefixed(const methodHandle& method, TRAPS) { #if INCLUDE_JVMTI
ResourceMark rm(THREAD);
int prefix_count; char** prefixes = JvmtiExport::get_all_native_method_prefixes(&prefix_count); char* in_name = method->name()->as_C_string(); char* wrapper_name = in_name; // last applied prefix will be first -- go backwards for (int i = prefix_count-1; i >= 0; i--) { char* prefix = prefixes[i];
size_t prefix_len = strlen(prefix); if (strncmp(prefix, wrapper_name, prefix_len) == 0) { // has this prefix remove it
wrapper_name += prefix_len;
}
} if (wrapper_name != in_name) { // we have a name for a wrapping method int wrapper_name_len = (int)strlen(wrapper_name);
TempNewSymbol wrapper_symbol = SymbolTable::probe(wrapper_name, wrapper_name_len); if (wrapper_symbol != NULL) {
Klass* k = method->method_holder();
Method* wrapper_method = k->lookup_method(wrapper_symbol, method->signature()); if (wrapper_method != NULL && !wrapper_method->is_native()) { // we found a wrapper method, use its native entry
method->set_is_prefixed_native(); return lookup_entry(methodHandle(THREAD, wrapper_method), THREAD);
}
}
} #endif// INCLUDE_JVMTI return NULL;
}
entry = lookup_entry(method, CHECK_NULL); if (entry != NULL) return entry;
// standard native method resolution has failed. Check if there are any // JVM TI prefixes which have been applied to the native method name.
entry = lookup_entry_prefixed(method, CHECK_NULL); if (entry != NULL) return entry;
// Native function not found, throw UnsatisfiedLinkError
stringStream ss;
ss.print("'");
method->print_external_name(&ss);
ss.print("'");
THROW_MSG_0(vmSymbols::java_lang_UnsatisfiedLinkError(), ss.as_string());
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.