Mercurial > hg > truffle
comparison src/share/vm/interpreter/linkResolver.cpp @ 6948:e522a00b91aa
Merge with http://hg.openjdk.java.net/hsx/hsx25/hotspot/ after NPG - C++ build works
author | Doug Simon <doug.simon@oracle.com> |
---|---|
date | Mon, 12 Nov 2012 23:14:12 +0100 |
parents | 18fb7da42534 |
children | 070d523b96a7 |
comparison
equal
deleted
inserted
replaced
6711:ae13cc658b80 | 6948:e522a00b91aa |
---|---|
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. |
21 * questions. | 21 * questions. |
22 * | 22 * |
23 */ | 23 */ |
24 | 24 |
25 #include "precompiled.hpp" | 25 #include "precompiled.hpp" |
26 #include "classfile/defaultMethods.hpp" | |
26 #include "classfile/systemDictionary.hpp" | 27 #include "classfile/systemDictionary.hpp" |
27 #include "classfile/vmSymbols.hpp" | 28 #include "classfile/vmSymbols.hpp" |
28 #include "compiler/compileBroker.hpp" | 29 #include "compiler/compileBroker.hpp" |
29 #include "gc_interface/collectedHeap.inline.hpp" | 30 #include "gc_interface/collectedHeap.inline.hpp" |
30 #include "interpreter/bytecode.hpp" | 31 #include "interpreter/bytecode.hpp" |
73 //------------------------------------------------------------------------------------------------------------------------ | 74 //------------------------------------------------------------------------------------------------------------------------ |
74 // Implementation of CallInfo | 75 // Implementation of CallInfo |
75 | 76 |
76 | 77 |
77 void CallInfo::set_static(KlassHandle resolved_klass, methodHandle resolved_method, TRAPS) { | 78 void CallInfo::set_static(KlassHandle resolved_klass, methodHandle resolved_method, TRAPS) { |
78 int vtable_index = methodOopDesc::nonvirtual_vtable_index; | 79 int vtable_index = Method::nonvirtual_vtable_index; |
79 set_common(resolved_klass, resolved_klass, resolved_method, resolved_method, vtable_index, CHECK); | 80 set_common(resolved_klass, resolved_klass, resolved_method, resolved_method, vtable_index, CHECK); |
80 } | 81 } |
81 | 82 |
82 | 83 |
83 void CallInfo::set_interface(KlassHandle resolved_klass, KlassHandle selected_klass, methodHandle resolved_method, methodHandle selected_method, TRAPS) { | 84 void CallInfo::set_interface(KlassHandle resolved_klass, KlassHandle selected_klass, methodHandle resolved_method, methodHandle selected_method, TRAPS) { |
84 // This is only called for interface methods. If the resolved_method | 85 // This is only called for interface methods. If the resolved_method |
85 // comes from java/lang/Object, it can be the subject of a virtual call, so | 86 // comes from java/lang/Object, it can be the subject of a virtual call, so |
86 // we should pick the vtable index from the resolved method. | 87 // we should pick the vtable index from the resolved method. |
87 // Other than that case, there is no valid vtable index to specify. | 88 // Other than that case, there is no valid vtable index to specify. |
88 int vtable_index = methodOopDesc::invalid_vtable_index; | 89 int vtable_index = Method::invalid_vtable_index; |
89 if (resolved_method->method_holder() == SystemDictionary::Object_klass()) { | 90 if (resolved_method->method_holder() == SystemDictionary::Object_klass()) { |
90 assert(resolved_method->vtable_index() == selected_method->vtable_index(), "sanity check"); | 91 assert(resolved_method->vtable_index() == selected_method->vtable_index(), "sanity check"); |
91 vtable_index = resolved_method->vtable_index(); | 92 vtable_index = resolved_method->vtable_index(); |
92 } | 93 } |
93 set_common(resolved_klass, selected_klass, resolved_method, selected_method, vtable_index, CHECK); | 94 set_common(resolved_klass, selected_klass, resolved_method, selected_method, vtable_index, CHECK); |
94 } | 95 } |
95 | 96 |
96 void CallInfo::set_virtual(KlassHandle resolved_klass, KlassHandle selected_klass, methodHandle resolved_method, methodHandle selected_method, int vtable_index, TRAPS) { | 97 void CallInfo::set_virtual(KlassHandle resolved_klass, KlassHandle selected_klass, methodHandle resolved_method, methodHandle selected_method, int vtable_index, TRAPS) { |
97 assert(vtable_index >= 0 || vtable_index == methodOopDesc::nonvirtual_vtable_index, "valid index"); | 98 assert(vtable_index >= 0 || vtable_index == Method::nonvirtual_vtable_index, "valid index"); |
98 set_common(resolved_klass, selected_klass, resolved_method, selected_method, vtable_index, CHECK); | 99 set_common(resolved_klass, selected_klass, resolved_method, selected_method, vtable_index, CHECK); |
99 assert(!resolved_method->is_compiled_lambda_form(), "these must be handled via an invokehandle call"); | 100 assert(!resolved_method->is_compiled_lambda_form(), "these must be handled via an invokehandle call"); |
100 } | 101 } |
101 | 102 |
102 void CallInfo::set_handle(methodHandle resolved_method, Handle resolved_appendix, TRAPS) { | 103 void CallInfo::set_handle(methodHandle resolved_method, Handle resolved_appendix, Handle resolved_method_type, TRAPS) { |
103 if (resolved_method.is_null()) { | 104 if (resolved_method.is_null()) { |
104 THROW_MSG(vmSymbols::java_lang_InternalError(), "resolved method is null"); | 105 THROW_MSG(vmSymbols::java_lang_InternalError(), "resolved method is null"); |
105 } | 106 } |
106 KlassHandle resolved_klass = SystemDictionaryHandles::MethodHandle_klass(); | 107 KlassHandle resolved_klass = SystemDictionary::MethodHandle_klass(); |
107 assert(resolved_method->intrinsic_id() == vmIntrinsics::_invokeBasic || | 108 assert(resolved_method->intrinsic_id() == vmIntrinsics::_invokeBasic || |
108 resolved_method->is_compiled_lambda_form(), | 109 resolved_method->is_compiled_lambda_form(), |
109 "linkMethod must return one of these"); | 110 "linkMethod must return one of these"); |
110 int vtable_index = methodOopDesc::nonvirtual_vtable_index; | 111 int vtable_index = Method::nonvirtual_vtable_index; |
111 assert(resolved_method->vtable_index() == vtable_index, ""); | 112 assert(resolved_method->vtable_index() == vtable_index, ""); |
112 set_common(resolved_klass, resolved_klass, resolved_method, resolved_method, vtable_index, CHECK); | 113 set_common(resolved_klass, resolved_klass, resolved_method, resolved_method, vtable_index, CHECK); |
113 _resolved_appendix = resolved_appendix; | 114 _resolved_appendix = resolved_appendix; |
115 _resolved_method_type = resolved_method_type; | |
114 } | 116 } |
115 | 117 |
116 void CallInfo::set_common(KlassHandle resolved_klass, KlassHandle selected_klass, methodHandle resolved_method, methodHandle selected_method, int vtable_index, TRAPS) { | 118 void CallInfo::set_common(KlassHandle resolved_klass, KlassHandle selected_klass, methodHandle resolved_method, methodHandle selected_method, int vtable_index, TRAPS) { |
117 assert(resolved_method->signature() == selected_method->signature(), "signatures must correspond"); | 119 assert(resolved_method->signature() == selected_method->signature(), "signatures must correspond"); |
118 _resolved_klass = resolved_klass; | 120 _resolved_klass = resolved_klass; |
129 // assert(CompilationPolicy::can_be_compiled(selected_method), "cannot compile"); | 131 // assert(CompilationPolicy::can_be_compiled(selected_method), "cannot compile"); |
130 if (THREAD->is_Compiler_thread()) { | 132 if (THREAD->is_Compiler_thread()) { |
131 // don't force compilation, resolve was on behalf of compiler | 133 // don't force compilation, resolve was on behalf of compiler |
132 return; | 134 return; |
133 } | 135 } |
134 if (instanceKlass::cast(selected_method->method_holder())->is_not_initialized()) { | 136 if (selected_method->method_holder()->is_not_initialized()) { |
135 // 'is_not_initialized' means not only '!is_initialized', but also that | 137 // 'is_not_initialized' means not only '!is_initialized', but also that |
136 // initialization has not been started yet ('!being_initialized') | 138 // initialization has not been started yet ('!being_initialized') |
137 // Do not force compilation of methods in uninitialized classes. | 139 // Do not force compilation of methods in uninitialized classes. |
138 // Note that doing this would throw an assert later, | 140 // Note that doing this would throw an assert later, |
139 // in CompileBroker::compile_method. | 141 // in CompileBroker::compile_method. |
150 | 152 |
151 //------------------------------------------------------------------------------------------------------------------------ | 153 //------------------------------------------------------------------------------------------------------------------------ |
152 // Klass resolution | 154 // Klass resolution |
153 | 155 |
154 void LinkResolver::check_klass_accessability(KlassHandle ref_klass, KlassHandle sel_klass, TRAPS) { | 156 void LinkResolver::check_klass_accessability(KlassHandle ref_klass, KlassHandle sel_klass, TRAPS) { |
155 if (!Reflection::verify_class_access(ref_klass->as_klassOop(), | 157 if (!Reflection::verify_class_access(ref_klass(), |
156 sel_klass->as_klassOop(), | 158 sel_klass(), |
157 true)) { | 159 true)) { |
158 ResourceMark rm(THREAD); | 160 ResourceMark rm(THREAD); |
159 Exceptions::fthrow( | 161 Exceptions::fthrow( |
160 THREAD_AND_LOCATION, | 162 THREAD_AND_LOCATION, |
161 vmSymbols::java_lang_IllegalAccessError(), | 163 vmSymbols::java_lang_IllegalAccessError(), |
166 return; | 168 return; |
167 } | 169 } |
168 } | 170 } |
169 | 171 |
170 void LinkResolver::resolve_klass(KlassHandle& result, constantPoolHandle pool, int index, TRAPS) { | 172 void LinkResolver::resolve_klass(KlassHandle& result, constantPoolHandle pool, int index, TRAPS) { |
171 klassOop result_oop = pool->klass_ref_at(index, CHECK); | 173 Klass* result_oop = pool->klass_ref_at(index, CHECK); |
172 result = KlassHandle(THREAD, result_oop); | 174 result = KlassHandle(THREAD, result_oop); |
173 } | 175 } |
174 | 176 |
175 void LinkResolver::resolve_klass_no_update(KlassHandle& result, constantPoolHandle pool, int index, TRAPS) { | 177 void LinkResolver::resolve_klass_no_update(KlassHandle& result, constantPoolHandle pool, int index, TRAPS) { |
176 klassOop result_oop = | 178 Klass* result_oop = |
177 constantPoolOopDesc::klass_ref_at_if_loaded_check(pool, index, CHECK); | 179 ConstantPool::klass_ref_at_if_loaded_check(pool, index, CHECK); |
178 result = KlassHandle(THREAD, result_oop); | 180 result = KlassHandle(THREAD, result_oop); |
179 } | 181 } |
180 | 182 |
181 | 183 |
182 //------------------------------------------------------------------------------------------------------------------------ | 184 //------------------------------------------------------------------------------------------------------------------------ |
183 // Method resolution | 185 // Method resolution |
184 // | 186 // |
185 // According to JVM spec. $5.4.3c & $5.4.3d | 187 // According to JVM spec. $5.4.3c & $5.4.3d |
186 | 188 |
187 void LinkResolver::lookup_method_in_klasses(methodHandle& result, KlassHandle klass, Symbol* name, Symbol* signature, TRAPS) { | 189 void LinkResolver::lookup_method_in_klasses(methodHandle& result, KlassHandle klass, Symbol* name, Symbol* signature, TRAPS) { |
188 methodOop result_oop = klass->uncached_lookup_method(name, signature); | 190 Method* result_oop = klass->uncached_lookup_method(name, signature); |
189 if (EnableInvokeDynamic && result_oop != NULL) { | 191 if (EnableInvokeDynamic && result_oop != NULL) { |
190 vmIntrinsics::ID iid = result_oop->intrinsic_id(); | 192 vmIntrinsics::ID iid = result_oop->intrinsic_id(); |
191 if (MethodHandles::is_signature_polymorphic(iid)) { | 193 if (MethodHandles::is_signature_polymorphic(iid)) { |
192 // Do not link directly to these. The VM must produce a synthetic one using lookup_polymorphic_method. | 194 // Do not link directly to these. The VM must produce a synthetic one using lookup_polymorphic_method. |
193 return; | 195 return; |
196 result = methodHandle(THREAD, result_oop); | 198 result = methodHandle(THREAD, result_oop); |
197 } | 199 } |
198 | 200 |
199 // returns first instance method | 201 // returns first instance method |
200 void LinkResolver::lookup_instance_method_in_klasses(methodHandle& result, KlassHandle klass, Symbol* name, Symbol* signature, TRAPS) { | 202 void LinkResolver::lookup_instance_method_in_klasses(methodHandle& result, KlassHandle klass, Symbol* name, Symbol* signature, TRAPS) { |
201 methodOop result_oop = klass->uncached_lookup_method(name, signature); | 203 Method* result_oop = klass->uncached_lookup_method(name, signature); |
202 result = methodHandle(THREAD, result_oop); | 204 result = methodHandle(THREAD, result_oop); |
203 while (!result.is_null() && result->is_static()) { | 205 while (!result.is_null() && result->is_static()) { |
204 klass = KlassHandle(THREAD, Klass::cast(result->method_holder())->super()); | 206 klass = KlassHandle(THREAD, Klass::cast(result->method_holder())->super()); |
205 result = methodHandle(THREAD, klass->uncached_lookup_method(name, signature)); | 207 result = methodHandle(THREAD, klass->uncached_lookup_method(name, signature)); |
206 } | 208 } |
207 } | 209 } |
208 | 210 |
209 | 211 |
210 int LinkResolver::vtable_index_of_miranda_method(KlassHandle klass, Symbol* name, Symbol* signature, TRAPS) { | 212 int LinkResolver::vtable_index_of_miranda_method(KlassHandle klass, Symbol* name, Symbol* signature, TRAPS) { |
211 ResourceMark rm(THREAD); | 213 ResourceMark rm(THREAD); |
212 klassVtable *vt = instanceKlass::cast(klass())->vtable(); | 214 klassVtable *vt = InstanceKlass::cast(klass())->vtable(); |
213 return vt->index_of_miranda(name, signature); | 215 return vt->index_of_miranda(name, signature); |
214 } | 216 } |
215 | 217 |
216 void LinkResolver::lookup_method_in_interfaces(methodHandle& result, KlassHandle klass, Symbol* name, Symbol* signature, TRAPS) { | 218 void LinkResolver::lookup_method_in_interfaces(methodHandle& result, KlassHandle klass, Symbol* name, Symbol* signature, TRAPS) { |
217 instanceKlass *ik = instanceKlass::cast(klass()); | 219 InstanceKlass *ik = InstanceKlass::cast(klass()); |
218 result = methodHandle(THREAD, ik->lookup_method_in_all_interfaces(name, signature)); | 220 result = methodHandle(THREAD, ik->lookup_method_in_all_interfaces(name, signature)); |
219 } | 221 } |
220 | 222 |
221 void LinkResolver::lookup_polymorphic_method(methodHandle& result, | 223 void LinkResolver::lookup_polymorphic_method(methodHandle& result, |
222 KlassHandle klass, Symbol* name, Symbol* full_signature, | 224 KlassHandle klass, Symbol* name, Symbol* full_signature, |
223 KlassHandle current_klass, | 225 KlassHandle current_klass, |
224 Handle* appendix_result_or_null, | 226 Handle *appendix_result_or_null, |
227 Handle *method_type_result, | |
225 TRAPS) { | 228 TRAPS) { |
226 vmIntrinsics::ID iid = MethodHandles::signature_polymorphic_name_id(name); | 229 vmIntrinsics::ID iid = MethodHandles::signature_polymorphic_name_id(name); |
227 if (TraceMethodHandles) { | 230 if (TraceMethodHandles) { |
228 tty->print_cr("lookup_polymorphic_method iid=%s %s.%s%s", | 231 tty->print_cr("lookup_polymorphic_method iid=%s %s.%s%s", |
229 vmIntrinsics::name_at(iid), klass->external_name(), | 232 vmIntrinsics::name_at(iid), klass->external_name(), |
262 && appendix_result_or_null != NULL) { | 265 && appendix_result_or_null != NULL) { |
263 // This is a method with type-checking semantics. | 266 // This is a method with type-checking semantics. |
264 // We will ask Java code to spin an adapter method for it. | 267 // We will ask Java code to spin an adapter method for it. |
265 if (!MethodHandles::enabled()) { | 268 if (!MethodHandles::enabled()) { |
266 // Make sure the Java part of the runtime has been booted up. | 269 // Make sure the Java part of the runtime has been booted up. |
267 klassOop natives = SystemDictionary::MethodHandleNatives_klass(); | 270 Klass* natives = SystemDictionary::MethodHandleNatives_klass(); |
268 if (natives == NULL || instanceKlass::cast(natives)->is_not_initialized()) { | 271 if (natives == NULL || InstanceKlass::cast(natives)->is_not_initialized()) { |
269 SystemDictionary::resolve_or_fail(vmSymbols::java_lang_invoke_MethodHandleNatives(), | 272 SystemDictionary::resolve_or_fail(vmSymbols::java_lang_invoke_MethodHandleNatives(), |
270 Handle(), | 273 Handle(), |
271 Handle(), | 274 Handle(), |
272 true, | 275 true, |
273 CHECK); | 276 CHECK); |
274 } | 277 } |
275 } | 278 } |
276 | 279 |
277 Handle appendix; | 280 Handle appendix; |
281 Handle method_type; | |
278 result = SystemDictionary::find_method_handle_invoker(name, | 282 result = SystemDictionary::find_method_handle_invoker(name, |
279 full_signature, | 283 full_signature, |
280 current_klass, | 284 current_klass, |
281 &appendix, | 285 &appendix, |
286 &method_type, | |
282 CHECK); | 287 CHECK); |
283 if (TraceMethodHandles) { | 288 if (TraceMethodHandles) { |
284 tty->print("lookup_polymorphic_method => (via Java) "); | 289 tty->print("lookup_polymorphic_method => (via Java) "); |
285 result->print_on(tty); | 290 result->print_on(tty); |
286 tty->print(" lookup_polymorphic_method => appendix = "); | 291 tty->print(" lookup_polymorphic_method => appendix = "); |
305 err_msg("%d != %d", actual_size_of_params, expected_size_of_params)); | 310 err_msg("%d != %d", actual_size_of_params, expected_size_of_params)); |
306 #endif //ASSERT | 311 #endif //ASSERT |
307 | 312 |
308 assert(appendix_result_or_null != NULL, ""); | 313 assert(appendix_result_or_null != NULL, ""); |
309 (*appendix_result_or_null) = appendix; | 314 (*appendix_result_or_null) = appendix; |
315 (*method_type_result) = method_type; | |
310 return; | 316 return; |
311 } | 317 } |
312 } | 318 } |
313 } | 319 } |
314 } | 320 } |
338 new_flags = new_flags | JVM_ACC_PUBLIC; | 344 new_flags = new_flags | JVM_ACC_PUBLIC; |
339 flags.set_flags(new_flags); | 345 flags.set_flags(new_flags); |
340 } | 346 } |
341 // assert(extra_arg_result_or_null != NULL, "must be able to return extra argument"); | 347 // assert(extra_arg_result_or_null != NULL, "must be able to return extra argument"); |
342 | 348 |
343 if (!Reflection::verify_field_access(ref_klass->as_klassOop(), | 349 if (!Reflection::verify_field_access(ref_klass(), |
344 resolved_klass->as_klassOop(), | 350 resolved_klass(), |
345 sel_klass->as_klassOop(), | 351 sel_klass(), |
346 flags, | 352 flags, |
347 true)) { | 353 true)) { |
348 ResourceMark rm(THREAD); | 354 ResourceMark rm(THREAD); |
349 Exceptions::fthrow( | 355 Exceptions::fthrow( |
350 THREAD_AND_LOCATION, | 356 THREAD_AND_LOCATION, |
362 void LinkResolver::resolve_method_statically(methodHandle& resolved_method, KlassHandle& resolved_klass, | 368 void LinkResolver::resolve_method_statically(methodHandle& resolved_method, KlassHandle& resolved_klass, |
363 Bytecodes::Code code, constantPoolHandle pool, int index, TRAPS) { | 369 Bytecodes::Code code, constantPoolHandle pool, int index, TRAPS) { |
364 | 370 |
365 // resolve klass | 371 // resolve klass |
366 if (code == Bytecodes::_invokedynamic) { | 372 if (code == Bytecodes::_invokedynamic) { |
367 resolved_klass = SystemDictionaryHandles::MethodHandle_klass(); | 373 resolved_klass = SystemDictionary::MethodHandle_klass(); |
368 Symbol* method_name = vmSymbols::invoke_name(); | 374 Symbol* method_name = vmSymbols::invoke_name(); |
369 Symbol* method_signature = pool->signature_ref_at(index); | 375 Symbol* method_signature = pool->signature_ref_at(index); |
370 KlassHandle current_klass(THREAD, pool->pool_holder()); | 376 KlassHandle current_klass(THREAD, pool->pool_holder()); |
371 resolve_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, true, CHECK); | 377 resolve_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, true, CHECK); |
372 return; | 378 return; |
379 KlassHandle current_klass(THREAD, pool->pool_holder()); | 385 KlassHandle current_klass(THREAD, pool->pool_holder()); |
380 | 386 |
381 if (pool->has_preresolution() | 387 if (pool->has_preresolution() |
382 || (resolved_klass() == SystemDictionary::MethodHandle_klass() && | 388 || (resolved_klass() == SystemDictionary::MethodHandle_klass() && |
383 MethodHandles::is_signature_polymorphic_name(resolved_klass(), method_name))) { | 389 MethodHandles::is_signature_polymorphic_name(resolved_klass(), method_name))) { |
384 methodOop result_oop = constantPoolOopDesc::method_at_if_loaded(pool, index); | 390 Method* result_oop = ConstantPool::method_at_if_loaded(pool, index); |
385 if (result_oop != NULL) { | 391 if (result_oop != NULL) { |
386 resolved_method = methodHandle(THREAD, result_oop); | 392 resolved_method = methodHandle(THREAD, result_oop); |
387 return; | 393 return; |
388 } | 394 } |
389 } | 395 } |
397 | 403 |
398 void LinkResolver::resolve_method(methodHandle& resolved_method, KlassHandle resolved_klass, | 404 void LinkResolver::resolve_method(methodHandle& resolved_method, KlassHandle resolved_klass, |
399 Symbol* method_name, Symbol* method_signature, | 405 Symbol* method_name, Symbol* method_signature, |
400 KlassHandle current_klass, bool check_access, TRAPS) { | 406 KlassHandle current_klass, bool check_access, TRAPS) { |
401 | 407 |
402 // 1. check if klass is not interface | |
403 if (resolved_klass->is_interface()) { | |
404 ResourceMark rm(THREAD); | |
405 char buf[200]; | |
406 jio_snprintf(buf, sizeof(buf), "Found interface %s, but class was expected", Klass::cast(resolved_klass())->external_name()); | |
407 THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(), buf); | |
408 } | |
409 | |
410 Handle nested_exception; | 408 Handle nested_exception; |
411 | 409 |
412 // 2. lookup method in resolved klass and its super klasses | 410 // 1. lookup method in resolved klass and its super klasses |
413 lookup_method_in_klasses(resolved_method, resolved_klass, method_name, method_signature, CHECK); | 411 lookup_method_in_klasses(resolved_method, resolved_klass, method_name, method_signature, CHECK); |
414 | 412 |
415 if (resolved_method.is_null()) { // not found in the class hierarchy | 413 if (resolved_method.is_null()) { // not found in the class hierarchy |
416 // 3. lookup method in all the interfaces implemented by the resolved klass | 414 // 2. lookup method in all the interfaces implemented by the resolved klass |
417 lookup_method_in_interfaces(resolved_method, resolved_klass, method_name, method_signature, CHECK); | 415 lookup_method_in_interfaces(resolved_method, resolved_klass, method_name, method_signature, CHECK); |
418 | 416 |
419 if (resolved_method.is_null()) { | 417 if (resolved_method.is_null()) { |
420 // JSR 292: see if this is an implicitly generated method MethodHandle.linkToVirtual(*...), etc | 418 // JSR 292: see if this is an implicitly generated method MethodHandle.linkToVirtual(*...), etc |
421 lookup_polymorphic_method(resolved_method, resolved_klass, method_name, method_signature, | 419 lookup_polymorphic_method(resolved_method, resolved_klass, method_name, method_signature, |
422 current_klass, (Handle*)NULL, THREAD); | 420 current_klass, (Handle*)NULL, (Handle*)NULL, THREAD); |
423 if (HAS_PENDING_EXCEPTION) { | 421 if (HAS_PENDING_EXCEPTION) { |
424 nested_exception = Handle(THREAD, PENDING_EXCEPTION); | 422 nested_exception = Handle(THREAD, PENDING_EXCEPTION); |
425 CLEAR_PENDING_EXCEPTION; | 423 CLEAR_PENDING_EXCEPTION; |
426 } | 424 } |
427 } | 425 } |
428 | 426 |
429 if (resolved_method.is_null()) { | 427 if (resolved_method.is_null()) { |
430 // 4. method lookup failed | 428 // 3. method lookup failed |
431 ResourceMark rm(THREAD); | 429 ResourceMark rm(THREAD); |
432 THROW_MSG_CAUSE(vmSymbols::java_lang_NoSuchMethodError(), | 430 THROW_MSG_CAUSE(vmSymbols::java_lang_NoSuchMethodError(), |
433 methodOopDesc::name_and_sig_as_C_string(Klass::cast(resolved_klass()), | 431 Method::name_and_sig_as_C_string(Klass::cast(resolved_klass()), |
434 method_name, | 432 method_name, |
435 method_signature), | 433 method_signature), |
436 nested_exception); | 434 nested_exception); |
437 } | 435 } |
438 } | 436 } |
439 | 437 |
438 // 4. check if klass is not interface | |
439 if (resolved_klass->is_interface() && resolved_method->is_abstract()) { | |
440 ResourceMark rm(THREAD); | |
441 char buf[200]; | |
442 jio_snprintf(buf, sizeof(buf), "Found interface %s, but class was expected", | |
443 resolved_klass()->external_name()); | |
444 THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(), buf); | |
445 } | |
446 | |
440 // 5. check if method is concrete | 447 // 5. check if method is concrete |
441 if (resolved_method->is_abstract() && !resolved_klass->is_abstract()) { | 448 if (resolved_method->is_abstract() && !resolved_klass->is_abstract()) { |
442 ResourceMark rm(THREAD); | 449 ResourceMark rm(THREAD); |
443 THROW_MSG(vmSymbols::java_lang_AbstractMethodError(), | 450 THROW_MSG(vmSymbols::java_lang_AbstractMethodError(), |
444 methodOopDesc::name_and_sig_as_C_string(Klass::cast(resolved_klass()), | 451 Method::name_and_sig_as_C_string(Klass::cast(resolved_klass()), |
445 method_name, | 452 method_name, |
446 method_signature)); | 453 method_signature)); |
447 } | 454 } |
448 | 455 |
449 // 6. access checks, access checking may be turned off when calling from within the VM. | 456 // 6. access checks, access checking may be turned off when calling from within the VM. |
456 KlassHandle(THREAD, resolved_method->method_holder()), | 463 KlassHandle(THREAD, resolved_method->method_holder()), |
457 resolved_method, | 464 resolved_method, |
458 CHECK); | 465 CHECK); |
459 | 466 |
460 // check loader constraints | 467 // check loader constraints |
461 Handle loader (THREAD, instanceKlass::cast(current_klass())->class_loader()); | 468 Handle loader (THREAD, InstanceKlass::cast(current_klass())->class_loader()); |
462 Handle class_loader (THREAD, instanceKlass::cast(resolved_method->method_holder())->class_loader()); | 469 Handle class_loader (THREAD, resolved_method->method_holder()->class_loader()); |
463 { | 470 { |
464 ResourceMark rm(THREAD); | 471 ResourceMark rm(THREAD); |
465 char* failed_type_name = | 472 char* failed_type_name = |
466 SystemDictionary::check_signature_loaders(method_signature, loader, | 473 SystemDictionary::check_signature_loaders(method_signature, loader, |
467 class_loader, true, CHECK); | 474 class_loader, true, CHECK); |
468 if (failed_type_name != NULL) { | 475 if (failed_type_name != NULL) { |
469 const char* msg = "loader constraint violation: when resolving method" | 476 const char* msg = "loader constraint violation: when resolving method" |
470 " \"%s\" the class loader (instance of %s) of the current class, %s," | 477 " \"%s\" the class loader (instance of %s) of the current class, %s," |
471 " and the class loader (instance of %s) for resolved class, %s, have" | 478 " and the class loader (instance of %s) for resolved class, %s, have" |
472 " different Class objects for the type %s used in the signature"; | 479 " different Class objects for the type %s used in the signature"; |
473 char* sig = methodOopDesc::name_and_sig_as_C_string(Klass::cast(resolved_klass()),method_name,method_signature); | 480 char* sig = Method::name_and_sig_as_C_string(Klass::cast(resolved_klass()),method_name,method_signature); |
474 const char* loader1 = SystemDictionary::loader_name(loader()); | 481 const char* loader1 = SystemDictionary::loader_name(loader()); |
475 char* current = instanceKlass::cast(current_klass())->name()->as_C_string(); | 482 char* current = InstanceKlass::cast(current_klass())->name()->as_C_string(); |
476 const char* loader2 = SystemDictionary::loader_name(class_loader()); | 483 const char* loader2 = SystemDictionary::loader_name(class_loader()); |
477 char* resolved = instanceKlass::cast(resolved_klass())->name()->as_C_string(); | 484 char* resolved = InstanceKlass::cast(resolved_klass())->name()->as_C_string(); |
478 size_t buflen = strlen(msg) + strlen(sig) + strlen(loader1) + | 485 size_t buflen = strlen(msg) + strlen(sig) + strlen(loader1) + |
479 strlen(current) + strlen(loader2) + strlen(resolved) + | 486 strlen(current) + strlen(loader2) + strlen(resolved) + |
480 strlen(failed_type_name); | 487 strlen(failed_type_name); |
481 char* buf = NEW_RESOURCE_ARRAY_IN_THREAD(THREAD, char, buflen); | 488 char* buf = NEW_RESOURCE_ARRAY_IN_THREAD(THREAD, char, buflen); |
482 jio_snprintf(buf, buflen, msg, sig, loader1, current, loader2, | 489 jio_snprintf(buf, buflen, msg, sig, loader1, current, loader2, |
510 lookup_method_in_interfaces(resolved_method, resolved_klass, method_name, method_signature, CHECK); | 517 lookup_method_in_interfaces(resolved_method, resolved_klass, method_name, method_signature, CHECK); |
511 if (resolved_method.is_null()) { | 518 if (resolved_method.is_null()) { |
512 // no method found | 519 // no method found |
513 ResourceMark rm(THREAD); | 520 ResourceMark rm(THREAD); |
514 THROW_MSG(vmSymbols::java_lang_NoSuchMethodError(), | 521 THROW_MSG(vmSymbols::java_lang_NoSuchMethodError(), |
515 methodOopDesc::name_and_sig_as_C_string(Klass::cast(resolved_klass()), | 522 Method::name_and_sig_as_C_string(Klass::cast(resolved_klass()), |
516 method_name, | 523 method_name, |
517 method_signature)); | 524 method_signature)); |
518 } | 525 } |
519 } | 526 } |
520 | 527 |
521 if (check_access) { | 528 if (check_access) { |
522 HandleMark hm(THREAD); | 529 HandleMark hm(THREAD); |
523 Handle loader (THREAD, instanceKlass::cast(current_klass())->class_loader()); | 530 Handle loader (THREAD, InstanceKlass::cast(current_klass())->class_loader()); |
524 Handle class_loader (THREAD, instanceKlass::cast(resolved_method->method_holder())->class_loader()); | 531 Handle class_loader (THREAD, resolved_method->method_holder()->class_loader()); |
525 { | 532 { |
526 ResourceMark rm(THREAD); | 533 ResourceMark rm(THREAD); |
527 char* failed_type_name = | 534 char* failed_type_name = |
528 SystemDictionary::check_signature_loaders(method_signature, loader, | 535 SystemDictionary::check_signature_loaders(method_signature, loader, |
529 class_loader, true, CHECK); | 536 class_loader, true, CHECK); |
531 const char* msg = "loader constraint violation: when resolving " | 538 const char* msg = "loader constraint violation: when resolving " |
532 "interface method \"%s\" the class loader (instance of %s) of the " | 539 "interface method \"%s\" the class loader (instance of %s) of the " |
533 "current class, %s, and the class loader (instance of %s) for " | 540 "current class, %s, and the class loader (instance of %s) for " |
534 "resolved class, %s, have different Class objects for the type %s " | 541 "resolved class, %s, have different Class objects for the type %s " |
535 "used in the signature"; | 542 "used in the signature"; |
536 char* sig = methodOopDesc::name_and_sig_as_C_string(Klass::cast(resolved_klass()),method_name,method_signature); | 543 char* sig = Method::name_and_sig_as_C_string(Klass::cast(resolved_klass()),method_name,method_signature); |
537 const char* loader1 = SystemDictionary::loader_name(loader()); | 544 const char* loader1 = SystemDictionary::loader_name(loader()); |
538 char* current = instanceKlass::cast(current_klass())->name()->as_C_string(); | 545 char* current = InstanceKlass::cast(current_klass())->name()->as_C_string(); |
539 const char* loader2 = SystemDictionary::loader_name(class_loader()); | 546 const char* loader2 = SystemDictionary::loader_name(class_loader()); |
540 char* resolved = instanceKlass::cast(resolved_klass())->name()->as_C_string(); | 547 char* resolved = InstanceKlass::cast(resolved_klass())->name()->as_C_string(); |
541 size_t buflen = strlen(msg) + strlen(sig) + strlen(loader1) + | 548 size_t buflen = strlen(msg) + strlen(sig) + strlen(loader1) + |
542 strlen(current) + strlen(loader2) + strlen(resolved) + | 549 strlen(current) + strlen(loader2) + strlen(resolved) + |
543 strlen(failed_type_name); | 550 strlen(failed_type_name); |
544 char* buf = NEW_RESOURCE_ARRAY_IN_THREAD(THREAD, char, buflen); | 551 char* buf = NEW_RESOURCE_ARRAY_IN_THREAD(THREAD, char, buflen); |
545 jio_snprintf(buf, buflen, msg, sig, loader1, current, loader2, | 552 jio_snprintf(buf, buflen, msg, sig, loader1, current, loader2, |
556 void LinkResolver::check_field_accessability(KlassHandle ref_klass, | 563 void LinkResolver::check_field_accessability(KlassHandle ref_klass, |
557 KlassHandle resolved_klass, | 564 KlassHandle resolved_klass, |
558 KlassHandle sel_klass, | 565 KlassHandle sel_klass, |
559 fieldDescriptor& fd, | 566 fieldDescriptor& fd, |
560 TRAPS) { | 567 TRAPS) { |
561 if (!Reflection::verify_field_access(ref_klass->as_klassOop(), | 568 if (!Reflection::verify_field_access(ref_klass(), |
562 resolved_klass->as_klassOop(), | 569 resolved_klass(), |
563 sel_klass->as_klassOop(), | 570 sel_klass(), |
564 fd.access_flags(), | 571 fd.access_flags(), |
565 true)) { | 572 true)) { |
566 ResourceMark rm(THREAD); | 573 ResourceMark rm(THREAD); |
567 Exceptions::fthrow( | 574 Exceptions::fthrow( |
568 THREAD_AND_LOCATION, | 575 THREAD_AND_LOCATION, |
603 THROW_MSG(vmSymbols::java_lang_NoSuchFieldError(), field->as_C_string()); | 610 THROW_MSG(vmSymbols::java_lang_NoSuchFieldError(), field->as_C_string()); |
604 } | 611 } |
605 | 612 |
606 // Resolve instance field | 613 // Resolve instance field |
607 fieldDescriptor fd; // find_field initializes fd if found | 614 fieldDescriptor fd; // find_field initializes fd if found |
608 KlassHandle sel_klass(THREAD, instanceKlass::cast(resolved_klass())->find_field(field, sig, &fd)); | 615 KlassHandle sel_klass(THREAD, InstanceKlass::cast(resolved_klass())->find_field(field, sig, &fd)); |
609 // check if field exists; i.e., if a klass containing the field def has been selected | 616 // check if field exists; i.e., if a klass containing the field def has been selected |
610 if (sel_klass.is_null()){ | 617 if (sel_klass.is_null()){ |
611 ResourceMark rm(THREAD); | 618 ResourceMark rm(THREAD); |
612 THROW_MSG(vmSymbols::java_lang_NoSuchFieldError(), field->as_C_string()); | 619 THROW_MSG(vmSymbols::java_lang_NoSuchFieldError(), field->as_C_string()); |
613 } | 620 } |
639 sel_klass->initialize(CHECK); | 646 sel_klass->initialize(CHECK); |
640 } | 647 } |
641 | 648 |
642 { | 649 { |
643 HandleMark hm(THREAD); | 650 HandleMark hm(THREAD); |
644 Handle ref_loader (THREAD, instanceKlass::cast(ref_klass())->class_loader()); | 651 Handle ref_loader (THREAD, InstanceKlass::cast(ref_klass())->class_loader()); |
645 Handle sel_loader (THREAD, instanceKlass::cast(sel_klass())->class_loader()); | 652 Handle sel_loader (THREAD, InstanceKlass::cast(sel_klass())->class_loader()); |
646 Symbol* signature_ref = pool->signature_ref_at(index); | 653 Symbol* signature_ref = pool->signature_ref_at(index); |
647 { | 654 { |
648 ResourceMark rm(THREAD); | 655 ResourceMark rm(THREAD); |
649 char* failed_type_name = | 656 char* failed_type_name = |
650 SystemDictionary::check_signature_loaders(signature_ref, | 657 SystemDictionary::check_signature_loaders(signature_ref, |
656 " \"%s\" the class loader (instance of %s) of the referring class, " | 663 " \"%s\" the class loader (instance of %s) of the referring class, " |
657 "%s, and the class loader (instance of %s) for the field's resolved " | 664 "%s, and the class loader (instance of %s) for the field's resolved " |
658 "type, %s, have different Class objects for that type"; | 665 "type, %s, have different Class objects for that type"; |
659 char* field_name = field->as_C_string(); | 666 char* field_name = field->as_C_string(); |
660 const char* loader1 = SystemDictionary::loader_name(ref_loader()); | 667 const char* loader1 = SystemDictionary::loader_name(ref_loader()); |
661 char* sel = instanceKlass::cast(sel_klass())->name()->as_C_string(); | 668 char* sel = InstanceKlass::cast(sel_klass())->name()->as_C_string(); |
662 const char* loader2 = SystemDictionary::loader_name(sel_loader()); | 669 const char* loader2 = SystemDictionary::loader_name(sel_loader()); |
663 size_t buflen = strlen(msg) + strlen(field_name) + strlen(loader1) + | 670 size_t buflen = strlen(msg) + strlen(field_name) + strlen(loader1) + |
664 strlen(sel) + strlen(loader2) + strlen(failed_type_name); | 671 strlen(sel) + strlen(loader2) + strlen(failed_type_name); |
665 char* buf = NEW_RESOURCE_ARRAY_IN_THREAD(THREAD, char, buflen); | 672 char* buf = NEW_RESOURCE_ARRAY_IN_THREAD(THREAD, char, buflen); |
666 jio_snprintf(buf, buflen, msg, field_name, loader1, sel, loader2, | 673 jio_snprintf(buf, buflen, msg, field_name, loader1, sel, loader2, |
716 | 723 |
717 // check if static | 724 // check if static |
718 if (!resolved_method->is_static()) { | 725 if (!resolved_method->is_static()) { |
719 ResourceMark rm(THREAD); | 726 ResourceMark rm(THREAD); |
720 char buf[200]; | 727 char buf[200]; |
721 jio_snprintf(buf, sizeof(buf), "Expected static method %s", methodOopDesc::name_and_sig_as_C_string(Klass::cast(resolved_klass()), | 728 jio_snprintf(buf, sizeof(buf), "Expected static method %s", Method::name_and_sig_as_C_string(Klass::cast(resolved_klass()), |
722 resolved_method->name(), | 729 resolved_method->name(), |
723 resolved_method->signature())); | 730 resolved_method->signature())); |
724 THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(), buf); | 731 THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(), buf); |
725 } | 732 } |
726 } | 733 } |
735 | 742 |
736 // throws linktime exceptions | 743 // throws linktime exceptions |
737 void LinkResolver::linktime_resolve_special_method(methodHandle& resolved_method, KlassHandle resolved_klass, | 744 void LinkResolver::linktime_resolve_special_method(methodHandle& resolved_method, KlassHandle resolved_klass, |
738 Symbol* method_name, Symbol* method_signature, | 745 Symbol* method_name, Symbol* method_signature, |
739 KlassHandle current_klass, bool check_access, TRAPS) { | 746 KlassHandle current_klass, bool check_access, TRAPS) { |
747 | |
748 if (resolved_klass->is_interface() && current_klass() != NULL) { | |
749 // If the target class is a direct interface, treat this as a "super" | |
750 // default call. | |
751 // | |
752 // If the current method is an overpass that happens to call a direct | |
753 // super-interface's method, then we'll end up rerunning the default method | |
754 // analysis even though we don't need to, but that's ok since it will end | |
755 // up with the same answer. | |
756 InstanceKlass* ik = InstanceKlass::cast(current_klass()); | |
757 Array<Klass*>* interfaces = ik->local_interfaces(); | |
758 int num_interfaces = interfaces->length(); | |
759 for (int index = 0; index < num_interfaces; index++) { | |
760 if (interfaces->at(index) == resolved_klass()) { | |
761 Method* method = DefaultMethods::find_super_default(current_klass(), | |
762 resolved_klass(), method_name, method_signature, CHECK); | |
763 resolved_method = methodHandle(THREAD, method); | |
764 return; | |
765 } | |
766 } | |
767 } | |
740 | 768 |
741 resolve_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, check_access, CHECK); | 769 resolve_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, check_access, CHECK); |
742 | 770 |
743 // check if method name is <init>, that it is found in same klass as static type | 771 // check if method name is <init>, that it is found in same klass as static type |
744 if (resolved_method->name() == vmSymbols::object_initializer_name() && | 772 if (resolved_method->name() == vmSymbols::object_initializer_name() && |
759 if (resolved_method->is_static()) { | 787 if (resolved_method->is_static()) { |
760 ResourceMark rm(THREAD); | 788 ResourceMark rm(THREAD); |
761 char buf[200]; | 789 char buf[200]; |
762 jio_snprintf(buf, sizeof(buf), | 790 jio_snprintf(buf, sizeof(buf), |
763 "Expecting non-static method %s", | 791 "Expecting non-static method %s", |
764 methodOopDesc::name_and_sig_as_C_string(Klass::cast(resolved_klass()), | 792 Method::name_and_sig_as_C_string(Klass::cast(resolved_klass()), |
765 resolved_method->name(), | 793 resolved_method->name(), |
766 resolved_method->signature())); | 794 resolved_method->signature())); |
767 THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(), buf); | 795 THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(), buf); |
768 } | 796 } |
769 } | 797 } |
777 | 805 |
778 // check if this is an old-style super call and do a new lookup if so | 806 // check if this is an old-style super call and do a new lookup if so |
779 { KlassHandle method_klass = KlassHandle(THREAD, | 807 { KlassHandle method_klass = KlassHandle(THREAD, |
780 resolved_method->method_holder()); | 808 resolved_method->method_holder()); |
781 | 809 |
782 if (check_access && | 810 const bool direct_calling_default_method = |
811 resolved_klass() != NULL && resolved_method() != NULL && | |
812 resolved_klass->is_interface() && !resolved_method->is_abstract(); | |
813 | |
814 if (!direct_calling_default_method && | |
815 check_access && | |
783 // a) check if ACC_SUPER flag is set for the current class | 816 // a) check if ACC_SUPER flag is set for the current class |
784 current_klass->is_super() && | 817 current_klass->is_super() && |
785 // b) check if the method class is a superclass of the current class (superclass relation is not reflexive!) | 818 // b) check if the method class is a superclass of the current class (superclass relation is not reflexive!) |
786 current_klass->is_subtype_of(method_klass()) && current_klass() != method_klass() && | 819 current_klass->is_subtype_of(method_klass()) && |
820 current_klass() != method_klass() && | |
787 // c) check if the method is not <init> | 821 // c) check if the method is not <init> |
788 resolved_method->name() != vmSymbols::object_initializer_name()) { | 822 resolved_method->name() != vmSymbols::object_initializer_name()) { |
789 // Lookup super method | 823 // Lookup super method |
790 KlassHandle super_klass(THREAD, current_klass->super()); | 824 KlassHandle super_klass(THREAD, current_klass->super()); |
791 lookup_instance_method_in_klasses(sel_method, super_klass, | 825 lookup_instance_method_in_klasses(sel_method, super_klass, |
793 resolved_method->signature(), CHECK); | 827 resolved_method->signature(), CHECK); |
794 // check if found | 828 // check if found |
795 if (sel_method.is_null()) { | 829 if (sel_method.is_null()) { |
796 ResourceMark rm(THREAD); | 830 ResourceMark rm(THREAD); |
797 THROW_MSG(vmSymbols::java_lang_AbstractMethodError(), | 831 THROW_MSG(vmSymbols::java_lang_AbstractMethodError(), |
798 methodOopDesc::name_and_sig_as_C_string(Klass::cast(resolved_klass()), | 832 Method::name_and_sig_as_C_string(Klass::cast(resolved_klass()), |
799 resolved_method->name(), | 833 resolved_method->name(), |
800 resolved_method->signature())); | 834 resolved_method->signature())); |
801 } | 835 } |
802 } | 836 } |
803 } | 837 } |
804 | 838 |
805 // check if not static | 839 // check if not static |
806 if (sel_method->is_static()) { | 840 if (sel_method->is_static()) { |
807 ResourceMark rm(THREAD); | 841 ResourceMark rm(THREAD); |
808 char buf[200]; | 842 char buf[200]; |
809 jio_snprintf(buf, sizeof(buf), "Expecting non-static method %s", methodOopDesc::name_and_sig_as_C_string(Klass::cast(resolved_klass()), | 843 jio_snprintf(buf, sizeof(buf), "Expecting non-static method %s", Method::name_and_sig_as_C_string(Klass::cast(resolved_klass()), |
810 resolved_method->name(), | 844 resolved_method->name(), |
811 resolved_method->signature())); | 845 resolved_method->signature())); |
812 THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(), buf); | 846 THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(), buf); |
813 } | 847 } |
814 | 848 |
815 // check if abstract | 849 // check if abstract |
816 if (sel_method->is_abstract()) { | 850 if (sel_method->is_abstract()) { |
817 ResourceMark rm(THREAD); | 851 ResourceMark rm(THREAD); |
818 THROW_MSG(vmSymbols::java_lang_AbstractMethodError(), | 852 THROW_MSG(vmSymbols::java_lang_AbstractMethodError(), |
819 methodOopDesc::name_and_sig_as_C_string(Klass::cast(resolved_klass()), | 853 Method::name_and_sig_as_C_string(Klass::cast(resolved_klass()), |
820 sel_method->name(), | 854 sel_method->name(), |
821 sel_method->signature())); | 855 sel_method->signature())); |
822 } | 856 } |
823 | 857 |
824 // setup result | 858 // setup result |
845 | 879 |
846 // check if not static | 880 // check if not static |
847 if (resolved_method->is_static()) { | 881 if (resolved_method->is_static()) { |
848 ResourceMark rm(THREAD); | 882 ResourceMark rm(THREAD); |
849 char buf[200]; | 883 char buf[200]; |
850 jio_snprintf(buf, sizeof(buf), "Expecting non-static method %s", methodOopDesc::name_and_sig_as_C_string(Klass::cast(resolved_klass()), | 884 jio_snprintf(buf, sizeof(buf), "Expecting non-static method %s", Method::name_and_sig_as_C_string(Klass::cast(resolved_klass()), |
851 resolved_method->name(), | 885 resolved_method->name(), |
852 resolved_method->signature())); | 886 resolved_method->signature())); |
853 THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(), buf); | 887 THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(), buf); |
854 } | 888 } |
855 } | 889 } |
862 KlassHandle recv_klass, | 896 KlassHandle recv_klass, |
863 bool check_null_and_abstract, | 897 bool check_null_and_abstract, |
864 TRAPS) { | 898 TRAPS) { |
865 | 899 |
866 // setup default return values | 900 // setup default return values |
867 int vtable_index = methodOopDesc::invalid_vtable_index; | 901 int vtable_index = Method::invalid_vtable_index; |
868 methodHandle selected_method; | 902 methodHandle selected_method; |
869 | 903 |
870 assert(recv.is_null() || recv->is_oop(), "receiver is not an oop"); | 904 assert(recv.is_null() || recv->is_oop(), "receiver is not an oop"); |
871 | 905 |
872 // runtime method resolution | 906 // runtime method resolution |
873 if (check_null_and_abstract && recv.is_null()) { // check if receiver exists | 907 if (check_null_and_abstract && recv.is_null()) { // check if receiver exists |
874 THROW(vmSymbols::java_lang_NullPointerException()); | 908 THROW(vmSymbols::java_lang_NullPointerException()); |
875 } | 909 } |
876 | 910 |
877 // Virtual methods cannot be resolved before its klass has been linked, for otherwise the methodOop's | 911 // Virtual methods cannot be resolved before its klass has been linked, for otherwise the Method*'s |
878 // has not been rewritten, and the vtable initialized. | 912 // has not been rewritten, and the vtable initialized. |
879 assert(instanceKlass::cast(resolved_method->method_holder())->is_linked(), "must be linked"); | 913 assert(resolved_method->method_holder()->is_linked(), "must be linked"); |
880 | 914 |
881 // Virtual methods cannot be resolved before its klass has been linked, for otherwise the methodOop's | 915 // Virtual methods cannot be resolved before its klass has been linked, for otherwise the Method*'s |
882 // has not been rewritten, and the vtable initialized. Make sure to do this after the nullcheck, since | 916 // has not been rewritten, and the vtable initialized. Make sure to do this after the nullcheck, since |
883 // a missing receiver might result in a bogus lookup. | 917 // a missing receiver might result in a bogus lookup. |
884 assert(instanceKlass::cast(resolved_method->method_holder())->is_linked(), "must be linked"); | 918 assert(resolved_method->method_holder()->is_linked(), "must be linked"); |
885 | 919 |
886 // do lookup based on receiver klass using the vtable index | 920 // do lookup based on receiver klass using the vtable index |
887 if (resolved_method->method_holder()->klass_part()->is_interface()) { // miranda method | 921 if (resolved_method->method_holder()->is_interface()) { // miranda method |
888 vtable_index = vtable_index_of_miranda_method(resolved_klass, | 922 vtable_index = vtable_index_of_miranda_method(resolved_klass, |
889 resolved_method->name(), | 923 resolved_method->name(), |
890 resolved_method->signature(), CHECK); | 924 resolved_method->signature(), CHECK); |
891 assert(vtable_index >= 0 , "we should have valid vtable index at this point"); | 925 assert(vtable_index >= 0 , "we should have valid vtable index at this point"); |
892 | 926 |
893 instanceKlass* inst = instanceKlass::cast(recv_klass()); | 927 InstanceKlass* inst = InstanceKlass::cast(recv_klass()); |
894 selected_method = methodHandle(THREAD, inst->method_at_vtable(vtable_index)); | 928 selected_method = methodHandle(THREAD, inst->method_at_vtable(vtable_index)); |
895 } else { | 929 } else { |
896 // at this point we are sure that resolved_method is virtual and not | 930 // at this point we are sure that resolved_method is virtual and not |
897 // a miranda method; therefore, it must have a valid vtable index. | 931 // a miranda method; therefore, it must have a valid vtable index. |
898 vtable_index = resolved_method->vtable_index(); | 932 vtable_index = resolved_method->vtable_index(); |
899 // We could get a negative vtable_index for final methods, | 933 // We could get a negative vtable_index for final methods, |
900 // because as an optimization they are they are never put in the vtable, | 934 // because as an optimization they are they are never put in the vtable, |
901 // unless they override an existing method. | 935 // unless they override an existing method. |
902 // If we do get a negative, it means the resolved method is the the selected | 936 // If we do get a negative, it means the resolved method is the the selected |
903 // method, and it can never be changed by an override. | 937 // method, and it can never be changed by an override. |
904 if (vtable_index == methodOopDesc::nonvirtual_vtable_index) { | 938 if (vtable_index == Method::nonvirtual_vtable_index) { |
905 assert(resolved_method->can_be_statically_bound(), "cannot override this method"); | 939 assert(resolved_method->can_be_statically_bound(), "cannot override this method"); |
906 selected_method = resolved_method; | 940 selected_method = resolved_method; |
907 } else { | 941 } else { |
908 // recv_klass might be an arrayKlassOop but all vtables start at | 942 // recv_klass might be an arrayKlassOop but all vtables start at |
909 // the same place. The cast is to avoid virtual call and assertion. | 943 // the same place. The cast is to avoid virtual call and assertion. |
910 instanceKlass* inst = (instanceKlass*)recv_klass()->klass_part(); | 944 InstanceKlass* inst = (InstanceKlass*)recv_klass(); |
911 selected_method = methodHandle(THREAD, inst->method_at_vtable(vtable_index)); | 945 selected_method = methodHandle(THREAD, inst->method_at_vtable(vtable_index)); |
912 } | 946 } |
913 } | 947 } |
914 | 948 |
915 // check if method exists | 949 // check if method exists |
916 if (selected_method.is_null()) { | 950 if (selected_method.is_null()) { |
917 ResourceMark rm(THREAD); | 951 ResourceMark rm(THREAD); |
918 THROW_MSG(vmSymbols::java_lang_AbstractMethodError(), | 952 THROW_MSG(vmSymbols::java_lang_AbstractMethodError(), |
919 methodOopDesc::name_and_sig_as_C_string(Klass::cast(resolved_klass()), | 953 Method::name_and_sig_as_C_string(Klass::cast(resolved_klass()), |
920 resolved_method->name(), | 954 resolved_method->name(), |
921 resolved_method->signature())); | 955 resolved_method->signature())); |
922 } | 956 } |
923 | 957 |
924 // check if abstract | 958 // check if abstract |
925 if (check_null_and_abstract && selected_method->is_abstract()) { | 959 if (check_null_and_abstract && selected_method->is_abstract()) { |
926 ResourceMark rm(THREAD); | 960 ResourceMark rm(THREAD); |
927 THROW_MSG(vmSymbols::java_lang_AbstractMethodError(), | 961 THROW_MSG(vmSymbols::java_lang_AbstractMethodError(), |
928 methodOopDesc::name_and_sig_as_C_string(Klass::cast(resolved_klass()), | 962 Method::name_and_sig_as_C_string(Klass::cast(resolved_klass()), |
929 selected_method->name(), | 963 selected_method->name(), |
930 selected_method->signature())); | 964 selected_method->signature())); |
931 } | 965 } |
932 | 966 |
933 // setup result | 967 // setup result |
976 resolved_method->signature(), CHECK); | 1010 resolved_method->signature(), CHECK); |
977 // check if method exists | 1011 // check if method exists |
978 if (sel_method.is_null()) { | 1012 if (sel_method.is_null()) { |
979 ResourceMark rm(THREAD); | 1013 ResourceMark rm(THREAD); |
980 THROW_MSG(vmSymbols::java_lang_AbstractMethodError(), | 1014 THROW_MSG(vmSymbols::java_lang_AbstractMethodError(), |
981 methodOopDesc::name_and_sig_as_C_string(Klass::cast(recv_klass()), | 1015 Method::name_and_sig_as_C_string(Klass::cast(recv_klass()), |
982 resolved_method->name(), | 1016 resolved_method->name(), |
983 resolved_method->signature())); | 1017 resolved_method->signature())); |
984 } | 1018 } |
985 // check if public | 1019 // check if public |
986 if (!sel_method->is_public()) { | 1020 if (!sel_method->is_public()) { |
987 ResourceMark rm(THREAD); | 1021 ResourceMark rm(THREAD); |
988 THROW_MSG(vmSymbols::java_lang_IllegalAccessError(), | 1022 THROW_MSG(vmSymbols::java_lang_IllegalAccessError(), |
989 methodOopDesc::name_and_sig_as_C_string(Klass::cast(recv_klass()), | 1023 Method::name_and_sig_as_C_string(Klass::cast(recv_klass()), |
990 sel_method->name(), | 1024 sel_method->name(), |
991 sel_method->signature())); | 1025 sel_method->signature())); |
992 } | 1026 } |
993 // check if abstract | 1027 // check if abstract |
994 if (check_null_and_abstract && sel_method->is_abstract()) { | 1028 if (check_null_and_abstract && sel_method->is_abstract()) { |
995 ResourceMark rm(THREAD); | 1029 ResourceMark rm(THREAD); |
996 THROW_MSG(vmSymbols::java_lang_AbstractMethodError(), | 1030 THROW_MSG(vmSymbols::java_lang_AbstractMethodError(), |
997 methodOopDesc::name_and_sig_as_C_string(Klass::cast(recv_klass()), | 1031 Method::name_and_sig_as_C_string(Klass::cast(recv_klass()), |
998 sel_method->name(), | 1032 sel_method->name(), |
999 sel_method->signature())); | 1033 sel_method->signature())); |
1000 } | 1034 } |
1001 // setup result | 1035 // setup result |
1002 result.set_interface(resolved_klass, recv_klass, resolved_method, sel_method, CHECK); | 1036 result.set_interface(resolved_klass, recv_klass, resolved_method, sel_method, CHECK); |
1078 EXCEPTION_MARK; | 1112 EXCEPTION_MARK; |
1079 CallInfo info; | 1113 CallInfo info; |
1080 resolve_virtual_call(info, Handle(), receiver_klass, resolved_klass, name, signature, current_klass, true, false, THREAD); | 1114 resolve_virtual_call(info, Handle(), receiver_klass, resolved_klass, name, signature, current_klass, true, false, THREAD); |
1081 if (HAS_PENDING_EXCEPTION) { | 1115 if (HAS_PENDING_EXCEPTION) { |
1082 CLEAR_PENDING_EXCEPTION; | 1116 CLEAR_PENDING_EXCEPTION; |
1083 return methodOopDesc::invalid_vtable_index; | 1117 return Method::invalid_vtable_index; |
1084 } | 1118 } |
1085 return info.vtable_index(); | 1119 return info.vtable_index(); |
1086 } | 1120 } |
1087 | 1121 |
1088 methodHandle LinkResolver::resolve_static_call_or_null( | 1122 methodHandle LinkResolver::resolve_static_call_or_null( |
1168 KlassHandle resolved_klass; | 1202 KlassHandle resolved_klass; |
1169 Symbol* method_name = NULL; | 1203 Symbol* method_name = NULL; |
1170 Symbol* method_signature = NULL; | 1204 Symbol* method_signature = NULL; |
1171 KlassHandle current_klass; | 1205 KlassHandle current_klass; |
1172 resolve_pool(resolved_klass, method_name, method_signature, current_klass, pool, index, CHECK); | 1206 resolve_pool(resolved_klass, method_name, method_signature, current_klass, pool, index, CHECK); |
1173 KlassHandle recvrKlass (THREAD, recv.is_null() ? (klassOop)NULL : recv->klass()); | 1207 KlassHandle recvrKlass (THREAD, recv.is_null() ? (Klass*)NULL : recv->klass()); |
1174 resolve_virtual_call(result, recv, recvrKlass, resolved_klass, method_name, method_signature, current_klass, true, true, CHECK); | 1208 resolve_virtual_call(result, recv, recvrKlass, resolved_klass, method_name, method_signature, current_klass, true, true, CHECK); |
1175 } | 1209 } |
1176 | 1210 |
1177 | 1211 |
1178 void LinkResolver::resolve_invokeinterface(CallInfo& result, Handle recv, constantPoolHandle pool, int index, TRAPS) { | 1212 void LinkResolver::resolve_invokeinterface(CallInfo& result, Handle recv, constantPoolHandle pool, int index, TRAPS) { |
1179 KlassHandle resolved_klass; | 1213 KlassHandle resolved_klass; |
1180 Symbol* method_name = NULL; | 1214 Symbol* method_name = NULL; |
1181 Symbol* method_signature = NULL; | 1215 Symbol* method_signature = NULL; |
1182 KlassHandle current_klass; | 1216 KlassHandle current_klass; |
1183 resolve_pool(resolved_klass, method_name, method_signature, current_klass, pool, index, CHECK); | 1217 resolve_pool(resolved_klass, method_name, method_signature, current_klass, pool, index, CHECK); |
1184 KlassHandle recvrKlass (THREAD, recv.is_null() ? (klassOop)NULL : recv->klass()); | 1218 KlassHandle recvrKlass (THREAD, recv.is_null() ? (Klass*)NULL : recv->klass()); |
1185 resolve_interface_call(result, recv, recvrKlass, resolved_klass, method_name, method_signature, current_klass, true, true, CHECK); | 1219 resolve_interface_call(result, recv, recvrKlass, resolved_klass, method_name, method_signature, current_klass, true, true, CHECK); |
1186 } | 1220 } |
1187 | 1221 |
1188 | 1222 |
1189 void LinkResolver::resolve_invokehandle(CallInfo& result, constantPoolHandle pool, int index, TRAPS) { | 1223 void LinkResolver::resolve_invokehandle(CallInfo& result, constantPoolHandle pool, int index, TRAPS) { |
1205 TRAPS) { | 1239 TRAPS) { |
1206 // JSR 292: this must be an implicitly generated method MethodHandle.invokeExact(*...) or similar | 1240 // JSR 292: this must be an implicitly generated method MethodHandle.invokeExact(*...) or similar |
1207 assert(resolved_klass() == SystemDictionary::MethodHandle_klass(), ""); | 1241 assert(resolved_klass() == SystemDictionary::MethodHandle_klass(), ""); |
1208 assert(MethodHandles::is_signature_polymorphic_name(method_name), ""); | 1242 assert(MethodHandles::is_signature_polymorphic_name(method_name), ""); |
1209 methodHandle resolved_method; | 1243 methodHandle resolved_method; |
1210 Handle resolved_appendix; | 1244 Handle resolved_appendix; |
1245 Handle resolved_method_type; | |
1211 lookup_polymorphic_method(resolved_method, resolved_klass, | 1246 lookup_polymorphic_method(resolved_method, resolved_klass, |
1212 method_name, method_signature, | 1247 method_name, method_signature, |
1213 current_klass, &resolved_appendix, CHECK); | 1248 current_klass, &resolved_appendix, &resolved_method_type, CHECK); |
1214 result.set_handle(resolved_method, resolved_appendix, CHECK); | 1249 result.set_handle(resolved_method, resolved_appendix, resolved_method_type, CHECK); |
1215 } | 1250 } |
1216 | 1251 |
1217 | 1252 |
1218 void LinkResolver::resolve_invokedynamic(CallInfo& result, constantPoolHandle pool, int index, TRAPS) { | 1253 void LinkResolver::resolve_invokedynamic(CallInfo& result, constantPoolHandle pool, int index, TRAPS) { |
1219 assert(EnableInvokeDynamic, ""); | 1254 assert(EnableInvokeDynamic, ""); |
1220 pool->set_invokedynamic(); // mark header to flag active call sites | 1255 pool->set_invokedynamic(); // mark header to flag active call sites |
1221 | 1256 |
1222 //resolve_pool(<resolved_klass>, method_name, method_signature, current_klass, pool, index, CHECK); | 1257 //resolve_pool(<resolved_klass>, method_name, method_signature, current_klass, pool, index, CHECK); |
1223 Symbol* method_name = pool->name_ref_at(index); | 1258 Symbol* method_name = pool->name_ref_at(index); |
1224 Symbol* method_signature = pool->signature_ref_at(index); | 1259 Symbol* method_signature = pool->signature_ref_at(index); |
1225 KlassHandle current_klass = KlassHandle(THREAD, pool->pool_holder()); | 1260 KlassHandle current_klass = KlassHandle(THREAD, pool->pool_holder()); |
1226 | 1261 |
1227 // Resolve the bootstrap specifier (BSM + optional arguments). | 1262 // Resolve the bootstrap specifier (BSM + optional arguments). |
1228 Handle bootstrap_specifier; | 1263 Handle bootstrap_specifier; |
1229 // Check if CallSite has been bound already: | 1264 // Check if CallSite has been bound already: |
1230 ConstantPoolCacheEntry* cpce = pool->cache()->secondary_entry_at(index); | 1265 ConstantPoolCacheEntry* cpce = pool->invokedynamic_cp_cache_entry_at(index); |
1231 if (cpce->is_f1_null()) { | 1266 if (cpce->is_f1_null()) { |
1232 int pool_index = pool->cache()->main_entry_at(index)->constant_pool_index(); | 1267 int pool_index = cpce->constant_pool_index(); |
1233 oop bsm_info = pool->resolve_bootstrap_specifier_at(pool_index, CHECK); | 1268 oop bsm_info = pool->resolve_bootstrap_specifier_at(pool_index, CHECK); |
1234 assert(bsm_info != NULL, ""); | 1269 assert(bsm_info != NULL, ""); |
1235 // FIXME: Cache this once per BootstrapMethods entry, not once per CONSTANT_InvokeDynamic. | 1270 // FIXME: Cache this once per BootstrapMethods entry, not once per CONSTANT_InvokeDynamic. |
1236 bootstrap_specifier = Handle(THREAD, bsm_info); | 1271 bootstrap_specifier = Handle(THREAD, bsm_info); |
1237 } | 1272 } |
1238 if (!cpce->is_f1_null()) { | 1273 if (!cpce->is_f1_null()) { |
1239 methodHandle method(THREAD, cpce->f2_as_vfinal_method()); | 1274 methodHandle method( THREAD, cpce->f1_as_method()); |
1240 Handle appendix(THREAD, cpce->has_appendix() ? cpce->f1_appendix() : (oop)NULL); | 1275 Handle appendix( THREAD, cpce->appendix_if_resolved(pool)); |
1241 result.set_handle(method, appendix, CHECK); | 1276 Handle method_type(THREAD, cpce->method_type_if_resolved(pool)); |
1277 result.set_handle(method, appendix, method_type, CHECK); | |
1242 return; | 1278 return; |
1243 } | 1279 } |
1244 | 1280 |
1245 if (TraceMethodHandles) { | 1281 if (TraceMethodHandles) { |
1246 tty->print_cr("resolve_invokedynamic #%d %s %s", | 1282 tty->print_cr("resolve_invokedynamic #%d %s %s", |
1247 constantPoolCacheOopDesc::decode_secondary_index(index), | 1283 ConstantPool::decode_invokedynamic_index(index), |
1248 method_name->as_C_string(), method_signature->as_C_string()); | 1284 method_name->as_C_string(), method_signature->as_C_string()); |
1249 tty->print(" BSM info: "); bootstrap_specifier->print(); | 1285 tty->print(" BSM info: "); bootstrap_specifier->print(); |
1250 } | 1286 } |
1251 | 1287 |
1252 resolve_dynamic_call(result, bootstrap_specifier, method_name, method_signature, current_klass, CHECK); | 1288 resolve_dynamic_call(result, bootstrap_specifier, method_name, method_signature, current_klass, CHECK); |
1258 KlassHandle current_klass, | 1294 KlassHandle current_klass, |
1259 TRAPS) { | 1295 TRAPS) { |
1260 // JSR 292: this must resolve to an implicitly generated method MH.linkToCallSite(*...) | 1296 // JSR 292: this must resolve to an implicitly generated method MH.linkToCallSite(*...) |
1261 // The appendix argument is likely to be a freshly-created CallSite. | 1297 // The appendix argument is likely to be a freshly-created CallSite. |
1262 Handle resolved_appendix; | 1298 Handle resolved_appendix; |
1299 Handle resolved_method_type; | |
1263 methodHandle resolved_method = | 1300 methodHandle resolved_method = |
1264 SystemDictionary::find_dynamic_call_site_invoker(current_klass, | 1301 SystemDictionary::find_dynamic_call_site_invoker(current_klass, |
1265 bootstrap_specifier, | 1302 bootstrap_specifier, |
1266 method_name, method_signature, | 1303 method_name, method_signature, |
1267 &resolved_appendix, | 1304 &resolved_appendix, |
1305 &resolved_method_type, | |
1268 THREAD); | 1306 THREAD); |
1269 if (HAS_PENDING_EXCEPTION) { | 1307 if (HAS_PENDING_EXCEPTION) { |
1270 if (TraceMethodHandles) { | 1308 if (TraceMethodHandles) { |
1271 tty->print_cr("invokedynamic throws BSME for "INTPTR_FORMAT, PENDING_EXCEPTION); | 1309 tty->print_cr("invokedynamic throws BSME for "INTPTR_FORMAT, PENDING_EXCEPTION); |
1272 PENDING_EXCEPTION->print(); | 1310 PENDING_EXCEPTION->print(); |
1282 // See the "Linking Exceptions" section for the invokedynamic instruction in the JVMS. | 1320 // See the "Linking Exceptions" section for the invokedynamic instruction in the JVMS. |
1283 Handle nested_exception(THREAD, PENDING_EXCEPTION); | 1321 Handle nested_exception(THREAD, PENDING_EXCEPTION); |
1284 CLEAR_PENDING_EXCEPTION; | 1322 CLEAR_PENDING_EXCEPTION; |
1285 THROW_CAUSE(vmSymbols::java_lang_BootstrapMethodError(), nested_exception) | 1323 THROW_CAUSE(vmSymbols::java_lang_BootstrapMethodError(), nested_exception) |
1286 } | 1324 } |
1287 result.set_handle(resolved_method, resolved_appendix, CHECK); | 1325 result.set_handle(resolved_method, resolved_appendix, resolved_method_type, CHECK); |
1288 } | 1326 } |
1289 | 1327 |
1290 //------------------------------------------------------------------------------------------------------------------------ | 1328 //------------------------------------------------------------------------------------------------------------------------ |
1291 #ifndef PRODUCT | 1329 #ifndef PRODUCT |
1292 | 1330 |