# HG changeset patch # User acorn # Date 1270587499 25200 # Node ID 9ce102c4501acf295056f56f85a6cc7d3539ef35 # Parent 47fdd3e9a8d4423946dad35c165c15412cd5ee71 6626217: Fixed loader constraint array handling Summary: Loader constraints track array elements, not arrays themselves. Reviewed-by: dcubed, kevinw diff -r 47fdd3e9a8d4 -r 9ce102c4501a src/share/vm/ci/ciEnv.cpp --- a/src/share/vm/ci/ciEnv.cpp Thu Dec 03 14:26:53 2009 -0800 +++ b/src/share/vm/ci/ciEnv.cpp Tue Apr 06 13:58:19 2010 -0700 @@ -390,30 +390,6 @@ return get_object(found_klass)->as_klass(); } - // If we fail to find an array klass, look again for its element type. - // The element type may be available either locally or via constraints. - // In either case, if we can find the element type in the system dictionary, - // we must build an array type around it. The CI requires array klasses - // to be loaded if their element klasses are loaded, except when memory - // is exhausted. - if (sym->byte_at(0) == '[' && - (sym->byte_at(1) == '[' || sym->byte_at(1) == 'L')) { - // We have an unloaded array. - // Build it on the fly if the element class exists. - symbolOop elem_sym = oopFactory::new_symbol(sym->as_utf8()+1, - sym->utf8_length()-1, - KILL_COMPILE_ON_FATAL_(fail_type)); - // Get element ciKlass recursively. - ciKlass* elem_klass = - get_klass_by_name_impl(accessing_klass, - get_object(elem_sym)->as_symbol(), - require_local); - if (elem_klass != NULL && elem_klass->is_loaded()) { - // Now make an array for it - return ciObjArrayKlass::make_impl(elem_klass); - } - } - if (require_local) return NULL; // Not yet loaded into the VM, or not governed by loader constraints. // Make a CI representative for it. diff -r 47fdd3e9a8d4 -r 9ce102c4501a src/share/vm/classfile/loaderConstraints.cpp --- a/src/share/vm/classfile/loaderConstraints.cpp Thu Dec 03 14:26:53 2009 -0800 +++ b/src/share/vm/classfile/loaderConstraints.cpp Tue Apr 06 13:58:19 2010 -0700 @@ -1,5 +1,5 @@ /* - * Copyright 2003-2006 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2003-2010 Sun Microsystems, 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 @@ -334,33 +334,6 @@ return NULL; } - -klassOop LoaderConstraintTable::find_constrained_elem_klass(symbolHandle name, - symbolHandle elem_name, - Handle loader, - TRAPS) { - LoaderConstraintEntry *p = *(find_loader_constraint(name, loader)); - if (p != NULL) { - assert(p->klass() == NULL, "Expecting null array klass"); - - // The array name has a constraint, but it will not have a class. Check - // each loader for an associated elem - for (int i = 0; i < p->num_loaders(); i++) { - Handle no_protection_domain; - - klassOop k = SystemDictionary::find(elem_name, p->loader(i), no_protection_domain, THREAD); - if (k != NULL) { - // Return the first elem klass found. - return k; - } - } - } - - // No constraints, or else no klass loaded yet. - return NULL; -} - - void LoaderConstraintTable::ensure_loader_constraint_capacity( LoaderConstraintEntry *p, int nfree) { diff -r 47fdd3e9a8d4 -r 9ce102c4501a src/share/vm/classfile/loaderConstraints.hpp --- a/src/share/vm/classfile/loaderConstraints.hpp Thu Dec 03 14:26:53 2009 -0800 +++ b/src/share/vm/classfile/loaderConstraints.hpp Tue Apr 06 13:58:19 2010 -0700 @@ -1,5 +1,5 @@ /* - * Copyright 2003-2009 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2003-2010 Sun Microsystems, 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 @@ -66,9 +66,6 @@ // bool is_method, TRAPS) klassOop find_constrained_klass(symbolHandle name, Handle loader); - klassOop find_constrained_elem_klass(symbolHandle name, symbolHandle elem_name, - Handle loader, TRAPS); - // Class loader constraints diff -r 47fdd3e9a8d4 -r 9ce102c4501a src/share/vm/classfile/systemDictionary.cpp --- a/src/share/vm/classfile/systemDictionary.cpp Thu Dec 03 14:26:53 2009 -0800 +++ b/src/share/vm/classfile/systemDictionary.cpp Tue Apr 06 13:58:19 2010 -0700 @@ -1,5 +1,5 @@ /* - * Copyright 1997-2009 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 1997-2010 Sun Microsystems, 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 @@ -2178,9 +2178,8 @@ // a loader constraint that would require this loader to return the // klass that is already loaded. if (FieldType::is_array(class_name())) { - // Array classes are hard because their klassOops are not kept in the - // constraint table. The array klass may be constrained, but the elem class - // may not be. + // For array classes, their klassOops are not kept in the + // constraint table. The element klassOops are. jint dimension; symbolOop object_key; BasicType t = FieldType::get_array_info(class_name(), &dimension, @@ -2190,8 +2189,9 @@ } else { symbolHandle elem_name(THREAD, object_key); MutexLocker mu(SystemDictionary_lock, THREAD); - klass = constraints()->find_constrained_elem_klass(class_name, elem_name, class_loader, THREAD); + klass = constraints()->find_constrained_klass(elem_name, class_loader); } + // If element class already loaded, allocate array klass if (klass != NULL) { klass = Klass::cast(klass)->array_klass_or_null(dimension); } @@ -2209,21 +2209,38 @@ Handle class_loader1, Handle class_loader2, Thread* THREAD) { - unsigned int d_hash1 = dictionary()->compute_hash(class_name, class_loader1); + symbolHandle constraint_name; + if (!FieldType::is_array(class_name())) { + constraint_name = class_name; + } else { + // For array classes, their klassOops are not kept in the + // constraint table. The element classes are. + jint dimension; + symbolOop object_key; + BasicType t = FieldType::get_array_info(class_name(), &dimension, + &object_key, CHECK_(false)); + // primitive types always pass + if (t != T_OBJECT) { + return true; + } else { + constraint_name = symbolHandle(THREAD, object_key); + } + } + unsigned int d_hash1 = dictionary()->compute_hash(constraint_name, class_loader1); + int d_index1 = dictionary()->hash_to_index(d_hash1); - unsigned int d_hash2 = dictionary()->compute_hash(class_name, class_loader2); + unsigned int d_hash2 = dictionary()->compute_hash(constraint_name, class_loader2); int d_index2 = dictionary()->hash_to_index(d_hash2); - { MutexLocker mu_s(SystemDictionary_lock, THREAD); // Better never do a GC while we're holding these oops No_Safepoint_Verifier nosafepoint; - klassOop klass1 = find_class(d_index1, d_hash1, class_name, class_loader1); - klassOop klass2 = find_class(d_index2, d_hash2, class_name, class_loader2); - return constraints()->add_entry(class_name, klass1, class_loader1, + klassOop klass1 = find_class(d_index1, d_hash1, constraint_name, class_loader1); + klassOop klass2 = find_class(d_index2, d_hash2, constraint_name, class_loader2); + return constraints()->add_entry(constraint_name, klass1, class_loader1, klass2, class_loader2); } } @@ -2301,6 +2318,7 @@ // Returns the name of the type that failed a loader constraint check, or // NULL if no constraint failed. The returned C string needs cleaning up // with a ResourceMark in the caller. No exception except OOME is thrown. +// Arrays are not added to the loader constraint table, their elements are. char* SystemDictionary::check_signature_loaders(symbolHandle signature, Handle loader1, Handle loader2, bool is_method, TRAPS) {