changeset 8686:e481feb718cb

Merge
author asaha
date Mon, 22 Jan 2018 15:10:36 -0800
parents dce201107e3e 5587cde50bbc
children 16be38cadc00
files .hgtags
diffstat 7 files changed, 61 insertions(+), 18 deletions(-) [+]
line wrap: on
line diff
--- 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
--- 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())) {
--- 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,
--- 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<Method*>* default_methods = InstanceKlass::cast(k)->default_methods();
         if (default_methods == NULL)
--- 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, "");
     }
--- 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);
     }
   }
--- 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 {}