changeset 5839:3e3da27b653d

8199226: Improve field accesses Reviewed-by: andrew
author mbalao
date Mon, 15 Oct 2018 02:47:40 +0100
parents ef476a2e3cc7
children a04d39804193
files src/share/vm/interpreter/linkResolver.cpp src/share/vm/interpreter/linkResolver.hpp src/share/vm/prims/methodHandles.cpp
diffstat 3 files changed, 40 insertions(+), 32 deletions(-) [+]
line wrap: on
line diff
--- a/src/share/vm/interpreter/linkResolver.cpp	Thu Aug 16 04:06:21 2018 +0100
+++ b/src/share/vm/interpreter/linkResolver.cpp	Mon Oct 15 02:47:40 2018 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2018, 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
@@ -582,6 +582,37 @@
   }
 }
 
+void LinkResolver::check_field_loader_constraints(KlassHandle ref_klass,
+                                                  KlassHandle sel_klass,
+                                                  Symbol* name,
+                                                  Symbol* sig, TRAPS) {
+  HandleMark hm(THREAD);
+  Handle ref_loader (THREAD, instanceKlass::cast(ref_klass())->class_loader());
+  Handle sel_loader (THREAD, instanceKlass::cast(sel_klass())->class_loader());
+  {
+    ResourceMark rm(THREAD);
+    char* failed_type_name =
+      SystemDictionary::check_signature_loaders(sig, ref_loader, sel_loader,
+                                                false, CHECK);
+    if (failed_type_name != NULL) {
+      const char* msg = "loader constraint violation: when resolving field"
+        " \"%s\" the class loader (instance of %s) of the referring class, "
+        "%s, and the class loader (instance of %s) for the field's resolved "
+        "type, %s, have different Class objects for that type";
+      char* field_name = name->as_C_string();
+      const char* loader1 = SystemDictionary::loader_name(ref_loader());
+      char* sel = instanceKlass::cast(sel_klass())->name()->as_C_string();
+      const char* loader2 = SystemDictionary::loader_name(sel_loader());
+      size_t buflen = strlen(msg) + strlen(field_name) + strlen(loader1) +
+        strlen(sel) + strlen(loader2) + strlen(failed_type_name);
+      char* buf = NEW_RESOURCE_ARRAY_IN_THREAD(THREAD, char, buflen);
+      jio_snprintf(buf, buflen, msg, field_name, loader1, sel, loader2,
+                   failed_type_name);
+      THROW_MSG(vmSymbols::java_lang_LinkageError(), buf);
+    }
+  }
+}
+
 void LinkResolver::resolve_field(FieldAccessInfo& result, constantPoolHandle pool, int index, Bytecodes::Code byte, bool check_only, TRAPS) {
   resolve_field(result, pool, index, byte, check_only, true, CHECK);
 }
@@ -644,37 +675,7 @@
   if (is_static && !check_only) {
     sel_klass->initialize(CHECK);
   }
-
-  {
-    HandleMark hm(THREAD);
-    Handle ref_loader (THREAD, instanceKlass::cast(ref_klass())->class_loader());
-    Handle sel_loader (THREAD, instanceKlass::cast(sel_klass())->class_loader());
-    Symbol*  signature_ref  = pool->signature_ref_at(index);
-    {
-      ResourceMark rm(THREAD);
-      char* failed_type_name =
-        SystemDictionary::check_signature_loaders(signature_ref,
-                                                  ref_loader, sel_loader,
-                                                  false,
-                                                  CHECK);
-      if (failed_type_name != NULL) {
-        const char* msg = "loader constraint violation: when resolving field"
-          " \"%s\" the class loader (instance of %s) of the referring class, "
-          "%s, and the class loader (instance of %s) for the field's resolved "
-          "type, %s, have different Class objects for that type";
-        char* field_name = field->as_C_string();
-        const char* loader1 = SystemDictionary::loader_name(ref_loader());
-        char* sel = instanceKlass::cast(sel_klass())->name()->as_C_string();
-        const char* loader2 = SystemDictionary::loader_name(sel_loader());
-        size_t buflen = strlen(msg) + strlen(field_name) + strlen(loader1) +
-          strlen(sel) + strlen(loader2) + strlen(failed_type_name);
-        char* buf = NEW_RESOURCE_ARRAY_IN_THREAD(THREAD, char, buflen);
-        jio_snprintf(buf, buflen, msg, field_name, loader1, sel, loader2,
-                     failed_type_name);
-        THROW_MSG(vmSymbols::java_lang_LinkageError(), buf);
-      }
-    }
-  }
+  LinkResolver::check_field_loader_constraints(ref_klass, sel_klass, field, sig, CHECK);
 
   // return information. note that the klass is set to the actual klass containing the
   // field, otherwise access of static fields in superclasses will not work.
--- a/src/share/vm/interpreter/linkResolver.hpp	Thu Aug 16 04:06:21 2018 +0100
+++ b/src/share/vm/interpreter/linkResolver.hpp	Mon Oct 15 02:47:40 2018 +0100
@@ -188,6 +188,7 @@
   static void resolve_invokehandle   (CallInfo& result,              constantPoolHandle pool, int index, TRAPS);
 
   static void resolve_invoke         (CallInfo& result, Handle recv, constantPoolHandle pool, int index, Bytecodes::Code byte, TRAPS);
+  static void check_field_loader_constraints(KlassHandle ref_klass, KlassHandle sel_klass, Symbol* name, Symbol* sig, TRAPS);
 };
 
 #endif // SHARE_VM_INTERPRETER_LINKRESOLVER_HPP
--- a/src/share/vm/prims/methodHandles.cpp	Thu Aug 16 04:06:21 2018 +0100
+++ b/src/share/vm/prims/methodHandles.cpp	Mon Oct 15 02:47:40 2018 +0100
@@ -767,6 +767,12 @@
       KlassHandle sel_klass(THREAD, instanceKlass::cast(defc())->find_field(name, type, &fd));
       // check if field exists; i.e., if a klass containing the field def has been selected
       if (sel_klass.is_null())  return empty;  // should not happen
+      if (sel_klass() != caller() && caller.not_null()) {
+          LinkResolver::check_field_loader_constraints(caller, sel_klass, name, type, THREAD);
+          if (HAS_PENDING_EXCEPTION) {
+            return empty;
+          }
+      }
       oop type = field_signature_type_or_null(fd.signature());
       oop name = field_name_or_null(fd.name());
       bool is_setter = (ref_kind_is_valid(ref_kind) && ref_kind_is_setter(ref_kind));