Mercurial > hg > graal-jvmci-8
comparison src/share/vm/prims/jni.cpp @ 23062:3300e511bc3a
8072588: JVM crashes in JNI if toString is declared as an interface method
Summary: Check for a valid itable index instead of checking if the holder is an interface
Reviewed-by: dsimms, dholmes
author | aeriksso |
---|---|
date | Tue, 02 Jun 2015 10:41:18 +0200 |
parents | c2ce24504334 |
children | dd9cc155639c c60b9a314312 32b682649973 |
comparison
equal
deleted
inserted
replaced
23061:81bed6c76a89 | 23062:3300e511bc3a |
---|---|
1323 Method* selected_method; | 1323 Method* selected_method; |
1324 { | 1324 { |
1325 Method* m = Method::resolve_jmethod_id(method_id); | 1325 Method* m = Method::resolve_jmethod_id(method_id); |
1326 number_of_parameters = m->size_of_parameters(); | 1326 number_of_parameters = m->size_of_parameters(); |
1327 Klass* holder = m->method_holder(); | 1327 Klass* holder = m->method_holder(); |
1328 if (!(holder)->is_interface()) { | 1328 if (call_type != JNI_VIRTUAL) { |
1329 selected_method = m; | |
1330 } else if (!m->has_itable_index()) { | |
1329 // non-interface call -- for that little speed boost, don't handlize | 1331 // non-interface call -- for that little speed boost, don't handlize |
1330 debug_only(No_Safepoint_Verifier nosafepoint;) | 1332 debug_only(No_Safepoint_Verifier nosafepoint;) |
1331 if (call_type == JNI_VIRTUAL) { | 1333 // jni_GetMethodID makes sure class is linked and initialized |
1332 // jni_GetMethodID makes sure class is linked and initialized | 1334 // so m should have a valid vtable index. |
1333 // so m should have a valid vtable index. | 1335 assert(m->valid_vtable_index(), "no valid vtable index"); |
1334 assert(!m->has_itable_index(), ""); | 1336 int vtbl_index = m->vtable_index(); |
1335 int vtbl_index = m->vtable_index(); | 1337 if (vtbl_index != Method::nonvirtual_vtable_index) { |
1336 if (vtbl_index != Method::nonvirtual_vtable_index) { | 1338 Klass* k = h_recv->klass(); |
1337 Klass* k = h_recv->klass(); | 1339 // k might be an arrayKlassOop but all vtables start at |
1338 // k might be an arrayKlassOop but all vtables start at | 1340 // the same place. The cast is to avoid virtual call and assertion. |
1339 // the same place. The cast is to avoid virtual call and assertion. | 1341 InstanceKlass *ik = (InstanceKlass*)k; |
1340 InstanceKlass *ik = (InstanceKlass*)k; | 1342 selected_method = ik->method_at_vtable(vtbl_index); |
1341 selected_method = ik->method_at_vtable(vtbl_index); | |
1342 } else { | |
1343 // final method | |
1344 selected_method = m; | |
1345 } | |
1346 } else { | 1343 } else { |
1347 // JNI_NONVIRTUAL call | 1344 // final method |
1348 selected_method = m; | 1345 selected_method = m; |
1349 } | 1346 } |
1350 } else { | 1347 } else { |
1351 // interface call | 1348 // interface call |
1352 KlassHandle h_holder(THREAD, holder); | 1349 KlassHandle h_holder(THREAD, holder); |
1353 | 1350 |
1354 if (call_type == JNI_VIRTUAL) { | 1351 int itbl_index = m->itable_index(); |
1355 int itbl_index = m->itable_index(); | 1352 Klass* k = h_recv->klass(); |
1356 Klass* k = h_recv->klass(); | 1353 selected_method = InstanceKlass::cast(k)->method_at_itable(h_holder(), itbl_index, CHECK); |
1357 selected_method = InstanceKlass::cast(k)->method_at_itable(h_holder(), itbl_index, CHECK); | |
1358 } else { | |
1359 selected_method = m; | |
1360 } | |
1361 } | 1354 } |
1362 } | 1355 } |
1363 | 1356 |
1364 methodHandle method(THREAD, selected_method); | 1357 methodHandle method(THREAD, selected_method); |
1365 | 1358 |