src/share/vm/interpreter/linkResolver.cpp

Sat, 07 Nov 2020 10:30:02 +0800

author
aoqi
date
Sat, 07 Nov 2020 10:30:02 +0800
changeset 10026
8c95980d0b66
parent 9448
73d689add964
permissions
-rw-r--r--

Added tag mips-jdk8u275-b01 for changeset d3b4d62f391f

aoqi@0 1 /*
hseigel@9403 2 * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
aoqi@0 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
aoqi@0 4 *
aoqi@0 5 * This code is free software; you can redistribute it and/or modify it
aoqi@0 6 * under the terms of the GNU General Public License version 2 only, as
aoqi@0 7 * published by the Free Software Foundation.
aoqi@0 8 *
aoqi@0 9 * This code is distributed in the hope that it will be useful, but WITHOUT
aoqi@0 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
aoqi@0 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
aoqi@0 12 * version 2 for more details (a copy is included in the LICENSE file that
aoqi@0 13 * accompanied this code).
aoqi@0 14 *
aoqi@0 15 * You should have received a copy of the GNU General Public License version
aoqi@0 16 * 2 along with this work; if not, write to the Free Software Foundation,
aoqi@0 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
aoqi@0 18 *
aoqi@0 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
aoqi@0 20 * or visit www.oracle.com if you need additional information or have any
aoqi@0 21 * questions.
aoqi@0 22 *
aoqi@0 23 */
aoqi@0 24
aoqi@0 25 #include "precompiled.hpp"
aoqi@0 26 #include "classfile/defaultMethods.hpp"
aoqi@0 27 #include "classfile/systemDictionary.hpp"
aoqi@0 28 #include "classfile/vmSymbols.hpp"
aoqi@0 29 #include "compiler/compileBroker.hpp"
aoqi@0 30 #include "gc_interface/collectedHeap.inline.hpp"
aoqi@0 31 #include "interpreter/bytecode.hpp"
aoqi@0 32 #include "interpreter/interpreterRuntime.hpp"
aoqi@0 33 #include "interpreter/linkResolver.hpp"
aoqi@0 34 #include "memory/resourceArea.hpp"
aoqi@0 35 #include "memory/universe.inline.hpp"
aoqi@0 36 #include "oops/instanceKlass.hpp"
aoqi@0 37 #include "oops/objArrayOop.hpp"
aoqi@0 38 #include "prims/methodHandles.hpp"
aoqi@0 39 #include "prims/nativeLookup.hpp"
aoqi@0 40 #include "runtime/compilationPolicy.hpp"
aoqi@0 41 #include "runtime/fieldDescriptor.hpp"
aoqi@0 42 #include "runtime/frame.inline.hpp"
aoqi@0 43 #include "runtime/handles.inline.hpp"
aoqi@0 44 #include "runtime/reflection.hpp"
aoqi@0 45 #include "runtime/signature.hpp"
aoqi@0 46 #include "runtime/thread.inline.hpp"
aoqi@0 47 #include "runtime/vmThread.hpp"
aoqi@0 48
aoqi@0 49
aoqi@0 50 //------------------------------------------------------------------------------------------------------------------------
aoqi@0 51 // Implementation of CallInfo
aoqi@0 52
aoqi@0 53
aoqi@0 54 void CallInfo::set_static(KlassHandle resolved_klass, methodHandle resolved_method, TRAPS) {
aoqi@0 55 int vtable_index = Method::nonvirtual_vtable_index;
aoqi@0 56 set_common(resolved_klass, resolved_klass, resolved_method, resolved_method, CallInfo::direct_call, vtable_index, CHECK);
aoqi@0 57 }
aoqi@0 58
aoqi@0 59
aoqi@0 60 void CallInfo::set_interface(KlassHandle resolved_klass, KlassHandle selected_klass, methodHandle resolved_method, methodHandle selected_method, int itable_index, TRAPS) {
aoqi@0 61 // This is only called for interface methods. If the resolved_method
aoqi@0 62 // comes from java/lang/Object, it can be the subject of a virtual call, so
aoqi@0 63 // we should pick the vtable index from the resolved method.
aoqi@0 64 // In that case, the caller must call set_virtual instead of set_interface.
aoqi@0 65 assert(resolved_method->method_holder()->is_interface(), "");
aoqi@0 66 assert(itable_index == resolved_method()->itable_index(), "");
aoqi@0 67 set_common(resolved_klass, selected_klass, resolved_method, selected_method, CallInfo::itable_call, itable_index, CHECK);
aoqi@0 68 }
aoqi@0 69
aoqi@0 70 void CallInfo::set_virtual(KlassHandle resolved_klass, KlassHandle selected_klass, methodHandle resolved_method, methodHandle selected_method, int vtable_index, TRAPS) {
aoqi@0 71 assert(vtable_index >= 0 || vtable_index == Method::nonvirtual_vtable_index, "valid index");
aoqi@0 72 assert(vtable_index < 0 || !resolved_method->has_vtable_index() || vtable_index == resolved_method->vtable_index(), "");
aoqi@0 73 CallKind kind = (vtable_index >= 0 && !resolved_method->can_be_statically_bound() ? CallInfo::vtable_call : CallInfo::direct_call);
aoqi@0 74 set_common(resolved_klass, selected_klass, resolved_method, selected_method, kind, vtable_index, CHECK);
aoqi@0 75 assert(!resolved_method->is_compiled_lambda_form(), "these must be handled via an invokehandle call");
aoqi@0 76 }
aoqi@0 77
aoqi@0 78 void CallInfo::set_handle(methodHandle resolved_method, Handle resolved_appendix, Handle resolved_method_type, TRAPS) {
aoqi@0 79 if (resolved_method.is_null()) {
aoqi@0 80 THROW_MSG(vmSymbols::java_lang_InternalError(), "resolved method is null");
aoqi@0 81 }
aoqi@0 82 KlassHandle resolved_klass = SystemDictionary::MethodHandle_klass();
aoqi@0 83 assert(resolved_method->intrinsic_id() == vmIntrinsics::_invokeBasic ||
aoqi@0 84 resolved_method->is_compiled_lambda_form(),
aoqi@0 85 "linkMethod must return one of these");
aoqi@0 86 int vtable_index = Method::nonvirtual_vtable_index;
aoqi@0 87 assert(!resolved_method->has_vtable_index(), "");
aoqi@0 88 set_common(resolved_klass, resolved_klass, resolved_method, resolved_method, CallInfo::direct_call, vtable_index, CHECK);
aoqi@0 89 _resolved_appendix = resolved_appendix;
aoqi@0 90 _resolved_method_type = resolved_method_type;
aoqi@0 91 }
aoqi@0 92
aoqi@0 93 void CallInfo::set_common(KlassHandle resolved_klass,
aoqi@0 94 KlassHandle selected_klass,
aoqi@0 95 methodHandle resolved_method,
aoqi@0 96 methodHandle selected_method,
aoqi@0 97 CallKind kind,
aoqi@0 98 int index,
aoqi@0 99 TRAPS) {
aoqi@0 100 assert(resolved_method->signature() == selected_method->signature(), "signatures must correspond");
aoqi@0 101 _resolved_klass = resolved_klass;
aoqi@0 102 _selected_klass = selected_klass;
aoqi@0 103 _resolved_method = resolved_method;
aoqi@0 104 _selected_method = selected_method;
aoqi@0 105 _call_kind = kind;
aoqi@0 106 _call_index = index;
aoqi@0 107 _resolved_appendix = Handle();
aoqi@0 108 DEBUG_ONLY(verify()); // verify before making side effects
aoqi@0 109
aoqi@0 110 if (CompilationPolicy::must_be_compiled(selected_method)) {
aoqi@0 111 // This path is unusual, mostly used by the '-Xcomp' stress test mode.
aoqi@0 112
aoqi@0 113 // Note: with several active threads, the must_be_compiled may be true
aoqi@0 114 // while can_be_compiled is false; remove assert
aoqi@0 115 // assert(CompilationPolicy::can_be_compiled(selected_method), "cannot compile");
aoqi@0 116 if (THREAD->is_Compiler_thread()) {
aoqi@0 117 // don't force compilation, resolve was on behalf of compiler
aoqi@0 118 return;
aoqi@0 119 }
aoqi@0 120 if (selected_method->method_holder()->is_not_initialized()) {
aoqi@0 121 // 'is_not_initialized' means not only '!is_initialized', but also that
aoqi@0 122 // initialization has not been started yet ('!being_initialized')
aoqi@0 123 // Do not force compilation of methods in uninitialized classes.
aoqi@0 124 // Note that doing this would throw an assert later,
aoqi@0 125 // in CompileBroker::compile_method.
aoqi@0 126 // We sometimes use the link resolver to do reflective lookups
aoqi@0 127 // even before classes are initialized.
aoqi@0 128 return;
aoqi@0 129 }
aoqi@0 130 CompileBroker::compile_method(selected_method, InvocationEntryBci,
aoqi@0 131 CompilationPolicy::policy()->initial_compile_level(),
aoqi@0 132 methodHandle(), 0, "must_be_compiled", CHECK);
aoqi@0 133 }
aoqi@0 134 }
aoqi@0 135
aoqi@0 136 // utility query for unreflecting a method
aoqi@0 137 CallInfo::CallInfo(Method* resolved_method, Klass* resolved_klass) {
aoqi@0 138 Klass* resolved_method_holder = resolved_method->method_holder();
aoqi@0 139 if (resolved_klass == NULL) { // 2nd argument defaults to holder of 1st
aoqi@0 140 resolved_klass = resolved_method_holder;
aoqi@0 141 }
aoqi@0 142 _resolved_klass = resolved_klass;
aoqi@0 143 _selected_klass = resolved_klass;
aoqi@0 144 _resolved_method = resolved_method;
aoqi@0 145 _selected_method = resolved_method;
aoqi@0 146 // classify:
aoqi@0 147 CallKind kind = CallInfo::unknown_kind;
aoqi@0 148 int index = resolved_method->vtable_index();
aoqi@0 149 if (resolved_method->can_be_statically_bound()) {
aoqi@0 150 kind = CallInfo::direct_call;
aoqi@0 151 } else if (!resolved_method_holder->is_interface()) {
aoqi@0 152 // Could be an Object method inherited into an interface, but still a vtable call.
aoqi@0 153 kind = CallInfo::vtable_call;
aoqi@0 154 } else if (!resolved_klass->is_interface()) {
aoqi@0 155 // A default or miranda method. Compute the vtable index.
aoqi@0 156 ResourceMark rm;
aoqi@0 157 klassVtable* vt = InstanceKlass::cast(resolved_klass)->vtable();
aoqi@0 158 index = LinkResolver::vtable_index_of_interface_method(resolved_klass,
aoqi@0 159 resolved_method);
aoqi@0 160 assert(index >= 0 , "we should have valid vtable index at this point");
aoqi@0 161
aoqi@0 162 kind = CallInfo::vtable_call;
aoqi@0 163 } else if (resolved_method->has_vtable_index()) {
aoqi@0 164 // Can occur if an interface redeclares a method of Object.
aoqi@0 165
aoqi@0 166 #ifdef ASSERT
aoqi@0 167 // Ensure that this is really the case.
aoqi@0 168 KlassHandle object_klass = SystemDictionary::Object_klass();
aoqi@0 169 Method * object_resolved_method = object_klass()->vtable()->method_at(index);
aoqi@0 170 assert(object_resolved_method->name() == resolved_method->name(),
aoqi@0 171 err_msg("Object and interface method names should match at vtable index %d, %s != %s",
aoqi@0 172 index, object_resolved_method->name()->as_C_string(), resolved_method->name()->as_C_string()));
aoqi@0 173 assert(object_resolved_method->signature() == resolved_method->signature(),
aoqi@0 174 err_msg("Object and interface method signatures should match at vtable index %d, %s != %s",
aoqi@0 175 index, object_resolved_method->signature()->as_C_string(), resolved_method->signature()->as_C_string()));
aoqi@0 176 #endif // ASSERT
aoqi@0 177
aoqi@0 178 kind = CallInfo::vtable_call;
aoqi@0 179 } else {
aoqi@0 180 // A regular interface call.
aoqi@0 181 kind = CallInfo::itable_call;
aoqi@0 182 index = resolved_method->itable_index();
aoqi@0 183 }
aoqi@0 184 assert(index == Method::nonvirtual_vtable_index || index >= 0, err_msg("bad index %d", index));
aoqi@0 185 _call_kind = kind;
aoqi@0 186 _call_index = index;
aoqi@0 187 _resolved_appendix = Handle();
aoqi@0 188 DEBUG_ONLY(verify());
aoqi@0 189 }
aoqi@0 190
aoqi@0 191 #ifdef ASSERT
aoqi@0 192 void CallInfo::verify() {
aoqi@0 193 switch (call_kind()) { // the meaning and allowed value of index depends on kind
aoqi@0 194 case CallInfo::direct_call:
aoqi@0 195 if (_call_index == Method::nonvirtual_vtable_index) break;
aoqi@0 196 // else fall through to check vtable index:
aoqi@0 197 case CallInfo::vtable_call:
aoqi@0 198 assert(resolved_klass()->verify_vtable_index(_call_index), "");
aoqi@0 199 break;
aoqi@0 200 case CallInfo::itable_call:
aoqi@0 201 assert(resolved_method()->method_holder()->verify_itable_index(_call_index), "");
aoqi@0 202 break;
aoqi@0 203 case CallInfo::unknown_kind:
aoqi@0 204 assert(call_kind() != CallInfo::unknown_kind, "CallInfo must be set");
aoqi@0 205 break;
aoqi@0 206 default:
aoqi@0 207 fatal(err_msg_res("Unexpected call kind %d", call_kind()));
aoqi@0 208 }
aoqi@0 209 }
aoqi@0 210 #endif //ASSERT
aoqi@0 211
aoqi@0 212
aoqi@0 213
aoqi@0 214 //------------------------------------------------------------------------------------------------------------------------
aoqi@0 215 // Klass resolution
aoqi@0 216
aoqi@0 217 void LinkResolver::check_klass_accessability(KlassHandle ref_klass, KlassHandle sel_klass, TRAPS) {
aoqi@0 218 if (!Reflection::verify_class_access(ref_klass(),
aoqi@0 219 sel_klass(),
aoqi@0 220 true)) {
aoqi@0 221 ResourceMark rm(THREAD);
aoqi@0 222 Exceptions::fthrow(
aoqi@0 223 THREAD_AND_LOCATION,
aoqi@0 224 vmSymbols::java_lang_IllegalAccessError(),
aoqi@0 225 "tried to access class %s from class %s",
aoqi@0 226 sel_klass->external_name(),
aoqi@0 227 ref_klass->external_name()
aoqi@0 228 );
aoqi@0 229 return;
aoqi@0 230 }
aoqi@0 231 }
aoqi@0 232
aoqi@0 233 void LinkResolver::resolve_klass(KlassHandle& result, constantPoolHandle pool, int index, TRAPS) {
aoqi@0 234 Klass* result_oop = pool->klass_ref_at(index, CHECK);
aoqi@0 235 result = KlassHandle(THREAD, result_oop);
aoqi@0 236 }
aoqi@0 237
aoqi@0 238 //------------------------------------------------------------------------------------------------------------------------
aoqi@0 239 // Method resolution
aoqi@0 240 //
aoqi@0 241 // According to JVM spec. $5.4.3c & $5.4.3d
aoqi@0 242
aoqi@0 243 // Look up method in klasses, including static methods
aoqi@0 244 // Then look up local default methods
aoqi@0 245 void LinkResolver::lookup_method_in_klasses(methodHandle& result, KlassHandle klass, Symbol* name, Symbol* signature, bool checkpolymorphism, bool in_imethod_resolve, TRAPS) {
aoqi@0 246 // Ignore overpasses so statics can be found during resolution
aoqi@0 247 Method* result_oop = klass->uncached_lookup_method(name, signature, Klass::skip_overpass);
aoqi@0 248
aoqi@0 249 if (klass->oop_is_array()) {
aoqi@0 250 // Only consider klass and super klass for arrays
aoqi@0 251 result = methodHandle(THREAD, result_oop);
aoqi@0 252 return;
aoqi@0 253 }
aoqi@0 254
aoqi@0 255 // JDK 8, JVMS 5.4.3.4: Interface method resolution should
aoqi@0 256 // ignore static and non-public methods of java.lang.Object,
aoqi@0 257 // like clone, finalize, registerNatives.
aoqi@0 258 if (in_imethod_resolve &&
aoqi@0 259 result_oop != NULL &&
aoqi@0 260 klass->is_interface() &&
aoqi@0 261 (result_oop->is_static() || !result_oop->is_public()) &&
aoqi@0 262 result_oop->method_holder() == SystemDictionary::Object_klass()) {
aoqi@0 263 result_oop = NULL;
aoqi@0 264 }
aoqi@0 265
aoqi@0 266 // Before considering default methods, check for an overpass in the
aoqi@0 267 // current class if a method has not been found.
aoqi@0 268 if (result_oop == NULL) {
aoqi@0 269 result_oop = InstanceKlass::cast(klass())->find_method(name, signature);
aoqi@0 270 }
aoqi@0 271
aoqi@0 272 if (result_oop == NULL) {
aoqi@0 273 Array<Method*>* default_methods = InstanceKlass::cast(klass())->default_methods();
aoqi@0 274 if (default_methods != NULL) {
aoqi@0 275 result_oop = InstanceKlass::find_method(default_methods, name, signature);
aoqi@0 276 }
aoqi@0 277 }
aoqi@0 278
aoqi@0 279 if (checkpolymorphism && EnableInvokeDynamic && result_oop != NULL) {
aoqi@0 280 vmIntrinsics::ID iid = result_oop->intrinsic_id();
aoqi@0 281 if (MethodHandles::is_signature_polymorphic(iid)) {
aoqi@0 282 // Do not link directly to these. The VM must produce a synthetic one using lookup_polymorphic_method.
aoqi@0 283 return;
aoqi@0 284 }
aoqi@0 285 }
aoqi@0 286 result = methodHandle(THREAD, result_oop);
aoqi@0 287 }
aoqi@0 288
aoqi@0 289 // returns first instance method
aoqi@0 290 // Looks up method in classes, then looks up local default methods
aoqi@0 291 void LinkResolver::lookup_instance_method_in_klasses(methodHandle& result, KlassHandle klass, Symbol* name, Symbol* signature, TRAPS) {
dbuck@8716 292 Method* result_oop = klass->uncached_lookup_method(name, signature, Klass::find_overpass);
aoqi@0 293 result = methodHandle(THREAD, result_oop);
aoqi@0 294 while (!result.is_null() && result->is_static() && result->method_holder()->super() != NULL) {
aoqi@0 295 KlassHandle super_klass = KlassHandle(THREAD, result->method_holder()->super());
dbuck@8716 296 result = methodHandle(THREAD, super_klass->uncached_lookup_method(name, signature, Klass::find_overpass));
aoqi@0 297 }
aoqi@0 298
aoqi@0 299 if (klass->oop_is_array()) {
aoqi@0 300 // Only consider klass and super klass for arrays
aoqi@0 301 return;
aoqi@0 302 }
aoqi@0 303
aoqi@0 304 if (result.is_null()) {
aoqi@0 305 Array<Method*>* default_methods = InstanceKlass::cast(klass())->default_methods();
aoqi@0 306 if (default_methods != NULL) {
aoqi@0 307 result = methodHandle(InstanceKlass::find_method(default_methods, name, signature));
aoqi@0 308 assert(result.is_null() || !result->is_static(), "static defaults not allowed");
aoqi@0 309 }
aoqi@0 310 }
aoqi@0 311 }
aoqi@0 312
aoqi@0 313 int LinkResolver::vtable_index_of_interface_method(KlassHandle klass,
aoqi@0 314 methodHandle resolved_method) {
aoqi@0 315
aoqi@0 316 int vtable_index = Method::invalid_vtable_index;
aoqi@0 317 Symbol* name = resolved_method->name();
aoqi@0 318 Symbol* signature = resolved_method->signature();
aoqi@0 319
aoqi@0 320 // First check in default method array
aoqi@0 321 if (!resolved_method->is_abstract() &&
aoqi@0 322 (InstanceKlass::cast(klass())->default_methods() != NULL)) {
dbuck@8716 323 int index = InstanceKlass::find_method_index(InstanceKlass::cast(klass())->default_methods(),
dbuck@8716 324 name, signature, Klass::find_overpass,
dbuck@8716 325 Klass::find_static, Klass::find_private);
aoqi@0 326 if (index >= 0 ) {
aoqi@0 327 vtable_index = InstanceKlass::cast(klass())->default_vtable_indices()->at(index);
aoqi@0 328 }
aoqi@0 329 }
aoqi@0 330 if (vtable_index == Method::invalid_vtable_index) {
aoqi@0 331 // get vtable_index for miranda methods
aoqi@0 332 ResourceMark rm;
aoqi@0 333 klassVtable *vt = InstanceKlass::cast(klass())->vtable();
aoqi@0 334 vtable_index = vt->index_of_miranda(name, signature);
aoqi@0 335 }
aoqi@0 336 return vtable_index;
aoqi@0 337 }
aoqi@0 338
aoqi@0 339 void LinkResolver::lookup_method_in_interfaces(methodHandle& result, KlassHandle klass, Symbol* name, Symbol* signature, TRAPS) {
aoqi@0 340 InstanceKlass *ik = InstanceKlass::cast(klass());
aoqi@0 341
aoqi@0 342 // Specify 'true' in order to skip default methods when searching the
aoqi@0 343 // interfaces. Function lookup_method_in_klasses() already looked for
aoqi@0 344 // the method in the default methods table.
aoqi@0 345 result = methodHandle(THREAD, ik->lookup_method_in_all_interfaces(name, signature, Klass::skip_defaults));
aoqi@0 346 }
aoqi@0 347
aoqi@0 348 void LinkResolver::lookup_polymorphic_method(methodHandle& result,
aoqi@0 349 KlassHandle klass, Symbol* name, Symbol* full_signature,
aoqi@0 350 KlassHandle current_klass,
aoqi@0 351 Handle *appendix_result_or_null,
aoqi@0 352 Handle *method_type_result,
aoqi@0 353 TRAPS) {
aoqi@0 354 vmIntrinsics::ID iid = MethodHandles::signature_polymorphic_name_id(name);
aoqi@0 355 if (TraceMethodHandles) {
aoqi@0 356 ResourceMark rm(THREAD);
aoqi@0 357 tty->print_cr("lookup_polymorphic_method iid=%s %s.%s%s",
aoqi@0 358 vmIntrinsics::name_at(iid), klass->external_name(),
aoqi@0 359 name->as_C_string(), full_signature->as_C_string());
aoqi@0 360 }
aoqi@0 361 if (EnableInvokeDynamic &&
aoqi@0 362 klass() == SystemDictionary::MethodHandle_klass() &&
aoqi@0 363 iid != vmIntrinsics::_none) {
aoqi@0 364 if (MethodHandles::is_signature_polymorphic_intrinsic(iid)) {
aoqi@0 365 // Most of these do not need an up-call to Java to resolve, so can be done anywhere.
aoqi@0 366 // Do not erase last argument type (MemberName) if it is a static linkTo method.
aoqi@0 367 bool keep_last_arg = MethodHandles::is_signature_polymorphic_static(iid);
aoqi@0 368 TempNewSymbol basic_signature =
aoqi@0 369 MethodHandles::lookup_basic_type_signature(full_signature, keep_last_arg, CHECK);
aoqi@0 370 if (TraceMethodHandles) {
aoqi@0 371 ResourceMark rm(THREAD);
aoqi@0 372 tty->print_cr("lookup_polymorphic_method %s %s => basic %s",
aoqi@0 373 name->as_C_string(),
aoqi@0 374 full_signature->as_C_string(),
aoqi@0 375 basic_signature->as_C_string());
aoqi@0 376 }
aoqi@0 377 result = SystemDictionary::find_method_handle_intrinsic(iid,
aoqi@0 378 basic_signature,
aoqi@0 379 CHECK);
aoqi@0 380 if (result.not_null()) {
aoqi@0 381 assert(result->is_method_handle_intrinsic(), "MH.invokeBasic or MH.linkTo* intrinsic");
aoqi@0 382 assert(result->intrinsic_id() != vmIntrinsics::_invokeGeneric, "wrong place to find this");
aoqi@0 383 assert(basic_signature == result->signature(), "predict the result signature");
aoqi@0 384 if (TraceMethodHandles) {
aoqi@0 385 tty->print("lookup_polymorphic_method => intrinsic ");
aoqi@0 386 result->print_on(tty);
aoqi@0 387 }
aoqi@0 388 return;
aoqi@0 389 }
aoqi@0 390 } else if (iid == vmIntrinsics::_invokeGeneric
aoqi@0 391 && !THREAD->is_Compiler_thread()
aoqi@0 392 && appendix_result_or_null != NULL) {
aoqi@0 393 // This is a method with type-checking semantics.
aoqi@0 394 // We will ask Java code to spin an adapter method for it.
aoqi@0 395 if (!MethodHandles::enabled()) {
aoqi@0 396 // Make sure the Java part of the runtime has been booted up.
aoqi@0 397 Klass* natives = SystemDictionary::MethodHandleNatives_klass();
aoqi@0 398 if (natives == NULL || InstanceKlass::cast(natives)->is_not_initialized()) {
aoqi@0 399 SystemDictionary::resolve_or_fail(vmSymbols::java_lang_invoke_MethodHandleNatives(),
aoqi@0 400 Handle(),
aoqi@0 401 Handle(),
aoqi@0 402 true,
aoqi@0 403 CHECK);
aoqi@0 404 }
aoqi@0 405 }
aoqi@0 406
aoqi@0 407 Handle appendix;
aoqi@0 408 Handle method_type;
aoqi@0 409 result = SystemDictionary::find_method_handle_invoker(name,
aoqi@0 410 full_signature,
aoqi@0 411 current_klass,
aoqi@0 412 &appendix,
aoqi@0 413 &method_type,
aoqi@0 414 CHECK);
aoqi@0 415 if (TraceMethodHandles) {
aoqi@0 416 tty->print("lookup_polymorphic_method => (via Java) ");
aoqi@0 417 result->print_on(tty);
aoqi@0 418 tty->print(" lookup_polymorphic_method => appendix = ");
aoqi@0 419 if (appendix.is_null()) tty->print_cr("(none)");
aoqi@0 420 else appendix->print_on(tty);
aoqi@0 421 }
aoqi@0 422 if (result.not_null()) {
aoqi@0 423 #ifdef ASSERT
aoqi@0 424 ResourceMark rm(THREAD);
aoqi@0 425
aoqi@0 426 TempNewSymbol basic_signature =
aoqi@0 427 MethodHandles::lookup_basic_type_signature(full_signature, CHECK);
aoqi@0 428 int actual_size_of_params = result->size_of_parameters();
aoqi@0 429 int expected_size_of_params = ArgumentSizeComputer(basic_signature).size();
aoqi@0 430 // +1 for MethodHandle.this, +1 for trailing MethodType
aoqi@0 431 if (!MethodHandles::is_signature_polymorphic_static(iid)) expected_size_of_params += 1;
aoqi@0 432 if (appendix.not_null()) expected_size_of_params += 1;
aoqi@0 433 if (actual_size_of_params != expected_size_of_params) {
aoqi@0 434 tty->print_cr("*** basic_signature=%s", basic_signature->as_C_string());
aoqi@0 435 tty->print_cr("*** result for %s: ", vmIntrinsics::name_at(iid));
aoqi@0 436 result->print();
aoqi@0 437 }
aoqi@0 438 assert(actual_size_of_params == expected_size_of_params,
aoqi@0 439 err_msg("%d != %d", actual_size_of_params, expected_size_of_params));
aoqi@0 440 #endif //ASSERT
aoqi@0 441
aoqi@0 442 assert(appendix_result_or_null != NULL, "");
aoqi@0 443 (*appendix_result_or_null) = appendix;
aoqi@0 444 (*method_type_result) = method_type;
aoqi@0 445 return;
aoqi@0 446 }
aoqi@0 447 }
aoqi@0 448 }
aoqi@0 449 }
aoqi@0 450
aoqi@0 451 void LinkResolver::check_method_accessability(KlassHandle ref_klass,
aoqi@0 452 KlassHandle resolved_klass,
aoqi@0 453 KlassHandle sel_klass,
aoqi@0 454 methodHandle sel_method,
aoqi@0 455 TRAPS) {
aoqi@0 456
aoqi@0 457 AccessFlags flags = sel_method->access_flags();
aoqi@0 458
aoqi@0 459 // Special case: arrays always override "clone". JVMS 2.15.
aoqi@0 460 // If the resolved klass is an array class, and the declaring class
aoqi@0 461 // is java.lang.Object and the method is "clone", set the flags
aoqi@0 462 // to public.
aoqi@0 463 //
aoqi@0 464 // We'll check for the method name first, as that's most likely
aoqi@0 465 // to be false (so we'll short-circuit out of these tests).
aoqi@0 466 if (sel_method->name() == vmSymbols::clone_name() &&
aoqi@0 467 sel_klass() == SystemDictionary::Object_klass() &&
aoqi@0 468 resolved_klass->oop_is_array()) {
aoqi@0 469 // We need to change "protected" to "public".
aoqi@0 470 assert(flags.is_protected(), "clone not protected?");
aoqi@0 471 jint new_flags = flags.as_int();
aoqi@0 472 new_flags = new_flags & (~JVM_ACC_PROTECTED);
aoqi@0 473 new_flags = new_flags | JVM_ACC_PUBLIC;
aoqi@0 474 flags.set_flags(new_flags);
aoqi@0 475 }
aoqi@0 476 // assert(extra_arg_result_or_null != NULL, "must be able to return extra argument");
aoqi@0 477
aoqi@0 478 if (!Reflection::verify_field_access(ref_klass(),
aoqi@0 479 resolved_klass(),
aoqi@0 480 sel_klass(),
aoqi@0 481 flags,
aoqi@0 482 true)) {
aoqi@0 483 ResourceMark rm(THREAD);
aoqi@0 484 Exceptions::fthrow(
aoqi@0 485 THREAD_AND_LOCATION,
aoqi@0 486 vmSymbols::java_lang_IllegalAccessError(),
aoqi@0 487 "tried to access method %s.%s%s from class %s",
aoqi@0 488 sel_klass->external_name(),
aoqi@0 489 sel_method->name()->as_C_string(),
aoqi@0 490 sel_method->signature()->as_C_string(),
aoqi@0 491 ref_klass->external_name()
aoqi@0 492 );
aoqi@0 493 return;
aoqi@0 494 }
aoqi@0 495 }
aoqi@0 496
aoqi@0 497 void LinkResolver::resolve_method_statically(methodHandle& resolved_method, KlassHandle& resolved_klass,
aoqi@0 498 Bytecodes::Code code, constantPoolHandle pool, int index, TRAPS) {
aoqi@0 499 // This method is used only
aoqi@0 500 // (1) in C2 from InlineTree::ok_to_inline (via ciMethod::check_call),
aoqi@0 501 // and
aoqi@0 502 // (2) in Bytecode_invoke::static_target
aoqi@0 503 // It appears to fail when applied to an invokeinterface call site.
aoqi@0 504 // FIXME: Remove this method and ciMethod::check_call; refactor to use the other LinkResolver entry points.
aoqi@0 505 // resolve klass
aoqi@0 506 if (code == Bytecodes::_invokedynamic) {
aoqi@0 507 resolved_klass = SystemDictionary::MethodHandle_klass();
aoqi@0 508 Symbol* method_name = vmSymbols::invoke_name();
aoqi@0 509 Symbol* method_signature = pool->signature_ref_at(index);
aoqi@0 510 KlassHandle current_klass(THREAD, pool->pool_holder());
aoqi@0 511 resolve_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, true, false, CHECK);
aoqi@0 512 return;
aoqi@0 513 }
aoqi@0 514
aoqi@0 515 resolve_klass(resolved_klass, pool, index, CHECK);
aoqi@0 516
aoqi@0 517 Symbol* method_name = pool->name_ref_at(index);
aoqi@0 518 Symbol* method_signature = pool->signature_ref_at(index);
aoqi@0 519 KlassHandle current_klass(THREAD, pool->pool_holder());
aoqi@0 520
aoqi@0 521 if (pool->has_preresolution()
aoqi@0 522 || (resolved_klass() == SystemDictionary::MethodHandle_klass() &&
aoqi@0 523 MethodHandles::is_signature_polymorphic_name(resolved_klass(), method_name))) {
aoqi@0 524 Method* result_oop = ConstantPool::method_at_if_loaded(pool, index);
aoqi@0 525 if (result_oop != NULL) {
aoqi@0 526 resolved_method = methodHandle(THREAD, result_oop);
aoqi@0 527 return;
aoqi@0 528 }
aoqi@0 529 }
aoqi@0 530
aoqi@0 531 if (code == Bytecodes::_invokeinterface) {
aoqi@0 532 resolve_interface_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, true, true, CHECK);
aoqi@0 533 } else if (code == Bytecodes::_invokevirtual) {
aoqi@0 534 resolve_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, true, true, CHECK);
aoqi@0 535 } else if (!resolved_klass->is_interface()) {
aoqi@0 536 resolve_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, true, false, CHECK);
aoqi@0 537 } else {
aoqi@0 538 bool nostatics = (code == Bytecodes::_invokestatic) ? false : true;
aoqi@0 539 resolve_interface_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, true, nostatics, CHECK);
aoqi@0 540 }
aoqi@0 541 }
aoqi@0 542
hseigel@8839 543 void LinkResolver::check_method_loader_constraints(methodHandle& resolved_method,
hseigel@8839 544 KlassHandle resolved_klass,
hseigel@8839 545 Symbol* method_name,
hseigel@8839 546 Symbol* method_signature,
hseigel@8839 547 KlassHandle current_klass,
hseigel@8839 548 const char* method_type, TRAPS) {
hseigel@8839 549 Handle loader (THREAD, InstanceKlass::cast(current_klass())->class_loader());
hseigel@8839 550 Handle class_loader (THREAD, resolved_method->method_holder()->class_loader());
hseigel@8839 551 {
hseigel@8839 552 ResourceMark rm(THREAD);
hseigel@8839 553 Symbol* failed_type_symbol =
hseigel@8839 554 SystemDictionary::check_signature_loaders(method_signature, loader,
hseigel@8839 555 class_loader, true, CHECK);
hseigel@8839 556 if (failed_type_symbol != NULL) {
hseigel@8839 557 const char* msg = "loader constraint violation: when resolving %s"
hseigel@8839 558 " \"%s\" the class loader (instance of %s) of the current class, %s,"
hseigel@8839 559 " and the class loader (instance of %s) for the method's defining class, %s, have"
hseigel@8839 560 " different Class objects for the type %s used in the signature";
hseigel@8839 561 char* sig = Method::name_and_sig_as_C_string(resolved_klass(), method_name, method_signature);
hseigel@8839 562 const char* loader1 = SystemDictionary::loader_name(loader());
hseigel@8839 563 char* current = InstanceKlass::cast(current_klass())->name()->as_C_string();
hseigel@8839 564 const char* loader2 = SystemDictionary::loader_name(class_loader());
hseigel@8839 565 char* target = InstanceKlass::cast(resolved_method->method_holder())
hseigel@8839 566 ->name()->as_C_string();
hseigel@8839 567 char* failed_type_name = failed_type_symbol->as_C_string();
hseigel@8839 568 size_t buflen = strlen(msg) + strlen(sig) + strlen(loader1) +
hseigel@8839 569 strlen(current) + strlen(loader2) + strlen(target) +
hseigel@8839 570 strlen(failed_type_name) + strlen(method_type) + 1;
hseigel@8839 571 char* buf = NEW_RESOURCE_ARRAY_IN_THREAD(THREAD, char, buflen);
hseigel@8839 572 jio_snprintf(buf, buflen, msg, method_type, sig, loader1, current, loader2,
hseigel@8839 573 target, failed_type_name);
hseigel@8839 574 THROW_MSG(vmSymbols::java_lang_LinkageError(), buf);
hseigel@8839 575 }
hseigel@8839 576 }
hseigel@8839 577 }
hseigel@8839 578
aoqi@0 579 void LinkResolver::resolve_method(methodHandle& resolved_method, KlassHandle resolved_klass,
aoqi@0 580 Symbol* method_name, Symbol* method_signature,
aoqi@0 581 KlassHandle current_klass, bool check_access,
aoqi@0 582 bool require_methodref, TRAPS) {
aoqi@0 583
aoqi@0 584 Handle nested_exception;
aoqi@0 585
aoqi@0 586 // 1. check if methodref required, that resolved_klass is not interfacemethodref
aoqi@0 587 if (require_methodref && resolved_klass->is_interface()) {
aoqi@0 588 ResourceMark rm(THREAD);
aoqi@0 589 char buf[200];
aoqi@0 590 jio_snprintf(buf, sizeof(buf), "Found interface %s, but class was expected",
aoqi@0 591 resolved_klass()->external_name());
aoqi@0 592 THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(), buf);
aoqi@0 593 }
aoqi@0 594
aoqi@0 595 // 2. lookup method in resolved klass and its super klasses
aoqi@0 596 lookup_method_in_klasses(resolved_method, resolved_klass, method_name, method_signature, true, false, CHECK);
aoqi@0 597
aoqi@0 598 if (resolved_method.is_null() && !resolved_klass->oop_is_array()) { // not found in the class hierarchy
aoqi@0 599 // 3. lookup method in all the interfaces implemented by the resolved klass
aoqi@0 600 lookup_method_in_interfaces(resolved_method, resolved_klass, method_name, method_signature, CHECK);
aoqi@0 601
aoqi@0 602 if (resolved_method.is_null()) {
aoqi@0 603 // JSR 292: see if this is an implicitly generated method MethodHandle.linkToVirtual(*...), etc
aoqi@0 604 lookup_polymorphic_method(resolved_method, resolved_klass, method_name, method_signature,
aoqi@0 605 current_klass, (Handle*)NULL, (Handle*)NULL, THREAD);
aoqi@0 606 if (HAS_PENDING_EXCEPTION) {
aoqi@0 607 nested_exception = Handle(THREAD, PENDING_EXCEPTION);
aoqi@0 608 CLEAR_PENDING_EXCEPTION;
aoqi@0 609 }
aoqi@0 610 }
aoqi@0 611 }
aoqi@0 612
aoqi@0 613 if (resolved_method.is_null()) {
aoqi@0 614 // 4. method lookup failed
aoqi@0 615 ResourceMark rm(THREAD);
aoqi@0 616 THROW_MSG_CAUSE(vmSymbols::java_lang_NoSuchMethodError(),
aoqi@0 617 Method::name_and_sig_as_C_string(resolved_klass(),
aoqi@0 618 method_name,
aoqi@0 619 method_signature),
aoqi@0 620 nested_exception);
aoqi@0 621 }
aoqi@0 622
aoqi@0 623 // 5. access checks, access checking may be turned off when calling from within the VM.
aoqi@0 624 if (check_access) {
aoqi@0 625 assert(current_klass.not_null() , "current_klass should not be null");
aoqi@0 626
aoqi@0 627 // check if method can be accessed by the referring class
aoqi@0 628 check_method_accessability(current_klass,
aoqi@0 629 resolved_klass,
aoqi@0 630 KlassHandle(THREAD, resolved_method->method_holder()),
aoqi@0 631 resolved_method,
aoqi@0 632 CHECK);
aoqi@0 633
aoqi@0 634 // check loader constraints
hseigel@8839 635 check_method_loader_constraints(resolved_method, resolved_klass, method_name,
hseigel@8839 636 method_signature, current_klass, "method", CHECK);
aoqi@0 637 }
aoqi@0 638 }
aoqi@0 639
aoqi@0 640 void LinkResolver::resolve_interface_method(methodHandle& resolved_method,
aoqi@0 641 KlassHandle resolved_klass,
aoqi@0 642 Symbol* method_name,
aoqi@0 643 Symbol* method_signature,
aoqi@0 644 KlassHandle current_klass,
aoqi@0 645 bool check_access,
aoqi@0 646 bool nostatics, TRAPS) {
aoqi@0 647
aoqi@0 648 // check if klass is interface
aoqi@0 649 if (!resolved_klass->is_interface()) {
aoqi@0 650 ResourceMark rm(THREAD);
aoqi@0 651 char buf[200];
aoqi@0 652 jio_snprintf(buf, sizeof(buf), "Found class %s, but interface was expected", resolved_klass()->external_name());
aoqi@0 653 THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(), buf);
aoqi@0 654 }
aoqi@0 655
aoqi@0 656 // lookup method in this interface or its super, java.lang.Object
aoqi@0 657 // JDK8: also look for static methods
aoqi@0 658 lookup_method_in_klasses(resolved_method, resolved_klass, method_name, method_signature, false, true, CHECK);
aoqi@0 659
aoqi@0 660 if (resolved_method.is_null() && !resolved_klass->oop_is_array()) {
aoqi@0 661 // lookup method in all the super-interfaces
aoqi@0 662 lookup_method_in_interfaces(resolved_method, resolved_klass, method_name, method_signature, CHECK);
aoqi@0 663 }
aoqi@0 664
aoqi@0 665 if (resolved_method.is_null()) {
aoqi@0 666 // no method found
aoqi@0 667 ResourceMark rm(THREAD);
aoqi@0 668 THROW_MSG(vmSymbols::java_lang_NoSuchMethodError(),
aoqi@0 669 Method::name_and_sig_as_C_string(resolved_klass(),
aoqi@0 670 method_name,
aoqi@0 671 method_signature));
aoqi@0 672 }
aoqi@0 673
aoqi@0 674 if (check_access) {
aoqi@0 675 // JDK8 adds non-public interface methods, and accessability check requirement
aoqi@0 676 assert(current_klass.not_null() , "current_klass should not be null");
aoqi@0 677
aoqi@0 678 // check if method can be accessed by the referring class
aoqi@0 679 check_method_accessability(current_klass,
aoqi@0 680 resolved_klass,
aoqi@0 681 KlassHandle(THREAD, resolved_method->method_holder()),
aoqi@0 682 resolved_method,
aoqi@0 683 CHECK);
aoqi@0 684
hseigel@8839 685 check_method_loader_constraints(resolved_method, resolved_klass, method_name,
hseigel@8839 686 method_signature, current_klass, "interface method", CHECK);
aoqi@0 687 }
aoqi@0 688
aoqi@0 689 if (nostatics && resolved_method->is_static()) {
aoqi@0 690 ResourceMark rm(THREAD);
aoqi@0 691 char buf[200];
aoqi@0 692 jio_snprintf(buf, sizeof(buf), "Expected instance not static method %s",
aoqi@0 693 Method::name_and_sig_as_C_string(resolved_klass(),
aoqi@0 694 resolved_method->name(), resolved_method->signature()));
aoqi@0 695 THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(), buf);
aoqi@0 696 }
aoqi@0 697
aoqi@0 698 if (TraceItables && Verbose) {
aoqi@0 699 ResourceMark rm(THREAD);
aoqi@0 700 tty->print("invokeinterface resolved method: caller-class:%s, compile-time-class:%s, method:%s, method_holder:%s, access_flags: ",
aoqi@0 701 (current_klass.is_null() ? "<NULL>" : current_klass->internal_name()),
aoqi@0 702 (resolved_klass.is_null() ? "<NULL>" : resolved_klass->internal_name()),
aoqi@0 703 Method::name_and_sig_as_C_string(resolved_klass(),
aoqi@0 704 resolved_method->name(),
aoqi@0 705 resolved_method->signature()),
aoqi@0 706 resolved_method->method_holder()->internal_name()
aoqi@0 707 );
aoqi@0 708 resolved_method->access_flags().print_on(tty);
aoqi@0 709 if (resolved_method->is_default_method()) {
aoqi@0 710 tty->print("default ");
aoqi@0 711 }
aoqi@0 712 if (resolved_method->is_overpass()) {
aoqi@0 713 tty->print("overpass");
aoqi@0 714 }
aoqi@0 715 tty->cr();
aoqi@0 716 }
aoqi@0 717 }
aoqi@0 718
aoqi@0 719 //------------------------------------------------------------------------------------------------------------------------
aoqi@0 720 // Field resolution
aoqi@0 721
aoqi@0 722 void LinkResolver::check_field_accessability(KlassHandle ref_klass,
aoqi@0 723 KlassHandle resolved_klass,
aoqi@0 724 KlassHandle sel_klass,
aoqi@0 725 fieldDescriptor& fd,
aoqi@0 726 TRAPS) {
aoqi@0 727 if (!Reflection::verify_field_access(ref_klass(),
aoqi@0 728 resolved_klass(),
aoqi@0 729 sel_klass(),
aoqi@0 730 fd.access_flags(),
aoqi@0 731 true)) {
aoqi@0 732 ResourceMark rm(THREAD);
aoqi@0 733 Exceptions::fthrow(
aoqi@0 734 THREAD_AND_LOCATION,
aoqi@0 735 vmSymbols::java_lang_IllegalAccessError(),
aoqi@0 736 "tried to access field %s.%s from class %s",
aoqi@0 737 sel_klass->external_name(),
aoqi@0 738 fd.name()->as_C_string(),
aoqi@0 739 ref_klass->external_name()
aoqi@0 740 );
aoqi@0 741 return;
aoqi@0 742 }
aoqi@0 743 }
aoqi@0 744
aoqi@0 745 void LinkResolver::resolve_field_access(fieldDescriptor& result, constantPoolHandle pool, int index, Bytecodes::Code byte, TRAPS) {
aoqi@0 746 // Load these early in case the resolve of the containing klass fails
aoqi@0 747 Symbol* field = pool->name_ref_at(index);
aoqi@0 748 Symbol* sig = pool->signature_ref_at(index);
aoqi@0 749
aoqi@0 750 // resolve specified klass
aoqi@0 751 KlassHandle resolved_klass;
aoqi@0 752 resolve_klass(resolved_klass, pool, index, CHECK);
aoqi@0 753
aoqi@0 754 KlassHandle current_klass(THREAD, pool->pool_holder());
aoqi@0 755 resolve_field(result, resolved_klass, field, sig, current_klass, byte, true, true, CHECK);
aoqi@0 756 }
aoqi@0 757
aoqi@0 758 void LinkResolver::resolve_field(fieldDescriptor& fd, KlassHandle resolved_klass, Symbol* field, Symbol* sig,
aoqi@0 759 KlassHandle current_klass, Bytecodes::Code byte, bool check_access, bool initialize_class,
aoqi@0 760 TRAPS) {
aoqi@0 761 assert(byte == Bytecodes::_getstatic || byte == Bytecodes::_putstatic ||
aoqi@0 762 byte == Bytecodes::_getfield || byte == Bytecodes::_putfield ||
aoqi@0 763 (byte == Bytecodes::_nop && !check_access), "bad field access bytecode");
aoqi@0 764
aoqi@0 765 bool is_static = (byte == Bytecodes::_getstatic || byte == Bytecodes::_putstatic);
aoqi@0 766 bool is_put = (byte == Bytecodes::_putfield || byte == Bytecodes::_putstatic);
aoqi@0 767
aoqi@0 768 // Check if there's a resolved klass containing the field
aoqi@0 769 if (resolved_klass.is_null()) {
aoqi@0 770 ResourceMark rm(THREAD);
aoqi@0 771 THROW_MSG(vmSymbols::java_lang_NoSuchFieldError(), field->as_C_string());
aoqi@0 772 }
aoqi@0 773
aoqi@0 774 // Resolve instance field
aoqi@0 775 KlassHandle sel_klass(THREAD, resolved_klass->find_field(field, sig, &fd));
aoqi@0 776 // check if field exists; i.e., if a klass containing the field def has been selected
aoqi@0 777 if (sel_klass.is_null()) {
aoqi@0 778 ResourceMark rm(THREAD);
aoqi@0 779 THROW_MSG(vmSymbols::java_lang_NoSuchFieldError(), field->as_C_string());
aoqi@0 780 }
aoqi@0 781
hseigel@9403 782 // Access checking may be turned off when calling from within the VM.
hseigel@9403 783 if (check_access) {
aoqi@0 784
hseigel@9403 785 // check access
hseigel@9403 786 check_field_accessability(current_klass, resolved_klass, sel_klass, fd, CHECK);
aoqi@0 787
hseigel@9403 788 // check for errors
hseigel@9403 789 if (is_static != fd.is_static()) {
hseigel@9403 790 ResourceMark rm(THREAD);
hseigel@9403 791 char msg[200];
hseigel@9403 792 jio_snprintf(msg, sizeof(msg), "Expected %s field %s.%s", is_static ? "static" : "non-static", resolved_klass()->external_name(), fd.name()->as_C_string());
hseigel@9403 793 THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(), msg);
hseigel@9403 794 }
hseigel@9403 795
hseigel@9403 796 // Final fields can only be accessed from its own class.
hseigel@9403 797 if (is_put && fd.access_flags().is_final() && sel_klass() != current_klass()) {
hseigel@9403 798 THROW(vmSymbols::java_lang_IllegalAccessError());
hseigel@9403 799 }
hseigel@9403 800
hseigel@9403 801 // initialize resolved_klass if necessary
hseigel@9403 802 // note 1: the klass which declared the field must be initialized (i.e, sel_klass)
hseigel@9403 803 // according to the newest JVM spec (5.5, p.170) - was bug (gri 7/28/99)
hseigel@9403 804 //
hseigel@9403 805 // note 2: we don't want to force initialization if we are just checking
hseigel@9403 806 // if the field access is legal; e.g., during compilation
hseigel@9403 807 if (is_static && initialize_class) {
hseigel@9403 808 sel_klass->initialize(CHECK);
hseigel@9403 809 }
aoqi@0 810 }
aoqi@0 811
hseigel@9403 812 if (sel_klass() != current_klass() && !current_klass.is_null()) {
aoqi@0 813 HandleMark hm(THREAD);
aoqi@0 814 Handle ref_loader (THREAD, InstanceKlass::cast(current_klass())->class_loader());
aoqi@0 815 Handle sel_loader (THREAD, InstanceKlass::cast(sel_klass())->class_loader());
aoqi@0 816 {
aoqi@0 817 ResourceMark rm(THREAD);
aoqi@0 818 Symbol* failed_type_symbol =
aoqi@0 819 SystemDictionary::check_signature_loaders(sig,
aoqi@0 820 ref_loader, sel_loader,
aoqi@0 821 false,
aoqi@0 822 CHECK);
aoqi@0 823 if (failed_type_symbol != NULL) {
aoqi@0 824 const char* msg = "loader constraint violation: when resolving field"
aoqi@0 825 " \"%s\" the class loader (instance of %s) of the referring class, "
aoqi@0 826 "%s, and the class loader (instance of %s) for the field's resolved "
aoqi@0 827 "type, %s, have different Class objects for that type";
aoqi@0 828 char* field_name = field->as_C_string();
aoqi@0 829 const char* loader1 = SystemDictionary::loader_name(ref_loader());
aoqi@0 830 char* sel = InstanceKlass::cast(sel_klass())->name()->as_C_string();
aoqi@0 831 const char* loader2 = SystemDictionary::loader_name(sel_loader());
aoqi@0 832 char* failed_type_name = failed_type_symbol->as_C_string();
aoqi@0 833 size_t buflen = strlen(msg) + strlen(field_name) + strlen(loader1) +
aoqi@0 834 strlen(sel) + strlen(loader2) + strlen(failed_type_name) + 1;
aoqi@0 835 char* buf = NEW_RESOURCE_ARRAY_IN_THREAD(THREAD, char, buflen);
aoqi@0 836 jio_snprintf(buf, buflen, msg, field_name, loader1, sel, loader2,
aoqi@0 837 failed_type_name);
aoqi@0 838 THROW_MSG(vmSymbols::java_lang_LinkageError(), buf);
aoqi@0 839 }
aoqi@0 840 }
aoqi@0 841 }
aoqi@0 842
aoqi@0 843 // return information. note that the klass is set to the actual klass containing the
aoqi@0 844 // field, otherwise access of static fields in superclasses will not work.
aoqi@0 845 }
aoqi@0 846
aoqi@0 847
aoqi@0 848 //------------------------------------------------------------------------------------------------------------------------
aoqi@0 849 // Invoke resolution
aoqi@0 850 //
aoqi@0 851 // Naming conventions:
aoqi@0 852 //
aoqi@0 853 // resolved_method the specified method (i.e., static receiver specified via constant pool index)
aoqi@0 854 // sel_method the selected method (selected via run-time lookup; e.g., based on dynamic receiver class)
aoqi@0 855 // resolved_klass the specified klass (i.e., specified via constant pool index)
aoqi@0 856 // recv_klass the receiver klass
aoqi@0 857
aoqi@0 858
aoqi@0 859 void LinkResolver::resolve_static_call(CallInfo& result, KlassHandle& resolved_klass, Symbol* method_name,
aoqi@0 860 Symbol* method_signature, KlassHandle current_klass,
aoqi@0 861 bool check_access, bool initialize_class, TRAPS) {
aoqi@0 862 methodHandle resolved_method;
aoqi@0 863 linktime_resolve_static_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, check_access, CHECK);
aoqi@0 864 resolved_klass = KlassHandle(THREAD, resolved_method->method_holder());
aoqi@0 865
aoqi@0 866 // Initialize klass (this should only happen if everything is ok)
aoqi@0 867 if (initialize_class && resolved_klass->should_be_initialized()) {
aoqi@0 868 resolved_klass->initialize(CHECK);
aoqi@0 869 linktime_resolve_static_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, check_access, CHECK);
aoqi@0 870 }
aoqi@0 871
aoqi@0 872 // setup result
aoqi@0 873 result.set_static(resolved_klass, resolved_method, CHECK);
aoqi@0 874 }
aoqi@0 875
aoqi@0 876 // throws linktime exceptions
aoqi@0 877 void LinkResolver::linktime_resolve_static_method(methodHandle& resolved_method, KlassHandle resolved_klass,
aoqi@0 878 Symbol* method_name, Symbol* method_signature,
aoqi@0 879 KlassHandle current_klass, bool check_access, TRAPS) {
aoqi@0 880
aoqi@0 881 if (!resolved_klass->is_interface()) {
aoqi@0 882 resolve_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, check_access, false, CHECK);
aoqi@0 883 } else {
aoqi@0 884 resolve_interface_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, check_access, false, CHECK);
aoqi@0 885 }
aoqi@0 886 assert(resolved_method->name() != vmSymbols::class_initializer_name(), "should have been checked in verifier");
aoqi@0 887
aoqi@0 888 // check if static
aoqi@0 889 if (!resolved_method->is_static()) {
aoqi@0 890 ResourceMark rm(THREAD);
aoqi@0 891 char buf[200];
aoqi@0 892 jio_snprintf(buf, sizeof(buf), "Expected static method %s", Method::name_and_sig_as_C_string(resolved_klass(),
aoqi@0 893 resolved_method->name(),
aoqi@0 894 resolved_method->signature()));
aoqi@0 895 THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(), buf);
aoqi@0 896 }
aoqi@0 897 }
aoqi@0 898
aoqi@0 899
coleenp@8739 900 void LinkResolver::resolve_special_call(CallInfo& result, Handle recv, KlassHandle resolved_klass, Symbol* method_name,
aoqi@0 901 Symbol* method_signature, KlassHandle current_klass, bool check_access, TRAPS) {
aoqi@0 902 methodHandle resolved_method;
aoqi@0 903 linktime_resolve_special_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, check_access, CHECK);
coleenp@8739 904 runtime_resolve_special_method(result, resolved_method, resolved_klass, current_klass, recv, check_access, CHECK);
aoqi@0 905 }
aoqi@0 906
aoqi@0 907 // throws linktime exceptions
aoqi@0 908 void LinkResolver::linktime_resolve_special_method(methodHandle& resolved_method, KlassHandle resolved_klass,
aoqi@0 909 Symbol* method_name, Symbol* method_signature,
aoqi@0 910 KlassHandle current_klass, bool check_access, TRAPS) {
aoqi@0 911
aoqi@0 912 // Invokespecial is called for multiple special reasons:
aoqi@0 913 // <init>
aoqi@0 914 // local private method invocation, for classes and interfaces
aoqi@0 915 // superclass.method, which can also resolve to a default method
aoqi@0 916 // and the selected method is recalculated relative to the direct superclass
aoqi@0 917 // superinterface.method, which explicitly does not check shadowing
aoqi@0 918
aoqi@0 919 if (!resolved_klass->is_interface()) {
aoqi@0 920 resolve_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, check_access, false, CHECK);
aoqi@0 921 } else {
aoqi@0 922 resolve_interface_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, check_access, true, CHECK);
aoqi@0 923 }
aoqi@0 924
aoqi@0 925 // check if method name is <init>, that it is found in same klass as static type
aoqi@0 926 if (resolved_method->name() == vmSymbols::object_initializer_name() &&
aoqi@0 927 resolved_method->method_holder() != resolved_klass()) {
aoqi@0 928 ResourceMark rm(THREAD);
aoqi@0 929 Exceptions::fthrow(
aoqi@0 930 THREAD_AND_LOCATION,
aoqi@0 931 vmSymbols::java_lang_NoSuchMethodError(),
aoqi@0 932 "%s: method %s%s not found",
aoqi@0 933 resolved_klass->external_name(),
aoqi@0 934 resolved_method->name()->as_C_string(),
aoqi@0 935 resolved_method->signature()->as_C_string()
aoqi@0 936 );
aoqi@0 937 return;
aoqi@0 938 }
aoqi@0 939
aoqi@0 940 // check if invokespecial's interface method reference is in an indirect superinterface
aoqi@0 941 if (!current_klass.is_null() && resolved_klass->is_interface()) {
aoqi@0 942 Klass *klass_to_check = !InstanceKlass::cast(current_klass())->is_anonymous() ?
aoqi@0 943 current_klass() :
aoqi@0 944 InstanceKlass::cast(current_klass())->host_klass();
aoqi@0 945 // As of the fix for 4486457 we disable verification for all of the
aoqi@0 946 // dynamically-generated bytecodes associated with the 1.4
aoqi@0 947 // reflection implementation, not just those associated with
aoqi@0 948 // sun/reflect/SerializationConstructorAccessor.
aoqi@0 949 bool is_reflect = JDK_Version::is_gte_jdk14x_version() &&
aoqi@0 950 UseNewReflection &&
aoqi@0 951 klass_to_check->is_subclass_of(
aoqi@0 952 SystemDictionary::reflect_MagicAccessorImpl_klass());
aoqi@0 953
aoqi@0 954 if (!is_reflect &&
aoqi@0 955 !InstanceKlass::cast(klass_to_check)->is_same_or_direct_interface(resolved_klass())) {
aoqi@0 956 ResourceMark rm(THREAD);
aoqi@0 957 char buf[200];
aoqi@0 958 jio_snprintf(buf, sizeof(buf),
aoqi@0 959 "Interface method reference: %s, is in an indirect superinterface of %s",
aoqi@0 960 Method::name_and_sig_as_C_string(resolved_klass(),
aoqi@0 961 resolved_method->name(),
aoqi@0 962 resolved_method->signature()),
aoqi@0 963 current_klass->external_name());
aoqi@0 964 THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(), buf);
aoqi@0 965 }
aoqi@0 966 }
aoqi@0 967
aoqi@0 968 // check if not static
aoqi@0 969 if (resolved_method->is_static()) {
aoqi@0 970 ResourceMark rm(THREAD);
aoqi@0 971 char buf[200];
aoqi@0 972 jio_snprintf(buf, sizeof(buf),
aoqi@0 973 "Expecting non-static method %s",
aoqi@0 974 Method::name_and_sig_as_C_string(resolved_klass(),
aoqi@0 975 resolved_method->name(),
aoqi@0 976 resolved_method->signature()));
aoqi@0 977 THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(), buf);
aoqi@0 978 }
aoqi@0 979
aoqi@0 980 if (TraceItables && Verbose) {
aoqi@0 981 ResourceMark rm(THREAD);
aoqi@0 982 tty->print("invokespecial resolved method: caller-class:%s, compile-time-class:%s, method:%s, method_holder:%s, access_flags: ",
aoqi@0 983 (current_klass.is_null() ? "<NULL>" : current_klass->internal_name()),
aoqi@0 984 (resolved_klass.is_null() ? "<NULL>" : resolved_klass->internal_name()),
aoqi@0 985 Method::name_and_sig_as_C_string(resolved_klass(),
aoqi@0 986 resolved_method->name(),
aoqi@0 987 resolved_method->signature()),
aoqi@0 988 resolved_method->method_holder()->internal_name()
aoqi@0 989 );
aoqi@0 990 resolved_method->access_flags().print_on(tty);
aoqi@0 991 if (resolved_method->is_default_method()) {
aoqi@0 992 tty->print("default ");
aoqi@0 993 }
aoqi@0 994 if (resolved_method->is_overpass()) {
aoqi@0 995 tty->print("overpass");
aoqi@0 996 }
aoqi@0 997 tty->cr();
aoqi@0 998 }
aoqi@0 999 }
aoqi@0 1000
aoqi@0 1001 // throws runtime exceptions
aoqi@0 1002 void LinkResolver::runtime_resolve_special_method(CallInfo& result, methodHandle resolved_method, KlassHandle resolved_klass,
coleenp@8739 1003 KlassHandle current_klass, Handle recv, bool check_access, TRAPS) {
aoqi@0 1004
aoqi@0 1005 // resolved method is selected method unless we have an old-style lookup
aoqi@0 1006 // for a superclass method
aoqi@0 1007 // Invokespecial for a superinterface, resolved method is selected method,
aoqi@0 1008 // no checks for shadowing
aoqi@0 1009 methodHandle sel_method(THREAD, resolved_method());
aoqi@0 1010
coleenp@8739 1011 if (check_access &&
coleenp@8739 1012 // check if the method is not <init>
coleenp@8739 1013 resolved_method->name() != vmSymbols::object_initializer_name()) {
coleenp@8739 1014
aoqi@0 1015 // check if this is an old-style super call and do a new lookup if so
aoqi@0 1016 // a) check if ACC_SUPER flag is set for the current class
coleenp@8739 1017 if ((current_klass->is_super() || !AllowNonVirtualCalls) &&
aoqi@0 1018 // b) check if the class of the resolved_klass is a superclass
aoqi@0 1019 // (not supertype in order to exclude interface classes) of the current class.
aoqi@0 1020 // This check is not performed for super.invoke for interface methods
aoqi@0 1021 // in super interfaces.
aoqi@0 1022 current_klass->is_subclass_of(resolved_klass()) &&
coleenp@8739 1023 current_klass() != resolved_klass()) {
aoqi@0 1024 // Lookup super method
aoqi@0 1025 KlassHandle super_klass(THREAD, current_klass->super());
aoqi@0 1026 lookup_instance_method_in_klasses(sel_method, super_klass,
aoqi@0 1027 resolved_method->name(),
aoqi@0 1028 resolved_method->signature(), CHECK);
aoqi@0 1029 // check if found
aoqi@0 1030 if (sel_method.is_null()) {
aoqi@0 1031 ResourceMark rm(THREAD);
aoqi@0 1032 THROW_MSG(vmSymbols::java_lang_AbstractMethodError(),
aoqi@0 1033 Method::name_and_sig_as_C_string(resolved_klass(),
aoqi@0 1034 resolved_method->name(),
aoqi@0 1035 resolved_method->signature()));
hseigel@8839 1036 } else if (sel_method() != resolved_method()) {
hseigel@8839 1037 check_method_loader_constraints(sel_method, resolved_klass,
hseigel@8839 1038 sel_method->name(), sel_method->signature(),
hseigel@8839 1039 current_klass, "method", CHECK);
aeriksso@7865 1040 }
aeriksso@7865 1041 }
coleenp@8739 1042
coleenp@8739 1043 // Check that the class of objectref (the receiver) is the current class or interface,
coleenp@8739 1044 // or a subtype of the current class or interface (the sender), otherwise invokespecial
coleenp@8739 1045 // throws IllegalAccessError.
coleenp@8739 1046 // The verifier checks that the sender is a subtype of the class in the I/MR operand.
coleenp@8739 1047 // The verifier also checks that the receiver is a subtype of the sender, if the sender is
coleenp@8739 1048 // a class. If the sender is an interface, the check has to be performed at runtime.
coleenp@8739 1049 InstanceKlass* sender = InstanceKlass::cast(current_klass());
coleenp@8739 1050 sender = sender->is_anonymous() ? InstanceKlass::cast(sender->host_klass()) : sender;
coleenp@8739 1051 if (sender->is_interface() && recv.not_null()) {
coleenp@8739 1052 Klass* receiver_klass = recv->klass();
coleenp@8739 1053 if (!receiver_klass->is_subtype_of(sender)) {
coleenp@8739 1054 ResourceMark rm(THREAD);
coleenp@8739 1055 char buf[500];
coleenp@8739 1056 jio_snprintf(buf, sizeof(buf),
coleenp@8739 1057 "Receiver class %s must be the current class or a subtype of interface %s",
coleenp@8739 1058 receiver_klass->name()->as_C_string(),
coleenp@8739 1059 sender->name()->as_C_string());
coleenp@8739 1060 THROW_MSG(vmSymbols::java_lang_IllegalAccessError(), buf);
aoqi@0 1061 }
aoqi@0 1062 }
aoqi@0 1063 }
aoqi@0 1064
aoqi@0 1065 // check if not static
aoqi@0 1066 if (sel_method->is_static()) {
aoqi@0 1067 ResourceMark rm(THREAD);
aoqi@0 1068 char buf[200];
aoqi@0 1069 jio_snprintf(buf, sizeof(buf), "Expecting non-static method %s", Method::name_and_sig_as_C_string(resolved_klass(),
aoqi@0 1070 resolved_method->name(),
aoqi@0 1071 resolved_method->signature()));
aoqi@0 1072 THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(), buf);
aoqi@0 1073 }
aoqi@0 1074
aoqi@0 1075 // check if abstract
aoqi@0 1076 if (sel_method->is_abstract()) {
aoqi@0 1077 ResourceMark rm(THREAD);
aoqi@0 1078 THROW_MSG(vmSymbols::java_lang_AbstractMethodError(),
aoqi@0 1079 Method::name_and_sig_as_C_string(resolved_klass(),
aoqi@0 1080 sel_method->name(),
aoqi@0 1081 sel_method->signature()));
aoqi@0 1082 }
aoqi@0 1083
aoqi@0 1084 if (TraceItables && Verbose) {
aoqi@0 1085 ResourceMark rm(THREAD);
aoqi@0 1086 tty->print("invokespecial selected method: resolved-class:%s, method:%s, method_holder:%s, access_flags: ",
aoqi@0 1087 (resolved_klass.is_null() ? "<NULL>" : resolved_klass->internal_name()),
aoqi@0 1088 Method::name_and_sig_as_C_string(resolved_klass(),
aoqi@0 1089 sel_method->name(),
aoqi@0 1090 sel_method->signature()),
aoqi@0 1091 sel_method->method_holder()->internal_name()
aoqi@0 1092 );
aoqi@0 1093 sel_method->access_flags().print_on(tty);
aoqi@0 1094 if (sel_method->is_default_method()) {
aoqi@0 1095 tty->print("default ");
aoqi@0 1096 }
aoqi@0 1097 if (sel_method->is_overpass()) {
aoqi@0 1098 tty->print("overpass");
aoqi@0 1099 }
aoqi@0 1100 tty->cr();
aoqi@0 1101 }
aoqi@0 1102
aoqi@0 1103 // setup result
aoqi@0 1104 result.set_static(resolved_klass, sel_method, CHECK);
aoqi@0 1105 }
aoqi@0 1106
aoqi@0 1107 void LinkResolver::resolve_virtual_call(CallInfo& result, Handle recv, KlassHandle receiver_klass, KlassHandle resolved_klass,
aoqi@0 1108 Symbol* method_name, Symbol* method_signature, KlassHandle current_klass,
aoqi@0 1109 bool check_access, bool check_null_and_abstract, TRAPS) {
aoqi@0 1110 methodHandle resolved_method;
aoqi@0 1111 linktime_resolve_virtual_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, check_access, CHECK);
aoqi@0 1112 runtime_resolve_virtual_method(result, resolved_method, resolved_klass, recv, receiver_klass, check_null_and_abstract, CHECK);
aoqi@0 1113 }
aoqi@0 1114
aoqi@0 1115 // throws linktime exceptions
aoqi@0 1116 void LinkResolver::linktime_resolve_virtual_method(methodHandle &resolved_method, KlassHandle resolved_klass,
aoqi@0 1117 Symbol* method_name, Symbol* method_signature,
aoqi@0 1118 KlassHandle current_klass, bool check_access, TRAPS) {
aoqi@0 1119 // normal method resolution
aoqi@0 1120 resolve_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, check_access, true, CHECK);
aoqi@0 1121
aoqi@0 1122 assert(resolved_method->name() != vmSymbols::object_initializer_name(), "should have been checked in verifier");
aoqi@0 1123 assert(resolved_method->name() != vmSymbols::class_initializer_name (), "should have been checked in verifier");
aoqi@0 1124
aoqi@0 1125 // check if private interface method
aoqi@0 1126 if (resolved_klass->is_interface() && resolved_method->is_private()) {
aoqi@0 1127 ResourceMark rm(THREAD);
aoqi@0 1128 char buf[200];
aoqi@0 1129 jio_snprintf(buf, sizeof(buf), "private interface method requires invokespecial, not invokevirtual: method %s, caller-class:%s",
aoqi@0 1130 Method::name_and_sig_as_C_string(resolved_klass(),
aoqi@0 1131 resolved_method->name(),
aoqi@0 1132 resolved_method->signature()),
aoqi@0 1133 (current_klass.is_null() ? "<NULL>" : current_klass->internal_name()));
aoqi@0 1134 THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(), buf);
aoqi@0 1135 }
aoqi@0 1136
aoqi@0 1137 // check if not static
aoqi@0 1138 if (resolved_method->is_static()) {
aoqi@0 1139 ResourceMark rm(THREAD);
aoqi@0 1140 char buf[200];
aoqi@0 1141 jio_snprintf(buf, sizeof(buf), "Expecting non-static method %s", Method::name_and_sig_as_C_string(resolved_klass(),
aoqi@0 1142 resolved_method->name(),
aoqi@0 1143 resolved_method->signature()));
aoqi@0 1144 THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(), buf);
aoqi@0 1145 }
aoqi@0 1146
aoqi@0 1147 if (PrintVtables && Verbose) {
aoqi@0 1148 ResourceMark rm(THREAD);
aoqi@0 1149 tty->print("invokevirtual resolved method: caller-class:%s, compile-time-class:%s, method:%s, method_holder:%s, access_flags: ",
aoqi@0 1150 (current_klass.is_null() ? "<NULL>" : current_klass->internal_name()),
aoqi@0 1151 (resolved_klass.is_null() ? "<NULL>" : resolved_klass->internal_name()),
aoqi@0 1152 Method::name_and_sig_as_C_string(resolved_klass(),
aoqi@0 1153 resolved_method->name(),
aoqi@0 1154 resolved_method->signature()),
aoqi@0 1155 resolved_method->method_holder()->internal_name()
aoqi@0 1156 );
aoqi@0 1157 resolved_method->access_flags().print_on(tty);
aoqi@0 1158 if (resolved_method->is_default_method()) {
aoqi@0 1159 tty->print("default ");
aoqi@0 1160 }
aoqi@0 1161 if (resolved_method->is_overpass()) {
aoqi@0 1162 tty->print("overpass");
aoqi@0 1163 }
aoqi@0 1164 tty->cr();
aoqi@0 1165 }
aoqi@0 1166 }
aoqi@0 1167
aoqi@0 1168 // throws runtime exceptions
aoqi@0 1169 void LinkResolver::runtime_resolve_virtual_method(CallInfo& result,
aoqi@0 1170 methodHandle resolved_method,
aoqi@0 1171 KlassHandle resolved_klass,
aoqi@0 1172 Handle recv,
aoqi@0 1173 KlassHandle recv_klass,
aoqi@0 1174 bool check_null_and_abstract,
aoqi@0 1175 TRAPS) {
aoqi@0 1176
aoqi@0 1177 // setup default return values
aoqi@0 1178 int vtable_index = Method::invalid_vtable_index;
aoqi@0 1179 methodHandle selected_method;
aoqi@0 1180
aoqi@0 1181 assert(recv.is_null() || recv->is_oop(), "receiver is not an oop");
aoqi@0 1182
aoqi@0 1183 // runtime method resolution
aoqi@0 1184 if (check_null_and_abstract && recv.is_null()) { // check if receiver exists
aoqi@0 1185 THROW(vmSymbols::java_lang_NullPointerException());
aoqi@0 1186 }
aoqi@0 1187
aoqi@0 1188 // Virtual methods cannot be resolved before its klass has been linked, for otherwise the Method*'s
aoqi@0 1189 // has not been rewritten, and the vtable initialized. Make sure to do this after the nullcheck, since
aoqi@0 1190 // a missing receiver might result in a bogus lookup.
aoqi@0 1191 assert(resolved_method->method_holder()->is_linked(), "must be linked");
aoqi@0 1192
aoqi@0 1193 // do lookup based on receiver klass using the vtable index
dbuck@8716 1194 if (resolved_method->method_holder()->is_interface()) { // default or miranda method
aoqi@0 1195 vtable_index = vtable_index_of_interface_method(resolved_klass,
aoqi@0 1196 resolved_method);
aoqi@0 1197 assert(vtable_index >= 0 , "we should have valid vtable index at this point");
aoqi@0 1198
aoqi@0 1199 InstanceKlass* inst = InstanceKlass::cast(recv_klass());
aoqi@0 1200 selected_method = methodHandle(THREAD, inst->method_at_vtable(vtable_index));
aoqi@0 1201 } else {
aoqi@0 1202 // at this point we are sure that resolved_method is virtual and not
dbuck@8716 1203 // a default or miranda method; therefore, it must have a valid vtable index.
aoqi@0 1204 assert(!resolved_method->has_itable_index(), "");
aoqi@0 1205 vtable_index = resolved_method->vtable_index();
aoqi@0 1206 // We could get a negative vtable_index for final methods,
aoqi@0 1207 // because as an optimization they are they are never put in the vtable,
aoqi@0 1208 // unless they override an existing method.
aoqi@0 1209 // If we do get a negative, it means the resolved method is the the selected
aoqi@0 1210 // method, and it can never be changed by an override.
aoqi@0 1211 if (vtable_index == Method::nonvirtual_vtable_index) {
aoqi@0 1212 assert(resolved_method->can_be_statically_bound(), "cannot override this method");
aoqi@0 1213 selected_method = resolved_method;
aoqi@0 1214 } else {
aoqi@0 1215 // recv_klass might be an arrayKlassOop but all vtables start at
aoqi@0 1216 // the same place. The cast is to avoid virtual call and assertion.
aoqi@0 1217 InstanceKlass* inst = (InstanceKlass*)recv_klass();
aoqi@0 1218 selected_method = methodHandle(THREAD, inst->method_at_vtable(vtable_index));
aoqi@0 1219 }
aoqi@0 1220 }
aoqi@0 1221
aoqi@0 1222 // check if method exists
aoqi@0 1223 if (selected_method.is_null()) {
aoqi@0 1224 ResourceMark rm(THREAD);
aoqi@0 1225 THROW_MSG(vmSymbols::java_lang_AbstractMethodError(),
aoqi@0 1226 Method::name_and_sig_as_C_string(resolved_klass(),
aoqi@0 1227 resolved_method->name(),
aoqi@0 1228 resolved_method->signature()));
aoqi@0 1229 }
aoqi@0 1230
aoqi@0 1231 // check if abstract
aoqi@0 1232 if (check_null_and_abstract && selected_method->is_abstract()) {
aoqi@0 1233 ResourceMark rm(THREAD);
aoqi@0 1234 THROW_MSG(vmSymbols::java_lang_AbstractMethodError(),
aoqi@0 1235 Method::name_and_sig_as_C_string(resolved_klass(),
aoqi@0 1236 selected_method->name(),
aoqi@0 1237 selected_method->signature()));
aoqi@0 1238 }
aoqi@0 1239
aoqi@0 1240 if (PrintVtables && Verbose) {
aoqi@0 1241 ResourceMark rm(THREAD);
aoqi@0 1242 tty->print("invokevirtual selected method: receiver-class:%s, resolved-class:%s, method:%s, method_holder:%s, vtable_index:%d, access_flags: ",
aoqi@0 1243 (recv_klass.is_null() ? "<NULL>" : recv_klass->internal_name()),
aoqi@0 1244 (resolved_klass.is_null() ? "<NULL>" : resolved_klass->internal_name()),
aoqi@0 1245 Method::name_and_sig_as_C_string(resolved_klass(),
aoqi@0 1246 resolved_method->name(),
aoqi@0 1247 resolved_method->signature()),
aoqi@0 1248 selected_method->method_holder()->internal_name(),
aoqi@0 1249 vtable_index
aoqi@0 1250 );
aoqi@0 1251 selected_method->access_flags().print_on(tty);
aoqi@0 1252 if (selected_method->is_default_method()) {
aoqi@0 1253 tty->print("default ");
aoqi@0 1254 }
aoqi@0 1255 if (selected_method->is_overpass()) {
aoqi@0 1256 tty->print("overpass");
aoqi@0 1257 }
aoqi@0 1258 tty->cr();
aoqi@0 1259 }
aoqi@0 1260 // setup result
aoqi@0 1261 result.set_virtual(resolved_klass, recv_klass, resolved_method, selected_method, vtable_index, CHECK);
aoqi@0 1262 }
aoqi@0 1263
aoqi@0 1264 void LinkResolver::resolve_interface_call(CallInfo& result, Handle recv, KlassHandle recv_klass, KlassHandle resolved_klass,
aoqi@0 1265 Symbol* method_name, Symbol* method_signature, KlassHandle current_klass,
aoqi@0 1266 bool check_access, bool check_null_and_abstract, TRAPS) {
aoqi@0 1267 methodHandle resolved_method;
aoqi@0 1268 linktime_resolve_interface_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, check_access, CHECK);
aoqi@0 1269 runtime_resolve_interface_method(result, resolved_method, resolved_klass, recv, recv_klass, check_null_and_abstract, CHECK);
aoqi@0 1270 }
aoqi@0 1271
aoqi@0 1272 // throws linktime exceptions
aoqi@0 1273 void LinkResolver::linktime_resolve_interface_method(methodHandle& resolved_method, KlassHandle resolved_klass, Symbol* method_name,
aoqi@0 1274 Symbol* method_signature, KlassHandle current_klass, bool check_access, TRAPS) {
aoqi@0 1275 // normal interface method resolution
aoqi@0 1276 resolve_interface_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, check_access, true, CHECK);
aoqi@0 1277
aoqi@0 1278 assert(resolved_method->name() != vmSymbols::object_initializer_name(), "should have been checked in verifier");
aoqi@0 1279 assert(resolved_method->name() != vmSymbols::class_initializer_name (), "should have been checked in verifier");
aoqi@0 1280 }
aoqi@0 1281
aoqi@0 1282 // throws runtime exceptions
aoqi@0 1283 void LinkResolver::runtime_resolve_interface_method(CallInfo& result, methodHandle resolved_method, KlassHandle resolved_klass,
aoqi@0 1284 Handle recv, KlassHandle recv_klass, bool check_null_and_abstract, TRAPS) {
aoqi@0 1285 // check if receiver exists
aoqi@0 1286 if (check_null_and_abstract && recv.is_null()) {
aoqi@0 1287 THROW(vmSymbols::java_lang_NullPointerException());
aoqi@0 1288 }
aoqi@0 1289
aoqi@0 1290 // check if private interface method
aoqi@0 1291 if (resolved_klass->is_interface() && resolved_method->is_private()) {
aoqi@0 1292 ResourceMark rm(THREAD);
aoqi@0 1293 char buf[200];
aoqi@0 1294 jio_snprintf(buf, sizeof(buf), "private interface method requires invokespecial, not invokeinterface: method %s",
aoqi@0 1295 Method::name_and_sig_as_C_string(resolved_klass(),
aoqi@0 1296 resolved_method->name(),
aoqi@0 1297 resolved_method->signature()));
aoqi@0 1298 THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(), buf);
aoqi@0 1299 }
aoqi@0 1300
aoqi@0 1301 // check if receiver klass implements the resolved interface
aoqi@0 1302 if (!recv_klass->is_subtype_of(resolved_klass())) {
aoqi@0 1303 ResourceMark rm(THREAD);
aoqi@0 1304 char buf[200];
aoqi@0 1305 jio_snprintf(buf, sizeof(buf), "Class %s does not implement the requested interface %s",
aoqi@0 1306 recv_klass()->external_name(),
aoqi@0 1307 resolved_klass()->external_name());
aoqi@0 1308 THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(), buf);
aoqi@0 1309 }
aoqi@0 1310
aoqi@0 1311 // do lookup based on receiver klass
aoqi@0 1312 methodHandle sel_method;
aoqi@0 1313 // This search must match the linktime preparation search for itable initialization
aoqi@0 1314 // to correctly enforce loader constraints for interface method inheritance
aoqi@0 1315 lookup_instance_method_in_klasses(sel_method, recv_klass,
aoqi@0 1316 resolved_method->name(),
aoqi@0 1317 resolved_method->signature(), CHECK);
aoqi@0 1318 if (sel_method.is_null() && !check_null_and_abstract) {
aoqi@0 1319 // In theory this is a harmless placeholder value, but
aoqi@0 1320 // in practice leaving in null affects the nsk default method tests.
aoqi@0 1321 // This needs further study.
aoqi@0 1322 sel_method = resolved_method;
aoqi@0 1323 }
aoqi@0 1324 // check if method exists
aoqi@0 1325 if (sel_method.is_null()) {
aoqi@0 1326 ResourceMark rm(THREAD);
aoqi@0 1327 THROW_MSG(vmSymbols::java_lang_AbstractMethodError(),
aoqi@0 1328 Method::name_and_sig_as_C_string(recv_klass(),
aoqi@0 1329 resolved_method->name(),
aoqi@0 1330 resolved_method->signature()));
aoqi@0 1331 }
aoqi@0 1332 // check access
aoqi@0 1333 // Throw Illegal Access Error if sel_method is not public.
aoqi@0 1334 if (!sel_method->is_public()) {
aoqi@0 1335 ResourceMark rm(THREAD);
aoqi@0 1336 THROW_MSG(vmSymbols::java_lang_IllegalAccessError(),
aoqi@0 1337 Method::name_and_sig_as_C_string(recv_klass(),
aoqi@0 1338 sel_method->name(),
aoqi@0 1339 sel_method->signature()));
aoqi@0 1340 }
aoqi@0 1341 // check if abstract
aoqi@0 1342 if (check_null_and_abstract && sel_method->is_abstract()) {
aoqi@0 1343 ResourceMark rm(THREAD);
aoqi@0 1344 THROW_MSG(vmSymbols::java_lang_AbstractMethodError(),
aoqi@0 1345 Method::name_and_sig_as_C_string(recv_klass(),
aoqi@0 1346 sel_method->name(),
aoqi@0 1347 sel_method->signature()));
aoqi@0 1348 }
aoqi@0 1349
aoqi@0 1350 if (TraceItables && Verbose) {
aoqi@0 1351 ResourceMark rm(THREAD);
aoqi@0 1352 tty->print("invokeinterface selected method: receiver-class:%s, resolved-class:%s, method:%s, method_holder:%s, access_flags: ",
aoqi@0 1353 (recv_klass.is_null() ? "<NULL>" : recv_klass->internal_name()),
aoqi@0 1354 (resolved_klass.is_null() ? "<NULL>" : resolved_klass->internal_name()),
aoqi@0 1355 Method::name_and_sig_as_C_string(resolved_klass(),
aoqi@0 1356 resolved_method->name(),
aoqi@0 1357 resolved_method->signature()),
aoqi@0 1358 sel_method->method_holder()->internal_name()
aoqi@0 1359 );
aoqi@0 1360 sel_method->access_flags().print_on(tty);
aoqi@0 1361 if (sel_method->is_default_method()) {
aoqi@0 1362 tty->print("default ");
aoqi@0 1363 }
aoqi@0 1364 if (sel_method->is_overpass()) {
aoqi@0 1365 tty->print("overpass");
aoqi@0 1366 }
aoqi@0 1367 tty->cr();
aoqi@0 1368 }
aoqi@0 1369 // setup result
aoqi@0 1370 if (!resolved_method->has_itable_index()) {
aoqi@0 1371 int vtable_index = resolved_method->vtable_index();
aoqi@0 1372 assert(vtable_index == sel_method->vtable_index(), "sanity check");
aoqi@0 1373 result.set_virtual(resolved_klass, recv_klass, resolved_method, sel_method, vtable_index, CHECK);
aoqi@0 1374 } else {
aoqi@0 1375 int itable_index = resolved_method()->itable_index();
aoqi@0 1376 result.set_interface(resolved_klass, recv_klass, resolved_method, sel_method, itable_index, CHECK);
aoqi@0 1377 }
aoqi@0 1378 }
aoqi@0 1379
aoqi@0 1380
aoqi@0 1381 methodHandle LinkResolver::linktime_resolve_interface_method_or_null(
aoqi@0 1382 KlassHandle resolved_klass,
aoqi@0 1383 Symbol* method_name,
aoqi@0 1384 Symbol* method_signature,
aoqi@0 1385 KlassHandle current_klass,
aoqi@0 1386 bool check_access) {
aoqi@0 1387 EXCEPTION_MARK;
aoqi@0 1388 methodHandle method_result;
aoqi@0 1389 linktime_resolve_interface_method(method_result, resolved_klass, method_name, method_signature, current_klass, check_access, THREAD);
aoqi@0 1390 if (HAS_PENDING_EXCEPTION) {
aoqi@0 1391 CLEAR_PENDING_EXCEPTION;
aoqi@0 1392 return methodHandle();
aoqi@0 1393 } else {
aoqi@0 1394 return method_result;
aoqi@0 1395 }
aoqi@0 1396 }
aoqi@0 1397
aoqi@0 1398 methodHandle LinkResolver::linktime_resolve_virtual_method_or_null(
aoqi@0 1399 KlassHandle resolved_klass,
aoqi@0 1400 Symbol* method_name,
aoqi@0 1401 Symbol* method_signature,
aoqi@0 1402 KlassHandle current_klass,
aoqi@0 1403 bool check_access) {
aoqi@0 1404 EXCEPTION_MARK;
aoqi@0 1405 methodHandle method_result;
aoqi@0 1406 linktime_resolve_virtual_method(method_result, resolved_klass, method_name, method_signature, current_klass, check_access, THREAD);
aoqi@0 1407 if (HAS_PENDING_EXCEPTION) {
aoqi@0 1408 CLEAR_PENDING_EXCEPTION;
aoqi@0 1409 return methodHandle();
aoqi@0 1410 } else {
aoqi@0 1411 return method_result;
aoqi@0 1412 }
aoqi@0 1413 }
aoqi@0 1414
aoqi@0 1415 methodHandle LinkResolver::resolve_virtual_call_or_null(
aoqi@0 1416 KlassHandle receiver_klass,
aoqi@0 1417 KlassHandle resolved_klass,
aoqi@0 1418 Symbol* name,
aoqi@0 1419 Symbol* signature,
vlivanov@7792 1420 KlassHandle current_klass,
vlivanov@7792 1421 bool check_access) {
aoqi@0 1422 EXCEPTION_MARK;
aoqi@0 1423 CallInfo info;
vlivanov@7792 1424 resolve_virtual_call(info, Handle(), receiver_klass, resolved_klass, name, signature, current_klass, check_access, false, THREAD);
aoqi@0 1425 if (HAS_PENDING_EXCEPTION) {
aoqi@0 1426 CLEAR_PENDING_EXCEPTION;
aoqi@0 1427 return methodHandle();
aoqi@0 1428 }
aoqi@0 1429 return info.selected_method();
aoqi@0 1430 }
aoqi@0 1431
aoqi@0 1432 methodHandle LinkResolver::resolve_interface_call_or_null(
aoqi@0 1433 KlassHandle receiver_klass,
aoqi@0 1434 KlassHandle resolved_klass,
aoqi@0 1435 Symbol* name,
aoqi@0 1436 Symbol* signature,
vlivanov@7792 1437 KlassHandle current_klass,
vlivanov@7792 1438 bool check_access) {
aoqi@0 1439 EXCEPTION_MARK;
aoqi@0 1440 CallInfo info;
vlivanov@7792 1441 resolve_interface_call(info, Handle(), receiver_klass, resolved_klass, name, signature, current_klass, check_access, false, THREAD);
aoqi@0 1442 if (HAS_PENDING_EXCEPTION) {
aoqi@0 1443 CLEAR_PENDING_EXCEPTION;
aoqi@0 1444 return methodHandle();
aoqi@0 1445 }
aoqi@0 1446 return info.selected_method();
aoqi@0 1447 }
aoqi@0 1448
aoqi@0 1449 int LinkResolver::resolve_virtual_vtable_index(
aoqi@0 1450 KlassHandle receiver_klass,
aoqi@0 1451 KlassHandle resolved_klass,
aoqi@0 1452 Symbol* name,
aoqi@0 1453 Symbol* signature,
aoqi@0 1454 KlassHandle current_klass) {
aoqi@0 1455 EXCEPTION_MARK;
aoqi@0 1456 CallInfo info;
aoqi@0 1457 resolve_virtual_call(info, Handle(), receiver_klass, resolved_klass, name, signature, current_klass, true, false, THREAD);
aoqi@0 1458 if (HAS_PENDING_EXCEPTION) {
aoqi@0 1459 CLEAR_PENDING_EXCEPTION;
aoqi@0 1460 return Method::invalid_vtable_index;
aoqi@0 1461 }
aoqi@0 1462 return info.vtable_index();
aoqi@0 1463 }
aoqi@0 1464
aoqi@0 1465 methodHandle LinkResolver::resolve_static_call_or_null(
aoqi@0 1466 KlassHandle resolved_klass,
aoqi@0 1467 Symbol* name,
aoqi@0 1468 Symbol* signature,
vlivanov@7792 1469 KlassHandle current_klass,
vlivanov@7792 1470 bool check_access) {
aoqi@0 1471 EXCEPTION_MARK;
aoqi@0 1472 CallInfo info;
vlivanov@7792 1473 resolve_static_call(info, resolved_klass, name, signature, current_klass, check_access, false, THREAD);
aoqi@0 1474 if (HAS_PENDING_EXCEPTION) {
aoqi@0 1475 CLEAR_PENDING_EXCEPTION;
aoqi@0 1476 return methodHandle();
aoqi@0 1477 }
aoqi@0 1478 return info.selected_method();
aoqi@0 1479 }
aoqi@0 1480
vlivanov@7792 1481 methodHandle LinkResolver::resolve_special_call_or_null(
vlivanov@7792 1482 KlassHandle resolved_klass,
vlivanov@7792 1483 Symbol* name,
vlivanov@7792 1484 Symbol* signature,
vlivanov@7792 1485 KlassHandle current_klass,
vlivanov@7792 1486 bool check_access) {
aoqi@0 1487 EXCEPTION_MARK;
aoqi@0 1488 CallInfo info;
coleenp@8739 1489 resolve_special_call(info, Handle(), resolved_klass, name, signature, current_klass, check_access, THREAD);
aoqi@0 1490 if (HAS_PENDING_EXCEPTION) {
aoqi@0 1491 CLEAR_PENDING_EXCEPTION;
aoqi@0 1492 return methodHandle();
aoqi@0 1493 }
aoqi@0 1494 return info.selected_method();
aoqi@0 1495 }
aoqi@0 1496
aoqi@0 1497
aoqi@0 1498
aoqi@0 1499 //------------------------------------------------------------------------------------------------------------------------
aoqi@0 1500 // ConstantPool entries
aoqi@0 1501
aoqi@0 1502 void LinkResolver::resolve_invoke(CallInfo& result, Handle recv, constantPoolHandle pool, int index, Bytecodes::Code byte, TRAPS) {
aoqi@0 1503 switch (byte) {
aoqi@0 1504 case Bytecodes::_invokestatic : resolve_invokestatic (result, pool, index, CHECK); break;
coleenp@8739 1505 case Bytecodes::_invokespecial : resolve_invokespecial (result, recv, pool, index, CHECK); break;
aoqi@0 1506 case Bytecodes::_invokevirtual : resolve_invokevirtual (result, recv, pool, index, CHECK); break;
aoqi@0 1507 case Bytecodes::_invokehandle : resolve_invokehandle (result, pool, index, CHECK); break;
aoqi@0 1508 case Bytecodes::_invokedynamic : resolve_invokedynamic (result, pool, index, CHECK); break;
aoqi@0 1509 case Bytecodes::_invokeinterface: resolve_invokeinterface(result, recv, pool, index, CHECK); break;
aoqi@0 1510 }
aoqi@0 1511 return;
aoqi@0 1512 }
aoqi@0 1513
aoqi@0 1514 void LinkResolver::resolve_pool(KlassHandle& resolved_klass, Symbol*& method_name, Symbol*& method_signature,
aoqi@0 1515 KlassHandle& current_klass, constantPoolHandle pool, int index, TRAPS) {
aoqi@0 1516 // resolve klass
aoqi@0 1517 resolve_klass(resolved_klass, pool, index, CHECK);
aoqi@0 1518
aoqi@0 1519 // Get name, signature, and static klass
aoqi@0 1520 method_name = pool->name_ref_at(index);
aoqi@0 1521 method_signature = pool->signature_ref_at(index);
aoqi@0 1522 current_klass = KlassHandle(THREAD, pool->pool_holder());
aoqi@0 1523 }
aoqi@0 1524
aoqi@0 1525
aoqi@0 1526 void LinkResolver::resolve_invokestatic(CallInfo& result, constantPoolHandle pool, int index, TRAPS) {
aoqi@0 1527 KlassHandle resolved_klass;
aoqi@0 1528 Symbol* method_name = NULL;
aoqi@0 1529 Symbol* method_signature = NULL;
aoqi@0 1530 KlassHandle current_klass;
aoqi@0 1531 resolve_pool(resolved_klass, method_name, method_signature, current_klass, pool, index, CHECK);
aoqi@0 1532 resolve_static_call(result, resolved_klass, method_name, method_signature, current_klass, true, true, CHECK);
aoqi@0 1533 }
aoqi@0 1534
aoqi@0 1535
coleenp@8739 1536 void LinkResolver::resolve_invokespecial(CallInfo& result, Handle recv, constantPoolHandle pool, int index, TRAPS) {
aoqi@0 1537 KlassHandle resolved_klass;
aoqi@0 1538 Symbol* method_name = NULL;
aoqi@0 1539 Symbol* method_signature = NULL;
aoqi@0 1540 KlassHandle current_klass;
aoqi@0 1541 resolve_pool(resolved_klass, method_name, method_signature, current_klass, pool, index, CHECK);
coleenp@8739 1542 resolve_special_call(result, recv, resolved_klass, method_name, method_signature, current_klass, true, CHECK);
aoqi@0 1543 }
aoqi@0 1544
aoqi@0 1545
aoqi@0 1546 void LinkResolver::resolve_invokevirtual(CallInfo& result, Handle recv,
aoqi@0 1547 constantPoolHandle pool, int index,
aoqi@0 1548 TRAPS) {
aoqi@0 1549
aoqi@0 1550 KlassHandle resolved_klass;
aoqi@0 1551 Symbol* method_name = NULL;
aoqi@0 1552 Symbol* method_signature = NULL;
aoqi@0 1553 KlassHandle current_klass;
aoqi@0 1554 resolve_pool(resolved_klass, method_name, method_signature, current_klass, pool, index, CHECK);
aoqi@0 1555 KlassHandle recvrKlass (THREAD, recv.is_null() ? (Klass*)NULL : recv->klass());
aoqi@0 1556 resolve_virtual_call(result, recv, recvrKlass, resolved_klass, method_name, method_signature, current_klass, true, true, CHECK);
aoqi@0 1557 }
aoqi@0 1558
aoqi@0 1559
aoqi@0 1560 void LinkResolver::resolve_invokeinterface(CallInfo& result, Handle recv, constantPoolHandle pool, int index, TRAPS) {
aoqi@0 1561 KlassHandle resolved_klass;
aoqi@0 1562 Symbol* method_name = NULL;
aoqi@0 1563 Symbol* method_signature = NULL;
aoqi@0 1564 KlassHandle current_klass;
aoqi@0 1565 resolve_pool(resolved_klass, method_name, method_signature, current_klass, pool, index, CHECK);
aoqi@0 1566 KlassHandle recvrKlass (THREAD, recv.is_null() ? (Klass*)NULL : recv->klass());
aoqi@0 1567 resolve_interface_call(result, recv, recvrKlass, resolved_klass, method_name, method_signature, current_klass, true, true, CHECK);
aoqi@0 1568 }
aoqi@0 1569
aoqi@0 1570
aoqi@0 1571 void LinkResolver::resolve_invokehandle(CallInfo& result, constantPoolHandle pool, int index, TRAPS) {
aoqi@0 1572 assert(EnableInvokeDynamic, "");
aoqi@0 1573 // This guy is reached from InterpreterRuntime::resolve_invokehandle.
aoqi@0 1574 KlassHandle resolved_klass;
aoqi@0 1575 Symbol* method_name = NULL;
aoqi@0 1576 Symbol* method_signature = NULL;
aoqi@0 1577 KlassHandle current_klass;
aoqi@0 1578 resolve_pool(resolved_klass, method_name, method_signature, current_klass, pool, index, CHECK);
aoqi@0 1579 if (TraceMethodHandles) {
aoqi@0 1580 ResourceMark rm(THREAD);
aoqi@0 1581 tty->print_cr("resolve_invokehandle %s %s", method_name->as_C_string(), method_signature->as_C_string());
aoqi@0 1582 }
aoqi@0 1583 resolve_handle_call(result, resolved_klass, method_name, method_signature, current_klass, CHECK);
aoqi@0 1584 }
aoqi@0 1585
aoqi@0 1586 void LinkResolver::resolve_handle_call(CallInfo& result, KlassHandle resolved_klass,
aoqi@0 1587 Symbol* method_name, Symbol* method_signature,
aoqi@0 1588 KlassHandle current_klass,
aoqi@0 1589 TRAPS) {
aoqi@0 1590 // JSR 292: this must be an implicitly generated method MethodHandle.invokeExact(*...) or similar
aoqi@0 1591 assert(resolved_klass() == SystemDictionary::MethodHandle_klass(), "");
aoqi@0 1592 assert(MethodHandles::is_signature_polymorphic_name(method_name), "");
aoqi@0 1593 methodHandle resolved_method;
aoqi@0 1594 Handle resolved_appendix;
aoqi@0 1595 Handle resolved_method_type;
aoqi@0 1596 lookup_polymorphic_method(resolved_method, resolved_klass,
aoqi@0 1597 method_name, method_signature,
aoqi@0 1598 current_klass, &resolved_appendix, &resolved_method_type, CHECK);
aoqi@0 1599 result.set_handle(resolved_method, resolved_appendix, resolved_method_type, CHECK);
aoqi@0 1600 }
aoqi@0 1601
aeriksso@7865 1602 static void wrap_invokedynamic_exception(TRAPS) {
aeriksso@7865 1603 if (HAS_PENDING_EXCEPTION) {
aeriksso@7865 1604 if (TraceMethodHandles) {
aeriksso@7865 1605 tty->print_cr("invokedynamic throws BSME for " INTPTR_FORMAT, p2i((void *)PENDING_EXCEPTION));
aeriksso@7865 1606 PENDING_EXCEPTION->print();
aeriksso@7865 1607 }
aeriksso@7865 1608 if (PENDING_EXCEPTION->is_a(SystemDictionary::BootstrapMethodError_klass())) {
aeriksso@7865 1609 // throw these guys, since they are already wrapped
aeriksso@7865 1610 return;
aeriksso@7865 1611 }
aeriksso@7865 1612 if (!PENDING_EXCEPTION->is_a(SystemDictionary::LinkageError_klass())) {
aeriksso@7865 1613 // intercept only LinkageErrors which might have failed to wrap
aeriksso@7865 1614 return;
aeriksso@7865 1615 }
aeriksso@7865 1616 // See the "Linking Exceptions" section for the invokedynamic instruction in the JVMS.
aeriksso@7865 1617 Handle nested_exception(THREAD, PENDING_EXCEPTION);
aeriksso@7865 1618 CLEAR_PENDING_EXCEPTION;
aeriksso@7865 1619 THROW_CAUSE(vmSymbols::java_lang_BootstrapMethodError(), nested_exception)
aeriksso@7865 1620 }
aeriksso@7865 1621 }
aoqi@0 1622
aoqi@0 1623 void LinkResolver::resolve_invokedynamic(CallInfo& result, constantPoolHandle pool, int index, TRAPS) {
aoqi@0 1624 assert(EnableInvokeDynamic, "");
aoqi@0 1625
aoqi@0 1626 //resolve_pool(<resolved_klass>, method_name, method_signature, current_klass, pool, index, CHECK);
aoqi@0 1627 Symbol* method_name = pool->name_ref_at(index);
aoqi@0 1628 Symbol* method_signature = pool->signature_ref_at(index);
aoqi@0 1629 KlassHandle current_klass = KlassHandle(THREAD, pool->pool_holder());
aoqi@0 1630
aoqi@0 1631 // Resolve the bootstrap specifier (BSM + optional arguments).
aoqi@0 1632 Handle bootstrap_specifier;
aoqi@0 1633 // Check if CallSite has been bound already:
aoqi@0 1634 ConstantPoolCacheEntry* cpce = pool->invokedynamic_cp_cache_entry_at(index);
aoqi@0 1635 if (cpce->is_f1_null()) {
aoqi@0 1636 int pool_index = cpce->constant_pool_index();
aeriksso@7865 1637 oop bsm_info = pool->resolve_bootstrap_specifier_at(pool_index, THREAD);
aeriksso@7865 1638 wrap_invokedynamic_exception(CHECK);
aoqi@0 1639 assert(bsm_info != NULL, "");
aoqi@0 1640 // FIXME: Cache this once per BootstrapMethods entry, not once per CONSTANT_InvokeDynamic.
aoqi@0 1641 bootstrap_specifier = Handle(THREAD, bsm_info);
aoqi@0 1642 }
aoqi@0 1643 if (!cpce->is_f1_null()) {
aoqi@0 1644 methodHandle method( THREAD, cpce->f1_as_method());
aoqi@0 1645 Handle appendix( THREAD, cpce->appendix_if_resolved(pool));
aoqi@0 1646 Handle method_type(THREAD, cpce->method_type_if_resolved(pool));
aeriksso@7865 1647 result.set_handle(method, appendix, method_type, THREAD);
aeriksso@7865 1648 wrap_invokedynamic_exception(CHECK);
aoqi@0 1649 return;
aoqi@0 1650 }
aoqi@0 1651
aoqi@0 1652 if (TraceMethodHandles) {
aoqi@0 1653 ResourceMark rm(THREAD);
aoqi@0 1654 tty->print_cr("resolve_invokedynamic #%d %s %s",
aoqi@0 1655 ConstantPool::decode_invokedynamic_index(index),
aoqi@0 1656 method_name->as_C_string(), method_signature->as_C_string());
aoqi@0 1657 tty->print(" BSM info: "); bootstrap_specifier->print();
aoqi@0 1658 }
aoqi@0 1659
aoqi@0 1660 resolve_dynamic_call(result, bootstrap_specifier, method_name, method_signature, current_klass, CHECK);
aoqi@0 1661 }
aoqi@0 1662
aoqi@0 1663 void LinkResolver::resolve_dynamic_call(CallInfo& result,
aoqi@0 1664 Handle bootstrap_specifier,
aoqi@0 1665 Symbol* method_name, Symbol* method_signature,
aoqi@0 1666 KlassHandle current_klass,
aoqi@0 1667 TRAPS) {
aoqi@0 1668 // JSR 292: this must resolve to an implicitly generated method MH.linkToCallSite(*...)
aoqi@0 1669 // The appendix argument is likely to be a freshly-created CallSite.
aoqi@0 1670 Handle resolved_appendix;
aoqi@0 1671 Handle resolved_method_type;
aoqi@0 1672 methodHandle resolved_method =
aoqi@0 1673 SystemDictionary::find_dynamic_call_site_invoker(current_klass,
aoqi@0 1674 bootstrap_specifier,
aoqi@0 1675 method_name, method_signature,
aoqi@0 1676 &resolved_appendix,
aoqi@0 1677 &resolved_method_type,
aoqi@0 1678 THREAD);
aeriksso@7865 1679 wrap_invokedynamic_exception(CHECK);
aeriksso@7865 1680 result.set_handle(resolved_method, resolved_appendix, resolved_method_type, THREAD);
aeriksso@7865 1681 wrap_invokedynamic_exception(CHECK);
aoqi@0 1682 }
aoqi@0 1683
aoqi@0 1684 //------------------------------------------------------------------------------------------------------------------------
aoqi@0 1685 #ifndef PRODUCT
aoqi@0 1686
aoqi@0 1687 void CallInfo::print() {
aoqi@0 1688 ResourceMark rm;
aoqi@0 1689 const char* kindstr = "unknown";
aoqi@0 1690 switch (_call_kind) {
aoqi@0 1691 case direct_call: kindstr = "direct"; break;
aoqi@0 1692 case vtable_call: kindstr = "vtable"; break;
aoqi@0 1693 case itable_call: kindstr = "itable"; break;
aoqi@0 1694 }
aoqi@0 1695 tty->print_cr("Call %s@%d %s", kindstr, _call_index,
aoqi@0 1696 _resolved_method.is_null() ? "(none)" : _resolved_method->name_and_sig_as_C_string());
aoqi@0 1697 }
aoqi@0 1698
aoqi@0 1699 #endif

mercurial