< prev index next >

src/hotspot/share/classfile/systemDictionary.cpp

Print this page

        

*** 1935,1944 **** --- 1935,2023 ---- // move the starting value forward to the limit: start_id = limit_id; } + bool SystemDictionary::register_native(Klass* k, Symbol* name, Symbol* signature, address entry, TRAPS) { + Method* method = k->lookup_method(name, signature); + if (method == NULL) { + ResourceMark rm; + stringStream st; + st.print("Method '"); + Method::print_external_name(&st, k, name, signature); + st.print("' name or signature does not match"); + THROW_MSG_(vmSymbols::java_lang_NoSuchMethodError(), st.as_string(), false); + } + if (!method->is_native()) { + // trying to register to a non-native method, see if a JVM TI agent has added prefix(es) + method = find_prefixed_native(k, name, signature, THREAD); + if (method == NULL) { + ResourceMark rm; + stringStream st; + st.print("Method '"); + Method::print_external_name(&st, k, name, signature); + st.print("' is not declared as native"); + THROW_MSG_(vmSymbols::java_lang_NoSuchMethodError(), st.as_string(), false); + } + } + + if (entry != NULL) { + method->set_native_function(entry, + Method::native_bind_event_is_interesting); + } else { + method->clear_native_function(); + } + if (PrintJNIResolving) { + ResourceMark rm(THREAD); + tty->print_cr("[Registering JNI native method %s.%s]", + method->method_holder()->external_name(), + method->name()->as_C_string()); + } + return true; + } + + // The RegisterNatives call being attempted tried to register with a method that + // is not native. Ask JVM TI what prefixes have been specified. Then check + // to see if the native method is now wrapped with the prefixes. See the + // SetNativeMethodPrefix(es) functions in the JVM TI Spec for details. + Method* SystemDictionary::find_prefixed_native(Klass* k, Symbol* name, Symbol* signature, TRAPS) { + #if INCLUDE_JVMTI + ResourceMark rm(THREAD); + Method* method; + int name_len = name->utf8_length(); + char* name_str = name->as_utf8(); + int prefix_count; + char** prefixes = JvmtiExport::get_all_native_method_prefixes(&prefix_count); + for (int i = 0; i < prefix_count; i++) { + char* prefix = prefixes[i]; + int prefix_len = (int)strlen(prefix); + + // try adding this prefix to the method name and see if it matches another method name + int trial_len = name_len + prefix_len; + char* trial_name_str = NEW_RESOURCE_ARRAY(char, trial_len + 1); + strcpy(trial_name_str, prefix); + strcat(trial_name_str, name_str); + TempNewSymbol trial_name = SymbolTable::probe(trial_name_str, trial_len); + if (trial_name == NULL) { + continue; // no such symbol, so this prefix wasn't used, try the next prefix + } + method = k->lookup_method(trial_name, signature); + if (method == NULL) { + continue; // signature doesn't match, try the next prefix + } + if (method->is_native()) { + method->set_is_prefixed_native(); + return method; // wahoo, we found a prefixed version of the method, return it + } + // found as non-native, so prefix is good, add it, probably just need more prefixes + name_len = trial_len; + name_str = trial_name_str; + } + #endif // INCLUDE_JVMTI + return NULL; // not found + } + void SystemDictionary::resolve_well_known_classes(TRAPS) { assert(WK_KLASS(Object_klass) == NULL, "well-known classes should only be initialized once"); // Create the ModuleEntry for java.base. This call needs to be done here, // after vmSymbols::initialize() is called but before any classes are pre-loaded.
*** 1974,1983 **** --- 2053,2071 ---- #endif { resolve_wk_klasses_through(WK_KLASS_ENUM_NAME(Class_klass), scan, CHECK); } + assert(WK_KLASS(Object_klass) != NULL, "well-known classes should now be initialized"); + + // Register native methods of Object + register_native(Object_klass(), vmSymbols::hashCode_name(), vmSymbols::void_int_signature(), (address)&JVM_IHashCode, THREAD); + register_native(Object_klass(), vmSymbols::wait_name(), vmSymbols::long_void_signature(), (address)&JVM_MonitorWait, THREAD); + register_native(Object_klass(), vmSymbols::notify_name(), vmSymbols::void_method_signature(), (address)&JVM_MonitorNotify, THREAD); + register_native(Object_klass(), vmSymbols::notifyAll_name(), vmSymbols::void_method_signature(), (address)&JVM_MonitorNotifyAll, THREAD); + register_native(Object_klass(), vmSymbols::clone_name(), vmSymbols::void_object_signature(), (address)&JVM_Clone, THREAD); + // Calculate offsets for String and Class classes since they are loaded and // can be used after this point. java_lang_String::compute_offsets(); java_lang_Class::compute_offsets();
< prev index next >