Mercurial > hg > openjdk > jdk7u > hotspot
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));