RFR 8139163: InstanceKlass::cast passes through NULL
Kim Barrett
kim.barrett at oracle.com
Fri Oct 23 00:10:18 UTC 2015
On Oct 22, 2015, at 4:05 PM, Coleen Phillimore <coleen.phillimore at oracle.com> wrote:
>
> Summary: Reduce raw (InstanceKlass*) casts and InstanceKlass::cast, which no long allows null
>
> Somewhat of a tedious thing to code review (sorry). Tested with internal remote-build-and-test.
>
> open webrev at http://cr.openjdk.java.net/~coleenp/8139163.01/
> bug link https://bugs.openjdk.java.net/browse/JDK-8139163.01
>
> Thanks,
> Coleen
Only a partial review; I didn't get through all the files, and have
run out of time today. Here's what I have so far. I'll continue
looking tomorrow.
------------------------------------------------------------------------------
src/share/vm/classfile/systemDictionary.cpp
1850 if ((*klassp) == NULL) {
1851 Klass* k;
1852 if (must_load) {
1853 k = resolve_or_fail(symbol, true, CHECK_0); // load required class
1854 } else {
1855 k = resolve_or_null(symbol, CHECK_0); // load optional klass
1856 }
1857 (*klassp) = InstanceKlass::cast(k);
1858 }
1859 return ((*klassp) != NULL);
The code would seem to imply that k passed to InstanceKlass::cast here
could be NULL. If not, then the final check for *klassp != NULL seems
unnecessary.
------------------------------------------------------------------------------
src/share/vm/gc/g1/g1CollectedHeap.cpp
4595 // this can be null so don't call InstanceKlass::cast
4596 return static_cast<InstanceKlass*>(klass);
But what if it's a non-NULL non-InstanceKlass?
Maybe add assert(klass == NULL || klass->is_instance(), ...).
------------------------------------------------------------------------------
src/share/vm/interpreter/linkResolver.cpp
310 InstanceKlass* ik = InstanceKlass::cast(klass());
311
312 // JDK 8, JVMS 5.4.3.4: Interface method resolution should
313 // ignore static and non-public methods of java.lang.Object,
314 // like clone, finalize, registerNatives.
315 if (in_imethod_resolve &&
316 result != NULL &&
317 ik->is_interface() &&
318 (result->is_static() || !result->is_public()) &&
319 result->method_holder() == SystemDictionary::Object_klass()) {
320 result = NULL;
321 }
In the old code, that block starting with the "JDK 8" comment doesn't
seem to require klass() to be an InstanceKlass (at least not
obviously). So moving the InstanceKlass::cast earlier might be an
unintended change.
There is later code that does require an InstanceKlass, so moving the
cast to after this block might be ok.
------------------------------------------------------------------------------
src/share/vm/interpreter/linkResolver.cpp
379 InstanceKlass* ik = InstanceKlass::cast(klass());
380
381 // First check in default method array
382 if (!resolved_method->is_abstract() &&
383 (InstanceKlass::cast(klass())->default_methods() != NULL)) {
384 int index = InstanceKlass::find_method_index(ik->default_methods(),
385 name, signature, Klass::find_overpass,
386 Klass::find_static, Klass::find_private);
387 if (index >= 0 ) {
388 vtable_index = ik->default_vtable_indices()->at(index);
389 }
390 }
391 if (vtable_index == Method::invalid_vtable_index) {
392 // get vtable_index for miranda methods
393 ResourceMark rm;
394 klassVtable *vt = ik->vtable();
395 vtable_index = vt->index_of_miranda(name, signature);
396 }
Another case where moving the InstanceKlass::cast earlier might be an
unintended behavioral change. For example, if
resolved_method->is_abstract() is true and the vtable_index doesn't
match then there is no other code that would require the result of the
cast, and so there wouldn't be a requirement for it to succeed.
------------------------------------------------------------------------------
src/share/vm/memory/heapInspection.cpp
351 const InstanceKlass* k = (InstanceKlass*)cie->klass();
352 Klass* super = cie->klass()->super();
Christian already pointed out the apparently no longer used k. Why
wasn't there an unused variable warning?
------------------------------------------------------------------------------
src/share/vm/oops/instanceKlass.cpp
1543 bool InstanceKlass::has_redefined_this_or_super() const {
1544 Klass* klass = const_cast<InstanceKlass*>(this);
1545 while (klass != NULL) {
1546 if (InstanceKlass::cast(klass)->has_been_redefined()) {
1547 return true;
1548 }
1549 klass = klass->super();
1550 }
1551 return false;
1552 }
I don't understand the initial const-removing cast here. Why not just
declare klass to be Klass const*? It used to be InstanceKlass const*.
------------------------------------------------------------------------------
src/share/vm/oops/instanceKlass.cpp
2326 bool InstanceKlass::is_same_class_package(Klass* class2) {
2348 bool InstanceKlass::is_same_class_package(oop classloader2, Symbol* classname2) {
Thank you!
------------------------------------------------------------------------------
src/share/vm/oops/instanceKlass.cpp
2898 InstanceKlass* ik = const_cast<InstanceKlass*>(this);
Casting away const. Ick! Can we have an RFE to fix this?
------------------------------------------------------------------------------
More information about the hotspot-dev
mailing list