< prev index next >
src/hotspot/share/classfile/systemDictionary.cpp
Print this page
@@ -1935,10 +1935,89 @@
// 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,10 +2053,19 @@
#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 >