changeset 7813:ef26f9d82c61

Add module version and location support
author hseigel
date Thu, 12 Feb 2015 10:05:10 -0500
parents aaab3e55ae2f
children bdf226dac421
files src/share/vm/classfile/classLoader.cpp src/share/vm/classfile/moduleEntry.cpp src/share/vm/classfile/moduleEntry.hpp src/share/vm/classfile/modules.cpp src/share/vm/classfile/modules.hpp src/share/vm/prims/jvm.cpp src/share/vm/trace/tracetypes.xml
diffstat 7 files changed, 79 insertions(+), 20 deletions(-) [+]
line wrap: on
line diff
--- a/src/share/vm/classfile/classLoader.cpp	Tue Feb 10 15:17:12 2015 -0800
+++ b/src/share/vm/classfile/classLoader.cpp	Thu Feb 12 10:05:10 2015 -0500
@@ -502,10 +502,12 @@
   // Add entry, without a java.lang.reflect.Module object yet.
   // The j.l.r.m will be added later.
   ModuleEntry* jb_module = NULL;
+  TempNewSymbol version_symbol = SymbolTable::new_symbol(Modules::default_version(), THREAD);
+  assert(version_symbol != NULL, "Symbol creation failed");
   {
     MutexLocker ml(Module_lock, THREAD);
     jb_module = null_cld_modules->locked_create_entry_or_null(
-                  NULL, vmSymbols::java_base(), null_cld);
+                  NULL, vmSymbols::java_base(), version_symbol, NULL, null_cld);
     assert(jb_module != NULL, "no entry created for java.base");
   }
 
@@ -536,9 +538,11 @@
 
   // Add entry, without a java.lang.reflect.Module object yet.
   // The j.l.r.m will be added later.
+  TempNewSymbol version_symbol = SymbolTable::new_symbol(Modules::default_version(), THREAD);
+  assert(version_symbol != NULL, "Symbol creation failed");
   MutexLocker ml(Module_lock, THREAD);
   ModuleEntry* jb_module = null_cld_modules->locked_create_entry_or_null(
-                             NULL, vmSymbols::java_base(), null_cld);
+    NULL, vmSymbols::java_base(), version_symbol, NULL, null_cld);
   assert(jb_module != NULL, "no entry created for java.base");
 
   if (TraceClassLoading) {
--- a/src/share/vm/classfile/moduleEntry.cpp	Tue Feb 10 15:17:12 2015 -0800
+++ b/src/share/vm/classfile/moduleEntry.cpp	Thu Feb 12 10:05:10 2015 -0500
@@ -113,6 +113,10 @@
       // Clean out the C heap allocated reads list first before freeing the entry
       to_remove->delete_reads();
       to_remove->name()->decrement_refcount();
+      to_remove->version()->decrement_refcount();
+      if (to_remove->location() != NULL) {
+        to_remove->location()->decrement_refcount();
+      }
 
       // Unlink from the Hashtable prior to freeing
       unlink_entry(to_remove);
@@ -124,7 +128,9 @@
   free_buckets();
 }
 
-ModuleEntry* ModuleEntryTable::new_entry(unsigned int hash, oop module, Symbol* name, ClassLoaderData* class_loader) {
+ModuleEntry* ModuleEntryTable::new_entry(unsigned int hash, oop module, Symbol* name,
+                                         Symbol* version, Symbol* location,
+                                         ClassLoaderData* class_loader) {
   assert_locked_or_safepoint(Module_lock);
 
   ModuleEntry* entry = (ModuleEntry*) NEW_C_HEAP_ARRAY2(char, entry_size(), mtClass, CURRENT_PC);
@@ -139,6 +145,13 @@
   entry->set_name(name);
   name->increment_refcount();
   entry->set_loader(class_loader);
+  entry->set_version(version);
+  version->increment_refcount();
+  vmassert(entry->location() == NULL, "Unexpected value");
+  if (location != NULL) {
+    entry->set_location(location);
+    location->increment_refcount();
+  }
   TRACE_INIT_MODULE_ID(entry);
 
   return entry;
@@ -150,13 +163,16 @@
 }
 
 ModuleEntry* ModuleEntryTable::locked_create_entry_or_null(oop module, Symbol* module_name,
+                                                           Symbol *module_version,
+                                                           Symbol *module_location,
                                                            ClassLoaderData* loader) {
   assert_locked_or_safepoint(Module_lock);
   // Check if module already exists.
   if (lookup_only(module_name) != NULL) {
     return NULL;
   } else {
-    ModuleEntry* entry = new_entry(compute_hash(module), module, module_name, loader);
+    ModuleEntry* entry = new_entry(compute_hash(module), module, module_name,
+                                   module_version, module_location, loader);
     add_entry(index_for(module), entry);
     return entry;
   }
@@ -278,9 +294,10 @@
 
 void ModuleEntry::print() {
   ResourceMark rm;
-  tty->print_cr("entry "PTR_FORMAT" oop "PTR_FORMAT" name %s loader %s version %s pkgs_with_qexports %d next "PTR_FORMAT,
+  tty->print_cr("entry "PTR_FORMAT" oop "PTR_FORMAT" name %s loader %s version %s location %s pkgs_with_qexports %d next "PTR_FORMAT,
                 p2i(this), p2i(literal()), name()->as_C_string(), loader()->loader_name(),
-                version(), _pkgs_with_qexports, p2i(next()));
+                version()->as_C_string(), location() != NULL ? location()->as_C_string() : "NULL",
+                _pkgs_with_qexports, p2i(next()));
 }
 #endif
 
--- a/src/share/vm/classfile/moduleEntry.hpp	Tue Feb 10 15:17:12 2015 -0800
+++ b/src/share/vm/classfile/moduleEntry.hpp	Thu Feb 12 10:05:10 2015 -0500
@@ -50,7 +50,8 @@
   Symbol* _name;
   ClassLoaderData* _loader;
   GrowableArray<ModuleEntry*>* _reads; // list of modules that are readable by this module
-  char* _version;  // module version number
+  Symbol* _version;   // module version number
+  Symbol* _location;  // module location
   bool _pkgs_with_qexports; // this module contains 1 or more packages with qualified exports
   TRACE_DEFINE_TRACE_ID_FIELD;
 
@@ -59,7 +60,8 @@
     _name = NULL;
     _loader = NULL;
     _reads = NULL;
-    _version = (char *)"0";
+    _version = NULL;
+    _location = NULL;
     _pkgs_with_qexports = false;
   }
 
@@ -72,8 +74,11 @@
   ClassLoaderData*   loader() const                 { return _loader; }
   void               set_loader(ClassLoaderData* l) { _loader = l; }
 
-  char*              version()                      { return _version; }
-  void               set_version(char* version)     { _version = version; }
+  Symbol*            version() const                { return _version; }
+  void               set_version(Symbol* version)   { _version = version; }
+
+  Symbol*            location() const               { return _location; }
+  void               set_location(Symbol* location) { _location = location; }
 
   bool               can_read(ModuleEntry* m) const;
   bool               has_reads() const;
@@ -140,7 +145,8 @@
 private:
   static bool _javabase_created;
 
-  ModuleEntry* new_entry(unsigned int hash, oop module, Symbol* name, ClassLoaderData* class_loader);
+  ModuleEntry* new_entry(unsigned int hash, oop module, Symbol* name, Symbol* version,
+                         Symbol* location, ClassLoaderData* class_loader);
   void set_javabase_entry(oop m);
   void add_entry(int index, ModuleEntry* new_entry);
 
@@ -153,6 +159,8 @@
   // Create module in loader's module entry table, if already exists then
   // return null.  Assume Module_lock has been locked by caller.
   ModuleEntry* locked_create_entry_or_null(oop module, Symbol* module_name,
+                                           Symbol* module_version,
+                                           Symbol* module_location,
                                            ClassLoaderData* loader);
 
   // only lookup module within loader's module entry table
--- a/src/share/vm/classfile/modules.cpp	Tue Feb 10 15:17:12 2015 -0800
+++ b/src/share/vm/classfile/modules.cpp	Thu Feb 12 10:05:10 2015 -0500
@@ -175,7 +175,8 @@
   return package_entry_table->lookup_only(pkg_symbol);
 }
 
-jobject Modules::define_module(JNIEnv *env, jstring name, jobject loader, jobjectArray packages) {
+jobject Modules::define_module(JNIEnv *env, jstring name, jstring version, jstring location,
+                               jobject loader, jobjectArray packages) {
   JavaThread *THREAD = JavaThread::thread_from_jni_environment(env);
   ResourceMark rm(THREAD);
 
@@ -186,8 +187,17 @@
   char *module_name =
     java_lang_String::as_utf8_string(JNIHandles::resolve_non_null(name));
 
+  const char *module_version;
+  if (version == NULL) {
+    module_version = default_version();
+  } else {
+    module_version = java_lang_String::as_utf8_string(JNIHandles::resolve_non_null(version));
+    if (module_version == NULL) module_version = default_version();
+  }
+
   if (TraceModules) {
-    tty->print_cr("[define_module(): Start of definition processing for module %s]", module_name);
+    tty->print_cr("[define_module(): Start of definition processing for module %s, version: %s]",
+      module_name != NULL ? module_name : "NULL", module_version);
   }
 
   if (!verify_module_name(module_name)) {
@@ -277,18 +287,34 @@
     // Add the module and its packages.
     if (!dupl_modules && dupl_pkg_index == -1) {
       // Create the entry for this module in the class loader's module entry table.
+
+      // Create symbol* entry for module version.
+      TempNewSymbol version_symbol = SymbolTable::new_symbol(module_version, CHECK_NULL);
+
+      // Create symbol* entry for module location.
+      const char* module_location = NULL;
+      TempNewSymbol location_symbol = NULL;
+      if (location != NULL) {
+        module_location =
+          java_lang_String::as_utf8_string(JNIHandles::resolve_non_null(location));
+        if (module_location != NULL) {
+          location_symbol = SymbolTable::new_symbol(module_location, CHECK_NULL);
+        }
+      }
+
       ClassLoaderData* loader_data =
         ClassLoaderData::class_loader_data_or_null(h_loader());
       assert(loader_data != NULL, "class loader data shouldn't be null");
       ModuleEntry* module_entry =
         module_table->locked_create_entry_or_null(jlrM_handle(), module_symbol,
-          loader_data);
+          version_symbol, location_symbol, loader_data);
 
       if (module_entry == NULL) {
         dupl_modules = true;
       } else {
         if (TraceModules) {
-          tty->print("[define_module(): creation of module: %s, ", module_name);
+          tty->print("[define_module(): creation of module: %s, version: %s, location: %s, ",
+            module_name, module_version, module_location != NULL ? module_location : "NULL");
           loader_data->print_value();
           tty->print_cr(", package #: %d]", pkg_list->length());
         }
--- a/src/share/vm/classfile/modules.hpp	Tue Feb 10 15:17:12 2015 -0800
+++ b/src/share/vm/classfile/modules.hpp	Thu Feb 12 10:05:10 2015 -0500
@@ -37,7 +37,7 @@
   // module to its class loader by creating the ModuleEntry record in the
   // ClassLoader's ModuleEntry table, creates PackageEntry records in the class
   // loader's PackageEntry table, and, if successful, creates and returns a
-  // java.lang.reflect.Module object.As in JVM_DefineClass the jstring format
+  // java.lang.reflect.Module object.  As in JVM_DefineClass the jstring format
   // for all package names must use "/" and not "."
   //
   //  IllegalArgumentExceptions are thrown for the following :
@@ -49,7 +49,8 @@
   // * Packages contains a duplicate package name
   // * A package already exists in another module for this class loader
   // * Class loader is not a subclass of java.lang.ClassLoader
-  static jobject define_module(JNIEnv *env, jstring name, jobject loader, jobjectArray packages);
+  static jobject define_module(JNIEnv *env, jstring name, jstring version,
+                               jstring location, jobject loader, jobjectArray packages);
 
   // This either does a qualified export of package in module from_module to module
   // to_module or, if to_module is null, does an unqualified export of package.
@@ -106,6 +107,8 @@
   // Return TRUE iff package is defined by loader
   static bool is_package_defined(Symbol* package_name, Handle h_loader, TRAPS);
 
+  static const char* default_version() { return "9.0"; }
+
 };
 
 #endif // SHARE_VM_CLASSFILE_MODULES_HPP
--- a/src/share/vm/prims/jvm.cpp	Tue Feb 10 15:17:12 2015 -0800
+++ b/src/share/vm/prims/jvm.cpp	Thu Feb 12 10:05:10 2015 -0500
@@ -961,7 +961,7 @@
 JVM_ENTRY(jobject, JVM_DefineModule(JNIEnv *env, jstring name, jstring version, jstring location,
                                     jobject loader, jobjectArray packages))
   JVMWrapper("JVM_DefineModule");
-  return Modules::define_module(env, name, loader, packages);
+  return Modules::define_module(env, name, version, location, loader, packages);
 JVM_END
 
 JVM_ENTRY(void, JVM_AddModuleExports(JNIEnv *env, jobject from_module, jstring package, jobject to_module))
--- a/src/share/vm/trace/tracetypes.xml	Tue Feb 10 15:17:12 2015 -0800
+++ b/src/share/vm/trace/tracetypes.xml	Thu Feb 12 10:05:10 2015 -0500
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!--
- Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2012, 2015, 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
@@ -180,7 +180,8 @@
     <content_type id="Module" hr_name="Module"
               type="U8" jvm_type="MODULE">
       <value type="SYMBOL" field="name" label="Name"/>
-      <value type="UTF8" field="version" label="Version"/>
+      <value type="SYMBOL" field="version" label="Version"/>
+      <value type="SYMBOL" field="location" label="Location"/>
       <value type="CLASS" field="classLoader" label="ClassLoader"/>
     </content_type>