8154587: Resolution fails for default method named 'clone'
Summary: Make sure default methods with the same names as those in j.l.Object get put in the default methods table where resolution can find them.
Reviewed-by: acorn, lfoltan
--- a/src/hotspot/share/classfile/defaultMethods.cpp Fri Dec 15 16:51:13 2017 +0100
+++ b/src/hotspot/share/classfile/defaultMethods.cpp Fri Dec 15 11:23:50 2017 -0500
@@ -26,6 +26,7 @@
#include "classfile/bytecodeAssembler.hpp"
#include "classfile/defaultMethods.hpp"
#include "classfile/symbolTable.hpp"
+#include "classfile/systemDictionary.hpp"
#include "logging/log.hpp"
#include "logging/logStream.hpp"
#include "memory/allocation.hpp"
@@ -683,10 +684,11 @@
Symbol* _method_name;
Symbol* _method_signature;
StatefulMethodFamily* _family;
+ bool _cur_class_is_interface;
public:
- FindMethodsByErasedSig(Symbol* name, Symbol* signature) :
- _method_name(name), _method_signature(signature),
+ FindMethodsByErasedSig(Symbol* name, Symbol* signature, bool is_interf) :
+ _method_name(name), _method_signature(signature), _cur_class_is_interface(is_interf),
_family(NULL) {}
void get_discovered_family(MethodFamily** family) {
@@ -709,14 +711,17 @@
InstanceKlass* iklass = current_class();
Method* m = iklass->find_method(_method_name, _method_signature);
- // private interface methods are not candidates for default methods
- // invokespecial to private interface methods doesn't use default method logic
- // private class methods are not candidates for default methods,
- // private methods do not override default methods, so need to perform
- // default method inheritance without including private methods
- // The overpasses are your supertypes' errors, we do not include them
- // future: take access controls into account for superclass methods
- if (m != NULL && !m->is_static() && !m->is_overpass() && !m->is_private()) {
+ // Private interface methods are not candidates for default methods.
+ // invokespecial to private interface methods doesn't use default method logic.
+ // Private class methods are not candidates for default methods.
+ // Private methods do not override default methods, so need to perform
+ // default method inheritance without including private methods.
+ // The overpasses are your supertypes' errors, we do not include them.
+ // Non-public methods in java.lang.Object are not candidates for default
+ // methods.
+ // Future: take access controls into account for superclass methods
+ if (m != NULL && !m->is_static() && !m->is_overpass() && !m->is_private() &&
+ (!_cur_class_is_interface || !SystemDictionary::is_nonpublic_Object_method(m))) {
if (_family == NULL) {
_family = new StatefulMethodFamily();
}
@@ -726,8 +731,8 @@
scope->add_mark(restorer);
} else {
// This is the rule that methods in classes "win" (bad word) over
- // methods in interfaces. This works because of single inheritance
- // private methods in classes do not "win", they will be found
+ // methods in interfaces. This works because of single inheritance.
+ // Private methods in classes do not "win", they will be found
// first on searching, but overriding for invokevirtual needs
// to find default method candidates for the same signature
_family->set_target_if_empty(m);
@@ -745,10 +750,10 @@
static void generate_erased_defaults(
InstanceKlass* klass, GrowableArray<EmptyVtableSlot*>* empty_slots,
- EmptyVtableSlot* slot, TRAPS) {
+ EmptyVtableSlot* slot, bool is_intf, TRAPS) {
// sets up a set of methods with the same exact erased signature
- FindMethodsByErasedSig visitor(slot->name(), slot->signature());
+ FindMethodsByErasedSig visitor(slot->name(), slot->signature(), is_intf);
visitor.run(klass);
MethodFamily* family;
@@ -817,7 +822,7 @@
slot->print_on(&ls);
ls.cr();
}
- generate_erased_defaults(klass, empty_slots, slot, CHECK);
+ generate_erased_defaults(klass, empty_slots, slot, klass->is_interface(), CHECK);
}
log_debug(defaultmethods)("Creating defaults and overpasses...");
create_defaults_and_exceptions(empty_slots, klass, CHECK);
--- a/src/hotspot/share/classfile/systemDictionary.hpp Fri Dec 15 16:51:13 2017 +0100
+++ b/src/hotspot/share/classfile/systemDictionary.hpp Fri Dec 15 11:23:50 2017 -0500
@@ -649,6 +649,12 @@
static bool is_platform_class_loader(oop class_loader);
static void clear_invoke_method_table();
+ // Returns TRUE if the method is a non-public member of class java.lang.Object.
+ static bool is_nonpublic_Object_method(Method* m) {
+ assert(m != NULL, "Unexpected NULL Method*");
+ return !m->is_public() && m->method_holder() == SystemDictionary::Object_klass();
+ }
+
protected:
static InstanceKlass* find_shared_class(Symbol* class_name);
--- a/src/hotspot/share/oops/cpCache.cpp Fri Dec 15 16:51:13 2017 +0100
+++ b/src/hotspot/share/oops/cpCache.cpp Fri Dec 15 11:23:50 2017 -0500
@@ -177,6 +177,7 @@
// instruction somehow links to a non-interface method (in Object).
// In that case, the method has no itable index and must be invoked as a virtual.
// Set a flag to keep track of this corner case.
+ assert(method->is_public(), "Calling non-public method in Object with invokeinterface");
change_to_virtual = true;
// ...and fall through as if we were handling invokevirtual:
--- a/src/hotspot/share/oops/klassVtable.cpp Fri Dec 15 16:51:13 2017 +0100
+++ b/src/hotspot/share/oops/klassVtable.cpp Fri Dec 15 11:23:50 2017 -0500
@@ -86,13 +86,14 @@
GrowableArray<Method*> new_mirandas(20);
// compute the number of mirandas methods that must be added to the end
- get_mirandas(&new_mirandas, all_mirandas, super, methods, NULL, local_interfaces);
+ get_mirandas(&new_mirandas, all_mirandas, super, methods, NULL, local_interfaces,
+ class_flags.is_interface());
*num_new_mirandas = new_mirandas.length();
// Interfaces do not need interface methods in their vtables
// This includes miranda methods and during later processing, default methods
if (!class_flags.is_interface()) {
- vtable_length += *num_new_mirandas * vtableEntry::size();
+ vtable_length += *num_new_mirandas * vtableEntry::size();
}
if (Universe::is_bootstrapping() && vtable_length == 0) {
@@ -454,8 +455,13 @@
} else {
super_method = method_at(i);
}
- // Check if method name matches
- if (super_method->name() == name && super_method->signature() == signature) {
+ // Check if method name matches. Ignore match if klass is an interface and the
+ // matching method is a non-public java.lang.Object method. (See JVMS 5.4.3.4)
+ // This is safe because the method at this slot should never get invoked.
+ // (TBD: put in a method to throw NoSuchMethodError if this slot is ever used.)
+ if (super_method->name() == name && super_method->signature() == signature &&
+ (!_klass->is_interface() ||
+ !SystemDictionary::is_nonpublic_Object_method(super_method))) {
// get super_klass for method_holder for the found method
InstanceKlass* super_klass = super_method->method_holder();
@@ -713,7 +719,7 @@
if (mhk->is_interface()) {
assert(m->is_public(), "should be public");
assert(ik()->implements_interface(method_holder) , "this class should implement the interface");
- if (is_miranda(m, ik()->methods(), ik()->default_methods(), ik()->super())) {
+ if (is_miranda(m, ik()->methods(), ik()->default_methods(), ik()->super(), klass()->is_interface())) {
return true;
}
}
@@ -738,7 +744,10 @@
// During the first run, the current instanceKlass has not yet been
// created, the superclasses and superinterfaces do have instanceKlasses
// but may not have vtables, the default_methods list is empty, no overpasses.
-// This is seen by default method creation.
+// Default method generation uses the all_mirandas array as the starter set for
+// maximally-specific default method calculation. So, for both classes and
+// interfaces, it is necessary that the first pass will find all non-private
+// interface instance methods, whether or not they are concrete.
//
// Pass 2: recalculated during vtable initialization: only include abstract methods.
// The goal of pass 2 is to walk through the superinterfaces to see if any of
@@ -772,7 +781,8 @@
// Part of the Miranda Rights in the US mean that if you do not have
// an attorney one will be appointed for you.
bool klassVtable::is_miranda(Method* m, Array<Method*>* class_methods,
- Array<Method*>* default_methods, const Klass* super) {
+ Array<Method*>* default_methods, const Klass* super,
+ bool is_interface) {
if (m->is_static() || m->is_private() || m->is_overpass()) {
return false;
}
@@ -800,8 +810,11 @@
for (const Klass* cursuper = super; cursuper != NULL; cursuper = cursuper->super())
{
- if (InstanceKlass::cast(cursuper)->find_local_method(name, signature,
- Klass::find_overpass, Klass::skip_static, Klass::skip_private) != NULL) {
+ Method* found_mth = InstanceKlass::cast(cursuper)->find_local_method(name, signature,
+ Klass::find_overpass, Klass::skip_static, Klass::skip_private);
+ // Ignore non-public methods in java.lang.Object if klass is an interface.
+ if (found_mth != NULL && (!is_interface ||
+ !SystemDictionary::is_nonpublic_Object_method(found_mth))) {
return false;
}
}
@@ -820,7 +833,7 @@
void klassVtable::add_new_mirandas_to_lists(
GrowableArray<Method*>* new_mirandas, GrowableArray<Method*>* all_mirandas,
Array<Method*>* current_interface_methods, Array<Method*>* class_methods,
- Array<Method*>* default_methods, const Klass* super) {
+ Array<Method*>* default_methods, const Klass* super, bool is_interface) {
// iterate thru the current interface's method to see if it a miranda
int num_methods = current_interface_methods->length();
@@ -839,7 +852,7 @@
}
if (!is_duplicate) { // we don't want duplicate miranda entries in the vtable
- if (is_miranda(im, class_methods, default_methods, super)) { // is it a miranda at all?
+ if (is_miranda(im, class_methods, default_methods, super, is_interface)) { // is it a miranda at all?
const InstanceKlass *sk = InstanceKlass::cast(super);
// check if it is a duplicate of a super's miranda
if (sk->lookup_method_in_all_interfaces(im->name(), im->signature(), Klass::find_defaults) == NULL) {
@@ -858,7 +871,8 @@
const Klass* super,
Array<Method*>* class_methods,
Array<Method*>* default_methods,
- Array<Klass*>* local_interfaces) {
+ Array<Klass*>* local_interfaces,
+ bool is_interface) {
assert((new_mirandas->length() == 0) , "current mirandas must be 0");
// iterate thru the local interfaces looking for a miranda
@@ -867,7 +881,7 @@
InstanceKlass *ik = InstanceKlass::cast(local_interfaces->at(i));
add_new_mirandas_to_lists(new_mirandas, all_mirandas,
ik->methods(), class_methods,
- default_methods, super);
+ default_methods, super, is_interface);
// iterate thru each local's super interfaces
Array<Klass*>* super_ifs = ik->transitive_interfaces();
int num_super_ifs = super_ifs->length();
@@ -875,7 +889,7 @@
InstanceKlass *sik = InstanceKlass::cast(super_ifs->at(j));
add_new_mirandas_to_lists(new_mirandas, all_mirandas,
sik->methods(), class_methods,
- default_methods, super);
+ default_methods, super, is_interface);
}
}
}
@@ -888,7 +902,8 @@
int klassVtable::fill_in_mirandas(int initialized) {
GrowableArray<Method*> mirandas(20);
get_mirandas(&mirandas, NULL, ik()->super(), ik()->methods(),
- ik()->default_methods(), ik()->local_interfaces());
+ ik()->default_methods(), ik()->local_interfaces(),
+ klass()->is_interface());
for (int i = 0; i < mirandas.length(); i++) {
if (log_develop_is_enabled(Trace, vtables)) {
Method* meth = mirandas.at(i);
--- a/src/hotspot/share/oops/klassVtable.hpp Fri Dec 15 16:51:13 2017 +0100
+++ b/src/hotspot/share/oops/klassVtable.hpp Fri Dec 15 11:23:50 2017 -0500
@@ -144,21 +144,24 @@
bool is_miranda_entry_at(int i);
int fill_in_mirandas(int initialized);
static bool is_miranda(Method* m, Array<Method*>* class_methods,
- Array<Method*>* default_methods, const Klass* super);
+ Array<Method*>* default_methods, const Klass* super,
+ bool is_interface);
static void add_new_mirandas_to_lists(
GrowableArray<Method*>* new_mirandas,
GrowableArray<Method*>* all_mirandas,
Array<Method*>* current_interface_methods,
Array<Method*>* class_methods,
Array<Method*>* default_methods,
- const Klass* super);
+ const Klass* super,
+ bool is_interface);
static void get_mirandas(
GrowableArray<Method*>* new_mirandas,
GrowableArray<Method*>* all_mirandas,
const Klass* super,
Array<Method*>* class_methods,
Array<Method*>* default_methods,
- Array<Klass*>* local_interfaces);
+ Array<Klass*>* local_interfaces,
+ bool is_interface);
void verify_against(outputStream* st, klassVtable* vt, int index);
inline InstanceKlass* ik() const;
// When loading a class from CDS archive at run time, and no class redefintion
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/clone/AbstractClone.java Fri Dec 15 11:23:50 2017 -0500
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2017, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+/*
+ * @test
+ * @bug 8154587
+ * @summary Check that invokeinterface of clone() works properly where clone() is
+ * an abstract method in a superinterface and also overridden locally.
+ * @run main AbstractClone
+ */
+
+public class AbstractClone {
+
+ interface I1 {
+ Object clone();
+ }
+
+ interface I2 extends I1 { }
+
+ static class C implements I2 {
+ public Object clone() {
+ return "In C's clone()";
+ }
+ }
+
+ static Object test(I2 i) { return i.clone(); }
+
+ public static void main(String[] args) {
+ String s = (String)test(new C());
+ if (!s.equals("In C's clone()")) {
+ throw new RuntimeException("Wrong clone() called");
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/clone/AbstractNoClones.jasm Fri Dec 15 11:23:50 2017 -0500
@@ -0,0 +1,142 @@
+/*
+ * Copyright (c) 2017, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+/*
+ * @test
+ * @bug 8154587
+ * @summary Check that invokeinterface of clone() works properly where clone() is
+ * an abstract method in a superinterface and not overridden locally.
+ * @compile AbstractNoClones.jasm
+ * @run main AbstractNoClones
+ */
+
+// The below .jasm code implements the following java code:
+//
+// public class AbstractNoClones {
+//
+// interface I1 {
+// Object clone();
+// }
+//
+// interface I2 extends I1 { }
+//
+// static class C implements I2 { }
+//
+// static Object test(I2 i) { return i.clone(); }
+//
+// public static void main(String[] args) {
+// try {
+// String s = (String)test(new C());
+// throw new RuntimeException("Expected IAE not thrown");
+// } catch (java.lang.IllegalAccessError e) {
+// if (!e.toString().contains("C.clone")) {
+// throw new RuntimeException("Wrong IllegalAccessError exception thrown");
+// }
+// }
+// }
+// }
+
+
+interface AbstractNoClones$I1 version 53:0 {
+
+ public abstract Method clone:"()Ljava/lang/Object;";
+
+ static abstract interface InnerClass I1=class AbstractNoClones$I1 of class AbstractNoClones;
+
+} // end Class AbstractNoClones$I1
+
+
+interface AbstractNoClones$I2 implements AbstractNoClones$I1 version 53:0 {
+
+ static abstract interface InnerClass I2=class AbstractNoClones$I2 of class AbstractNoClones;
+ static abstract interface InnerClass I1=class AbstractNoClones$I1 of class AbstractNoClones;
+
+} // end Class AbstractNoClones$I2
+
+
+super class AbstractNoClones$C implements AbstractNoClones$I2 version 53:0 {
+
+ Method "<init>":"()V" stack 1 locals 1 {
+ aload_0;
+ invokespecial Method java/lang/Object."<init>":"()V";
+ return;
+ }
+
+ static InnerClass C=class AbstractNoClones$C of class AbstractNoClones;
+ static abstract interface InnerClass I2=class AbstractNoClones$I2 of class AbstractNoClones;
+
+} // end Class AbstractNoClones$C
+
+
+super public class AbstractNoClones version 53:0 {
+
+ public Method "<init>":"()V" stack 1 locals 1 {
+ aload_0;
+ invokespecial Method java/lang/Object."<init>":"()V";
+ return;
+ }
+
+ static Method test:"(LAbstractNoClones$I2;)Ljava/lang/Object;" stack 1 locals 1 {
+ aload_0;
+ invokeinterface InterfaceMethod AbstractNoClones$I2.clone:"()Ljava/lang/Object;", 1;
+ areturn;
+ }
+
+ public static Method main:"([Ljava/lang/String;)V" stack 3 locals 2 {
+ try t0;
+ new class AbstractNoClones$C;
+ dup;
+ invokespecial Method AbstractNoClones$C."<init>":"()V";
+ invokestatic Method test:"(LAbstractNoClones$I2;)Ljava/lang/Object;";
+ checkcast class java/lang/String;
+ astore_1;
+ new class java/lang/RuntimeException;
+ dup;
+ ldc String "Expected IAE not thrown";
+ invokespecial Method java/lang/RuntimeException."<init>":"(Ljava/lang/String;)V";
+ athrow;
+ endtry t0;
+ catch t0 java/lang/IllegalAccessError;
+ stack_frame_type stack1;
+ stack_map class java/lang/IllegalAccessError;
+ astore_1;
+ aload_1;
+ invokevirtual Method java/lang/IllegalAccessError.toString:"()Ljava/lang/String;";
+ ldc String "C.clone";
+ invokevirtual Method java/lang/String.contains:"(Ljava/lang/CharSequence;)Z";
+ ifne L47;
+ new class java/lang/RuntimeException;
+ dup;
+ ldc String "Wrong IllegalAccessError exception thrown";
+ invokespecial Method java/lang/RuntimeException."<init>":"(Ljava/lang/String;)V";
+ athrow;
+ L47: stack_frame_type same;
+ return;
+ }
+
+ static InnerClass C=class AbstractNoClones$C of class AbstractNoClones;
+ static abstract interface InnerClass I2=class AbstractNoClones$I2 of class AbstractNoClones;
+ static abstract interface InnerClass I1=class AbstractNoClones$I1 of class AbstractNoClones;
+
+} // end Class AbstractNoClones
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/clone/DefaultClone.jasm Fri Dec 15 11:23:50 2017 -0500
@@ -0,0 +1,145 @@
+/*
+ * Copyright (c) 2017, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+/*
+ * @test
+ * @bug 8154587
+ * @summary Check that a default method named clone() does not get masked by
+ * java.lang.Object.clone() during resolution.
+ * @compile DefaultClone.jasm
+ * @run main DefaultClone
+ */
+
+// The below .jasm code implements the following java code:
+//
+// public class DefaultClone {
+//
+// interface I1 {
+// default Object clone() {
+// return "In I1's clone()";
+// }
+// }
+//
+//
+// interface I2 extends I1 { }
+//
+//
+// static class C implements I2 {
+// public Object clone() {
+// return "In C's clone()";
+// }
+// }
+//
+//
+// static Object test(I2 i) { return i.clone(); }
+//
+// public static void main(String[] args) {
+// String s = (String)test(new C());
+// if (!s.equals("In C's clone()")) {
+// throw new RuntimeException("Wrong clone() called");
+// }
+// }
+// }
+
+
+interface DefaultClone$I1 version 53:0 {
+
+ public Method clone:"()Ljava/lang/Object;" stack 1 locals 1 {
+ ldc String "In I1\'s clone()";
+ areturn;
+ }
+
+ static abstract interface InnerClass I1=class DefaultClone$I1 of class DefaultClone;
+
+} // end Class DefaultClone$I1
+
+
+
+interface DefaultClone$I2 implements DefaultClone$I1 version 53:0 {
+
+ static abstract interface InnerClass I2=class DefaultClone$I2 of class DefaultClone;
+ static abstract interface InnerClass I1=class DefaultClone$I1 of class DefaultClone;
+
+} // end Class DefaultClone$I2
+
+
+super class DefaultClone$C implements DefaultClone$I2 version 53:0 {
+
+ Method "<init>":"()V" stack 1 locals 1 {
+ aload_0;
+ invokespecial Method java/lang/Object."<init>":"()V";
+ return;
+ }
+
+ public Method clone:"()Ljava/lang/Object;" stack 1 locals 1 {
+ ldc String "In C\'s clone()";
+ areturn;
+ }
+
+ static InnerClass C=class DefaultClone$C of class DefaultClone;
+ static abstract interface InnerClass I2=class DefaultClone$I2 of class DefaultClone;
+
+} // end Class DefaultClone$C
+
+
+super public class DefaultClone version 53:0 {
+
+ public Method "<init>":"()V" stack 1 locals 1 {
+ aload_0;
+ invokespecial Method java/lang/Object."<init>":"()V";
+ return;
+ }
+
+ static Method test:"(LDefaultClone$I2;)Ljava/lang/Object;" stack 1 locals 1 {
+ aload_0;
+ invokeinterface InterfaceMethod DefaultClone$I2.clone:"()Ljava/lang/Object;", 1;
+ areturn;
+ }
+
+ public static Method main:"([Ljava/lang/String;)V" stack 3 locals 2 {
+ new class DefaultClone$C;
+ dup;
+ invokespecial Method DefaultClone$C."<init>":"()V";
+ invokestatic Method test:"(LDefaultClone$I2;)Ljava/lang/Object;";
+ checkcast class java/lang/String;
+ astore_1;
+ aload_1;
+ ldc String "In C\'s clone()";
+ invokevirtual Method java/lang/String.equals:"(Ljava/lang/Object;)Z";
+ ifne L33;
+ new class java/lang/RuntimeException;
+ dup;
+ ldc String "Wrong clone() called";
+ invokespecial Method java/lang/RuntimeException."<init>":"(Ljava/lang/String;)V";
+ athrow;
+ L33: stack_frame_type append;
+ locals_map class java/lang/String;
+ return;
+ }
+
+ static InnerClass C=class DefaultClone$C of class DefaultClone;
+ static abstract interface InnerClass I2=class DefaultClone$I2 of class DefaultClone;
+ static abstract interface InnerClass I1=class DefaultClone$I1 of class DefaultClone;
+
+} // end Class DefaultClone
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/clone/DefaultFinalize.jasm Fri Dec 15 11:23:50 2017 -0500
@@ -0,0 +1,144 @@
+/*
+ * Copyright (c) 2017, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+/*
+ * @test
+ * @bug 8154587
+ * @summary Check that a default method named finalize() does not get masked by
+ * java.lang.Object.finalize() during resolution.
+ * @compile DefaultFinalize.jasm
+ * @run main DefaultFinalize
+ */
+
+// The below .jasm code implements the following java code:
+//
+// public class DefaultFinalize {
+//
+// static String res;
+//
+// interface I1 {
+// default void finalize() {
+// res = "In I1's finalize()";
+// }
+// }
+//
+// interface I2 extends I1 { }
+//
+// static class C implements I2 {
+// public void finalize() {
+// res = "In C's finalize()";
+// }
+// }
+//
+// static void test(I2 i) { i.finalize(); }
+//
+// public static void main(String[] args) {
+// test(new C());
+// if (!res.equals("In C's finalize()")) {
+// throw new RuntimeException("Wrong finalize() method called");
+// }
+// }
+// }
+
+
+interface DefaultFinalize$I1 version 54:0 {
+
+ public Method finalize:"()V" stack 1 locals 1 {
+ ldc String "In I1\'s finalize()";
+ putstatic Field DefaultFinalize.res:"Ljava/lang/String;";
+ return;
+ }
+
+ static abstract interface InnerClass I1=class DefaultFinalize$I1 of class DefaultFinalize;
+
+} // end Class DefaultFinalize$I1
+
+
+interface DefaultFinalize$I2 implements DefaultFinalize$I1 version 54:0 {
+
+ static abstract interface InnerClass I2=class DefaultFinalize$I2 of class DefaultFinalize;
+ static abstract interface InnerClass I1=class DefaultFinalize$I1 of class DefaultFinalize;
+
+} // end Class DefaultFinalize$I2
+
+
+super class DefaultFinalize$C implements DefaultFinalize$I2 version 54:0 {
+
+ Method "<init>":"()V" stack 1 locals 1 {
+ aload_0;
+ invokespecial Method java/lang/Object."<init>":"()V";
+ return;
+ }
+
+ public Method finalize:"()V" stack 1 locals 1 {
+ ldc String "In C\'s finalize()";
+ putstatic Field DefaultFinalize.res:"Ljava/lang/String;";
+ return;
+ }
+
+ static InnerClass C=class DefaultFinalize$C of class DefaultFinalize;
+ static abstract interface InnerClass I2=class DefaultFinalize$I2 of class DefaultFinalize;
+
+} // end Class DefaultFinalize$C
+
+
+super public class DefaultFinalize version 54:0 {
+
+ static Field res:"Ljava/lang/String;";
+
+ public Method "<init>":"()V" stack 1 locals 1 {
+ aload_0;
+ invokespecial Method java/lang/Object."<init>":"()V";
+ return;
+ }
+
+ static Method test:"(LDefaultFinalize$I2;)V" stack 1 locals 1 {
+ aload_0;
+ invokeinterface InterfaceMethod DefaultFinalize$I2.finalize:"()V", 1;
+ return;
+ }
+
+ public static Method main:"([Ljava/lang/String;)V" stack 3 locals 1 {
+ new class DefaultFinalize$C;
+ dup;
+ invokespecial Method DefaultFinalize$C."<init>":"()V";
+ invokestatic Method test:"(LDefaultFinalize$I2;)V";
+ getstatic Field res:"Ljava/lang/String;";
+ ldc String "In C\'s finalize()";
+ invokevirtual Method java/lang/String.equals:"(Ljava/lang/Object;)Z";
+ ifne L31;
+ new class java/lang/RuntimeException;
+ dup;
+ ldc String "Wrong finalize() method called";
+ invokespecial Method java/lang/RuntimeException."<init>":"(Ljava/lang/String;)V";
+ athrow;
+ L31: stack_frame_type same;
+ return;
+ }
+
+ static InnerClass C=class DefaultFinalize$C of class DefaultFinalize;
+ static abstract interface InnerClass I2=class DefaultFinalize$I2 of class DefaultFinalize;
+ static abstract interface InnerClass I1=class DefaultFinalize$I1 of class DefaultFinalize;
+
+} // end Class DefaultFinalize
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/clone/DefaultHashCode.jasm Fri Dec 15 11:23:50 2017 -0500
@@ -0,0 +1,126 @@
+/*
+ * Copyright (c) 2017, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+/*
+ * @test
+ * @bug 8154587
+ * @summary Check that invokeinterface calls the right hashCode() method when
+ * there is both a local method named hashCode() and a default method
+ * named hashCode().
+ * @compile DefaultHashCode.jasm
+ * @run main DefaultHashCode
+ */
+
+// The below .jasm code implements the following java code:
+//
+// public class DefaultHashCode {
+//
+// interface I2 {
+// default int hashCode() {
+// return 5;
+// }
+// }
+//
+// static class C implements I2 {
+// public int hashCode() {
+// return 4;
+// }
+// }
+//
+// static int test(I2 i) { return i.hashCode(); }
+//
+// public static void main(String[] args) {
+// if (test(new C()) != 4) {
+// throw new RuntimeException("Wrong hashCode() function called");
+// }
+// }
+// }
+
+
+interface DefaultHashCode$I2 version 53:0 {
+
+ public Method hashCode:"()I" stack 1 locals 1 {
+ iconst_5;
+ ireturn;
+ }
+
+ static abstract interface InnerClass I2=class DefaultHashCode$I2 of class DefaultHashCode;
+
+} // end Class DefaultHashCode$I2
+
+
+super class DefaultHashCode$C implements DefaultHashCode$I2 version 53:0 {
+
+ Method "<init>":"()V" stack 1 locals 1 {
+ aload_0;
+ invokespecial Method java/lang/Object."<init>":"()V";
+ return;
+ }
+
+ public Method hashCode:"()I" stack 1 locals 1 {
+ iconst_4;
+ ireturn;
+ }
+
+ static InnerClass C=class DefaultHashCode$C of class DefaultHashCode;
+ static abstract interface InnerClass I2=class DefaultHashCode$I2 of class DefaultHashCode;
+
+} // end Class DefaultHashCode$C
+
+
+super public class DefaultHashCode version 53:0 {
+
+ public Method "<init>":"()V" stack 1 locals 1 {
+ aload_0;
+ invokespecial Method java/lang/Object."<init>":"()V";
+ return;
+ }
+
+ static Method test:"(LDefaultHashCode$I2;)I" stack 1 locals 1 {
+ aload_0;
+ invokeinterface InterfaceMethod DefaultHashCode$I2.hashCode:"()I", 1;
+ ireturn;
+ }
+
+ public static Method main:"([Ljava/lang/String;)V" stack 3 locals 1 {
+ new class DefaultHashCode$C;
+ dup;
+ invokespecial Method DefaultHashCode$C."<init>":"()V";
+ invokestatic Method test:"(LDefaultHashCode$I2;)I";
+ iconst_4;
+ if_icmpeq L24;
+ new class java/lang/RuntimeException;
+ dup;
+ ldc String "Wrong hashCode() function called";
+ invokespecial Method java/lang/RuntimeException."<init>":"(Ljava/lang/String;)V";
+ athrow;
+ L24: stack_frame_type same;
+ return;
+ }
+
+ static InnerClass C=class DefaultHashCode$C of class DefaultHashCode;
+ static abstract interface InnerClass I2=class DefaultHashCode$I2 of class DefaultHashCode;
+
+} // end Class DefaultHashCode
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/clone/DefaultNoCloneInC.jasm Fri Dec 15 11:23:50 2017 -0500
@@ -0,0 +1,151 @@
+/*
+ * Copyright (c) 2017, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+/*
+ * @test
+ * @bug 8154587
+ * @summary Check that calling clone() with an invokeinterface opcode throws an IAE
+ * even if there is a default method named clone() in a super interface.
+ * @compile DefaultNoCloneInC.jasm
+ * @run main DefaultNoCloneInC
+ */
+
+// The below .jasm code implements the following java code:
+//
+// public class DefaultNoCloneInC {
+//
+// interface I1 {
+// default Object clone() {
+// return "In I1's clone()";
+// }
+// }
+//
+//
+// interface I2 extends I1 { }
+//
+//
+// static class C implements I2 { }
+//
+//
+// static Object test(I2 i) { return i.clone(); }
+//
+// public static void main(String[] args) {
+// try {
+// String s = (String)test(new C());
+// throw new RuntimeException("Expected IAE not thrown");
+// } catch (java.lang.IllegalAccessError e) {
+// if (!e.toString().contains("C.clone")) {
+// throw new RuntimeException("Wrong IllegalAccessError exception thrown");
+// }
+// }
+// }
+// }
+
+
+interface DefaultNoCloneInC$I1 version 53:0 {
+
+ public Method clone:"()Ljava/lang/Object;" stack 1 locals 1 {
+ ldc String "In I1\'s clone()";
+ areturn;
+ }
+
+ static abstract interface InnerClass I1=class DefaultNoCloneInC$I1 of class DefaultNoCloneInC;
+
+} // end Class DefaultNoCloneInC$I1
+
+
+interface DefaultNoCloneInC$I2 implements DefaultNoCloneInC$I1 version 53:0 {
+
+ static abstract interface InnerClass I2=class DefaultNoCloneInC$I2 of class DefaultNoCloneInC;
+ static abstract interface InnerClass I1=class DefaultNoCloneInC$I1 of class DefaultNoCloneInC;
+
+} // end Class DefaultNoCloneInC$I2
+
+
+super class DefaultNoCloneInC$C implements DefaultNoCloneInC$I2 version 53:0 {
+
+
+ Method "<init>":"()V" stack 1 locals 1 {
+ aload_0;
+ invokespecial Method java/lang/Object."<init>":"()V";
+ return;
+ }
+
+ static InnerClass C=class DefaultNoCloneInC$C of class DefaultNoCloneInC;
+ static abstract interface InnerClass I2=class DefaultNoCloneInC$I2 of class DefaultNoCloneInC;
+
+} // end Class DefaultNoCloneInC$C
+
+
+super public class DefaultNoCloneInC version 53:0 {
+
+ public Method "<init>":"()V" stack 1 locals 1 {
+ aload_0;
+ invokespecial Method java/lang/Object."<init>":"()V";
+ return;
+ }
+
+ static Method test:"(LDefaultNoCloneInC$I2;)Ljava/lang/Object;" stack 1 locals 1 {
+ aload_0;
+ invokeinterface InterfaceMethod DefaultNoCloneInC$I2.clone:"()Ljava/lang/Object;", 1;
+ areturn;
+ }
+
+ public static Method main:"([Ljava/lang/String;)V" stack 3 locals 2 {
+ try t0;
+ new class DefaultNoCloneInC$C;
+ dup;
+ invokespecial Method DefaultNoCloneInC$C."<init>":"()V";
+ invokestatic Method test:"(LDefaultNoCloneInC$I2;)Ljava/lang/Object;";
+ checkcast class java/lang/String;
+ astore_1;
+ new class java/lang/RuntimeException;
+ dup;
+ ldc String "Expected IAE not thrown";
+ invokespecial Method java/lang/RuntimeException."<init>":"(Ljava/lang/String;)V";
+ athrow;
+ endtry t0;
+ catch t0 java/lang/IllegalAccessError;
+ stack_frame_type stack1;
+ stack_map class java/lang/IllegalAccessError;
+ astore_1;
+ aload_1;
+ invokevirtual Method java/lang/IllegalAccessError.toString:"()Ljava/lang/String;";
+ ldc String "C.clone";
+ invokevirtual Method java/lang/String.contains:"(Ljava/lang/CharSequence;)Z";
+ ifne L47;
+ new class java/lang/RuntimeException;
+ dup;
+ ldc String "Wrong IllegalAccessError exception thrown";
+ invokespecial Method java/lang/RuntimeException."<init>":"(Ljava/lang/String;)V";
+ athrow;
+ L47: stack_frame_type same;
+ return;
+ }
+
+ static InnerClass C=class DefaultNoCloneInC$C of class DefaultNoCloneInC;
+ static abstract interface InnerClass I2=class DefaultNoCloneInC$I2 of class DefaultNoCloneInC;
+ static abstract interface InnerClass I1=class DefaultNoCloneInC$I1 of class DefaultNoCloneInC;
+
+} // end Class DefaultNoCloneInC
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/clone/LocalClone.jasm Fri Dec 15 11:23:50 2017 -0500
@@ -0,0 +1,144 @@
+/*
+ * Copyright (c) 2017, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+/*
+ * @test
+ * @bug 8154587
+ * @summary Check that method resolution for invokeinterface of clone() fails
+ * if it cannot find a public method named clone().
+ * @compile LocalClone.jasm
+ * @run main LocalClone
+ */
+
+// The below .jasm code implements the following java code:
+//
+// interface I1 { }
+//
+//
+// public class LocalClone {
+//
+// interface I2 extends I1 { }
+//
+//
+// static class C implements I2 {
+// public Object clone() {
+// return "In C's clone()";
+// }
+// }
+//
+// static Object test(I2 i) { return i.clone(); }
+//
+// public static void main(String[] args) {
+// try {
+// String s = (String)test(new C());
+// throw new RuntimeException("Expected NSME not thrown");
+// } catch (java.lang.NoSuchMethodError e) {
+// if (!e.toString().contains("I2.clone")) {
+// throw new RuntimeException("Wrong NoSuchMethodError exception thrown");
+// }
+// }
+// }
+// }
+
+
+interface I1 version 53:0 { } // end Class I1
+
+
+interface LocalClone$I2 implements I1 version 53:0 {
+
+ static abstract interface InnerClass I2=class LocalClone$I2 of class LocalClone;
+
+} // end Class LocalClone$I2
+
+
+super class LocalClone$C implements LocalClone$I2 version 53:0 {
+
+ Method "<init>":"()V" stack 1 locals 1 {
+ aload_0;
+ invokespecial Method java/lang/Object."<init>":"()V";
+ return;
+ }
+
+ public Method clone:"()Ljava/lang/Object;" stack 1 locals 1 {
+ ldc String "In C\'s clone()";
+ areturn;
+ }
+
+ static InnerClass C=class LocalClone$C of class LocalClone;
+ static abstract interface InnerClass I2=class LocalClone$I2 of class LocalClone;
+
+} // end Class LocalClone$C
+
+
+super public class LocalClone version 53:0 {
+
+ public Method "<init>":"()V" stack 1 locals 1 {
+ aload_0;
+ invokespecial Method java/lang/Object."<init>":"()V";
+ return;
+ }
+
+ static Method test:"(LLocalClone$I2;)Ljava/lang/Object;" stack 1 locals 1 {
+ aload_0;
+ invokeinterface InterfaceMethod LocalClone$I2.clone:"()Ljava/lang/Object;", 1;
+ areturn;
+ }
+
+ public static Method main:"([Ljava/lang/String;)V" stack 3 locals 2 {
+ try t0;
+ new class LocalClone$C;
+ dup;
+ invokespecial Method LocalClone$C."<init>":"()V";
+ invokestatic Method test:"(LLocalClone$I2;)Ljava/lang/Object;";
+ checkcast class java/lang/String;
+ astore_1;
+ new class java/lang/RuntimeException;
+ dup;
+ ldc String "Expected NSME not thrown";
+ invokespecial Method java/lang/RuntimeException."<init>":"(Ljava/lang/String;)V";
+ athrow;
+ endtry t0;
+ catch t0 java/lang/NoSuchMethodError;
+ stack_frame_type stack1;
+ stack_map class java/lang/NoSuchMethodError;
+ astore_1;
+ aload_1;
+ invokevirtual Method java/lang/NoSuchMethodError.toString:"()Ljava/lang/String;";
+ ldc String "I2.clone";
+ invokevirtual Method java/lang/String.contains:"(Ljava/lang/CharSequence;)Z";
+ ifne L47;
+ new class java/lang/RuntimeException;
+ dup;
+ ldc String "Wrong NoSuchMethodError exception thrown";
+ invokespecial Method java/lang/RuntimeException."<init>":"(Ljava/lang/String;)V";
+ athrow;
+ L47: stack_frame_type same;
+ return;
+ }
+
+ static InnerClass C=class LocalClone$C of class LocalClone;
+ static abstract interface InnerClass I2=class LocalClone$I2 of class LocalClone;
+
+} // end Class LocalClone
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/clone/NoClones.jasm Fri Dec 15 11:23:50 2017 -0500
@@ -0,0 +1,133 @@
+/*
+ * Copyright (c) 2017, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+/*
+ * @test
+ * @bug 8154587
+ * @summary Check that a NoSuchMethodError exception gets thrown if invokeinterface
+ * calls clone() and there is no public implementation of clone().
+ * @compile NoClones.jasm
+ * @run main NoClones
+ */
+
+// The below .jasm code implements the following java code:
+//
+// interface I1 { }
+//
+//
+// public class NoClones {
+//
+// interface I2 extends I1 { }
+//
+// static class C implements I2 { }
+//
+// static Object test(I2 i) { return i.clone(); }
+//
+// public static void main(String[] args) {
+// try {
+// String s = (String)test(new C());
+// throw new RuntimeException("Expected NSME not thrown");
+// } catch (java.lang.NoSuchMethodError e) {
+// if (!e.toString().contains("I2.clone")) {
+// throw new RuntimeException("Wrong NoSuchMethodError exception thrown");
+// }
+// }
+// }
+// }
+
+
+interface I1 version 53:0 { } // end Class I1
+
+
+interface NoClones$I2 implements I1 version 53:0 {
+
+ static abstract interface InnerClass I2=class NoClones$I2 of class NoClones;
+
+} // end Class NoClones$I2
+
+
+super class NoClones$C implements NoClones$I2 version 53:0 {
+
+ Method "<init>":"()V" stack 1 locals 1 {
+ aload_0;
+ invokespecial Method java/lang/Object."<init>":"()V";
+ return;
+ }
+
+ static InnerClass C=class NoClones$C of class NoClones;
+ static abstract interface InnerClass I2=class NoClones$I2 of class NoClones;
+
+} // end Class NoClones$C
+
+
+super public class NoClones version 53:0 {
+
+ public Method "<init>":"()V" stack 1 locals 1 {
+ aload_0;
+ invokespecial Method java/lang/Object."<init>":"()V";
+ return;
+ }
+
+ static Method test:"(LNoClones$I2;)Ljava/lang/Object;" stack 1 locals 1 {
+ aload_0;
+ invokeinterface InterfaceMethod NoClones$I2.clone:"()Ljava/lang/Object;", 1;
+ areturn;
+ }
+
+ public static Method main:"([Ljava/lang/String;)V" stack 3 locals 2 {
+ try t0;
+ new class NoClones$C;
+ dup;
+ invokespecial Method NoClones$C."<init>":"()V";
+ invokestatic Method test:"(LNoClones$I2;)Ljava/lang/Object;";
+ checkcast class java/lang/String;
+ astore_1;
+ new class java/lang/RuntimeException;
+ dup;
+ ldc String "Expected NSME not thrown";
+ invokespecial Method java/lang/RuntimeException."<init>":"(Ljava/lang/String;)V";
+ athrow;
+ endtry t0;
+ catch t0 java/lang/NoSuchMethodError;
+ stack_frame_type stack1;
+ stack_map class java/lang/NoSuchMethodError;
+ astore_1;
+ aload_1;
+ invokevirtual Method java/lang/NoSuchMethodError.toString:"()Ljava/lang/String;";
+ ldc String "I2.clone";
+ invokevirtual Method java/lang/String.contains:"(Ljava/lang/CharSequence;)Z";
+ ifne L47;
+ new class java/lang/RuntimeException;
+ dup;
+ ldc String "Wrong NoSuchMethodError exception thrown";
+ invokespecial Method java/lang/RuntimeException."<init>":"(Ljava/lang/String;)V";
+ athrow;
+ L47: stack_frame_type same;
+ return;
+ }
+
+ static InnerClass C=class NoClones$C of class NoClones;
+ static abstract interface InnerClass I2=class NoClones$I2 of class NoClones;
+
+} // end Class NoClones
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/clone/invokevirtual/DefMethClone.jasm Fri Dec 15 11:23:50 2017 -0500
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2017, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+interface DefMethClone version 54:0 {
+
+ public Method clone:"()Ljava/lang/Object;" stack 1 locals 1 {
+ ldc String "In DefMethClone\'s clone()";
+ areturn;
+ }
+
+} // end Class DefMethClone
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/clone/invokevirtual/HasLocalClone.jasm Fri Dec 15 11:23:50 2017 -0500
@@ -0,0 +1,96 @@
+/*
+ * Copyright (c) 2017, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+/*
+ * @test
+ * @bug 8154587
+ * @summary Check that invokevirtual of clone() finds the clone() method that
+ * is local to the calling class.
+ * @compile DefMethClone.jasm SuperClass.jasm I1.java HasLocalClone.jasm
+ * @run main/othervm -noverify HasLocalClone
+ */
+
+// The below .jasm code implements the following java code:
+//
+// public class HasLocalClone extends SuperClass implements I1 {
+//
+// public Object clone() {
+// return "In HasLocalClone's clone()";
+// }
+//
+// static Object test(SuperClass a) { return a.clone(); }
+//
+// public static void main(String[] args) {
+// String s = (String)test(new HasLocalClone());
+// if (!s.equals("In HasLocalCloneC's clone()")) {
+// throw new RuntimeException("Wrong clone() called: " + s);
+// }
+// }
+// }
+
+
+super public class HasLocalClone extends SuperClass implements I1 version 54:0 {
+
+ public Method "<init>":"()V" stack 1 locals 1 {
+ aload_0;
+ invokespecial Method SuperClass."<init>":"()V";
+ return;
+ }
+
+ public Method clone:"()Ljava/lang/Object;" stack 1 locals 1 {
+ ldc String "In HasLocalClone\'s clone()";
+ areturn;
+ }
+
+ static Method test:"(LSuperClass;)Ljava/lang/Object;" stack 1 locals 1 {
+ aload_0;
+ invokevirtual Method SuperClass.clone:"()Ljava/lang/Object;";
+ areturn;
+ }
+
+ public static Method main:"([Ljava/lang/String;)V" stack 3 locals 2 {
+ new class HasLocalClone;
+ dup;
+ invokespecial Method "<init>":"()V";
+ invokestatic Method test:"(LSuperClass;)Ljava/lang/Object;";
+ checkcast class java/lang/String;
+ astore_1;
+ aload_1;
+ ldc String "In HasLocalClone\'s clone()";
+ invokevirtual Method java/lang/String.equals:"(Ljava/lang/Object;)Z";
+ ifne L37;
+ new class java/lang/RuntimeException;
+ dup;
+ aload_1;
+ invokedynamic InvokeDynamic REF_invokeStatic:java/lang/invoke/StringConcatFactory.makeConcatWithConstants:"(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/String;[Ljava/lang/Object;)Ljava/lang/invoke/CallSite;":makeConcatWithConstants:"(Ljava/lang/String;)Ljava/lang/String;" String "Wrong clone() called: ";
+ invokespecial Method java/lang/RuntimeException."<init>":"(Ljava/lang/String;)V";
+ athrow;
+ L37: stack_frame_type append;
+ locals_map class java/lang/String;
+ return;
+ }
+
+ public static final InnerClass Lookup=class java/lang/invoke/MethodHandles$Lookup of class java/lang/invoke/MethodHandles;
+
+} // end Class HasLocalClone
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/clone/invokevirtual/I1.java Fri Dec 15 11:23:50 2017 -0500
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2017, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+interface I1 extends DefMethClone { }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/clone/invokevirtual/I1Abstr.java Fri Dec 15 11:23:50 2017 -0500
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2017, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+interface I1Abstr extends DefMethClone {
+ Object clone();
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/clone/invokevirtual/NoLocalClone.jasm Fri Dec 15 11:23:50 2017 -0500
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2017, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+/*
+ * @test
+ * @bug 8154587
+ * @summary Check that invokevirtual of clone() calls java.lang.Object.clone()
+ * even if a superinterface has a default method named clone().
+ * @compile DefMethClone.jasm SuperClass.jasm I1.java NoLocalClone.jasm
+ * @run main/othervm -noverify NoLocalClone
+ */
+
+// The below .jasm code implements the following java code:
+//
+// public class NoLocalClone extends SuperClass implements Cloneable,I1 {
+//
+// static Object test(SuperClass a) { return a.clone(); }
+//
+// public static void main(String[] args) {
+// Object obj = test(new NoLocalClone());
+// if (!(obj instanceof NoLocalClone)) {
+// throw new RuntimeException("Wrong clone() called.");
+// }
+// }
+// }
+
+super public class NoLocalClone extends SuperClass implements java/lang/Cloneable, I1 version 54:0 {
+
+ public Method "<init>":"()V" stack 1 locals 1 {
+ aload_0;
+ invokespecial Method SuperClass."<init>":"()V";
+ return;
+ }
+
+ static Method test:"(LSuperClass;)Ljava/lang/Object;" stack 1 locals 1 {
+ aload_0;
+ invokevirtual Method SuperClass.clone:"()Ljava/lang/Object;";
+ areturn;
+ }
+
+ public static Method main:"([Ljava/lang/String;)V" stack 3 locals 2 {
+ new class NoLocalClone;
+ dup;
+ invokespecial Method "<init>":"()V";
+ invokestatic Method test:"(LSuperClass;)Ljava/lang/Object;";
+ astore_1;
+ aload_1;
+ instanceof class NoLocalClone;
+ ifne L31;
+ new class java/lang/RuntimeException;
+ dup;
+ ldc String "Wrong clone() called.";
+ invokespecial Method java/lang/RuntimeException."<init>":"(Ljava/lang/String;)V";
+ athrow;
+ L31: stack_frame_type append;
+ locals_map class java/lang/Object;
+ return;
+ }
+
+} // end Class NoLocalClone
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/clone/invokevirtual/NoLocalCloneAbstr.jasm Fri Dec 15 11:23:50 2017 -0500
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2017, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+/*
+ * @test
+ * @bug 8154587
+ * @summary Check that invokevirtual of clone() calls java.lang.Object.clone()
+ * even if a superinterface has an abstract method named clone().
+ * @compile DefMethClone.jasm SuperClass.jasm I1Abstr.java NoLocalCloneAbstr.jasm
+ * @run main/othervm -noverify NoLocalCloneAbstr
+ */
+
+// The below .jasm code implements the following java code:
+//
+// public class NoLocalCloneAbstr extends SuperClass implements Cloneable,I1Abstr {
+//
+// static Object test(SuperClass a) { return a.clone(); }
+//
+// public static void main(String[] args) {
+// Object obj = test(new NoLocalCloneAbstr());
+// if (!(obj instanceof NoLocalCloneAbstr)) {
+// throw new RuntimeException("Wrong clone() called.");
+// }
+// }
+// }
+
+super public class NoLocalCloneAbstr extends SuperClass implements java/lang/Cloneable, I1Abstr version 54:0 {
+
+ public Method "<init>":"()V" stack 1 locals 1 {
+ aload_0;
+ invokespecial Method SuperClass."<init>":"()V";
+ return;
+ }
+
+ static Method test:"(LSuperClass;)Ljava/lang/Object;" stack 1 locals 1 {
+ aload_0;
+ invokevirtual Method SuperClass.clone:"()Ljava/lang/Object;";
+ areturn;
+ }
+
+ public static Method main:"([Ljava/lang/String;)V" stack 3 locals 2 {
+ new class NoLocalCloneAbstr;
+ dup;
+ invokespecial Method "<init>":"()V";
+ invokestatic Method test:"(LSuperClass;)Ljava/lang/Object;";
+ astore_1;
+ aload_1;
+ instanceof class NoLocalCloneAbstr;
+ ifne L31;
+ new class java/lang/RuntimeException;
+ dup;
+ ldc String "Wrong clone() called.";
+ invokespecial Method java/lang/RuntimeException."<init>":"(Ljava/lang/String;)V";
+ athrow;
+ L31: stack_frame_type append;
+ locals_map class java/lang/Object;
+ return;
+ }
+
+} // end Class NoLocalCloneAbstr
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/clone/invokevirtual/SuperClass.jasm Fri Dec 15 11:23:50 2017 -0500
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2017, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+super public class SuperClass implements DefMethClone version 54:0 {
+
+ public Method "<init>":"()V" stack 1 locals 1 {
+ aload_0;
+ invokespecial Method java/lang/Object."<init>":"()V";
+ return;
+ }
+
+} // end Class SuperClass