equal
deleted
inserted
replaced
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()) { |