hotspot/src/share/vm/interpreter/linkResolver.cpp
changeset 35913 928548a43408
parent 35606 d873b64009cc
parent 35901 f5028c67e7cb
child 36508 5f9eee6b383b
child 36819 bca375d368ed
equal deleted inserted replaced
35607:d73b0b6a24e6 35913:928548a43408
     1 /*
     1 /*
     2  * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
     2  * Copyright (c) 1997, 2016, 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.
   166     // Could be an Object method inherited into an interface, but still a vtable call.
   166     // Could be an Object method inherited into an interface, but still a vtable call.
   167     kind = CallInfo::vtable_call;
   167     kind = CallInfo::vtable_call;
   168   } else if (!resolved_klass->is_interface()) {
   168   } else if (!resolved_klass->is_interface()) {
   169     // A default or miranda method.  Compute the vtable index.
   169     // A default or miranda method.  Compute the vtable index.
   170     ResourceMark rm;
   170     ResourceMark rm;
   171     klassVtable* vt = InstanceKlass::cast(resolved_klass)->vtable();
   171     klassVtable* vt = resolved_klass->vtable();
   172     index = LinkResolver::vtable_index_of_interface_method(resolved_klass,
   172     index = LinkResolver::vtable_index_of_interface_method(resolved_klass,
   173                            resolved_method);
   173                            resolved_method);
   174     assert(index >= 0 , "we should have valid vtable index at this point");
   174     assert(index >= 0 , "we should have valid vtable index at this point");
   175 
   175 
   176     kind = CallInfo::vtable_call;
   176     kind = CallInfo::vtable_call;
   816                  Method::name_and_sig_as_C_string(resolved_klass(),
   816                  Method::name_and_sig_as_C_string(resolved_klass(),
   817                  resolved_method->name(), resolved_method->signature()));
   817                  resolved_method->name(), resolved_method->signature()));
   818     THROW_MSG_NULL(vmSymbols::java_lang_IncompatibleClassChangeError(), buf);
   818     THROW_MSG_NULL(vmSymbols::java_lang_IncompatibleClassChangeError(), buf);
   819   }
   819   }
   820 
   820 
   821   if (develop_log_is_enabled(Trace, itables)) {
   821   if (log_develop_is_enabled(Trace, itables)) {
   822     trace_method_resolution("invokeinterface resolved method: caller-class",
   822     trace_method_resolution("invokeinterface resolved method: caller-class",
   823                             link_info.current_klass(), resolved_klass,
   823                             link_info.current_klass(), resolved_klass,
   824                             resolved_method, true);
   824                             resolved_method, true);
   825   }
   825   }
   826 
   826 
  1064                                                   resolved_method->name(),
  1064                                                   resolved_method->name(),
  1065                                                   resolved_method->signature()));
  1065                                                   resolved_method->signature()));
  1066     THROW_MSG_NULL(vmSymbols::java_lang_IncompatibleClassChangeError(), buf);
  1066     THROW_MSG_NULL(vmSymbols::java_lang_IncompatibleClassChangeError(), buf);
  1067   }
  1067   }
  1068 
  1068 
  1069   if (develop_log_is_enabled(Trace, itables)) {
  1069   if (log_develop_is_enabled(Trace, itables)) {
  1070     trace_method_resolution("invokespecial resolved method: caller-class:",
  1070     trace_method_resolution("invokespecial resolved method: caller-class:",
  1071                             current_klass, resolved_klass, resolved_method, true);
  1071                             current_klass, resolved_klass, resolved_method, true);
  1072   }
  1072   }
  1073 
  1073 
  1074   return resolved_method;
  1074   return resolved_method;
  1135               Method::name_and_sig_as_C_string(resolved_klass(),
  1135               Method::name_and_sig_as_C_string(resolved_klass(),
  1136                                                sel_method->name(),
  1136                                                sel_method->name(),
  1137                                                sel_method->signature()));
  1137                                                sel_method->signature()));
  1138   }
  1138   }
  1139 
  1139 
  1140   if (develop_log_is_enabled(Trace, itables)) {
  1140   if (log_develop_is_enabled(Trace, itables)) {
  1141     trace_method_resolution("invokespecial selected method: resolved-class:",
  1141     trace_method_resolution("invokespecial selected method: resolved-class:",
  1142                             resolved_klass, resolved_klass, sel_method, true);
  1142                             resolved_klass, resolved_klass, sel_method, true);
  1143   }
  1143   }
  1144 
  1144 
  1145   // setup result
  1145   // setup result
  1188                                                                                                              resolved_method->name(),
  1188                                                                                                              resolved_method->name(),
  1189                                                                                                              resolved_method->signature()));
  1189                                                                                                              resolved_method->signature()));
  1190     THROW_MSG_NULL(vmSymbols::java_lang_IncompatibleClassChangeError(), buf);
  1190     THROW_MSG_NULL(vmSymbols::java_lang_IncompatibleClassChangeError(), buf);
  1191   }
  1191   }
  1192 
  1192 
  1193   if (develop_log_is_enabled(Trace, vtables)) {
  1193   if (log_develop_is_enabled(Trace, vtables)) {
  1194     trace_method_resolution("invokevirtual resolved method: caller-class:",
  1194     trace_method_resolution("invokevirtual resolved method: caller-class:",
  1195                             current_klass, resolved_klass, resolved_method, false);
  1195                             current_klass, resolved_klass, resolved_method, false);
  1196   }
  1196   }
  1197 
  1197 
  1198   return resolved_method;
  1198   return resolved_method;
  1227   if (resolved_method->method_holder()->is_interface()) { // default or miranda method
  1227   if (resolved_method->method_holder()->is_interface()) { // default or miranda method
  1228     vtable_index = vtable_index_of_interface_method(resolved_klass,
  1228     vtable_index = vtable_index_of_interface_method(resolved_klass,
  1229                            resolved_method);
  1229                            resolved_method);
  1230     assert(vtable_index >= 0 , "we should have valid vtable index at this point");
  1230     assert(vtable_index >= 0 , "we should have valid vtable index at this point");
  1231 
  1231 
  1232     InstanceKlass* inst = InstanceKlass::cast(recv_klass());
  1232     selected_method = methodHandle(THREAD, recv_klass->method_at_vtable(vtable_index));
  1233     selected_method = methodHandle(THREAD, inst->method_at_vtable(vtable_index));
       
  1234   } else {
  1233   } else {
  1235     // at this point we are sure that resolved_method is virtual and not
  1234     // at this point we are sure that resolved_method is virtual and not
  1236     // a default or miranda method; therefore, it must have a valid vtable index.
  1235     // a default or miranda method; therefore, it must have a valid vtable index.
  1237     assert(!resolved_method->has_itable_index(), "");
  1236     assert(!resolved_method->has_itable_index(), "");
  1238     vtable_index = resolved_method->vtable_index();
  1237     vtable_index = resolved_method->vtable_index();
  1243     // method, and it can never be changed by an override.
  1242     // method, and it can never be changed by an override.
  1244     if (vtable_index == Method::nonvirtual_vtable_index) {
  1243     if (vtable_index == Method::nonvirtual_vtable_index) {
  1245       assert(resolved_method->can_be_statically_bound(), "cannot override this method");
  1244       assert(resolved_method->can_be_statically_bound(), "cannot override this method");
  1246       selected_method = resolved_method;
  1245       selected_method = resolved_method;
  1247     } else {
  1246     } else {
  1248       // recv_klass might be an arrayKlassOop but all vtables start at
  1247       selected_method = methodHandle(THREAD, recv_klass->method_at_vtable(vtable_index));
  1249       // the same place. The cast is to avoid virtual call and assertion.
       
  1250       InstanceKlass* inst = (InstanceKlass*)recv_klass();
       
  1251       selected_method = methodHandle(THREAD, inst->method_at_vtable(vtable_index));
       
  1252     }
  1248     }
  1253   }
  1249   }
  1254 
  1250 
  1255   // check if method exists
  1251   // check if method exists
  1256   if (selected_method.is_null()) {
  1252   if (selected_method.is_null()) {
  1268               Method::name_and_sig_as_C_string(resolved_klass(),
  1264               Method::name_and_sig_as_C_string(resolved_klass(),
  1269                                                       selected_method->name(),
  1265                                                       selected_method->name(),
  1270                                                       selected_method->signature()));
  1266                                                       selected_method->signature()));
  1271   }
  1267   }
  1272 
  1268 
  1273   if (develop_log_is_enabled(Trace, vtables)) {
  1269   if (log_develop_is_enabled(Trace, vtables)) {
  1274     trace_method_resolution("invokevirtual selected method: receiver-class:",
  1270     trace_method_resolution("invokevirtual selected method: receiver-class:",
  1275                             recv_klass, resolved_klass, selected_method,
  1271                             recv_klass, resolved_klass, selected_method,
  1276                             false, vtable_index);
  1272                             false, vtable_index);
  1277   }
  1273   }
  1278   // setup result
  1274   // setup result
  1367               Method::name_and_sig_as_C_string(recv_klass(),
  1363               Method::name_and_sig_as_C_string(recv_klass(),
  1368                                                       sel_method->name(),
  1364                                                       sel_method->name(),
  1369                                                       sel_method->signature()));
  1365                                                       sel_method->signature()));
  1370   }
  1366   }
  1371 
  1367 
  1372   if (develop_log_is_enabled(Trace, itables)) {
  1368   if (log_develop_is_enabled(Trace, itables)) {
  1373     trace_method_resolution("invokeinterface selected method: receiver-class",
  1369     trace_method_resolution("invokeinterface selected method: receiver-class",
  1374                             recv_klass, resolved_klass, sel_method, true);
  1370                             recv_klass, resolved_klass, sel_method, true);
  1375   }
  1371   }
  1376   // setup result
  1372   // setup result
  1377   if (!resolved_method->has_itable_index()) {
  1373   if (!resolved_method->has_itable_index()) {