dependencies bug

John Rose john.r.rose at oracle.com
Tue Oct 25 01:01:01 PDT 2011


On Oct 24, 2011, at 4:48 PM, Tom Rodriguez wrote:

> Note that the subclass has a static method with the same name and signature as the super.  javac would never allow this but it's a legal class file.  We've got a piece of code roughly like this:
> 
> invokeinterface019c  i = new invokeinterface019d();
> i.f1(0, 0);
> 
> We head down into CHA to bind the method f1 and call check_method_context, where it looks up the method in invokeinterface019d using just the name and signature, which returns the static method.  We then assert because the methods aren't the same.  check_method_context appears to be slightly sloppy about it's checking so I'm assuming it should have a guard like this:
> 
> diff -r 8d6869d5ef1a src/share/vm/code/dependencies.cpp                                                                                                
> --- a/src/share/vm/code/dependencies.cpp                                                                                                                
> +++ b/src/share/vm/code/dependencies.cpp                                                                                                                
> @@ -795,6 +795,9 @@
>       if (!(lm->is_public() || lm->is_protected()))                                                                                                    
>         // Method is [package-]private, so the override story is complex.                                                                              
>         return true;  // Must punt the assertion to true.                                                                                              
> +      if (lm->is_static())                                                                                                                            
> +        // Static doesn't override non-static                                                                                                          
> +        return true;  // Punt                                                                                                                          
>       if (   !Dependencies::is_concrete_method(lm)                                                                                                    
> && !Dependencies::is_concrete_method(m)                                                                                                      
>           && Klass::cast(lm->method_holder())->is_subtype_of(m->method_holder()))

Yes, that's a reasonable detuning of the assert.  But I think it would be better if you were to make the two overloadings of Dependencies::is_concrete_method be consistent.  (I think that would fix the same assertion bug.)  The first occurrence of is_abstract is_concrete_method(methodOop m) was probably a typo for is_static.

> The other interesting bit is that the reason this showed up in the metadata repo is because separation of oops and metadata exposed this mistake, which was fixed:
> 
> diff -r 42783d1414b2 src/share/vm/oops/constantPoolKlass.cpp                                                                                            
> --- a/src/share/vm/oops/constantPoolKlass.cpp                                                                                                          
> +++ b/src/share/vm/oops/constantPoolKlass.cpp                                                                                                          
> @@ -532,7 +532,7 @@
>     if (cp->tag_at(i).is_unresolved_klass()) {                                                                                                        
>       // This will force loading of the class                                                                                                          
>       klassOop klass = cp->klass_at(i, CHECK);                                                                                                        
> -      if (klass->is_instance()) {                                                                                                                      
> +      if (klass->klass_part()->oop_is_instance()) {                                                                                                    
>         // Force initialization of class                                                                                                              
> instanceKlass::cast(klass)->initialize(CHECK);                                                                                                
>       }
> 
> The previous code would never succeed because a klass is never an instance, so we weren't actually preloading any classes in the constant pool.

Wow.  That's turn-of-the-century dead code.  Ancient zombies from the crypt.

-- John


More information about the hotspot-compiler-dev mailing list