comparison src/share/vm/prims/nativeLookup.cpp @ 6152:958bb4b7be49

Merge
author asaha
date Tue, 10 Apr 2012 10:42:34 -0700
parents 2d503de963b3
children 93c71eb28866
comparison
equal deleted inserted replaced
6151:e778c29768e6 6152:958bb4b7be49
1 /* 1 /*
2 * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved. 2 * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 * 4 *
5 * This code is free software; you can redistribute it and/or modify it 5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as 6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. 7 * published by the Free Software Foundation.
89 mangle_name_on(&st, method->name()); 89 mangle_name_on(&st, method->name());
90 return st.as_string(); 90 return st.as_string();
91 } 91 }
92 92
93 93
94 char* NativeLookup::critical_jni_name(methodHandle method) {
95 stringStream st;
96 // Prefix
97 st.print("JavaCritical_");
98 // Klass name
99 mangle_name_on(&st, method->klass_name());
100 st.print("_");
101 // Method name
102 mangle_name_on(&st, method->name());
103 return st.as_string();
104 }
105
106
94 char* NativeLookup::long_jni_name(methodHandle method) { 107 char* NativeLookup::long_jni_name(methodHandle method) {
95 // Signature ignore the wrapping parenteses and the trailing return type 108 // Signature ignore the wrapping parenteses and the trailing return type
96 stringStream st; 109 stringStream st;
97 Symbol* signature = method->signature(); 110 Symbol* signature = method->signature();
98 st.print("__"); 111 st.print("__");
106 119
107 extern "C" { 120 extern "C" {
108 void JNICALL JVM_RegisterUnsafeMethods(JNIEnv *env, jclass unsafecls); 121 void JNICALL JVM_RegisterUnsafeMethods(JNIEnv *env, jclass unsafecls);
109 void JNICALL JVM_RegisterMethodHandleMethods(JNIEnv *env, jclass unsafecls); 122 void JNICALL JVM_RegisterMethodHandleMethods(JNIEnv *env, jclass unsafecls);
110 void JNICALL JVM_RegisterPerfMethods(JNIEnv *env, jclass perfclass); 123 void JNICALL JVM_RegisterPerfMethods(JNIEnv *env, jclass perfclass);
124 void JNICALL JVM_RegisterWhiteBoxMethods(JNIEnv *env, jclass wbclass);
111 } 125 }
112 126
113 #define CC (char*) /* cast a literal from (const char*) */ 127 #define CC (char*) /* cast a literal from (const char*) */
114 #define FN_PTR(f) CAST_FROM_FN_PTR(void*, &f) 128 #define FN_PTR(f) CAST_FROM_FN_PTR(void*, &f)
115 129
118 { CC"Java_java_io_ObjectOutputStream_getPrimitiveFieldValues", NULL, FN_PTR(JVM_GetPrimitiveFieldValues) }, // intercept ObjectOutputStream getPrimitiveFieldValues for faster serialization 132 { CC"Java_java_io_ObjectOutputStream_getPrimitiveFieldValues", NULL, FN_PTR(JVM_GetPrimitiveFieldValues) }, // intercept ObjectOutputStream getPrimitiveFieldValues for faster serialization
119 { CC"Java_java_io_ObjectInputStream_setPrimitiveFieldValues", NULL, FN_PTR(JVM_SetPrimitiveFieldValues) }, // intercept ObjectInputStream setPrimitiveFieldValues for faster serialization 133 { CC"Java_java_io_ObjectInputStream_setPrimitiveFieldValues", NULL, FN_PTR(JVM_SetPrimitiveFieldValues) }, // intercept ObjectInputStream setPrimitiveFieldValues for faster serialization
120 134
121 { CC"Java_sun_misc_Unsafe_registerNatives", NULL, FN_PTR(JVM_RegisterUnsafeMethods) }, 135 { CC"Java_sun_misc_Unsafe_registerNatives", NULL, FN_PTR(JVM_RegisterUnsafeMethods) },
122 { CC"Java_java_lang_invoke_MethodHandleNatives_registerNatives", NULL, FN_PTR(JVM_RegisterMethodHandleMethods) }, 136 { CC"Java_java_lang_invoke_MethodHandleNatives_registerNatives", NULL, FN_PTR(JVM_RegisterMethodHandleMethods) },
123 { CC"Java_sun_misc_Perf_registerNatives", NULL, FN_PTR(JVM_RegisterPerfMethods) } 137 { CC"Java_sun_misc_Perf_registerNatives", NULL, FN_PTR(JVM_RegisterPerfMethods) },
138 { CC"Java_sun_hotspot_WhiteBox_registerNatives", NULL, FN_PTR(JVM_RegisterWhiteBoxMethods) },
124 }; 139 };
125 140
126 static address lookup_special_native(char* jni_name) { 141 static address lookup_special_native(char* jni_name) {
127 int i = !JDK_Version::is_gte_jdk14x_version() ? 0 : 2; // see comment in lookup_special_native_methods 142 int i = !JDK_Version::is_gte_jdk14x_version() ? 0 : 2; // see comment in lookup_special_native_methods
128 int count = sizeof(lookup_special_native_methods) / sizeof(JNINativeMethod); 143 int count = sizeof(lookup_special_native_methods) / sizeof(JNINativeMethod);
191 206
192 return entry; 207 return entry;
193 } 208 }
194 209
195 210
211 address NativeLookup::lookup_critical_style(methodHandle method, char* pure_name, const char* long_name, int args_size, bool os_style) {
212 if (!method->has_native_function()) {
213 return NULL;
214 }
215
216 address current_entry = method->native_function();
217
218 char dll_name[JVM_MAXPATHLEN];
219 int offset;
220 if (os::dll_address_to_library_name(current_entry, dll_name, sizeof(dll_name), &offset)) {
221 char ebuf[32];
222 void* dll = os::dll_load(dll_name, ebuf, sizeof(ebuf));
223 if (dll != NULL) {
224 // Compute complete JNI name for style
225 stringStream st;
226 if (os_style) os::print_jni_name_prefix_on(&st, args_size);
227 st.print_raw(pure_name);
228 st.print_raw(long_name);
229 if (os_style) os::print_jni_name_suffix_on(&st, args_size);
230 char* jni_name = st.as_string();
231 return (address)os::dll_lookup(dll, jni_name);
232 }
233 }
234
235 return NULL;
236 }
237
238
196 // Check all the formats of native implementation name to see if there is one 239 // Check all the formats of native implementation name to see if there is one
197 // for the specified method. 240 // for the specified method.
198 address NativeLookup::lookup_entry(methodHandle method, bool& in_base_library, TRAPS) { 241 address NativeLookup::lookup_entry(methodHandle method, bool& in_base_library, TRAPS) {
199 address entry = NULL; 242 address entry = NULL;
200 in_base_library = false; 243 in_base_library = false;
222 entry = lookup_style(method, pure_name, "", args_size, false, in_base_library, CHECK_NULL); 265 entry = lookup_style(method, pure_name, "", args_size, false, in_base_library, CHECK_NULL);
223 if (entry != NULL) return entry; 266 if (entry != NULL) return entry;
224 267
225 // 4) Try JNI long style without os prefix/suffix 268 // 4) Try JNI long style without os prefix/suffix
226 entry = lookup_style(method, pure_name, long_name, args_size, false, in_base_library, CHECK_NULL); 269 entry = lookup_style(method, pure_name, long_name, args_size, false, in_base_library, CHECK_NULL);
270
271 return entry; // NULL indicates not found
272 }
273
274 // Check all the formats of native implementation name to see if there is one
275 // for the specified method.
276 address NativeLookup::lookup_critical_entry(methodHandle method) {
277 if (!CriticalJNINatives) return NULL;
278
279 if (method->is_synchronized() ||
280 !method->is_static()) {
281 // Only static non-synchronized methods are allowed
282 return NULL;
283 }
284
285 ResourceMark rm;
286 address entry = NULL;
287
288 Symbol* signature = method->signature();
289 for (int end = 0; end < signature->utf8_length(); end++) {
290 if (signature->byte_at(end) == 'L') {
291 // Don't allow object types
292 return NULL;
293 }
294 }
295
296 // Compute critical name
297 char* critical_name = critical_jni_name(method);
298
299 // Compute argument size
300 int args_size = 1 // JNIEnv
301 + (method->is_static() ? 1 : 0) // class for static methods
302 + method->size_of_parameters(); // actual parameters
303
304
305 // 1) Try JNI short style
306 entry = lookup_critical_style(method, critical_name, "", args_size, true);
307 if (entry != NULL) return entry;
308
309 // Compute long name
310 char* long_name = long_jni_name(method);
311
312 // 2) Try JNI long style
313 entry = lookup_critical_style(method, critical_name, long_name, args_size, true);
314 if (entry != NULL) return entry;
315
316 // 3) Try JNI short style without os prefix/suffix
317 entry = lookup_critical_style(method, critical_name, "", args_size, false);
318 if (entry != NULL) return entry;
319
320 // 4) Try JNI long style without os prefix/suffix
321 entry = lookup_critical_style(method, critical_name, long_name, args_size, false);
227 322
228 return entry; // NULL indicates not found 323 return entry; // NULL indicates not found
229 } 324 }
230 325
231 // Check if there are any JVM TI prefixes which have been applied to the native method name. 326 // Check if there are any JVM TI prefixes which have been applied to the native method name.