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