diff -r c80f6ecb0bb3 -r 5f9eee6b383b hotspot/src/share/vm/classfile/javaClasses.cpp --- a/hotspot/src/share/vm/classfile/javaClasses.cpp Tue Mar 15 13:48:21 2016 -0700 +++ b/hotspot/src/share/vm/classfile/javaClasses.cpp Thu Mar 17 19:04:01 2016 +0000 @@ -24,7 +24,9 @@ #include "precompiled.hpp" #include "classfile/altHashing.hpp" +#include "classfile/classLoaderData.inline.hpp" #include "classfile/javaClasses.inline.hpp" +#include "classfile/moduleEntry.hpp" #include "classfile/stringTable.hpp" #include "classfile/vmSymbols.hpp" #include "code/debugInfo.hpp" @@ -768,7 +770,7 @@ } } } - create_mirror(k, Handle(NULL), Handle(NULL), CHECK); + create_mirror(k, Handle(NULL), Handle(NULL), Handle(NULL), CHECK); } void java_lang_Class::initialize_mirror_fields(KlassHandle k, @@ -789,7 +791,7 @@ } void java_lang_Class::create_mirror(KlassHandle k, Handle class_loader, - Handle protection_domain, TRAPS) { + Handle module, Handle protection_domain, TRAPS) { assert(k->java_mirror() == NULL, "should only assign mirror once"); // Use this moment of initialization to cache modifier_flags also, // to support Class.getModifiers(). Instance classes recalculate @@ -849,11 +851,25 @@ assert(class_loader() == k->class_loader(), "should be same"); set_class_loader(mirror(), class_loader()); + // set the module field in the java_lang_Class instance + // This may be null during bootstrap but will get fixed up later on. + set_module(mirror(), module()); + // Setup indirection from klass->mirror last // after any exceptions can happen during allocations. if (!k.is_null()) { k->set_java_mirror(mirror()); } + + // Keep list of classes needing java.base module fixup. + if (!ModuleEntryTable::javabase_defined()) { + if (fixup_module_field_list() == NULL) { + GrowableArray* list = + new (ResourceObj::C_HEAP, mtClass) GrowableArray(500, true); + set_fixup_module_field_list(list); + } + fixup_module_field_list()->push(k()); + } } else { if (fixup_mirror_list() == NULL) { GrowableArray* list = @@ -864,6 +880,10 @@ } } +void java_lang_Class::fixup_module_field(KlassHandle k, Handle module) { + assert(_module_offset != 0, "must have been computed already"); + java_lang_Class::set_module(k->java_mirror(), module()); +} int java_lang_Class::oop_size(oop java_class) { assert(_oop_size_offset != 0, "must be set"); @@ -931,6 +951,16 @@ return java_class->obj_field(_class_loader_offset); } +oop java_lang_Class::module(oop java_class) { + assert(_module_offset != 0, "must be set"); + return java_class->obj_field(_module_offset); +} + +void java_lang_Class::set_module(oop java_class, oop module) { + assert(_module_offset != 0, "must be set"); + java_class->obj_field_put(_module_offset, module); +} + oop java_lang_Class::create_basic_type_mirror(const char* basic_type_name, BasicType type, TRAPS) { // This should be improved by adding a field at the Java level or by // introducing a new VM klass (see comment in ClassFileParser) @@ -1116,6 +1146,10 @@ k, vmSymbols::componentType_name(), vmSymbols::class_signature()); + compute_offset(_module_offset, + k, vmSymbols::module_name(), + vmSymbols::module_signature()); + // Init lock is a C union with component_mirror. Only instanceKlass mirrors have // init_lock and only ArrayKlass mirrors have component_mirror. Since both are oops // GC treats them the same. @@ -1668,28 +1702,48 @@ buf_len += (int)strlen(source_file_name); } + char *module_name = NULL, *module_version = NULL; + ModuleEntry* module = holder->module(); + if (module->is_named()) { + module_name = module->name()->as_C_string(); + buf_len += (int)strlen(module_name); + if (module->version() != NULL) { + module_version = module->version()->as_C_string(); + buf_len += (int)strlen(module_version); + } + } + // Allocate temporary buffer with extra space for formatting and line number char* buf = NEW_RESOURCE_ARRAY(char, buf_len + 64); // Print stack trace line in buffer - sprintf(buf, "\tat %s.%s", klass_name, method_name); + sprintf(buf, "\tat %s.%s(", klass_name, method_name); + + // Print module information + if (module_name != NULL) { + if (module_version != NULL) { + sprintf(buf + (int)strlen(buf), "%s@%s/", module_name, module_version); + } else { + sprintf(buf + (int)strlen(buf), "%s/", module_name); + } + } if (!version_matches(method, version)) { - strcat(buf, "(Redefined)"); + strcat(buf, "Redefined)"); } else { int line_number = Backtrace::get_line_number(method, bci); if (line_number == -2) { - strcat(buf, "(Native Method)"); + strcat(buf, "Native Method)"); } else { if (source_file_name != NULL && (line_number != -1)) { // Sourcename and linenumber - sprintf(buf + (int)strlen(buf), "(%s:%d)", source_file_name, line_number); + sprintf(buf + (int)strlen(buf), "%s:%d)", source_file_name, line_number); } else if (source_file_name != NULL) { // Just sourcename - sprintf(buf + (int)strlen(buf), "(%s)", source_file_name); + sprintf(buf + (int)strlen(buf), "%s)", source_file_name); } else { // Neither sourcename nor linenumber - sprintf(buf + (int)strlen(buf), "(Unknown Source)"); + sprintf(buf + (int)strlen(buf), "Unknown Source)"); } nmethod* nm = method->code(); if (WizardMode && nm != NULL) { @@ -2094,6 +2148,20 @@ oop methodname = StringTable::intern(sym, CHECK_0); java_lang_StackTraceElement::set_methodName(element(), methodname); + // Fill in module name and version + ModuleEntry* module = holder->module(); + if (module->is_named()) { + oop module_name = StringTable::intern(module->name(), CHECK_0); + java_lang_StackTraceElement::set_moduleName(element(), module_name); + oop module_version; + if (module->version() != NULL) { + module_version = StringTable::intern(module->version(), CHECK_0); + } else { + module_version = NULL; + } + java_lang_StackTraceElement::set_moduleVersion(element(), module_version); + } + if (!version_matches(method, version)) { // The method was redefined, accurate line number information isn't available java_lang_StackTraceElement::set_fileName(element(), NULL); @@ -2753,6 +2821,80 @@ } +int java_lang_reflect_Module::loader_offset; +int java_lang_reflect_Module::name_offset; +int java_lang_reflect_Module::_module_entry_offset = -1; + +Handle java_lang_reflect_Module::create(Handle loader, Handle module_name, TRAPS) { + assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem"); + + Symbol* name = vmSymbols::java_lang_reflect_Module(); + Klass* k = SystemDictionary::resolve_or_fail(name, true, CHECK_NH); + instanceKlassHandle klass (THREAD, k); + + Handle jlrmh = klass->allocate_instance_handle(CHECK_NH); + JavaValue result(T_VOID); + JavaCalls::call_special(&result, jlrmh, KlassHandle(THREAD, klass()), + vmSymbols::object_initializer_name(), + vmSymbols::java_lang_reflect_module_init_signature(), + loader, module_name, CHECK_NH); + return jlrmh; +} + +void java_lang_reflect_Module::compute_offsets() { + Klass* k = SystemDictionary::reflect_Module_klass(); + if(NULL != k) { + compute_offset(loader_offset, k, vmSymbols::loader_name(), vmSymbols::classloader_signature()); + compute_offset(name_offset, k, vmSymbols::name_name(), vmSymbols::string_signature()); + MODULE_INJECTED_FIELDS(INJECTED_FIELD_COMPUTE_OFFSET); + } +} + + +oop java_lang_reflect_Module::loader(oop module) { + assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem"); + return module->obj_field(loader_offset); +} + +void java_lang_reflect_Module::set_loader(oop module, oop value) { + assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem"); + module->obj_field_put(loader_offset, value); +} + +oop java_lang_reflect_Module::name(oop module) { + assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem"); + return module->obj_field(name_offset); +} + +void java_lang_reflect_Module::set_name(oop module, oop value) { + assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem"); + module->obj_field_put(name_offset, value); +} + +ModuleEntry* java_lang_reflect_Module::module_entry(oop module, TRAPS) { + assert(_module_entry_offset != -1, "Uninitialized module_entry_offset"); + assert(module != NULL, "module can't be null"); + assert(module->is_oop(), "module must be oop"); + + ModuleEntry* module_entry = (ModuleEntry*)module->address_field(_module_entry_offset); + if (module_entry == NULL) { + // If the inject field containing the ModuleEntry* is null then return the + // class loader's unnamed module. + oop loader = java_lang_reflect_Module::loader(module); + Handle h_loader = Handle(THREAD, loader); + ClassLoaderData* loader_cld = SystemDictionary::register_loader(h_loader, CHECK_NULL); + return loader_cld->modules()->unnamed_module(); + } + return module_entry; +} + +void java_lang_reflect_Module::set_module_entry(oop module, ModuleEntry* module_entry) { + assert(_module_entry_offset != -1, "Uninitialized module_entry_offset"); + assert(module != NULL, "module can't be null"); + assert(module->is_oop(), "module must be oop"); + module->address_field_put(_module_entry_offset, (address)module_entry); +} + Handle sun_reflect_ConstantPool::create(TRAPS) { assert(Universe::is_fully_initialized(), "Need to find another solution to the reflection problem"); Klass* k = SystemDictionary::reflect_ConstantPool_klass(); @@ -3352,6 +3494,7 @@ bool java_lang_ClassLoader::offsets_computed = false; int java_lang_ClassLoader::_loader_data_offset = -1; int java_lang_ClassLoader::parallelCapable_offset = -1; +int java_lang_ClassLoader::unnamedModule_offset = -1; ClassLoaderData** java_lang_ClassLoader::loader_data_addr(oop loader) { assert(loader != NULL && loader->is_oop(), "loader must be oop"); @@ -3371,6 +3514,9 @@ compute_optional_offset(parallelCapable_offset, k1, vmSymbols::parallelCapable_name(), vmSymbols::concurrenthashmap_signature()); + compute_offset(unnamedModule_offset, + k1, vmSymbols::unnamedModule_name(), vmSymbols::module_signature()); + CLASSLOADER_INJECTED_FIELDS(INJECTED_FIELD_COMPUTE_OFFSET); } @@ -3438,6 +3584,10 @@ return loader; } +oop java_lang_ClassLoader::unnamedModule(oop loader) { + assert(is_instance(loader), "loader must be oop"); + return loader->obj_field(unnamedModule_offset); +} // Support for java_lang_System int java_lang_System::in_offset_in_bytes() { @@ -3470,11 +3620,13 @@ int java_lang_Class::_oop_size_offset; int java_lang_Class::_static_oop_field_count_offset; int java_lang_Class::_class_loader_offset; +int java_lang_Class::_module_offset; int java_lang_Class::_protection_domain_offset; int java_lang_Class::_component_mirror_offset; int java_lang_Class::_init_lock_offset; int java_lang_Class::_signers_offset; GrowableArray* java_lang_Class::_fixup_mirror_list = NULL; +GrowableArray* java_lang_Class::_fixup_module_field_list = NULL; int java_lang_Throwable::backtrace_offset; int java_lang_Throwable::detailMessage_offset; int java_lang_Throwable::cause_offset; @@ -3534,6 +3686,8 @@ int java_lang_StackTraceElement::methodName_offset; int java_lang_StackTraceElement::fileName_offset; int java_lang_StackTraceElement::lineNumber_offset; +int java_lang_StackTraceElement::moduleName_offset; +int java_lang_StackTraceElement::moduleVersion_offset; int java_lang_StackFrameInfo::_declaringClass_offset; int java_lang_StackFrameInfo::_memberName_offset; int java_lang_StackFrameInfo::_bci_offset; @@ -3575,6 +3729,14 @@ element->int_field_put(lineNumber_offset, value); } +void java_lang_StackTraceElement::set_moduleName(oop element, oop value) { + element->obj_field_put(moduleName_offset, value); +} + +void java_lang_StackTraceElement::set_moduleVersion(oop element, oop value) { + element->obj_field_put(moduleVersion_offset, value); +} + // Support for java_lang_StackFrameInfo void java_lang_StackFrameInfo::set_declaringClass(oop element, oop value) { element->obj_field_put(_declaringClass_offset, value); @@ -3713,6 +3875,8 @@ java_lang_System::static_security_offset = java_lang_System::hc_static_security_offset * x; // java_lang_StackTraceElement + java_lang_StackTraceElement::moduleName_offset = java_lang_StackTraceElement::hc_moduleName_offset * x + header; + java_lang_StackTraceElement::moduleVersion_offset = java_lang_StackTraceElement::hc_moduleVersion_offset * x + header; java_lang_StackTraceElement::declaringClass_offset = java_lang_StackTraceElement::hc_declaringClass_offset * x + header; java_lang_StackTraceElement::methodName_offset = java_lang_StackTraceElement::hc_methodName_offset * x + header; java_lang_StackTraceElement::fileName_offset = java_lang_StackTraceElement::hc_fileName_offset * x + header; @@ -3752,6 +3916,7 @@ sun_reflect_ConstantPool::compute_offsets(); sun_reflect_UnsafeStaticFieldAccessorImpl::compute_offsets(); java_lang_reflect_Parameter::compute_offsets(); + java_lang_reflect_Module::compute_offsets(); java_lang_StackFrameInfo::compute_offsets(); java_lang_LiveStackFrameInfo::compute_offsets(); @@ -3899,7 +4064,7 @@ // java.lang.ClassLoader - CHECK_OFFSET("java/lang/ClassLoader", java_lang_ClassLoader, parent, "Ljava/lang/ClassLoader;"); + CHECK_OFFSET("java/lang/ClassLoader", java_lang_ClassLoader, parent, "Ljava/lang/ClassLoader;"); // java.lang.System