# HG changeset patch # User asaha # Date 1516662636 28800 # Node ID e481feb718cba6a0f19fa08ec2086a6ffb828d7a # Parent dce201107e3ee92d1a2058a4b6d981cf6b791cbf# Parent 5587cde50bbc2aa031aefb47eaa36b041f5e7c4b Merge diff -r dce201107e3e -r e481feb718cb .hgtags --- a/.hgtags Thu Jan 18 06:01:19 2018 +0000 +++ b/.hgtags Mon Jan 22 15:10:36 2018 -0800 @@ -1035,6 +1035,11 @@ 0a9d8db98fc5f0302da6520ba329f41baa092ae0 jdk8u152-b14 c1bf165d3b27e864a9f8eec5bb0c1e746a972ad5 jdk8u152-b15 98b4b0661837817cc39047000e1a7efa6015af7c jdk8u152-b16 +91894ffc746c1681172aaa37e2cf5bff69560f20 jdk8u152-b31 +d278f122e65dfb5d239ed420a534df75f527a504 jdk8u152-b32 +c066fe30d0a141b14ab7788cbbd35eba11196e72 jdk8u152-b33 +12a0cebfae93a638dc69a34f8276e1ef43b11b7a jdk8u152-b34 +f6719c3d02787da6e232703f61efc931ead7683b jdk8u152-b35 2d5100bddeb80cf767485b787fc3051311e3d7b9 jdk8u151-b00 596b584c68b73ec635347807571463580deb955f jdk8u151-b01 1f6f436360d5cd375b806aec1c78abb8fcb4e5f6 jdk8u151-b02 @@ -1125,6 +1130,10 @@ c3618e1cdefdda6c262f082791bfd988e0e9d9c9 jdk8u162-b10 39e2895b795aded8b584626fb019d35f12e9d1e7 jdk8u162-b11 69aec2ca5d905dde1d0f29a89076d02a531808a3 jdk8u162-b12 +caac74fe3cfa9a8c859c28c97d1046a58252af27 jdk8u162-b31 +a17bab9405474602b18cd62e060a09b17d6413ac jdk8u171-b00 +ebfd57cc21e6b7f0c22b17c666b6b28c9340e207 jdk8u171-b01 +1acd7c1b80241def8fac90f70b0df16356adad47 jdk8u171-b02 f299cf0b7baea1ae85f139f97adb9ab5499f402a jdk8u172-b00 d10254debf7c1342416062bf1ba5258f16a8ce00 jdk8u172-b01 653d9e0cd3f4023675c9eece7f0d563287f1d34f jdk8u172-b02 diff -r dce201107e3e -r e481feb718cb src/share/vm/classfile/verificationType.cpp --- a/src/share/vm/classfile/verificationType.cpp Thu Jan 18 06:01:19 2018 +0000 +++ b/src/share/vm/classfile/verificationType.cpp Mon Jan 22 15:10:36 2018 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 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 @@ -63,6 +63,7 @@ name(), Handle(THREAD, klass->class_loader()), Handle(THREAD, klass->protection_domain()), true, CHECK_false); KlassHandle this_class(THREAD, obj); + klass->class_loader_data()->record_dependency(obj, CHECK_false); if (this_class->is_interface() && (!from_field_is_protected || from.name() != vmSymbols::java_lang_Object())) { @@ -74,6 +75,7 @@ Klass* from_class = SystemDictionary::resolve_or_fail( from.name(), Handle(THREAD, klass->class_loader()), Handle(THREAD, klass->protection_domain()), true, CHECK_false); + klass->class_loader_data()->record_dependency(from_class, CHECK_false); bool result = InstanceKlass::cast(from_class)->is_subclass_of(this_class()); if (result && DumpSharedSpaces) { if (klass()->is_subclass_of(from_class) && klass()->is_subclass_of(this_class())) { diff -r dce201107e3e -r e481feb718cb src/share/vm/classfile/verifier.cpp --- a/src/share/vm/classfile/verifier.cpp Thu Jan 18 06:01:19 2018 +0000 +++ b/src/share/vm/classfile/verifier.cpp Mon Jan 22 15:10:36 2018 -0800 @@ -1949,9 +1949,11 @@ oop loader = current_class()->class_loader(); oop protection_domain = current_class()->protection_domain(); - return SystemDictionary::resolve_or_fail( + Klass* kls = SystemDictionary::resolve_or_fail( name, Handle(THREAD, loader), Handle(THREAD, protection_domain), true, CHECK_NULL); + current_class()->class_loader_data()->record_dependency(kls, CHECK_NULL); + return kls; } bool ClassVerifier::is_protected_access(instanceKlassHandle this_class, diff -r dce201107e3e -r e481feb718cb src/share/vm/code/dependencies.cpp --- a/src/share/vm/code/dependencies.cpp Thu Jan 18 06:01:19 2018 +0000 +++ b/src/share/vm/code/dependencies.cpp Mon Jan 22 15:10:36 2018 -0800 @@ -793,6 +793,14 @@ _signature = NULL; initialize(participant); } + ClassHierarchyWalker(Klass* participants[], int num_participants) { + _name = NULL; + _signature = NULL; + initialize(NULL); + for (int i = 0; i < num_participants; ++i) { + add_participant(participants[i]); + } + } // This is common code for two searches: One for concrete subtypes, // the other for concrete method implementations and overrides. @@ -891,6 +899,24 @@ // Search class hierarchy first. Method* m = InstanceKlass::cast(k)->find_instance_method(_name, _signature); if (!Dependencies::is_concrete_method(m, k)) { + // Check for re-abstraction of method + if (!k->is_interface() && m != NULL && m->is_abstract()) { + // Found a matching abstract method 'm' in the class hierarchy. + // This is fine iff 'k' is an abstract class and all concrete subtypes + // of 'k' override 'm' and are participates of the current search. + ClassHierarchyWalker wf(_participants, _num_participants); + Klass* w = wf.find_witness_subtype(k); + if (w != NULL) { + Method* wm = InstanceKlass::cast(w)->find_instance_method(_name, _signature); + if (!Dependencies::is_concrete_method(wm, w)) { + // Found a concrete subtype 'w' which does not override abstract method 'm'. + // Bail out because 'm' could be called with 'w' as receiver (leading to an + // AbstractMethodError) and thus the method we are looking for is not unique. + _found_methods[_num_participants] = m; + return true; + } + } + } // Check interface defaults also, if any exist. Array* default_methods = InstanceKlass::cast(k)->default_methods(); if (default_methods == NULL) diff -r dce201107e3e -r e481feb718cb src/share/vm/oops/cpCache.cpp --- a/src/share/vm/oops/cpCache.cpp Thu Jan 18 06:01:19 2018 +0000 +++ b/src/share/vm/oops/cpCache.cpp Mon Jan 22 15:10:36 2018 -0800 @@ -226,14 +226,13 @@ // virtual method in java.lang.Object. This is a corner case in the spec // but is presumably legal. javac does not generate this code. // - // We set bytecode_1() to _invokeinterface, because that is the - // bytecode # used by the interpreter to see if it is resolved. + // We do not set bytecode_1() to _invokeinterface, because that is the + // bytecode # used by the interpreter to see if it is resolved. In this + // case, the method gets reresolved with caller for each interface call + // because the actual selected method may not be public. + // // We set bytecode_2() to _invokevirtual. // See also interpreterRuntime.cpp. (8/25/2000) - // Only set resolved for the invokeinterface case if method is public. - // Otherwise, the method needs to be reresolved with caller for each - // interface call. - if (method->is_public()) set_bytecode_1(invoke_code); } else { assert(invoke_code == Bytecodes::_invokevirtual, ""); } diff -r dce201107e3e -r e481feb718cb src/share/vm/prims/jvm.cpp --- a/src/share/vm/prims/jvm.cpp Thu Jan 18 06:01:19 2018 +0000 +++ b/src/share/vm/prims/jvm.cpp Mon Jan 22 15:10:36 2018 -0800 @@ -24,6 +24,7 @@ #include "precompiled.hpp" #include "classfile/classLoader.hpp" +#include "classfile/classLoaderData.inline.hpp" #include "classfile/classLoaderExt.hpp" #include "classfile/javaAssertions.hpp" #include "classfile/javaClasses.hpp" @@ -952,6 +953,12 @@ Handle h_prot (THREAD, protection_domain); jclass result = find_class_from_class_loader(env, h_name, init, h_loader, h_prot, true, thread); + if (result != NULL) { + oop mirror = JNIHandles::resolve_non_null(result); + Klass* to_class = java_lang_Class::as_Klass(mirror); + ClassLoaderData* cld = ClassLoaderData::class_loader_data(h_loader()); + cld->record_dependency(to_class, CHECK_NULL); + } if (TraceClassResolution && result != NULL) { // this function is generally only used for class loading during verification. @@ -3654,15 +3661,16 @@ JVM_END -// Return the first non-null class loader up the execution stack, or null -// if only code from the null class loader is on the stack. +// Returns first non-privileged class loader on the stack (excluding reflection +// generated frames) or null if only classes loaded by the boot class loader +// and extension class loader are found on the stack. JVM_ENTRY(jobject, JVM_LatestUserDefinedLoader(JNIEnv *env)) for (vframeStream vfst(thread); !vfst.at_end(); vfst.next()) { // UseNewReflection vfst.skip_reflection_related_frames(); // Only needed for 1.4 reflection oop loader = vfst.method()->method_holder()->class_loader(); - if (loader != NULL) { + if (loader != NULL && !SystemDictionary::is_ext_class_loader(loader)) { return JNIHandles::make_local(env, loader); } } diff -r dce201107e3e -r e481feb718cb test/runtime/RedefineTests/RedefineInterfaceCall.java --- a/test/runtime/RedefineTests/RedefineInterfaceCall.java Thu Jan 18 06:01:19 2018 +0000 +++ b/test/runtime/RedefineTests/RedefineInterfaceCall.java Mon Jan 22 15:10:36 2018 -0800 @@ -25,16 +25,13 @@ * @test * @bug 8174962 * @summary Redefine class with interface method call - * @library /testlibrary /test/lib - * @modules java.base/jdk.internal.misc - * @modules java.compiler - * java.instrument - * jdk.jartool/sun.tools.jar + * @library /testlibrary + * @build RedefineClassHelper * @run main RedefineClassHelper - * @run main/othervm -javaagent:redefineagent.jar RedefineInterfaceCall + * @run main/othervm -javaagent:redefineagent.jar -XX:TraceRedefineClasses=3174407 RedefineInterfaceCall */ -import static jdk.testlibrary.Asserts.assertEquals; +import static com.oracle.java.testlibrary.Asserts.assertEquals; interface I1 { default int m() { return 0; } } interface I2 extends I1 {}