< prev index next >

src/hotspot/share/oops/instanceKlass.cpp

Print this page

        

*** 326,335 **** --- 326,381 ---- } } return nest_host_k; } + + // Dynamic nest member support: set this class's nest host to the given class. + // This occurs as part of the class definition, as soon as the instanceKlass + // has been created and doesn't require further resolution. The code: + // lookup().defineClass(bytes_for_X, NESTMATE); + // results in: + // class_of_X.set_nest_host(lookup().lookupClass().getNestHost()) + // So we know that current class is "pristine" and its _nest_host must be NULL. + // We also know the "host" is a valid nest-host in the same package so we can + // assert some of those facts. + void InstanceKlass::set_nest_host(InstanceKlass* host, TRAPS) { + assert(host != NULL, "NULL nest host specified"); + assert(_nest_host == NULL, "current class has resolved nest-host"); + assert((host->_nest_host == NULL && host->_nest_host_index == 0) || + (host->_nest_host == host), "proposed host is not a valid nest-host"); + // Can't assert this as package is not set yet: + // assert(is_same_class_package(host), "proposed host is in wrong package"); + + const char * error_msg = NULL; + // There are two validity checks that have to be made: + // 1. The current class must not expect a statically defined nest-host + if (_nest_host_index == 0) { + // 2. The current class can't itself be a nest-host + if (_nest_members == NULL || + _nest_members == Universe::the_empty_short_array()) { + _nest_host = host; + return; + } + else { + error_msg = "the current class is already a nest-host"; + } + } + else { + error_msg = "the current class is already a member of a nest"; + } + + ResourceMark rm(THREAD); + Exceptions::fthrow(THREAD_AND_LOCATION, + vmSymbols::java_lang_ClassFormatError(), + "Type %s can not be a dynamic nest member of %s: %s", + this->external_name(), + host->external_name(), + error_msg + ); + } + // check if 'this' and k are nestmates (same nest_host), or k is our nest_host, // or we are k's nest_host - all of which is covered by comparing the two // resolved_nest_hosts bool InstanceKlass::has_nestmate_access_to(InstanceKlass* k, TRAPS) {
*** 367,377 **** InstanceKlass* InstanceKlass::allocate_instance_klass(const ClassFileParser& parser, TRAPS) { const int size = InstanceKlass::size(parser.vtable_size(), parser.itable_size(), nonstatic_oop_map_size(parser.total_oop_map_count()), parser.is_interface(), ! parser.is_unsafe_anonymous(), should_store_fingerprint(parser.is_unsafe_anonymous())); const Symbol* const class_name = parser.class_name(); assert(class_name != NULL, "invariant"); ClassLoaderData* loader_data = parser.loader_data(); --- 413,423 ---- InstanceKlass* InstanceKlass::allocate_instance_klass(const ClassFileParser& parser, TRAPS) { const int size = InstanceKlass::size(parser.vtable_size(), parser.itable_size(), nonstatic_oop_map_size(parser.total_oop_map_count()), parser.is_interface(), ! (parser.is_nonfindable() || parser.is_unsafe_anonymous()), should_store_fingerprint(parser.is_unsafe_anonymous())); const Symbol* const class_name = parser.class_name(); assert(class_name != NULL, "invariant"); ClassLoaderData* loader_data = parser.loader_data();
*** 439,448 **** --- 485,495 ---- _reference_type(parser.reference_type()) { set_vtable_length(parser.vtable_size()); set_kind(kind); set_access_flags(parser.access_flags()); + set_is_nonfindable(parser.is_nonfindable()); set_is_unsafe_anonymous(parser.is_unsafe_anonymous()); set_layout_helper(Klass::instance_layout_helper(parser.layout_size(), false)); assert(NULL == _methods, "underlying memory not zeroed?");
*** 2214,2236 **** } return true; } ! bool InstanceKlass::should_store_fingerprint(bool is_unsafe_anonymous) { #if INCLUDE_AOT // We store the fingerprint into the InstanceKlass only in the following 2 cases: if (CalculateClassFingerprint) { // (1) We are running AOT to generate a shared library. return true; } if (DumpSharedSpaces) { // (2) We are running -Xshare:dump to create a shared archive return true; } ! if (UseAOT && is_unsafe_anonymous) { ! // (3) We are using AOT code from a shared library and see an unsafe anonymous class return true; } #endif // In all other cases we might set the _misc_has_passed_fingerprint_check bit, --- 2261,2283 ---- } return true; } ! bool InstanceKlass::should_store_fingerprint(bool is_nonfindable) { #if INCLUDE_AOT // We store the fingerprint into the InstanceKlass only in the following 2 cases: if (CalculateClassFingerprint) { // (1) We are running AOT to generate a shared library. return true; } if (DumpSharedSpaces) { // (2) We are running -Xshare:dump to create a shared archive return true; } ! if (UseAOT && is_nonfindable) { ! // (3) We are using AOT code from a shared library and see a nonfindable or unsafe anonymous class return true; } #endif // In all other cases we might set the _misc_has_passed_fingerprint_check bit,
*** 2533,2542 **** --- 2580,2590 ---- } #endif // Decrement symbol reference counts associated with the unloaded class. if (_name != NULL) _name->decrement_refcount(); + // unreference array name derived from this class name (arrays of an unloaded // class can't be referenced anymore). if (_array_name != NULL) _array_name->decrement_refcount(); if (_source_debug_extension != NULL) FREE_C_HEAP_ARRAY(char, _source_debug_extension); }
*** 2619,2628 **** --- 2667,2695 ---- if (is_unsafe_anonymous()) { assert(unsafe_anonymous_host() != NULL, "unsafe anonymous class must have a host class"); return unsafe_anonymous_host()->module(); } + if (is_nonfindable() && + in_unnamed_package() && + class_loader_data()->is_shortlived()) { + // For a weak nonfindable class defined to an unnamed package, + // the short-lived CLD will not have an unnamed module created for it. + // Two choices to find the correct ModuleEntry: + // 1. If nonfindable class is within a nest, use nest host's module + // 2. Find the unnamed module off from the class loader + // For now option #2 is used since a nest host is not set until + // after the instance class is created in jvm_lookup_define_class(). + if (class_loader_data()->is_boot_class_loader_data()) { + return ClassLoaderData::the_null_class_loader_data()->unnamed_module(); + } else { + oop module = java_lang_ClassLoader::unnamedModule(class_loader_data()->class_loader()); + assert(java_lang_Module::is_instance(module), "Not an instance of java.lang.Module"); + return java_lang_Module::module_entry(module); + } + } + // Class is in a named package if (!in_unnamed_package()) { return _package_entry->module(); }
< prev index next >