diff --git a/.hgtags b/.hgtags index 01eab12f5916137d99a9d8cfb615f70a5292e252..1b5e36195c20414b1f9945f8848dd981e09b574d 100644 --- a/.hgtags +++ b/.hgtags @@ -1035,6 +1035,11 @@ cdfe7ec6f29293d7c2f64239518e8947733ad85c jdk8u152-b12 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 @@ cd7f8ee4553d0f884ddc150ceefcb5b48b12ca21 jdk8u162-b06 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 --git a/src/share/vm/classfile/verificationType.cpp b/src/share/vm/classfile/verificationType.cpp index 716a72d0d2aef2e76441ab6fce7226bc227e90e1..61715d92d5072cb536db287b943e99a50914756a 100644 --- a/src/share/vm/classfile/verificationType.cpp +++ b/src/share/vm/classfile/verificationType.cpp @@ -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 @@ bool VerificationType::is_reference_assignable_from( 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 @@ bool VerificationType::is_reference_assignable_from( 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 --git a/src/share/vm/classfile/verifier.cpp b/src/share/vm/classfile/verifier.cpp index b53b4aeda4d1b77194016f3a00848b4f851680a7..82509ff16b2514a46ff1854639153eefc3af1df4 100644 --- a/src/share/vm/classfile/verifier.cpp +++ b/src/share/vm/classfile/verifier.cpp @@ -1949,9 +1949,11 @@ Klass* ClassVerifier::load_class(Symbol* name, TRAPS) { 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 --git a/src/share/vm/code/dependencies.cpp b/src/share/vm/code/dependencies.cpp index 7317036d6842c3df146ebc06105e32183db4cd05..c284160e0e32cd58cf8296e15c2204881bff1ff9 100644 --- a/src/share/vm/code/dependencies.cpp +++ b/src/share/vm/code/dependencies.cpp @@ -793,6 +793,14 @@ class ClassHierarchyWalker { _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 @@ class ClassHierarchyWalker { // 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 --git a/src/share/vm/oops/cpCache.cpp b/src/share/vm/oops/cpCache.cpp index e8838a6443fa87aa7db0eee916aa170aca3dccb4..8899fa7b953076c7d9b63fb9d9d1b64e7e6c62ae 100644 --- a/src/share/vm/oops/cpCache.cpp +++ b/src/share/vm/oops/cpCache.cpp @@ -226,14 +226,13 @@ void ConstantPoolCacheEntry::set_direct_or_vtable_call(Bytecodes::Code invoke_co // 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 --git a/src/share/vm/prims/jvm.cpp b/src/share/vm/prims/jvm.cpp index 36aa9cb669c5120ff50c34833db93838a0aee6e9..17caabbee0cb3e9956a77eb1a336e375ee0514bf 100644 --- a/src/share/vm/prims/jvm.cpp +++ b/src/share/vm/prims/jvm.cpp @@ -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 @@ JVM_ENTRY(jclass, JVM_FindClassFromClass(JNIEnv *env, const char *name, 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_ENTRY(jobject, JVM_AllocateNewArray(JNIEnv *env, jobject obj, jclass currCla 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 --git a/test/runtime/RedefineTests/RedefineInterfaceCall.java b/test/runtime/RedefineTests/RedefineInterfaceCall.java index 2342ea1f20348cd39a651336398925a933c14587..01945f6f698290c7e0fd7cdb0bc419b311e77794 100644 --- a/test/runtime/RedefineTests/RedefineInterfaceCall.java +++ b/test/runtime/RedefineTests/RedefineInterfaceCall.java @@ -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 {}