# HG changeset patch # User shade # Date 1547487275 -3600 # Mon Jan 14 18:34:35 2019 +0100 # Node ID 7e33acb841cfe28fdbc2f2d78d139361ee7ffc8f # Parent cf80666df79aea737a48fe250fa93d16c31c6567 8216307: StackTraceElement::fill_in can use existing Module name and version Reviewed-by: XXX diff --git a/src/hotspot/share/classfile/javaClasses.cpp b/src/hotspot/share/classfile/javaClasses.cpp --- a/src/hotspot/share/classfile/javaClasses.cpp +++ b/src/hotspot/share/classfile/javaClasses.cpp @@ -2594,11 +2594,20 @@ // Fill in module name and version ModuleEntry* module = holder->module(); if (module->is_named()) { - oop module_name = StringTable::intern(module->name(), CHECK); + oop module_name = java_lang_Module::name(module->module()); + assert(module_name != NULL, "module name is set"); java_lang_StackTraceElement::set_moduleName(element(), module_name); oop module_version; if (module->version() != NULL) { - module_version = StringTable::intern(module->version(), CHECK); + oop md = java_lang_Module::module_descriptor(module->module()); + assert(md != NULL, "module descriptor is set"); + oop mdv = java_lang_module_ModuleDescriptor::version(md); + if (mdv != NULL) { + module_version = java_lang_module_ModuleDescriptor_Version::version(mdv); + } else { + module_version = java_lang_module_ModuleDescriptor::raw_version(md); + } + assert(module_version != NULL, "module version string is set"); } else { module_version = NULL; } @@ -3103,6 +3112,7 @@ int java_lang_Module::loader_offset; int java_lang_Module::name_offset; +int java_lang_Module::module_descriptor_offset; int java_lang_Module::_module_entry_offset = -1; Handle java_lang_Module::create(Handle loader, Handle module_name, TRAPS) { @@ -3113,8 +3123,9 @@ } #define MODULE_FIELDS_DO(macro) \ - macro(loader_offset, k, vmSymbols::loader_name(), classloader_signature, false); \ - macro(name_offset, k, vmSymbols::name_name(), string_signature, false) + macro(loader_offset, k, vmSymbols::loader_name(), classloader_signature, false); \ + macro(name_offset, k, vmSymbols::name_name(), string_signature, false); \ + macro(module_descriptor_offset, k, vmSymbols::descriptor_name(), module_descriptor_signature, false); \ void java_lang_Module::compute_offsets() { InstanceKlass* k = SystemDictionary::Module_klass(); @@ -3149,6 +3160,12 @@ module->obj_field_put(name_offset, value); } +oop java_lang_Module::module_descriptor(oop module) { + assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem"); + assert(java_lang_Module::is_instance(module), "sanity"); + return module->obj_field(module_descriptor_offset); +} + ModuleEntry* java_lang_Module::module_entry(oop module) { assert(_module_entry_offset != -1, "Uninitialized module_entry_offset"); assert(module != NULL, "module can't be null"); @@ -3173,6 +3190,66 @@ module->address_field_put(_module_entry_offset, (address)module_entry); } +int java_lang_module_ModuleDescriptor::version_offset; +int java_lang_module_ModuleDescriptor::raw_version_offset; + +#define MODULE_DESCRIPTOR_FIELDS_DO(macro) \ + macro(version_offset, k, vmSymbols::version_name(), module_descriptor_version_signature, false); \ + macro(raw_version_offset, k, vmSymbols::raw_version_string_name(), string_signature, false); \ + +void java_lang_module_ModuleDescriptor::compute_offsets() { + InstanceKlass* k = SystemDictionary::ModuleDescriptor_klass(); + MODULE_DESCRIPTOR_FIELDS_DO(FIELD_COMPUTE_OFFSET); +} + +#if INCLUDE_CDS +void java_lang_module_ModuleDescriptor::serialize_offsets(SerializeClosure* f) { + MODULE_DESCRIPTOR_FIELDS_DO(FIELD_SERIALIZE_OFFSET); +} +#endif + +inline bool java_lang_module_ModuleDescriptor::is_instance(oop obj) { + return obj != NULL && obj->klass() == SystemDictionary::ModuleDescriptor_klass(); +} + +oop java_lang_module_ModuleDescriptor::version(oop module_descriptor) { + assert(java_lang_module_ModuleDescriptor::is_instance(module_descriptor), "sanity"); + assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem"); + return module_descriptor->obj_field(version_offset); +} + +oop java_lang_module_ModuleDescriptor::raw_version(oop module_descriptor) { + assert(java_lang_module_ModuleDescriptor::is_instance(module_descriptor), "sanity"); + assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem"); + return module_descriptor->obj_field(raw_version_offset); +} + +int java_lang_module_ModuleDescriptor_Version::version_offset; + +#define MODULE_DESCRIPTOR_VERSION_FIELDS_DO(macro) \ + macro(version_offset, k, vmSymbols::version_name(), string_signature, false); \ + +void java_lang_module_ModuleDescriptor_Version::compute_offsets() { + InstanceKlass* k = SystemDictionary::ModuleDescriptor_Version_klass(); + MODULE_DESCRIPTOR_VERSION_FIELDS_DO(FIELD_COMPUTE_OFFSET); +} + +#if INCLUDE_CDS +void java_lang_module_ModuleDescriptor_Version::serialize_offsets(SerializeClosure* f) { + MODULE_DESCRIPTOR_VERSION_FIELDS_DO(FIELD_SERIALIZE_OFFSET); +} +#endif + +inline bool java_lang_module_ModuleDescriptor_Version::is_instance(oop obj) { + return obj != NULL && obj->klass() == SystemDictionary::ModuleDescriptor_Version_klass(); +} + +oop java_lang_module_ModuleDescriptor_Version::version(oop module_descriptor_version) { + assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem"); + assert(java_lang_module_ModuleDescriptor_Version::is_instance(module_descriptor_version), "sanity"); + return module_descriptor_version->obj_field(version_offset); +} + Handle reflect_ConstantPool::create(TRAPS) { assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem"); InstanceKlass* k = SystemDictionary::reflect_ConstantPool_klass(); diff --git a/src/hotspot/share/classfile/javaClasses.hpp b/src/hotspot/share/classfile/javaClasses.hpp --- a/src/hotspot/share/classfile/javaClasses.hpp +++ b/src/hotspot/share/classfile/javaClasses.hpp @@ -78,6 +78,8 @@ f(reflect_UnsafeStaticFieldAccessorImpl) \ f(java_lang_reflect_Parameter) \ f(java_lang_Module) \ + f(java_lang_module_ModuleDescriptor) \ + f(java_lang_module_ModuleDescriptor_Version) \ f(java_lang_StackTraceElement) \ f(java_lang_StackFrameInfo) \ f(java_lang_LiveStackFrameInfo) \ @@ -775,6 +777,7 @@ private: static int loader_offset; static int name_offset; + static int module_descriptor_offset; static int _module_entry_offset; static void compute_offsets(); @@ -794,12 +797,50 @@ static oop name(oop module); static void set_name(oop module, oop value); + static oop module_descriptor(oop module); + static ModuleEntry* module_entry(oop module); static void set_module_entry(oop module, ModuleEntry* module_entry); friend class JavaClasses; }; +class java_lang_module_ModuleDescriptor { + private: + static int version_offset; + static int raw_version_offset; + static void compute_offsets(); + + public: + static void serialize_offsets(SerializeClosure* f) NOT_CDS_RETURN; + + // Testers + static bool is_instance(oop obj); + + // Accessors + static oop version(oop module_descriptor); + static oop raw_version(oop module_descriptor); + + friend class JavaClasses; +}; + +class java_lang_module_ModuleDescriptor_Version { + private: + static int version_offset; + static void compute_offsets(); + + public: + static void serialize_offsets(SerializeClosure* f) NOT_CDS_RETURN; + + // Testers + static bool is_instance(oop obj); + + // Accessors + static oop version(oop module_descriptor_version); + + friend class JavaClasses; +}; + // Interface to jdk.internal.reflect.ConstantPool objects class reflect_ConstantPool { private: diff --git a/src/hotspot/share/classfile/systemDictionary.hpp b/src/hotspot/share/classfile/systemDictionary.hpp --- a/src/hotspot/share/classfile/systemDictionary.hpp +++ b/src/hotspot/share/classfile/systemDictionary.hpp @@ -140,6 +140,8 @@ do_klass(ThreadGroup_klass, java_lang_ThreadGroup ) \ do_klass(Properties_klass, java_util_Properties ) \ do_klass(Module_klass, java_lang_Module ) \ + do_klass(ModuleDescriptor_klass, java_lang_module_ModuleDescriptor ) \ + do_klass(ModuleDescriptor_Version_klass, java_lang_module_ModuleDescriptor_Version ) \ do_klass(reflect_AccessibleObject_klass, java_lang_reflect_AccessibleObject ) \ do_klass(reflect_Field_klass, java_lang_reflect_Field ) \ do_klass(reflect_Parameter_klass, java_lang_reflect_Parameter ) \ diff --git a/src/hotspot/share/classfile/vmSymbols.hpp b/src/hotspot/share/classfile/vmSymbols.hpp --- a/src/hotspot/share/classfile/vmSymbols.hpp +++ b/src/hotspot/share/classfile/vmSymbols.hpp @@ -58,6 +58,8 @@ template(java_lang_Class, "java/lang/Class") \ template(java_lang_Package, "java/lang/Package") \ template(java_lang_Module, "java/lang/Module") \ + template(java_lang_module_ModuleDescriptor, "java/lang/module/ModuleDescriptor") \ + template(java_lang_module_ModuleDescriptor_Version, "java/lang/module/ModuleDescriptor$Version")\ template(java_lang_String, "java/lang/String") \ template(java_lang_StringLatin1, "java/lang/StringLatin1") \ template(java_lang_StringUTF16, "java/lang/StringUTF16") \ @@ -430,7 +432,9 @@ template(vmdependencies_name, "vmdependencies") \ template(last_cleanup_name, "last_cleanup") \ template(loader_name, "loader") \ + template(descriptor_name, "descriptor") \ template(getModule_name, "getModule") \ + template(raw_version_string_name, "rawVersionString") \ template(input_stream_void_signature, "(Ljava/io/InputStream;)V") \ template(input_stream_signature, "Ljava/io/InputStream;") \ template(print_stream_signature, "Ljava/io/PrintStream;") \ @@ -543,6 +547,8 @@ template(reference_signature, "Ljava/lang/ref/Reference;") \ template(executable_signature, "Ljava/lang/reflect/Executable;") \ template(module_signature, "Ljava/lang/Module;") \ + template(module_descriptor_signature, "Ljava/lang/module/ModuleDescriptor;") \ + template(module_descriptor_version_signature, "Ljava/lang/module/ModuleDescriptor$Version;") \ template(concurrenthashmap_signature, "Ljava/util/concurrent/ConcurrentHashMap;") \ template(String_StringBuilder_signature, "(Ljava/lang/String;)Ljava/lang/StringBuilder;") \ template(int_StringBuilder_signature, "(I)Ljava/lang/StringBuilder;") \ diff --git a/src/java.base/share/classes/java/lang/module/ModuleDescriptor.java b/src/java.base/share/classes/java/lang/module/ModuleDescriptor.java --- a/src/java.base/share/classes/java/lang/module/ModuleDescriptor.java +++ b/src/java.base/share/classes/java/lang/module/ModuleDescriptor.java @@ -1245,7 +1245,8 @@ Set packages, String mainClass) { - assert version == null || rawVersionString == null; + // Either one, and only one should be set. + assert ((version != null) ^ (rawVersionString != null)); this.name = name; this.version = version; this.rawVersionString = rawVersionString; diff --git a/test/hotspot/jtreg/runtime/modules/ExceptionModuleName.java b/test/hotspot/jtreg/runtime/modules/ExceptionModuleName.java new file mode 100644 --- /dev/null +++ b/test/hotspot/jtreg/runtime/modules/ExceptionModuleName.java @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2019, Red Hat, Inc. 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 + * 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. + */ + +/* + * @test + * @modules java.base/jdk.internal.misc + * @library /test/lib .. + * @compile pe/c.java + * @build sun.hotspot.WhiteBox + * @compile/module=java.base java/lang/ModuleHelper.java + * @run driver ClassFileInstaller sun.hotspot.WhiteBox + * sun.hotspot.WhiteBox$WhiteBoxPermission + * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI ExceptionModuleName + */ + +import static jdk.test.lib.Asserts.*; + +public class ExceptionModuleName { + + public static void main(String args[]) throws Throwable { + Object javaBaseModule = Class.forName("java.lang.Object").getModule(); + assertNotNull(javaBaseModule, "java.base Module should not be null"); + + ClassLoader cl = ExceptionModuleName.class.getClassLoader(); + + Object mod = ModuleHelper.ModuleObject("my_module", cl, new String[] { "pe" }); + assertNotNull(mod, "Module should not be null"); + ModuleHelper.DefineModule(mod, false, "9.0", "my_module/here", new String[] { "pe" }); + ModuleHelper.AddReadsModule(mod, javaBaseModule); + + ModuleHelper.AddModuleExportsToAll(mod, "pe"); + + Class c = Class.forName("pe.c"); + try { + c.newInstance(); + throw new RuntimeException("Failed to get ISE"); + } catch (IllegalStateException e) { + if (e.getMessage() == null || !e.getMessage().contains("Expected message")) { + throw new RuntimeException("Wrong message", e); + } + + StackTraceElement[] fs = e.getStackTrace(); + if (fs.length < 1) { + throw new RuntimeException("Wrong number of stack trace elements", e); + } + + StackTraceElement top = fs[0]; + if (!"pe.c.c(c.java:43)".equals(top.toString())) { + throw new RuntimeException("Wrong top frame", e); + } + } + } +} + diff --git a/test/hotspot/jtreg/runtime/modules/pe/c.java b/test/hotspot/jtreg/runtime/modules/pe/c.java new file mode 100644 --- /dev/null +++ b/test/hotspot/jtreg/runtime/modules/pe/c.java @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2019, Red Hat Inc. 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 + * 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. + */ + +package pe; + +public class c { + public c() throws Exception { + throw new IllegalStateException("Expected message"); + } +}