--- old/src/hotspot/share/classfile/systemDictionary.cpp 2019-10-17 16:50:36.497955574 +0200 +++ new/src/hotspot/share/classfile/systemDictionary.cpp 2019-10-17 16:50:36.069953452 +0200 @@ -1937,6 +1937,85 @@ 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"); @@ -1976,6 +2055,15 @@ 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(); --- old/src/hotspot/share/classfile/systemDictionary.hpp 2019-10-17 16:50:37.345959779 +0200 +++ new/src/hotspot/share/classfile/systemDictionary.hpp 2019-10-17 16:50:36.925957696 +0200 @@ -218,7 +218,6 @@ \ /*end*/ - class SystemDictionary : AllStatic { friend class BootstrapInfo; friend class VMStructs; @@ -382,7 +381,8 @@ int limit = (int)end_id + 1; resolve_wk_klasses_until((WKID) limit, start_id, THREAD); } - + static bool register_native(Klass* k, Symbol* name, Symbol* signature, address entry, TRAPS); + static Method* find_prefixed_native(Klass* k, Symbol* name, Symbol* signature, TRAPS); public: #define WK_KLASS_DECLARE(name, symbol) \ static InstanceKlass* name() { return check_klass(_well_known_klasses[WK_KLASS_ENUM_NAME(name)]); } \ @@ -630,21 +630,6 @@ // Basic find on classes in the midst of being loaded static Symbol* find_placeholder(Symbol* name, ClassLoaderData* loader_data); - // Add a placeholder for a class being loaded - static void add_placeholder(int index, - Symbol* class_name, - ClassLoaderData* loader_data); - static void remove_placeholder(int index, - Symbol* class_name, - ClassLoaderData* loader_data); - - // Performs cleanups after resolve_super_or_fail. This typically needs - // to be called on failure. - // Won't throw, but can block. - static void resolution_cleanups(Symbol* class_name, - ClassLoaderData* loader_data, - TRAPS); - // Resolve well-known classes so they can be used like SystemDictionary::String_klass() static void resolve_well_known_classes(TRAPS); --- old/src/hotspot/share/prims/jni.cpp 2019-10-17 16:50:38.141963726 +0200 +++ new/src/hotspot/share/prims/jni.cpp 2019-10-17 16:50:37.721961644 +0200 @@ -2909,89 +2909,6 @@ HOTSPOT_JNI_SETDOUBLEARRAYREGION_RETURN()) -// -// Interception of natives -// - -// 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. -static Method* 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 -} - -static bool 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; -} - DT_RETURN_MARK_DECL(RegisterNatives, jint , HOTSPOT_JNI_REGISTERNATIVES_RETURN(_ret_ref)); @@ -3024,8 +2941,8 @@ THROW_MSG_(vmSymbols::java_lang_NoSuchMethodError(), st.as_string(), -1); } - bool res = register_native(k, name, signature, - (address) methods[index].fnPtr, THREAD); + bool res = SystemDictionary::register_native(k, name, signature, + (address) methods[index].fnPtr, THREAD); if (!res) { ret = -1; break; --- old/src/java.base/share/classes/java/lang/Object.java 2019-10-17 16:50:38.949967733 +0200 +++ new/src/java.base/share/classes/java/lang/Object.java 2019-10-17 16:50:38.529965650 +0200 @@ -38,11 +38,6 @@ */ public class Object { - private static native void registerNatives(); - static { - registerNatives(); - } - /** * Constructs a new object. */ --- old/src/java.base/share/native/libjava/Object.c 2019-10-17 16:50:39.733971621 +0200 +++ new/src/java.base/share/native/libjava/Object.c 2019-10-17 16:50:39.309969518 +0200 @@ -39,21 +39,6 @@ #include "java_lang_Object.h" -static JNINativeMethod methods[] = { - {"hashCode", "()I", (void *)&JVM_IHashCode}, - {"wait", "(J)V", (void *)&JVM_MonitorWait}, - {"notify", "()V", (void *)&JVM_MonitorNotify}, - {"notifyAll", "()V", (void *)&JVM_MonitorNotifyAll}, - {"clone", "()Ljava/lang/Object;", (void *)&JVM_Clone}, -}; - -JNIEXPORT void JNICALL -Java_java_lang_Object_registerNatives(JNIEnv *env, jclass cls) -{ - (*env)->RegisterNatives(env, cls, - methods, sizeof(methods)/sizeof(methods[0])); -} - JNIEXPORT jclass JNICALL Java_java_lang_Object_getClass(JNIEnv *env, jobject this) {