RFR 8139163: InstanceKlass::cast passes through NULL

Kim Barrett kim.barrett at oracle.com
Fri Oct 23 20:29:06 UTC 2015


On Oct 22, 2015, at 9:57 PM, Coleen Phillimore <coleen.phillimore at oracle.com> wrote:
> 
> On 10/22/15 8:10 PM, Kim Barrett wrote:
>> 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(), ...).
> 
> But that's the exactly the line above it.

Right you are.  Sorry for the noise.

>> 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.
> 
> It is an InstanceKlass at this point and I use 'ik' in this 'if' statement so I need it here.

ik doesn’t need to be used in that “if” statement; the old code used klass and was changed
in a way that isn’t strictly necessary.  And there is nothing about the original “if” statement
that requires it to be an InstanceKlass.  That said, there is the earlier klass->oop_is_array()
and since array and instance fully partition Klass, then you are right that at the new earlier
location of the cast we do know the cast is ok.  So no further change needed here.

>> 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.
> 
> I need 'ik' here too and it is an InstanceKlass (we bailed out already for array klass), but I missed a cast at line 383 that I don't need.

I overlooked the earlier array check here too.  OK.

>> 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?
> 
> No idea.

Because we don’t turn on unused-variable warnings.  Sigh.




More information about the hotspot-dev mailing list