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;