changeset 9278:c6d743401cc0

ProtectionDomain support for shared module classes from bootmodules.jimage.
author jiangli
date Fri, 02 Oct 2015 16:24:46 -0400
parents 4b35845dbbc6
children 16c18ec6764d
files src/share/vm/classfile/classLoader.cpp src/share/vm/classfile/classLoader.hpp src/share/vm/classfile/classLoaderData.cpp src/share/vm/classfile/classLoaderData.hpp src/share/vm/classfile/moduleEntry.cpp src/share/vm/classfile/moduleEntry.hpp src/share/vm/memory/filemap.hpp src/share/vm/runtime/jniHandles.cpp src/share/vm/runtime/jniHandles.hpp
diffstat 9 files changed, 53 insertions(+), 2 deletions(-) [+]
line wrap: on
line diff
--- a/src/share/vm/classfile/classLoader.cpp	Fri Oct 02 13:13:09 2015 +0100
+++ b/src/share/vm/classfile/classLoader.cpp	Fri Oct 02 16:24:46 2015 -0400
@@ -445,7 +445,7 @@
 #endif
 
 bool ClassPathImageEntry::is_jrt() {
-  return ClassLoader::string_ends_with(name(), BOOT_IMAGE_NAME);
+  return ClassLoader::is_jrt(name());
 }
 
 #if INCLUDE_CDS
--- a/src/share/vm/classfile/classLoader.hpp	Fri Oct 02 13:13:09 2015 +0100
+++ b/src/share/vm/classfile/classLoader.hpp	Fri Oct 02 16:24:46 2015 -0400
@@ -408,6 +408,8 @@
 
   static bool string_ends_with(const char* str, const char* str_to_find);
 
+  static bool is_jrt(const char* name) { return string_ends_with(name, BOOT_IMAGE_NAME); }
+
   static void initialize_module_loader_map(JImageFile* jimage);
 
   static jshort module_to_classloader(const char* module_name);
--- a/src/share/vm/classfile/classLoaderData.cpp	Fri Oct 02 13:13:09 2015 +0100
+++ b/src/share/vm/classfile/classLoaderData.cpp	Fri Oct 02 16:24:46 2015 -0400
@@ -499,6 +499,10 @@
   return handles()->allocate_handle(h());
 }
 
+void ClassLoaderData::remove_handle(jobject h) {
+  _handles->release_handle(h);
+}
+
 // Add this metadata pointer to be freed when it's safe.  This is only during
 // class unloading because Handles might point to this metadata field.
 void ClassLoaderData::add_to_deallocate_list(Metadata* m) {
--- a/src/share/vm/classfile/classLoaderData.hpp	Fri Oct 02 13:13:09 2015 +0100
+++ b/src/share/vm/classfile/classLoaderData.hpp	Fri Oct 02 16:24:46 2015 -0400
@@ -179,7 +179,8 @@
   volatile int _claimed;   // true if claimed, for example during GC traces.
                            // To avoid applying oop closure more than once.
                            // Has to be an int because we cas it.
-  JNIHandleBlock* _handles; // Handles to constant pool arrays
+  JNIHandleBlock* _handles; // Handles to constant pool arrays, Modules, etc, which
+                            // have the same life cycle of the corresponding ClassLoader.
 
   Klass* _klasses;         // The classes defined by the class loader.
   PackageEntryTable* _packages; // The packages defined by the class loader.
@@ -303,6 +304,7 @@
   const char* loader_name();
 
   jobject add_handle(Handle h);
+  void remove_handle(jobject h);
   void add_class(Klass* k);
   void remove_class(Klass* k);
   bool contains_klass(Klass* k);
--- a/src/share/vm/classfile/moduleEntry.cpp	Fri Oct 02 13:13:09 2015 +0100
+++ b/src/share/vm/classfile/moduleEntry.cpp	Fri Oct 02 16:24:46 2015 -0400
@@ -38,6 +38,22 @@
 
 ModuleEntry* ModuleEntryTable::_javabase_module = NULL;
 
+// Returns the shared ProtectionDomain
+Handle ModuleEntry::shared_protection_domain() {
+  return Handle(JNIHandles::resolve(_pd));
+}
+
+// Set the shared ProtectionDomain atomically
+void ModuleEntry::set_shared_protection_domain(ClassLoaderData *loader_data,
+                                               Handle pd_h) {
+  // Create a JNI handle for the shared ProtectionDomain and save it atomically.
+  // If someone beats us setting the _pd cache, the created JNI handle is destroyed.
+  jobject obj = loader_data->add_handle(pd_h);
+  if (Atomic::cmpxchg_ptr(obj, &_pd, NULL) != NULL) {
+    loader_data->remove_handle(obj);
+  }
+}
+
 // Returns true if this module can read module m
 bool ModuleEntry::can_read(ModuleEntry* m) const {
   assert(m != NULL, "No module to lookup in this module's reads list");
--- a/src/share/vm/classfile/moduleEntry.hpp	Fri Oct 02 13:13:09 2015 +0100
+++ b/src/share/vm/classfile/moduleEntry.hpp	Fri Oct 02 16:24:46 2015 -0400
@@ -50,6 +50,8 @@
 class ModuleEntry : public HashtableEntry<Symbol*, mtClass> {
 private:
   jobject _jlrM;                       // java.lang.reflect.Module
+  jobject _pd;                         // java.security.ProtectionDomain, cached
+                                       // for shared classes from this module
   ClassLoaderData* _loader;
   GrowableArray<ModuleEntry*>* _reads; // list of modules that are readable by this module
   Symbol* _version;                    // module version number
@@ -61,6 +63,7 @@
   void init() {
     _jlrM = NULL;
     _loader = NULL;
+    _pd = NULL;
     _reads = NULL;
     _version = NULL;
     _location = NULL;
@@ -73,6 +76,15 @@
   jobject            jlrM_module() const            { return _jlrM; }
   void               set_jlrM_module(jobject j)     { _jlrM = j; }
 
+  // The shared ProtectionDomain reference is set once the VM loads a shared class
+  // originated from the current Module. The referenced ProtectionDomain object is
+  // created by the ClassLoader when loading a class (shared or non-shared) from the
+  // Module for the first time. This ProtectionDomain object is used for all
+  // classes from the Module loaded by the same ClassLoader.
+  Handle             shared_protection_domain();
+  void               set_shared_protection_domain(ClassLoaderData *loader_data,
+                                                  Handle pd);
+
   ClassLoaderData*   loader() const                 { return _loader; }
   void               set_loader(ClassLoaderData* l) { _loader = l; }
 
--- a/src/share/vm/memory/filemap.hpp	Fri Oct 02 13:13:09 2015 +0100
+++ b/src/share/vm/memory/filemap.hpp	Fri Oct 02 16:24:46 2015 -0400
@@ -54,6 +54,10 @@
   bool is_dir() {
     return _filesize == -1;
   }
+
+  bool is_jrt() {
+    return ClassLoader::is_jrt(_name);
+  }
 };
 
 class FileMapInfo : public CHeapObj<mtInternal> {
--- a/src/share/vm/runtime/jniHandles.cpp	Fri Oct 02 13:13:09 2015 +0100
+++ b/src/share/vm/runtime/jniHandles.cpp	Fri Oct 02 16:24:46 2015 -0400
@@ -478,6 +478,14 @@
   return allocate_handle(obj);  // retry
 }
 
+void JNIHandleBlock::release_handle(jobject h) {
+  if (h != NULL) {
+    assert(chain_contains(h), "does not contain the JNI handle");
+    // Mark the handle as deleted, allocate will reuse it
+    *((oop*)h) = JNIHandles::deleted_handle();
+  }
+}
+
 
 void JNIHandleBlock::rebuild_free_list() {
   assert(_allocate_before_rebuild == 0 && _free_list == NULL, "just checking");
--- a/src/share/vm/runtime/jniHandles.hpp	Fri Oct 02 13:13:09 2015 +0100
+++ b/src/share/vm/runtime/jniHandles.hpp	Fri Oct 02 16:24:46 2015 -0400
@@ -138,6 +138,9 @@
   // Handle allocation
   jobject allocate_handle(oop obj);
 
+  // Release Handle
+  void release_handle(jobject);
+
   // Block allocation and block free list management
   static JNIHandleBlock* allocate_block(Thread* thread = NULL);
   static void release_block(JNIHandleBlock* block, Thread* thread = NULL);