changeset 4153:a21a0e7df91d

8180711: Better invokespecial checks Reviewed-by: acorn, ahgross, rhalade Contributed-by: harold.seigel@oracle.com
author hseigel
date Tue, 01 Aug 2017 09:47:45 -0400
parents dabc0ba4b1a6
children 5a4ac9a9eb79
files src/share/vm/interpreter/linkResolver.cpp src/share/vm/interpreter/linkResolver.hpp
diffstat 2 files changed, 48 insertions(+), 55 deletions(-) [+]
line wrap: on
line diff
--- a/src/share/vm/interpreter/linkResolver.cpp	Wed Aug 30 15:42:01 2017 +0300
+++ b/src/share/vm/interpreter/linkResolver.cpp	Tue Aug 01 09:47:45 2017 -0400
@@ -342,6 +342,42 @@
 }
 
 
+void LinkResolver::check_method_loader_constraints(methodHandle& resolved_method,
+                                                   KlassHandle resolved_klass,
+                                                   Symbol* method_name,
+                                                   Symbol* method_signature,
+                                                   KlassHandle current_klass,
+                                                   const char* method_type, TRAPS) {
+  Handle loader (THREAD, instanceKlass::cast(current_klass())->class_loader());
+  Handle class_loader (THREAD, instanceKlass::cast(resolved_method->method_holder())->class_loader());
+  {
+    ResourceMark rm(THREAD);
+    char* failed_type_name =
+      SystemDictionary::check_signature_loaders(method_signature, loader,
+                                                class_loader, true, CHECK);
+    if (failed_type_name != NULL) {
+      const char* msg = "loader constraint violation: when resolving %s"
+        " \"%s\" the class loader (instance of %s) of the current class, %s,"
+        " and the class loader (instance of %s) for the method's defining class, %s, have"
+        " different Class objects for the type %s used in the signature";
+      char* sig = methodOopDesc::name_and_sig_as_C_string(Klass::cast(resolved_klass()),
+              method_name, method_signature);
+      const char* loader1 = SystemDictionary::loader_name(loader());
+      char* current = instanceKlass::cast(current_klass())->name()->as_C_string();
+      const char* loader2 = SystemDictionary::loader_name(class_loader());
+      char* target = instanceKlass::cast(resolved_method->method_holder())
+                     ->name()->as_C_string();
+      size_t buflen = strlen(msg) + strlen(sig) + strlen(loader1) +
+        strlen(current) + strlen(loader2) + strlen(target) +
+        strlen(failed_type_name) + strlen(method_type) + 1;
+      char* buf = NEW_RESOURCE_ARRAY_IN_THREAD(THREAD, char, buflen);
+      jio_snprintf(buf, buflen, msg, method_type, sig, loader1, current, loader2,
+                   target, failed_type_name);
+      THROW_MSG(vmSymbols::java_lang_LinkageError(), buf);
+    }
+  }
+}
+
 void LinkResolver::resolve_method(methodHandle& resolved_method, KlassHandle resolved_klass,
                                   Symbol* method_name, Symbol* method_signature,
                                   KlassHandle current_klass, bool check_access, TRAPS) {
@@ -397,32 +433,8 @@
                                CHECK);
 
     // check loader constraints
-    Handle loader (THREAD, instanceKlass::cast(current_klass())->class_loader());
-    Handle class_loader (THREAD, instanceKlass::cast(resolved_method->method_holder())->class_loader());
-    {
-      ResourceMark rm(THREAD);
-      char* failed_type_name =
-        SystemDictionary::check_signature_loaders(method_signature, loader,
-                                                  class_loader, true, CHECK);
-      if (failed_type_name != NULL) {
-        const char* msg = "loader constraint violation: when resolving method"
-          " \"%s\" the class loader (instance of %s) of the current class, %s,"
-          " and the class loader (instance of %s) for resolved class, %s, have"
-          " different Class objects for the type %s used in the signature";
-        char* sig = methodOopDesc::name_and_sig_as_C_string(Klass::cast(resolved_klass()),method_name,method_signature);
-        const char* loader1 = SystemDictionary::loader_name(loader());
-        char* current = instanceKlass::cast(current_klass())->name()->as_C_string();
-        const char* loader2 = SystemDictionary::loader_name(class_loader());
-        char* resolved = instanceKlass::cast(resolved_klass())->name()->as_C_string();
-        size_t buflen = strlen(msg) + strlen(sig) + strlen(loader1) +
-          strlen(current) + strlen(loader2) + strlen(resolved) +
-          strlen(failed_type_name);
-        char* buf = NEW_RESOURCE_ARRAY_IN_THREAD(THREAD, char, buflen);
-        jio_snprintf(buf, buflen, msg, sig, loader1, current, loader2,
-                     resolved, failed_type_name);
-        THROW_MSG(vmSymbols::java_lang_LinkageError(), buf);
-      }
-    }
+    check_method_loader_constraints(resolved_method, resolved_klass, method_name,
+                                    method_signature, current_klass, "method", CHECK);
   }
 }
 
@@ -459,34 +471,8 @@
   }
 
   if (check_access) {
-    HandleMark hm(THREAD);
-    Handle loader (THREAD, instanceKlass::cast(current_klass())->class_loader());
-    Handle class_loader (THREAD, instanceKlass::cast(resolved_method->method_holder())->class_loader());
-    {
-      ResourceMark rm(THREAD);
-      char* failed_type_name =
-        SystemDictionary::check_signature_loaders(method_signature, loader,
-                                                  class_loader, true, CHECK);
-      if (failed_type_name != NULL) {
-        const char* msg = "loader constraint violation: when resolving "
-          "interface method \"%s\" the class loader (instance of %s) of the "
-          "current class, %s, and the class loader (instance of %s) for "
-          "resolved class, %s, have different Class objects for the type %s "
-          "used in the signature";
-        char* sig = methodOopDesc::name_and_sig_as_C_string(Klass::cast(resolved_klass()),method_name,method_signature);
-        const char* loader1 = SystemDictionary::loader_name(loader());
-        char* current = instanceKlass::cast(current_klass())->name()->as_C_string();
-        const char* loader2 = SystemDictionary::loader_name(class_loader());
-        char* resolved = instanceKlass::cast(resolved_klass())->name()->as_C_string();
-        size_t buflen = strlen(msg) + strlen(sig) + strlen(loader1) +
-          strlen(current) + strlen(loader2) + strlen(resolved) +
-          strlen(failed_type_name);
-        char* buf = NEW_RESOURCE_ARRAY_IN_THREAD(THREAD, char, buflen);
-        jio_snprintf(buf, buflen, msg, sig, loader1, current, loader2,
-                     resolved, failed_type_name);
-        THROW_MSG(vmSymbols::java_lang_LinkageError(), buf);
-      }
-    }
+    check_method_loader_constraints(resolved_method, resolved_klass, method_name,
+                                    method_signature, current_klass, "interface method", CHECK);
   }
 }
 
@@ -738,6 +724,10 @@
                   methodOopDesc::name_and_sig_as_C_string(Klass::cast(resolved_klass()),
                                             resolved_method->name(),
                                             resolved_method->signature()));
+      } else if (sel_method() != resolved_method()) {
+        check_method_loader_constraints(sel_method, resolved_klass,
+                                        sel_method->name(), sel_method->signature(),
+                                        current_klass, "method", CHECK);
       }
     }
   }
--- a/src/share/vm/interpreter/linkResolver.hpp	Wed Aug 30 15:42:01 2017 +0300
+++ b/src/share/vm/interpreter/linkResolver.hpp	Tue Aug 01 09:47:45 2017 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 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
@@ -121,6 +121,9 @@
   static void resolve_pool  (KlassHandle& resolved_klass, Symbol*& method_name, Symbol*& method_signature, KlassHandle& current_klass, constantPoolHandle pool, int index, TRAPS);
 
   static void resolve_interface_method(methodHandle& resolved_method, KlassHandle resolved_klass, Symbol* method_name, Symbol* method_signature, KlassHandle current_klass, bool check_access, TRAPS);
+  static void check_method_loader_constraints(methodHandle& resolved_method, KlassHandle resolved_klass,
+                                              Symbol* method_name, Symbol* method_signature,
+                                              KlassHandle current_klass, const char* method_type, TRAPS);
   static void resolve_method          (methodHandle& resolved_method, KlassHandle resolved_klass, Symbol* method_name, Symbol* method_signature, KlassHandle current_klass, bool check_access, TRAPS);
 
   static void linktime_resolve_static_method    (methodHandle& resolved_method, KlassHandle resolved_klass, Symbol* method_name, Symbol* method_signature, KlassHandle current_klass, bool check_access, TRAPS);