Duplicate :
|
InstanceKlass records an _implementor field for classes implementing a given interface. The field's value has 3 states: (1) NULL - no implementor (2) implementor Klass* - one implementor (3) self - more than one implementor The field is initialized with NULL and set the first time an implementor is added. The next time an implementor is added _implementor already has a value != self indicating there was already a different implementor so the logic moves to state (3). This logic overlooks diamond shapes in interface class hierarchies of the following form: interface I { void foo();} interface I1 extends I {} interface I2 extends I {} static class Impl implements I1, I2 { @Override public void foo() {...} } There are 2 paths in the class hierarchy leading to I. Thus, the current logic wrongly detects this to be case (3) since it does not check if the klass in case (2) was already seen before. The fix is extending case (2) with logic checking if the value of the _implementor field is the same as the currently added implementor. This bug was revealed in Graal where we use the single implementor logic for invokeinterface devirtualization.