Mercurial > hg > release > icedtea7-forest-2.6 > hotspot
changeset 6652:56142fb6814b icedtea-2.6.14
Merge jdk7u181-b01
author | andrew |
---|---|
date | Thu, 17 May 2018 02:55:37 +0100 |
parents | 942409603ae4 (current diff) b98edfb9bd25 (diff) |
children | 592120da2a2b |
files | .hgtags src/share/vm/classfile/javaClasses.cpp src/share/vm/classfile/javaClasses.hpp src/share/vm/classfile/verifier.cpp src/share/vm/prims/jvm.cpp |
diffstat | 8 files changed, 202 insertions(+), 3 deletions(-) [+] |
line wrap: on
line diff
--- a/.hgtags Thu Apr 19 17:55:26 2018 +0100 +++ b/.hgtags Thu May 17 02:55:37 2018 +0100 @@ -920,3 +920,4 @@ f96baf6b460751580465a599ed2fba0c912e4bad icedtea-2.6.13 79d8447a461c7319969585c363649901b4c2773a icedtea-2.6.14pre01 205c34770f355f726055a716ecc8991dd3bbd8fd jdk7u181-b00 +6865c5a6ec36e80772ec47e14f7926b92053b551 jdk7u181-b01
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/vm/classfile/classLoaderDependencies.cpp Thu May 17 02:55:37 2018 +0100 @@ -0,0 +1,131 @@ +/* + * Copyright (c) 2018, Red Hat, Inc. and/or its affiliates. + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +#include "precompiled.hpp" +#include "classfile/classLoaderDependencies.hpp" +#include "classfile/javaClasses.hpp" +#include "memory/oopFactory.hpp" +#include "utilities/debug.hpp" + +void ClassLoaderDependencies::record_dependency(KlassHandle from_klass, + KlassHandle to_klass, + TRAPS) { + + oop to_class_loader_oop = to_klass->class_loader(); + + // Dependency to the Null Class Loader doesn't + // need to be recorded because it never goes away. + if (to_class_loader_oop == NULL) { + return; + } + + oop from_class_loader_oop = from_klass->class_loader(); + + // The Null Class Loader does not generate dependencies to record. + if (from_class_loader_oop == NULL) { + return; + } + + oop current_class_loader_oop = from_class_loader_oop; + do { + if (current_class_loader_oop == to_class_loader_oop) { + return; // This class loader is in the parent list, no need to add it. + } + current_class_loader_oop = java_lang_ClassLoader::parent(current_class_loader_oop); + } while (current_class_loader_oop != NULL); + + ClassLoaderDependencies::add(Handle(THREAD, from_class_loader_oop), + Handle(THREAD, to_class_loader_oop), + CHECK); +} + +void ClassLoaderDependencies::add(Handle from_class_loader_h, + Handle dependency, + TRAPS) { + + objArrayOop list_head = java_lang_ClassLoader::dependencies(from_class_loader_h()); + + // Check first if this dependency is already in the list. + // Save a pointer to the last to add to under the lock. + objArrayOop ok = list_head; + objArrayOop last = NULL; + while (ok != NULL) { + last = ok; + if (ok->obj_at(0) == dependency()) { + // Don't need to add it + return; + } + ok = (objArrayOop)ok->obj_at(1); + } + + // Must handle over GC points + assert (last != NULL, "dependencies should be initialized"); + objArrayHandle last_handle(THREAD, last); + + // Create a new dependency node with fields for (class_loader, next) + objArrayOop deps = oopFactory::new_objectArray(2, CHECK); + deps->obj_at_put(0, dependency()); + + // Must handle over GC points + objArrayHandle new_dependency(THREAD, deps); + + // Add the dependency under lock + ClassLoaderDependencies::locked_add(objArrayHandle(THREAD, list_head), + last_handle, + new_dependency, + THREAD); +} + +void ClassLoaderDependencies::locked_add(objArrayHandle list_head, + objArrayHandle last_handle, + objArrayHandle new_dependency, + Thread* THREAD) { + + // Have to lock and put the new dependency on the end of the dependency + // array so the card mark for CMS sees that this dependency is new. + // Can probably do this lock free with some effort. + ObjectLocker ol(list_head, THREAD); + + oop loader = new_dependency->obj_at(0); + + // Since the dependencies are only added, add to the end. + objArrayOop end = last_handle(); + objArrayOop last = NULL; + while (end != NULL) { + last = end; + // check again if another thread added it to the end. + if (end->obj_at(0) == loader) { + // Don't need to add it + return; + } + end = (objArrayOop)end->obj_at(1); + } + assert (last != NULL, "dependencies should be initialized"); + // fill in the first element with the oop in new_dependency. + if (last->obj_at(0) == NULL) { + last->obj_at_put(0, new_dependency->obj_at(0)); + } else { + last->obj_at_put(1, new_dependency()); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/vm/classfile/classLoaderDependencies.hpp Thu May 17 02:55:37 2018 +0100 @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2018, Red Hat, Inc. and/or its affiliates. + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +#ifndef SHARE_VM_CLASSFILE_CLASSLOADERDEPENDENCIES_HPP +#define SHARE_VM_CLASSFILE_CLASSLOADERDEPENDENCIES_HPP + +#include "runtime/handles.hpp" +#include "utilities/exceptions.hpp" + +class ClassLoaderDependencies { +public: + static void record_dependency(KlassHandle from_klass, KlassHandle to_klass, TRAPS); +private: + static void add(Handle from_class_loader_h, Handle dependency, TRAPS); + static void locked_add(objArrayHandle list_head, objArrayHandle last_handle, objArrayHandle new_dependency, TRAPS); +}; + +#endif // SHARE_VM_CLASSFILE_CLASSLOADERDEPENDENCIES_HPP
--- a/src/share/vm/classfile/javaClasses.cpp Thu Apr 19 17:55:26 2018 +0100 +++ b/src/share/vm/classfile/javaClasses.cpp Thu May 17 02:55:37 2018 +0100 @@ -2834,6 +2834,14 @@ return loader->obj_field(parent_offset); } +objArrayOop java_lang_ClassLoader::dependencies(oop loader) { + assert(is_instance(loader), "loader must be oop"); + oop dependencies = loader->obj_field(dependencies_offset); + assert(dependencies != NULL, "dependencies must be initialized"); + assert(dependencies->is_objArray(), "dependencies must be an array"); + return objArrayOop(dependencies); +} + bool java_lang_ClassLoader::isAncestor(oop loader, oop cl) { assert(is_instance(loader), "loader must be oop"); assert(cl == NULL || is_instance(cl), "cl argument must be oop"); @@ -2969,6 +2977,7 @@ int java_lang_ref_SoftReference::timestamp_offset; int java_lang_ref_SoftReference::static_clock_offset; int java_lang_ClassLoader::parent_offset; +int java_lang_ClassLoader::dependencies_offset; int java_lang_System::static_in_offset; int java_lang_System::static_out_offset; int java_lang_System::static_err_offset; @@ -3093,6 +3102,7 @@ // java_lang_ClassLoader java_lang_ClassLoader::parent_offset = java_lang_ClassLoader::hc_parent_offset * x + header; + java_lang_ClassLoader::dependencies_offset = java_lang_ClassLoader::hc_dependencies_offset * x + header; // java_lang_System java_lang_System::static_in_offset = java_lang_System::hc_static_in_offset * x;
--- a/src/share/vm/classfile/javaClasses.hpp Thu Apr 19 17:55:26 2018 +0100 +++ b/src/share/vm/classfile/javaClasses.hpp Thu May 17 02:55:37 2018 +0100 @@ -1179,17 +1179,20 @@ class java_lang_ClassLoader : AllStatic { private: enum { - hc_parent_offset = 0 + hc_parent_offset = 0, + hc_dependencies_offset = 1 }; static bool offsets_computed; static int parent_offset; static int parallelCapable_offset; + static int dependencies_offset; static void compute_offsets(); public: static oop parent(oop loader); + static objArrayOop dependencies(oop loader); static bool isAncestor(oop loader, oop cl); // Support for parallelCapable field
--- a/src/share/vm/classfile/verificationType.cpp Thu Apr 19 17:55:26 2018 +0100 +++ b/src/share/vm/classfile/verificationType.cpp Thu May 17 02:55:37 2018 +0100 @@ -23,6 +23,7 @@ */ #include "precompiled.hpp" +#include "classfile/classLoaderDependencies.hpp" #include "classfile/symbolTable.hpp" #include "classfile/verificationType.hpp" #include "classfile/verifier.hpp" @@ -62,6 +63,8 @@ Handle(THREAD, klass->protection_domain()), true, CHECK_false); KlassHandle this_class(THREAD, obj); + ClassLoaderDependencies::record_dependency(klass, this_class, CHECK_false); + if (this_class->is_interface()) { // We treat interfaces as java.lang.Object, including // java.lang.Cloneable and java.io.Serializable @@ -70,7 +73,9 @@ klassOop from_class = SystemDictionary::resolve_or_fail( from.name(), Handle(THREAD, klass->class_loader()), Handle(THREAD, klass->protection_domain()), true, CHECK_false); - return instanceKlass::cast(from_class)->is_subclass_of(this_class()); + KlassHandle from_class_handle(THREAD, from_class); + ClassLoaderDependencies::record_dependency(klass, from_class_handle, CHECK_false); + return instanceKlass::cast(from_class_handle())->is_subclass_of(this_class()); } } else if (is_array() && from.is_array()) { VerificationType comp_this = get_component(context, CHECK_false);
--- a/src/share/vm/classfile/verifier.cpp Thu Apr 19 17:55:26 2018 +0100 +++ b/src/share/vm/classfile/verifier.cpp Thu May 17 02:55:37 2018 +0100 @@ -24,6 +24,7 @@ #include "precompiled.hpp" #include "classfile/classFileStream.hpp" +#include "classfile/classLoaderDependencies.hpp" #include "classfile/javaClasses.hpp" #include "classfile/stackMapTable.hpp" #include "classfile/stackMapFrame.hpp" @@ -1946,9 +1947,11 @@ oop loader = current_class()->class_loader(); oop protection_domain = current_class()->protection_domain(); - return SystemDictionary::resolve_or_fail( + klassOop kls = SystemDictionary::resolve_or_fail( name, Handle(THREAD, loader), Handle(THREAD, protection_domain), true, CHECK_NULL); + ClassLoaderDependencies::record_dependency(current_class(), kls, CHECK_NULL); + return kls; } bool ClassVerifier::is_protected_access(instanceKlassHandle this_class,
--- a/src/share/vm/prims/jvm.cpp Thu Apr 19 17:55:26 2018 +0100 +++ b/src/share/vm/prims/jvm.cpp Thu May 17 02:55:37 2018 +0100 @@ -24,6 +24,7 @@ #include "precompiled.hpp" #include "classfile/classLoader.hpp" +#include "classfile/classLoaderDependencies.hpp" #include "classfile/javaAssertions.hpp" #include "classfile/javaClasses.hpp" #include "classfile/symbolTable.hpp" @@ -913,6 +914,12 @@ 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); + klassOop to_class = java_lang_Class::as_klassOop(mirror); + ClassLoaderDependencies::record_dependency(from_class, to_class, CHECK_NULL); + } + if (TraceClassResolution && result != NULL) { // this function is generally only used for class loading during verification. ResourceMark rm;