Mercurial > hg > openjdk > jdk6 > hotspot
changeset 4068:2b7debe8a16a
8036805: Correct linker method lookup.
8036810: Correct linker field lookup
Summary: Correct handling of array of primitive type qualifiers during field and method resolution.
Reviewed-by: lfoltan
author | sgabdura |
---|---|
date | Wed, 08 Oct 2014 12:39:26 +0100 |
parents | ba03bb58ca5a |
children | b4d53afe0673 |
files | src/share/vm/interpreter/linkResolver.cpp src/share/vm/oops/arrayKlass.cpp src/share/vm/oops/arrayKlass.hpp src/share/vm/oops/klass.cpp src/share/vm/oops/klass.hpp |
diffstat | 5 files changed, 48 insertions(+), 16 deletions(-) [+] |
line wrap: on
line diff
--- a/src/share/vm/interpreter/linkResolver.cpp Wed Oct 08 01:45:41 2014 +0100 +++ b/src/share/vm/interpreter/linkResolver.cpp Wed Oct 08 12:39:26 2014 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -179,6 +179,14 @@ void LinkResolver::lookup_method_in_klasses(methodHandle& result, KlassHandle klass, Symbol* name, Symbol* signature, TRAPS) { methodOop result_oop = klass->uncached_lookup_method(name, signature); + + //JDK 6 does not support default methods, but this code ported from JDK8 to keep code consistent for all JDK. + if (klass->oop_is_array()) { + // Only consider klass and super klass for arrays + result = methodHandle(THREAD, result_oop); + return; + } + if (EnableInvokeDynamic && result_oop != NULL) { switch (result_oop->intrinsic_id()) { case vmIntrinsics::_invokeExact: @@ -349,7 +357,7 @@ // 2. lookup method in resolved klass and its super klasses lookup_method_in_klasses(resolved_method, resolved_klass, method_name, method_signature, CHECK); - if (resolved_method.is_null()) { // not found in the class hierarchy + if (resolved_method.is_null() && !resolved_klass->oop_is_array()) { // not found in the class hierarchy // 3. lookup method in all the interfaces implemented by the resolved klass lookup_method_in_interfaces(resolved_method, resolved_klass, method_name, method_signature, CHECK); @@ -436,17 +444,18 @@ // lookup method in this interface or its super, java.lang.Object lookup_instance_method_in_klasses(resolved_method, resolved_klass, method_name, method_signature, CHECK); - if (resolved_method.is_null()) { + if (resolved_method.is_null() && !resolved_klass->oop_is_array()) { // lookup method in all the super-interfaces lookup_method_in_interfaces(resolved_method, resolved_klass, method_name, method_signature, CHECK); - if (resolved_method.is_null()) { - // no method found - ResourceMark rm(THREAD); - THROW_MSG(vmSymbols::java_lang_NoSuchMethodError(), - methodOopDesc::name_and_sig_as_C_string(Klass::cast(resolved_klass()), - method_name, - method_signature)); - } + } + + if (resolved_method.is_null()) { + // no method found + ResourceMark rm(THREAD); + THROW_MSG(vmSymbols::java_lang_NoSuchMethodError(), + methodOopDesc::name_and_sig_as_C_string(Klass::cast(resolved_klass()), + method_name, + method_signature)); } if (check_access) { @@ -536,7 +545,7 @@ // Resolve instance field fieldDescriptor fd; // find_field initializes fd if found - KlassHandle sel_klass(THREAD, instanceKlass::cast(resolved_klass())->find_field(field, sig, &fd)); + KlassHandle sel_klass(THREAD, resolved_klass->find_field(field, sig, &fd)); // check if field exists; i.e., if a klass containing the field def has been selected if (sel_klass.is_null()){ ResourceMark rm(THREAD);
--- a/src/share/vm/oops/arrayKlass.cpp Wed Oct 08 01:45:41 2014 +0100 +++ b/src/share/vm/oops/arrayKlass.cpp Wed Oct 08 12:39:26 2014 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -64,6 +64,13 @@ return NULL; } +// find field according to JVM spec 5.4.3.2, returns the klass in which the field is defined +klassOop arrayKlass::find_field(Symbol* name, Symbol* sig, fieldDescriptor* fd) const { + // There are no fields in an array klass but look to the super class (Object) + assert(super(), "super klass must be present"); + return Klass::cast(super())->find_field(name, sig, fd); +} + methodOop arrayKlass::uncached_lookup_method(Symbol* name, Symbol* signature) const { // There are no methods in an array klass but the super class (Object) has some assert(super(), "super klass must be present");
--- a/src/share/vm/oops/arrayKlass.hpp Wed Oct 08 01:45:41 2014 +0100 +++ b/src/share/vm/oops/arrayKlass.hpp Wed Oct 08 12:39:26 2014 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -30,6 +30,8 @@ #include "oops/klassOop.hpp" #include "oops/klassVtable.hpp" +class fieldDescriptor; + // arrayKlass is the abstract baseclass for all array classes class arrayKlass: public Klass { @@ -83,6 +85,9 @@ virtual oop multi_allocate(int rank, jint* sizes, TRAPS); objArrayOop allocate_arrayArray(int n, int length, TRAPS); + // find field according to JVM spec 5.4.3.2, returns the klass in which the field is defined + klassOop find_field(Symbol* name, Symbol* sig, fieldDescriptor* fd) const; + // Lookup operations methodOop uncached_lookup_method(Symbol* name, Symbol* signature) const;
--- a/src/share/vm/oops/klass.cpp Wed Oct 08 01:45:41 2014 +0100 +++ b/src/share/vm/oops/klass.cpp Wed Oct 08 12:39:26 2014 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -118,6 +118,15 @@ return is_subclass_of(k); } +klassOop Klass::find_field(Symbol* name, Symbol* sig, fieldDescriptor* fd) const { +#ifdef ASSERT + tty->print_cr("Error: find_field called on a klass oop." + " Likely error: reflection method does not correctly" + " wrap return value in a mirror object."); +#endif + ShouldNotReachHere(); + return NULL; +} methodOop Klass::uncached_lookup_method(Symbol* name, Symbol* signature) const { #ifdef ASSERT
--- a/src/share/vm/oops/klass.hpp Wed Oct 08 01:45:41 2014 +0100 +++ b/src/share/vm/oops/klass.hpp Wed Oct 08 12:39:26 2014 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -88,6 +88,7 @@ class klassVtable; class KlassHandle; class OrderAccess; +class fieldDescriptor; // Holder (or cage) for the C++ vtable of each kind of Klass. // We want to tightly constrain the location of the C++ vtable in the overall layout. @@ -514,6 +515,7 @@ virtual void initialize(TRAPS); // lookup operation for MethodLookupCache friend class MethodLookupCache; + virtual klassOop find_field(Symbol* name, Symbol* signature, fieldDescriptor* fd) const; virtual methodOop uncached_lookup_method(Symbol* name, Symbol* signature) const; public: methodOop lookup_method(Symbol* name, Symbol* signature) const {