Mercurial > hg > openjdk > jdk7u > hotspot
view src/share/vm/classfile/classLoaderDependencies.cpp @ 5860:e00eb0a88cae
8226318: Class Loader Dependencies improvements
Reviewed-by: adinn, andrew
author | mbalao |
---|---|
date | Tue, 18 Jun 2019 14:23:10 -0300 |
parents | e14a43e8767f |
children |
line wrap: on
line source
/* * Copyright (c) 2018, 2019, 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(oop from_class_loader, oop to_class_loader, TRAPS) { // Dependency to the Null Class Loader doesn't // need to be recorded because it never goes away. if (to_class_loader == NULL) { return; } // The Null Class Loader does not generate dependencies to record. if (from_class_loader == NULL) { return; } oop current_class_loader_oop = from_class_loader; do { if (current_class_loader_oop == to_class_loader) { 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), Handle(THREAD, to_class_loader), 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 head_handle(THREAD, list_head); 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(head_handle, 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()); } }