src/hotspot/share/prims/nativeLookup.cpp
changeset 57600 3d44a84147cc
parent 54847 59ea39bb2809
child 57710 05ff6e27de45
equal deleted inserted replaced
57599:98dfaf0f9442 57600:3d44a84147cc
   136 #if INCLUDE_JFR
   136 #if INCLUDE_JFR
   137   { CC"Java_jdk_jfr_internal_JVM_registerNatives",                 NULL, FN_PTR(jfr_register_natives)            },
   137   { CC"Java_jdk_jfr_internal_JVM_registerNatives",                 NULL, FN_PTR(jfr_register_natives)            },
   138 #endif
   138 #endif
   139 };
   139 };
   140 
   140 
   141 static address lookup_special_native(char* jni_name) {
   141 static address lookup_special_native(const char* jni_name) {
   142   int count = sizeof(lookup_special_native_methods) / sizeof(JNINativeMethod);
   142   int count = sizeof(lookup_special_native_methods) / sizeof(JNINativeMethod);
   143   for (int i = 0; i < count; i++) {
   143   for (int i = 0; i < count; i++) {
   144     // NB: To ignore the jni prefix and jni postfix strstr is used matching.
   144     // NB: To ignore the jni prefix and jni postfix strstr is used matching.
   145     if (strstr(jni_name, lookup_special_native_methods[i].name) != NULL) {
   145     if (strstr(jni_name, lookup_special_native_methods[i].name) != NULL) {
   146       return CAST_FROM_FN_PTR(address, lookup_special_native_methods[i].fnPtr);
   146       return CAST_FROM_FN_PTR(address, lookup_special_native_methods[i].fnPtr);
   149   return NULL;
   149   return NULL;
   150 }
   150 }
   151 
   151 
   152 address NativeLookup::lookup_style(const methodHandle& method, char* pure_name, const char* long_name, int args_size, bool os_style, bool& in_base_library, TRAPS) {
   152 address NativeLookup::lookup_style(const methodHandle& method, char* pure_name, const char* long_name, int args_size, bool os_style, bool& in_base_library, TRAPS) {
   153   address entry;
   153   address entry;
   154   // Compute complete JNI name for style
   154   const char* jni_name = compute_complete_jni_name(pure_name, long_name, args_size, os_style);
   155   stringStream st;
   155 
   156   if (os_style) os::print_jni_name_prefix_on(&st, args_size);
       
   157   st.print_raw(pure_name);
       
   158   st.print_raw(long_name);
       
   159   if (os_style) os::print_jni_name_suffix_on(&st, args_size);
       
   160   char* jni_name = st.as_string();
       
   161 
   156 
   162   // If the loader is null we have a system class, so we attempt a lookup in
   157   // If the loader is null we have a system class, so we attempt a lookup in
   163   // the native Java library. This takes care of any bootstrapping problems.
   158   // the native Java library. This takes care of any bootstrapping problems.
   164   // Note: It is critical for bootstrapping that Java_java_lang_ClassLoader_00024NativeLibrary_find
   159   // Note: It is critical for bootstrapping that Java_java_lang_ClassLoader_00024NativeLibrary_find
   165   // gets found the first time around - otherwise an infinite loop can occure. This is
   160   // gets found the first time around - otherwise an infinite loop can occure. This is
   203   }
   198   }
   204 
   199 
   205   return entry;
   200   return entry;
   206 }
   201 }
   207 
   202 
   208 
   203 const char* NativeLookup::compute_complete_jni_name(const char* pure_name, const char* long_name, int args_size, bool os_style) {
   209 address NativeLookup::lookup_critical_style(const methodHandle& method, char* pure_name, const char* long_name, int args_size, bool os_style) {
   204   stringStream st;
   210   if (!method->has_native_function()) {
   205   if (os_style) {
   211     return NULL;
   206     os::print_jni_name_prefix_on(&st, args_size);
   212   }
   207   }
   213 
   208 
   214   address current_entry = method->native_function();
   209   st.print_raw(pure_name);
   215 
   210   st.print_raw(long_name);
   216   char dll_name[JVM_MAXPATHLEN];
   211   if (os_style) {
   217   int offset;
   212     os::print_jni_name_suffix_on(&st, args_size);
   218   if (os::dll_address_to_library_name(current_entry, dll_name, sizeof(dll_name), &offset)) {
   213   }
   219     char ebuf[32];
   214 
   220     void* dll = os::dll_load(dll_name, ebuf, sizeof(ebuf));
   215   return st.as_string();
   221     if (dll != NULL) {
   216 }
   222       // Compute complete JNI name for style
   217 
   223       stringStream st;
   218 address NativeLookup::lookup_critical_style(void* dll, const char* pure_name, const char* long_name, int args_size, bool os_style) {
   224       if (os_style) os::print_jni_name_prefix_on(&st, args_size);
   219   const char* jni_name = compute_complete_jni_name(pure_name, long_name, args_size, os_style);
   225       st.print_raw(pure_name);
   220   assert(dll != NULL, "dll must be loaded");
   226       st.print_raw(long_name);
   221   return (address)os::dll_lookup(dll, jni_name);
   227       if (os_style) os::print_jni_name_suffix_on(&st, args_size);
   222 }
   228       char* jni_name = st.as_string();
       
   229       address critical_entry = (address)os::dll_lookup(dll, jni_name);
       
   230       // Close the handle to avoid keeping the library alive if the native method holder is unloaded.
       
   231       // This is fine because the library is still kept alive by JNI (see JVM_LoadLibrary). As soon
       
   232       // as the holder class and the library are unloaded (see JVM_UnloadLibrary), the native wrapper
       
   233       // that calls 'critical_entry' becomes unreachable and is unloaded as well.
       
   234       os::dll_unload(dll);
       
   235       return critical_entry;
       
   236     }
       
   237   }
       
   238 
       
   239   return NULL;
       
   240 }
       
   241 
       
   242 
   223 
   243 // Check all the formats of native implementation name to see if there is one
   224 // Check all the formats of native implementation name to see if there is one
   244 // for the specified method.
   225 // for the specified method.
   245 address NativeLookup::lookup_entry(const methodHandle& method, bool& in_base_library, TRAPS) {
   226 address NativeLookup::lookup_entry(const methodHandle& method, bool& in_base_library, TRAPS) {
   246   address entry = NULL;
   227   address entry = NULL;
   284     // Only static non-synchronized methods are allowed
   265     // Only static non-synchronized methods are allowed
   285     return NULL;
   266     return NULL;
   286   }
   267   }
   287 
   268 
   288   ResourceMark rm;
   269   ResourceMark rm;
   289   address entry = NULL;
       
   290 
   270 
   291   Symbol* signature = method->signature();
   271   Symbol* signature = method->signature();
   292   for (int end = 0; end < signature->utf8_length(); end++) {
   272   for (int end = 0; end < signature->utf8_length(); end++) {
   293     if (signature->char_at(end) == 'L') {
   273     if (signature->char_at(end) == 'L') {
   294       // Don't allow object types
   274       // Don't allow object types
   295       return NULL;
   275       return NULL;
   296     }
   276     }
   297   }
   277   }
   298 
   278 
   299   // Compute critical name
       
   300   char* critical_name = critical_jni_name(method);
       
   301 
       
   302   // Compute argument size
   279   // Compute argument size
   303   int args_size = method->size_of_parameters();
   280   int args_size = method->size_of_parameters();
   304   for (SignatureStream ss(signature); !ss.at_return_type(); ss.next()) {
   281   for (SignatureStream ss(signature); !ss.at_return_type(); ss.next()) {
   305     if (ss.is_array()) {
   282     if (ss.is_array()) {
   306       args_size += T_INT_size; // array length parameter
   283       args_size += T_INT_size; // array length parameter
   307     }
   284     }
   308   }
   285   }
   309 
   286 
       
   287   void* dll = dll_load(method);
       
   288   address entry = NULL;
       
   289 
       
   290   if (dll != NULL) {
       
   291     entry = lookup_critical_style(dll, method, args_size);
       
   292     // Close the handle to avoid keeping the library alive if the native method holder is unloaded.
       
   293     // This is fine because the library is still kept alive by JNI (see JVM_LoadLibrary). As soon
       
   294     // as the holder class and the library are unloaded (see JVM_UnloadLibrary), the native wrapper
       
   295     // that calls 'critical_entry' becomes unreachable and is unloaded as well.
       
   296     os::dll_unload(dll);
       
   297   }
       
   298 
       
   299   return entry; // NULL indicates not found
       
   300 }
       
   301 
       
   302 void* NativeLookup::dll_load(const methodHandle& method) {
       
   303   if (method->has_native_function()) {
       
   304 
       
   305     address current_entry = method->native_function();
       
   306 
       
   307     char dll_name[JVM_MAXPATHLEN];
       
   308     int offset;
       
   309     if (os::dll_address_to_library_name(current_entry, dll_name, sizeof(dll_name), &offset)) {
       
   310       char ebuf[32];
       
   311       return os::dll_load(dll_name, ebuf, sizeof(ebuf));
       
   312     }
       
   313   }
       
   314 
       
   315   return NULL;
       
   316 }
       
   317 
       
   318 address NativeLookup::lookup_critical_style(void* dll, const methodHandle& method, int args_size) {
       
   319   address entry = NULL;
       
   320   const char* critical_name = critical_jni_name(method);
       
   321 
   310   // 1) Try JNI short style
   322   // 1) Try JNI short style
   311   entry = lookup_critical_style(method, critical_name, "",        args_size, true);
   323   entry = lookup_critical_style(dll, critical_name, "",        args_size, true);
   312   if (entry != NULL) return entry;
   324   if (entry != NULL) {
   313 
   325     return entry;
   314   // Compute long name
   326   }
   315   char* long_name = long_jni_name(method);
   327 
       
   328   const char* long_name = long_jni_name(method);
   316 
   329 
   317   // 2) Try JNI long style
   330   // 2) Try JNI long style
   318   entry = lookup_critical_style(method, critical_name, long_name, args_size, true);
   331   entry = lookup_critical_style(dll, critical_name, long_name, args_size, true);
   319   if (entry != NULL) return entry;
   332   if (entry != NULL) {
       
   333     return entry;
       
   334   }
   320 
   335 
   321   // 3) Try JNI short style without os prefix/suffix
   336   // 3) Try JNI short style without os prefix/suffix
   322   entry = lookup_critical_style(method, critical_name, "",        args_size, false);
   337   entry = lookup_critical_style(dll, critical_name, "",        args_size, false);
   323   if (entry != NULL) return entry;
   338   if (entry != NULL) {
       
   339     return entry;
       
   340   }
   324 
   341 
   325   // 4) Try JNI long style without os prefix/suffix
   342   // 4) Try JNI long style without os prefix/suffix
   326   entry = lookup_critical_style(method, critical_name, long_name, args_size, false);
   343   return lookup_critical_style(dll, critical_name, long_name, args_size, false);
   327 
       
   328   return entry; // NULL indicates not found
       
   329 }
   344 }
   330 
   345 
   331 // Check if there are any JVM TI prefixes which have been applied to the native method name.
   346 // Check if there are any JVM TI prefixes which have been applied to the native method name.
   332 // If any are found, remove them before attemping the look up of the
   347 // If any are found, remove them before attemping the look up of the
   333 // native implementation again.
   348 // native implementation again.