< prev index next >

src/hotspot/share/classfile/systemDictionary.cpp

Print this page

        

*** 72,82 **** #include "oops/typeArrayKlass.hpp" #include "prims/jvmtiExport.hpp" #include "prims/methodHandles.hpp" #include "runtime/arguments.hpp" #include "runtime/biasedLocking.hpp" - #include "runtime/fieldType.hpp" #include "runtime/handles.inline.hpp" #include "runtime/java.hpp" #include "runtime/javaCalls.hpp" #include "runtime/mutexLocker.hpp" #include "runtime/sharedRuntime.hpp" --- 72,81 ----
*** 238,248 **** // Forwards to resolve_array_class_or_null or resolve_instance_class_or_null Klass* SystemDictionary::resolve_or_null(Symbol* class_name, Handle class_loader, Handle protection_domain, TRAPS) { ! if (FieldType::is_array(class_name)) { return resolve_array_class_or_null(class_name, class_loader, protection_domain, THREAD); } else { return resolve_instance_class_or_null_helper(class_name, class_loader, protection_domain, THREAD); } } --- 237,247 ---- // Forwards to resolve_array_class_or_null or resolve_instance_class_or_null Klass* SystemDictionary::resolve_or_null(Symbol* class_name, Handle class_loader, Handle protection_domain, TRAPS) { ! if (Signature::is_array(class_name)) { return resolve_array_class_or_null(class_name, class_loader, protection_domain, THREAD); } else { return resolve_instance_class_or_null_helper(class_name, class_loader, protection_domain, THREAD); } }
*** 250,261 **** // name may be in the form of "java/lang/Object" or "Ljava/lang/Object;" InstanceKlass* SystemDictionary::resolve_instance_class_or_null_helper(Symbol* class_name, Handle class_loader, Handle protection_domain, TRAPS) { ! assert(class_name != NULL && !FieldType::is_array(class_name), "must be"); ! if (FieldType::is_obj(class_name)) { ResourceMark rm(THREAD); // Ignore wrapping L and ;. TempNewSymbol name = SymbolTable::new_symbol(class_name->as_C_string() + 1, class_name->utf8_length() - 2); return resolve_instance_class_or_null(name, class_loader, protection_domain, THREAD); --- 249,260 ---- // name may be in the form of "java/lang/Object" or "Ljava/lang/Object;" InstanceKlass* SystemDictionary::resolve_instance_class_or_null_helper(Symbol* class_name, Handle class_loader, Handle protection_domain, TRAPS) { ! assert(class_name != NULL && !Signature::is_array(class_name), "must be"); ! if (Signature::has_envelope(class_name)) { ResourceMark rm(THREAD); // Ignore wrapping L and ;. TempNewSymbol name = SymbolTable::new_symbol(class_name->as_C_string() + 1, class_name->utf8_length() - 2); return resolve_instance_class_or_null(name, class_loader, protection_domain, THREAD);
*** 272,299 **** Klass* SystemDictionary::resolve_array_class_or_null(Symbol* class_name, Handle class_loader, Handle protection_domain, TRAPS) { ! assert(FieldType::is_array(class_name), "must be array"); Klass* k = NULL; ! FieldArrayInfo fd; ! // dimension and object_key in FieldArrayInfo are assigned as a side-effect ! // of this call ! BasicType t = FieldType::get_array_info(class_name, fd, CHECK_NULL); ! if (t == T_OBJECT) { ! // naked oop "k" is OK here -- we assign back into it ! k = SystemDictionary::resolve_instance_class_or_null(fd.object_key(), class_loader, protection_domain, CHECK_NULL); if (k != NULL) { ! k = k->array_klass(fd.dimension(), CHECK_NULL); } } else { k = Universe::typeArrayKlassObj(t); ! k = TypeArrayKlass::cast(k)->array_klass(fd.dimension(), CHECK_NULL); } return k; } --- 271,298 ---- Klass* SystemDictionary::resolve_array_class_or_null(Symbol* class_name, Handle class_loader, Handle protection_domain, TRAPS) { ! assert(Signature::is_array(class_name), "must be array"); ! ResourceMark rm(THREAD); ! SignatureStream ss(class_name, false); ! int ndims = ss.skip_array_prefix(); // skip all '['s Klass* k = NULL; ! BasicType t = ss.type(); ! if (ss.has_envelope()) { ! Symbol* obj_class = ss.as_symbol(); ! k = SystemDictionary::resolve_instance_class_or_null(obj_class, class_loader, protection_domain, CHECK_NULL); if (k != NULL) { ! k = k->array_klass(ndims, CHECK_NULL); } } else { k = Universe::typeArrayKlassObj(t); ! k = TypeArrayKlass::cast(k)->array_klass(ndims, CHECK_NULL); } return k; }
*** 340,350 **** Symbol* super_name, Handle class_loader, Handle protection_domain, bool is_superclass, TRAPS) { ! assert(!FieldType::is_array(super_name), "invalid super class name"); #if INCLUDE_CDS if (DumpSharedSpaces) { // Special processing for handling UNREGISTERED shared classes. InstanceKlass* k = SystemDictionaryShared::dump_time_resolve_super_or_fail(child_name, super_name, class_loader, protection_domain, is_superclass, CHECK_NULL); --- 339,349 ---- Symbol* super_name, Handle class_loader, Handle protection_domain, bool is_superclass, TRAPS) { ! assert(!Signature::is_array(super_name), "invalid super class name"); #if INCLUDE_CDS if (DumpSharedSpaces) { // Special processing for handling UNREGISTERED shared classes. InstanceKlass* k = SystemDictionaryShared::dump_time_resolve_super_or_fail(child_name, super_name, class_loader, protection_domain, is_superclass, CHECK_NULL);
*** 652,663 **** // name must be in the form of "java/lang/Object" -- cannot be "Ljava/lang/Object;" InstanceKlass* SystemDictionary::resolve_instance_class_or_null(Symbol* name, Handle class_loader, Handle protection_domain, TRAPS) { ! assert(name != NULL && !FieldType::is_array(name) && ! !FieldType::is_obj(name), "invalid class name"); EventClassLoad class_load_start_event; HandleMark hm(THREAD); --- 651,662 ---- // name must be in the form of "java/lang/Object" -- cannot be "Ljava/lang/Object;" InstanceKlass* SystemDictionary::resolve_instance_class_or_null(Symbol* name, Handle class_loader, Handle protection_domain, TRAPS) { ! assert(name != NULL && !Signature::is_array(name) && ! !Signature::has_envelope(name), "invalid class name"); EventClassLoad class_load_start_event; HandleMark hm(THREAD);
*** 958,980 **** Handle protection_domain, TRAPS) { Klass* k = NULL; assert(class_name != NULL, "class name must be non NULL"); ! if (FieldType::is_array(class_name)) { // The name refers to an array. Parse the name. // dimension and object_key in FieldArrayInfo are assigned as a // side-effect of this call ! FieldArrayInfo fd; ! BasicType t = FieldType::get_array_info(class_name, fd, CHECK_(NULL)); if (t != T_OBJECT) { k = Universe::typeArrayKlassObj(t); } else { ! k = SystemDictionary::find(fd.object_key(), class_loader, protection_domain, THREAD); } if (k != NULL) { ! k = k->array_klass_or_null(fd.dimension()); } } else { k = find(class_name, class_loader, protection_domain, THREAD); } return k; --- 957,981 ---- Handle protection_domain, TRAPS) { Klass* k = NULL; assert(class_name != NULL, "class name must be non NULL"); ! if (Signature::is_array(class_name)) { // The name refers to an array. Parse the name. // dimension and object_key in FieldArrayInfo are assigned as a // side-effect of this call ! SignatureStream ss(class_name, false); ! int ndims = ss.skip_array_prefix(); // skip all '['s ! BasicType t = ss.type(); if (t != T_OBJECT) { k = Universe::typeArrayKlassObj(t); } else { ! Symbol* obj_class = ss.as_symbol(); ! k = SystemDictionary::find(obj_class, class_loader, protection_domain, THREAD); } if (k != NULL) { ! k = k->array_klass_or_null(ndims); } } else { k = find(class_name, class_loader, protection_domain, THREAD); } return k;
*** 2165,2188 **** return klass; // Now look to see if it has been loaded elsewhere, and is subject to // a loader constraint that would require this loader to return the // klass that is already loaded. ! if (FieldType::is_array(class_name)) { // For array classes, their Klass*s are not kept in the // constraint table. The element Klass*s are. ! FieldArrayInfo fd; ! BasicType t = FieldType::get_array_info(class_name, fd, CHECK_(NULL)); if (t != T_OBJECT) { klass = Universe::typeArrayKlassObj(t); } else { MutexLocker mu(THREAD, SystemDictionary_lock); ! klass = constraints()->find_constrained_klass(fd.object_key(), class_loader); } // If element class already loaded, allocate array klass if (klass != NULL) { ! klass = klass->array_klass_or_null(fd.dimension()); } } else { MutexLocker mu(THREAD, SystemDictionary_lock); // Non-array classes are easy: simply check the constraint table. klass = constraints()->find_constrained_klass(class_name, class_loader); --- 2166,2191 ---- return klass; // Now look to see if it has been loaded elsewhere, and is subject to // a loader constraint that would require this loader to return the // klass that is already loaded. ! if (Signature::is_array(class_name)) { // For array classes, their Klass*s are not kept in the // constraint table. The element Klass*s are. ! SignatureStream ss(class_name, false); ! int ndims = ss.skip_array_prefix(); // skip all '['s ! BasicType t = ss.type(); if (t != T_OBJECT) { klass = Universe::typeArrayKlassObj(t); } else { MutexLocker mu(THREAD, SystemDictionary_lock); ! Symbol* obj_class = ss.as_symbol(); ! klass = constraints()->find_constrained_klass(obj_class, class_loader); } // If element class already loaded, allocate array klass if (klass != NULL) { ! klass = klass->array_klass_or_null(ndims); } } else { MutexLocker mu(THREAD, SystemDictionary_lock); // Non-array classes are easy: simply check the constraint table. klass = constraints()->find_constrained_klass(class_name, class_loader);
*** 2198,2222 **** Thread* THREAD) { ClassLoaderData* loader_data1 = class_loader_data(class_loader1); ClassLoaderData* loader_data2 = class_loader_data(class_loader2); Symbol* constraint_name = NULL; ! // Needs to be in same scope as constraint_name in case a Symbol is created and ! // assigned to constraint_name. ! FieldArrayInfo fd; ! if (!FieldType::is_array(class_name)) { constraint_name = class_name; } else { // For array classes, their Klass*s are not kept in the // constraint table. The element classes are. ! BasicType t = FieldType::get_array_info(class_name, fd, CHECK_(false)); ! // primitive types always pass ! if (t != T_OBJECT) { ! return true; ! } else { ! constraint_name = fd.object_key(); ! } } Dictionary* dictionary1 = loader_data1->dictionary(); unsigned int d_hash1 = dictionary1->compute_hash(constraint_name); --- 2201,2226 ---- Thread* THREAD) { ClassLoaderData* loader_data1 = class_loader_data(class_loader1); ClassLoaderData* loader_data2 = class_loader_data(class_loader2); Symbol* constraint_name = NULL; ! ! if (!Signature::is_array(class_name)) { constraint_name = class_name; } else { // For array classes, their Klass*s are not kept in the // constraint table. The element classes are. ! SignatureStream ss(class_name, false); ! ss.skip_array_prefix(); // skip all '['s ! if (!ss.has_envelope()) { ! return true; // primitive types always pass ! } ! constraint_name = ss.as_symbol(); ! // Increment refcount to keep constraint_name alive after ! // SignatureStream is destructed. It will be decremented below ! // before returning. ! constraint_name->increment_refcount(); } Dictionary* dictionary1 = loader_data1->dictionary(); unsigned int d_hash1 = dictionary1->compute_hash(constraint_name);
*** 2225,2236 **** { MutexLocker mu_s(THREAD, SystemDictionary_lock); InstanceKlass* klass1 = find_class(d_hash1, constraint_name, dictionary1); InstanceKlass* klass2 = find_class(d_hash2, constraint_name, dictionary2); ! return constraints()->add_entry(constraint_name, klass1, class_loader1, klass2, class_loader2); } } // Add entry to resolution error table to record the error when the first // attempt to resolve a reference to a class has failed. --- 2229,2244 ---- { MutexLocker mu_s(THREAD, SystemDictionary_lock); InstanceKlass* klass1 = find_class(d_hash1, constraint_name, dictionary1); InstanceKlass* klass2 = find_class(d_hash2, constraint_name, dictionary2); ! bool result = constraints()->add_entry(constraint_name, klass1, class_loader1, klass2, class_loader2); + if (Signature::is_array(class_name)) { + constraint_name->decrement_refcount(); + } + return result; } } // Add entry to resolution error table to record the error when the first // attempt to resolve a reference to a class has failed.
*** 2323,2341 **** // Nothing to do if loaders are the same. if (loader1() == loader2()) { return NULL; } ! SignatureStream sig_strm(signature, is_method); ! while (!sig_strm.is_done()) { ! if (sig_strm.is_object()) { ! Symbol* sig = sig_strm.as_symbol(); if (!add_loader_constraint(sig, loader1, loader2, THREAD)) { return sig; } } - sig_strm.next(); } return NULL; } --- 2331,2350 ---- // Nothing to do if loaders are the same. if (loader1() == loader2()) { return NULL; } ! for (SignatureStream ss(signature, is_method); !ss.is_done(); ss.next()) { ! if (ss.is_reference()) { ! Symbol* sig = ss.as_symbol(); ! // Note: In the future, if template-like types can take ! // arguments, we will want to recognize them and dig out class ! // names hiding inside the argument lists. if (!add_loader_constraint(sig, loader1, loader2, THREAD)) { return sig; } } } return NULL; }
*** 2472,2489 **** return klass->is_public() && (InstanceKlass::cast(klass)->is_same_class_package(SystemDictionary::Object_klass()) || // java.lang InstanceKlass::cast(klass)->is_same_class_package(SystemDictionary::MethodHandle_klass())); // java.lang.invoke } - - // Return the Java mirror (java.lang.Class instance) for a single-character - // descriptor. This result, when available, is the same as produced by the - // heavier API point of the same name that takes a Symbol. - oop SystemDictionary::find_java_mirror_for_type(char signature_char) { - return java_lang_Class::primitive_mirror(char2type(signature_char)); - } - // Find or construct the Java mirror (java.lang.Class instance) for a // for the given field type signature, as interpreted relative to the // given class loader. Handles primitives, void, references, arrays, // and all other reflectable types, except method types. // N.B. Code in reflection should use this entry point. --- 2481,2490 ----
*** 2496,2531 **** Handle empty; assert(accessing_klass == NULL || (class_loader.is_null() && protection_domain.is_null()), "one or the other, or perhaps neither"); ! Symbol* type = signature; // What we have here must be a valid field descriptor, // and all valid field descriptors are supported. // Produce the same java.lang.Class that reflection reports. ! if (type->utf8_length() == 1) { // It's a primitive. (Void has a primitive mirror too.) ! char ch = type->char_at(0); ! assert(is_java_primitive(char2type(ch)) || ch == JVM_SIGNATURE_VOID, ""); ! return Handle(THREAD, find_java_mirror_for_type(ch)); ! } else if (FieldType::is_obj(type) || FieldType::is_array(type)) { // It's a reference type. if (accessing_klass != NULL) { class_loader = Handle(THREAD, accessing_klass->class_loader()); protection_domain = Handle(THREAD, accessing_klass->protection_domain()); } Klass* constant_type_klass; if (failure_mode == SignatureStream::ReturnNull) { ! constant_type_klass = resolve_or_null(type, class_loader, protection_domain, CHECK_(empty)); } else { bool throw_error = (failure_mode == SignatureStream::NCDFError); ! constant_type_klass = resolve_or_fail(type, class_loader, protection_domain, throw_error, CHECK_(empty)); } if (constant_type_klass == NULL) { return Handle(); // report failure this way } --- 2497,2530 ---- Handle empty; assert(accessing_klass == NULL || (class_loader.is_null() && protection_domain.is_null()), "one or the other, or perhaps neither"); ! SignatureStream ss(signature, false); // What we have here must be a valid field descriptor, // and all valid field descriptors are supported. // Produce the same java.lang.Class that reflection reports. ! if (ss.is_primitive() || (ss.type() == T_VOID)) { // It's a primitive. (Void has a primitive mirror too.) ! return Handle(THREAD, java_lang_Class::primitive_mirror(ss.type())); ! } else if (ss.is_reference()) { // It's a reference type. if (accessing_klass != NULL) { class_loader = Handle(THREAD, accessing_klass->class_loader()); protection_domain = Handle(THREAD, accessing_klass->protection_domain()); } Klass* constant_type_klass; if (failure_mode == SignatureStream::ReturnNull) { ! constant_type_klass = resolve_or_null(signature, class_loader, protection_domain, CHECK_(empty)); } else { bool throw_error = (failure_mode == SignatureStream::NCDFError); ! constant_type_klass = resolve_or_fail(signature, class_loader, protection_domain, throw_error, CHECK_(empty)); } if (constant_type_klass == NULL) { return Handle(); // report failure this way }
*** 2584,2594 **** oop mirror = NULL; if (can_be_cached) { // Use neutral class loader to lookup candidate classes to be placed in the cache. mirror = ss.as_java_mirror(Handle(), Handle(), SignatureStream::ReturnNull, CHECK_(empty)); ! if (mirror == NULL || (ss.is_object() && !is_always_visible_class(mirror))) { // Fall back to accessing_klass context. can_be_cached = false; } } if (!can_be_cached) { --- 2583,2593 ---- oop mirror = NULL; if (can_be_cached) { // Use neutral class loader to lookup candidate classes to be placed in the cache. mirror = ss.as_java_mirror(Handle(), Handle(), SignatureStream::ReturnNull, CHECK_(empty)); ! if (mirror == NULL || (ss.is_reference() && !is_always_visible_class(mirror))) { // Fall back to accessing_klass context. can_be_cached = false; } } if (!can_be_cached) {
< prev index next >