Print this page
rev 2143 : 6839872: remove implementation inheritance from JSR 292 APIs
Summary: Move all JSR 292 classes into the java.dyn package.
Reviewed-by:
Split |
Close |
Expand all |
Collapse all |
--- old/src/share/vm/prims/nativeLookup.cpp
+++ new/src/share/vm/prims/nativeLookup.cpp
1 1 /*
2 - * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
2 + * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
3 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 4 *
5 5 * This code is free software; you can redistribute it and/or modify it
6 6 * under the terms of the GNU General Public License version 2 only, as
7 7 * published by the Free Software Foundation.
8 8 *
9 9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 12 * version 2 for more details (a copy is included in the LICENSE file that
13 13 * accompanied this code).
14 14 *
15 15 * You should have received a copy of the GNU General Public License version
16 16 * 2 along with this work; if not, write to the Free Software Foundation,
17 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 18 *
19 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 20 * or visit www.oracle.com if you need additional information or have any
21 21 * questions.
22 22 *
23 23 */
24 24
25 25 #include "precompiled.hpp"
26 26 #include "classfile/javaClasses.hpp"
27 27 #include "classfile/systemDictionary.hpp"
28 28 #include "classfile/vmSymbols.hpp"
29 29 #include "memory/oopFactory.hpp"
30 30 #include "memory/resourceArea.hpp"
31 31 #include "memory/universe.inline.hpp"
32 32 #include "oops/instanceKlass.hpp"
33 33 #include "oops/methodOop.hpp"
34 34 #include "oops/oop.inline.hpp"
35 35 #include "oops/symbol.hpp"
36 36 #include "prims/jvm_misc.hpp"
37 37 #include "prims/nativeLookup.hpp"
38 38 #include "runtime/arguments.hpp"
39 39 #include "runtime/handles.inline.hpp"
40 40 #include "runtime/javaCalls.hpp"
41 41 #include "runtime/sharedRuntime.hpp"
42 42 #include "runtime/signature.hpp"
43 43 #ifdef TARGET_OS_FAMILY_linux
44 44 # include "os_linux.inline.hpp"
45 45 #endif
46 46 #ifdef TARGET_OS_FAMILY_solaris
47 47 # include "os_solaris.inline.hpp"
48 48 #endif
49 49 #ifdef TARGET_OS_FAMILY_windows
50 50 # include "os_windows.inline.hpp"
51 51 #endif
52 52
53 53
54 54 static void mangle_name_on(outputStream* st, Symbol* name, int begin, int end) {
55 55 char* bytes = (char*)name->bytes() + begin;
56 56 char* end_bytes = (char*)name->bytes() + end;
57 57 while (bytes < end_bytes) {
58 58 jchar c;
59 59 bytes = UTF8::next(bytes, &c);
60 60 if (c <= 0x7f && isalnum(c)) {
61 61 st->put((char) c);
62 62 } else {
63 63 if (c == '_') st->print("_1");
64 64 else if (c == '/') st->print("_");
65 65 else if (c == ';') st->print("_2");
66 66 else if (c == '[') st->print("_3");
67 67 else st->print("_%.5x", c);
68 68 }
69 69 }
70 70 }
71 71
72 72
73 73 static void mangle_name_on(outputStream* st, Symbol* name) {
74 74 mangle_name_on(st, name, 0, name->utf8_length());
75 75 }
76 76
77 77
78 78 char* NativeLookup::pure_jni_name(methodHandle method) {
79 79 stringStream st;
80 80 // Prefix
81 81 st.print("Java_");
82 82 // Klass name
83 83 mangle_name_on(&st, method->klass_name());
84 84 st.print("_");
85 85 // Method name
86 86 mangle_name_on(&st, method->name());
87 87 return st.as_string();
88 88 }
89 89
90 90
91 91 char* NativeLookup::long_jni_name(methodHandle method) {
92 92 // Signature ignore the wrapping parenteses and the trailing return type
93 93 stringStream st;
94 94 Symbol* signature = method->signature();
95 95 st.print("__");
96 96 // find ')'
97 97 int end;
98 98 for (end = 0; end < signature->utf8_length() && signature->byte_at(end) != ')'; end++);
99 99 // skip first '('
↓ open down ↓ |
87 lines elided |
↑ open up ↑ |
100 100 mangle_name_on(&st, signature, 1, end);
101 101 return st.as_string();
102 102 }
103 103
104 104 extern "C" {
105 105 void JNICALL JVM_RegisterUnsafeMethods(JNIEnv *env, jclass unsafecls);
106 106 void JNICALL JVM_RegisterMethodHandleMethods(JNIEnv *env, jclass unsafecls);
107 107 void JNICALL JVM_RegisterPerfMethods(JNIEnv *env, jclass perfclass);
108 108 }
109 109
110 +#define CC (char*) /* cast a literal from (const char*) */
111 +#define FN_PTR(f) CAST_FROM_FN_PTR(void*, &f)
112 +
113 +static JNINativeMethod lookup_special_native_methods[] = {
114 + // Next two functions only exist for compatibility with 1.3.1 and earlier.
115 + { CC"Java_java_io_ObjectOutputStream_getPrimitiveFieldValues", NULL, FN_PTR(JVM_GetPrimitiveFieldValues) }, // intercept ObjectOutputStream getPrimitiveFieldValues for faster serialization
116 + { CC"Java_java_io_ObjectInputStream_setPrimitiveFieldValues", NULL, FN_PTR(JVM_SetPrimitiveFieldValues) }, // intercept ObjectInputStream setPrimitiveFieldValues for faster serialization
117 +
118 + { CC"Java_sun_misc_Unsafe_registerNatives", NULL, FN_PTR(JVM_RegisterUnsafeMethods) },
119 + { CC"Java_sun_dyn_MethodHandleNatives_registerNatives", NULL, FN_PTR(JVM_RegisterMethodHandleMethods) }, // AllowTransitionalJSR292
120 + { CC"Java_java_dyn_MethodHandleNatives_registerNatives", NULL, FN_PTR(JVM_RegisterMethodHandleMethods) }, // AllowTransitionalJSR292
121 + { CC"Java_sun_misc_Perf_registerNatives", NULL, FN_PTR(JVM_RegisterPerfMethods) }
122 +};
123 +
110 124 static address lookup_special_native(char* jni_name) {
111 - // NB: To ignore the jni prefix and jni postfix strstr is used matching.
112 - if (!JDK_Version::is_gte_jdk14x_version()) {
113 - // These functions only exist for compatibility with 1.3.1 and earlier
114 - // Intercept ObjectOutputStream getPrimitiveFieldValues for faster serialization
115 - if (strstr(jni_name, "Java_java_io_ObjectOutputStream_getPrimitiveFieldValues") != NULL) {
116 - return CAST_FROM_FN_PTR(address, JVM_GetPrimitiveFieldValues);
125 + int i = !JDK_Version::is_gte_jdk14x_version() ? 0 : 2; // see comment in lookup_special_native_methods
126 + int count = sizeof(lookup_special_native_methods) / sizeof(JNINativeMethod);
127 + for (; i < count; i++) {
128 + // NB: To ignore the jni prefix and jni postfix strstr is used matching.
129 + if (strstr(jni_name, lookup_special_native_methods[i].name) != NULL) {
130 + return CAST_FROM_FN_PTR(address, lookup_special_native_methods[i].fnPtr);
117 131 }
118 - // Intercept ObjectInputStream setPrimitiveFieldValues for faster serialization
119 - if (strstr(jni_name, "Java_java_io_ObjectInputStream_setPrimitiveFieldValues") != NULL) {
120 - return CAST_FROM_FN_PTR(address, JVM_SetPrimitiveFieldValues);
121 - }
122 - }
123 - if (strstr(jni_name, "Java_sun_misc_Unsafe_registerNatives") != NULL) {
124 - return CAST_FROM_FN_PTR(address, JVM_RegisterUnsafeMethods);
125 132 }
126 - if (strstr(jni_name, "Java_sun_dyn_MethodHandleNatives_registerNatives") != NULL) {
127 - return CAST_FROM_FN_PTR(address, JVM_RegisterMethodHandleMethods);
128 - }
129 - if (strstr(jni_name, "Java_sun_misc_Perf_registerNatives") != NULL) {
130 - return CAST_FROM_FN_PTR(address, JVM_RegisterPerfMethods);
131 - }
132 -
133 133 return NULL;
134 134 }
135 135
136 136 address NativeLookup::lookup_style(methodHandle method, char* pure_name, const char* long_name, int args_size, bool os_style, bool& in_base_library, TRAPS) {
137 137 address entry;
138 138 // Compute complete JNI name for style
139 139 stringStream st;
140 140 if (os_style) os::print_jni_name_prefix_on(&st, args_size);
141 141 st.print_raw(pure_name);
142 142 st.print_raw(long_name);
143 143 if (os_style) os::print_jni_name_suffix_on(&st, args_size);
144 144 char* jni_name = st.as_string();
145 145
146 146 // If the loader is null we have a system class, so we attempt a lookup in
147 147 // the native Java library. This takes care of any bootstrapping problems.
148 148 // Note: It is critical for bootstrapping that Java_java_lang_ClassLoader_00024NativeLibrary_find
149 149 // gets found the first time around - otherwise an infinite loop can occure. This is
150 150 // another VM/library dependency
151 151 Handle loader(THREAD,
152 152 instanceKlass::cast(method->method_holder())->class_loader());
153 153 if (loader.is_null()) {
154 154 entry = lookup_special_native(jni_name);
155 155 if (entry == NULL) {
156 156 entry = (address) os::dll_lookup(os::native_java_library(), jni_name);
157 157 }
158 158 if (entry != NULL) {
159 159 in_base_library = true;
160 160 return entry;
161 161 }
162 162 }
163 163
164 164 // Otherwise call static method findNative in ClassLoader
165 165 KlassHandle klass (THREAD, SystemDictionary::ClassLoader_klass());
166 166 Handle name_arg = java_lang_String::create_from_str(jni_name, CHECK_NULL);
167 167
168 168 JavaValue result(T_LONG);
169 169 JavaCalls::call_static(&result,
170 170 klass,
171 171 vmSymbols::findNative_name(),
172 172 vmSymbols::classloader_string_long_signature(),
173 173 // Arguments
174 174 loader,
175 175 name_arg,
176 176 CHECK_NULL);
177 177 entry = (address) (intptr_t) result.get_jlong();
178 178
179 179 if (entry == NULL) {
180 180 // findNative didn't find it, if there are any agent libraries look in them
181 181 AgentLibrary* agent;
182 182 for (agent = Arguments::agents(); agent != NULL; agent = agent->next()) {
183 183 entry = (address) os::dll_lookup(agent->os_lib(), jni_name);
184 184 if (entry != NULL) {
185 185 return entry;
186 186 }
187 187 }
188 188 }
189 189
190 190 return entry;
191 191 }
192 192
193 193
194 194 // Check all the formats of native implementation name to see if there is one
195 195 // for the specified method.
196 196 address NativeLookup::lookup_entry(methodHandle method, bool& in_base_library, TRAPS) {
197 197 address entry = NULL;
198 198 in_base_library = false;
199 199 // Compute pure name
200 200 char* pure_name = pure_jni_name(method);
201 201
202 202 // Compute argument size
203 203 int args_size = 1 // JNIEnv
204 204 + (method->is_static() ? 1 : 0) // class for static methods
205 205 + method->size_of_parameters(); // actual parameters
206 206
207 207
208 208 // 1) Try JNI short style
209 209 entry = lookup_style(method, pure_name, "", args_size, true, in_base_library, CHECK_NULL);
210 210 if (entry != NULL) return entry;
211 211
212 212 // Compute long name
213 213 char* long_name = long_jni_name(method);
214 214
215 215 // 2) Try JNI long style
216 216 entry = lookup_style(method, pure_name, long_name, args_size, true, in_base_library, CHECK_NULL);
217 217 if (entry != NULL) return entry;
218 218
219 219 // 3) Try JNI short style without os prefix/suffix
220 220 entry = lookup_style(method, pure_name, "", args_size, false, in_base_library, CHECK_NULL);
221 221 if (entry != NULL) return entry;
222 222
223 223 // 4) Try JNI long style without os prefix/suffix
224 224 entry = lookup_style(method, pure_name, long_name, args_size, false, in_base_library, CHECK_NULL);
225 225
226 226 return entry; // NULL indicates not found
227 227 }
228 228
229 229 // Check if there are any JVM TI prefixes which have been applied to the native method name.
230 230 // If any are found, remove them before attemping the look up of the
231 231 // native implementation again.
232 232 // See SetNativeMethodPrefix in the JVM TI Spec for more details.
233 233 address NativeLookup::lookup_entry_prefixed(methodHandle method, bool& in_base_library, TRAPS) {
234 234 ResourceMark rm(THREAD);
235 235
236 236 int prefix_count;
237 237 char** prefixes = JvmtiExport::get_all_native_method_prefixes(&prefix_count);
238 238 char* in_name = method->name()->as_C_string();
239 239 char* wrapper_name = in_name;
240 240 // last applied prefix will be first -- go backwards
241 241 for (int i = prefix_count-1; i >= 0; i--) {
242 242 char* prefix = prefixes[i];
243 243 size_t prefix_len = strlen(prefix);
244 244 if (strncmp(prefix, wrapper_name, prefix_len) == 0) {
245 245 // has this prefix remove it
246 246 wrapper_name += prefix_len;
247 247 }
248 248 }
249 249 if (wrapper_name != in_name) {
250 250 // we have a name for a wrapping method
251 251 int wrapper_name_len = (int)strlen(wrapper_name);
252 252 TempNewSymbol wrapper_symbol = SymbolTable::probe(wrapper_name, wrapper_name_len);
253 253 if (wrapper_symbol != NULL) {
254 254 KlassHandle kh(method->method_holder());
255 255 methodOop wrapper_method = Klass::cast(kh())->lookup_method(wrapper_symbol,
256 256 method->signature());
257 257 if (wrapper_method != NULL && !wrapper_method->is_native()) {
258 258 // we found a wrapper method, use its native entry
259 259 method->set_is_prefixed_native();
260 260 return lookup_entry(wrapper_method, in_base_library, THREAD);
261 261 }
262 262 }
263 263 }
264 264 return NULL;
265 265 }
266 266
267 267 address NativeLookup::lookup_base(methodHandle method, bool& in_base_library, TRAPS) {
268 268 address entry = NULL;
269 269 ResourceMark rm(THREAD);
270 270
271 271 entry = lookup_entry(method, in_base_library, THREAD);
272 272 if (entry != NULL) return entry;
273 273
274 274 // standard native method resolution has failed. Check if there are any
275 275 // JVM TI prefixes which have been applied to the native method name.
276 276 entry = lookup_entry_prefixed(method, in_base_library, THREAD);
277 277 if (entry != NULL) return entry;
278 278
279 279 // Native function not found, throw UnsatisfiedLinkError
280 280 THROW_MSG_0(vmSymbols::java_lang_UnsatisfiedLinkError(),
281 281 method->name_and_sig_as_C_string());
282 282 }
283 283
284 284
285 285 address NativeLookup::lookup(methodHandle method, bool& in_base_library, TRAPS) {
286 286 if (!method->has_native_function()) {
287 287 address entry = lookup_base(method, in_base_library, CHECK_NULL);
288 288 method->set_native_function(entry,
289 289 methodOopDesc::native_bind_event_is_interesting);
290 290 // -verbose:jni printing
291 291 if (PrintJNIResolving) {
292 292 ResourceMark rm(THREAD);
293 293 tty->print_cr("[Dynamic-linking native method %s.%s ... JNI]",
294 294 Klass::cast(method->method_holder())->external_name(),
295 295 method->name()->as_C_string());
296 296 }
297 297 }
298 298 return method->native_function();
299 299 }
300 300
301 301 address NativeLookup::base_library_lookup(const char* class_name, const char* method_name, const char* signature) {
302 302 EXCEPTION_MARK;
303 303 bool in_base_library = true; // SharedRuntime inits some math methods.
304 304 TempNewSymbol c_name = SymbolTable::new_symbol(class_name, CATCH);
305 305 TempNewSymbol m_name = SymbolTable::new_symbol(method_name, CATCH);
306 306 TempNewSymbol s_name = SymbolTable::new_symbol(signature, CATCH);
307 307
308 308 // Find the class
309 309 klassOop k = SystemDictionary::resolve_or_fail(c_name, true, CATCH);
310 310 instanceKlassHandle klass (THREAD, k);
311 311
312 312 // Find method and invoke standard lookup
313 313 methodHandle method (THREAD,
314 314 klass->uncached_lookup_method(m_name, s_name));
315 315 address result = lookup(method, in_base_library, CATCH);
316 316 assert(in_base_library, "must be in basic library");
317 317 guarantee(result != NULL, "must be non NULL");
318 318 return result;
319 319 }
↓ open down ↓ |
177 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX