comparison src/share/vm/classfile/systemDictionary.cpp @ 1336:0c3f888b7636

6626217: Fixed loader constraint array handling Summary: Loader constraints track array elements, not arrays themselves. Reviewed-by: dcubed, kevinw
author acorn
date Tue, 19 Jan 2010 16:03:09 -0500
parents 987e948ebbc8
children 09ac706c2623
comparison
equal deleted inserted replaced
1334:b5d78a3b8843 1336:0c3f888b7636
2162 2162
2163 // Now look to see if it has been loaded elsewhere, and is subject to 2163 // Now look to see if it has been loaded elsewhere, and is subject to
2164 // a loader constraint that would require this loader to return the 2164 // a loader constraint that would require this loader to return the
2165 // klass that is already loaded. 2165 // klass that is already loaded.
2166 if (FieldType::is_array(class_name())) { 2166 if (FieldType::is_array(class_name())) {
2167 // Array classes are hard because their klassOops are not kept in the 2167 // For array classes, their klassOops are not kept in the
2168 // constraint table. The array klass may be constrained, but the elem class 2168 // constraint table. The element klassOops are.
2169 // may not be.
2170 jint dimension; 2169 jint dimension;
2171 symbolOop object_key; 2170 symbolOop object_key;
2172 BasicType t = FieldType::get_array_info(class_name(), &dimension, 2171 BasicType t = FieldType::get_array_info(class_name(), &dimension,
2173 &object_key, CHECK_(NULL)); 2172 &object_key, CHECK_(NULL));
2174 if (t != T_OBJECT) { 2173 if (t != T_OBJECT) {
2175 klass = Universe::typeArrayKlassObj(t); 2174 klass = Universe::typeArrayKlassObj(t);
2176 } else { 2175 } else {
2177 symbolHandle elem_name(THREAD, object_key); 2176 symbolHandle elem_name(THREAD, object_key);
2178 MutexLocker mu(SystemDictionary_lock, THREAD); 2177 MutexLocker mu(SystemDictionary_lock, THREAD);
2179 klass = constraints()->find_constrained_elem_klass(class_name, elem_name, class_loader, THREAD); 2178 klass = constraints()->find_constrained_klass(elem_name, class_loader);
2180 } 2179 }
2180 // If element class already loaded, allocate array klass
2181 if (klass != NULL) { 2181 if (klass != NULL) {
2182 klass = Klass::cast(klass)->array_klass_or_null(dimension); 2182 klass = Klass::cast(klass)->array_klass_or_null(dimension);
2183 } 2183 }
2184 } else { 2184 } else {
2185 MutexLocker mu(SystemDictionary_lock, THREAD); 2185 MutexLocker mu(SystemDictionary_lock, THREAD);
2193 2193
2194 bool SystemDictionary::add_loader_constraint(symbolHandle class_name, 2194 bool SystemDictionary::add_loader_constraint(symbolHandle class_name,
2195 Handle class_loader1, 2195 Handle class_loader1,
2196 Handle class_loader2, 2196 Handle class_loader2,
2197 Thread* THREAD) { 2197 Thread* THREAD) {
2198 unsigned int d_hash1 = dictionary()->compute_hash(class_name, class_loader1); 2198 symbolHandle constraint_name;
2199 if (!FieldType::is_array(class_name())) {
2200 constraint_name = class_name;
2201 } else {
2202 // For array classes, their klassOops are not kept in the
2203 // constraint table. The element classes are.
2204 jint dimension;
2205 symbolOop object_key;
2206 BasicType t = FieldType::get_array_info(class_name(), &dimension,
2207 &object_key, CHECK_(false));
2208 // primitive types always pass
2209 if (t != T_OBJECT) {
2210 return true;
2211 } else {
2212 constraint_name = symbolHandle(THREAD, object_key);
2213 }
2214 }
2215 unsigned int d_hash1 = dictionary()->compute_hash(constraint_name, class_loader1);
2199 int d_index1 = dictionary()->hash_to_index(d_hash1); 2216 int d_index1 = dictionary()->hash_to_index(d_hash1);
2200 2217
2201 unsigned int d_hash2 = dictionary()->compute_hash(class_name, class_loader2); 2218 unsigned int d_hash2 = dictionary()->compute_hash(constraint_name, class_loader2);
2202 int d_index2 = dictionary()->hash_to_index(d_hash2); 2219 int d_index2 = dictionary()->hash_to_index(d_hash2);
2203
2204 { 2220 {
2205 MutexLocker mu_s(SystemDictionary_lock, THREAD); 2221 MutexLocker mu_s(SystemDictionary_lock, THREAD);
2206 2222
2207 // Better never do a GC while we're holding these oops 2223 // Better never do a GC while we're holding these oops
2208 No_Safepoint_Verifier nosafepoint; 2224 No_Safepoint_Verifier nosafepoint;
2209 2225
2210 klassOop klass1 = find_class(d_index1, d_hash1, class_name, class_loader1); 2226 klassOop klass1 = find_class(d_index1, d_hash1, constraint_name, class_loader1);
2211 klassOop klass2 = find_class(d_index2, d_hash2, class_name, class_loader2); 2227 klassOop klass2 = find_class(d_index2, d_hash2, constraint_name, class_loader2);
2212 return constraints()->add_entry(class_name, klass1, class_loader1, 2228 return constraints()->add_entry(constraint_name, klass1, class_loader1,
2213 klass2, class_loader2); 2229 klass2, class_loader2);
2214 } 2230 }
2215 } 2231 }
2216 2232
2217 // Add entry to resolution error table to record the error when the first 2233 // Add entry to resolution error table to record the error when the first
2218 // attempt to resolve a reference to a class has failed. 2234 // attempt to resolve a reference to a class has failed.
2285 // Make sure all class components (including arrays) in the given 2301 // Make sure all class components (including arrays) in the given
2286 // signature will be resolved to the same class in both loaders. 2302 // signature will be resolved to the same class in both loaders.
2287 // Returns the name of the type that failed a loader constraint check, or 2303 // Returns the name of the type that failed a loader constraint check, or
2288 // NULL if no constraint failed. The returned C string needs cleaning up 2304 // NULL if no constraint failed. The returned C string needs cleaning up
2289 // with a ResourceMark in the caller. No exception except OOME is thrown. 2305 // with a ResourceMark in the caller. No exception except OOME is thrown.
2306 // Arrays are not added to the loader constraint table, their elements are.
2290 char* SystemDictionary::check_signature_loaders(symbolHandle signature, 2307 char* SystemDictionary::check_signature_loaders(symbolHandle signature,
2291 Handle loader1, Handle loader2, 2308 Handle loader1, Handle loader2,
2292 bool is_method, TRAPS) { 2309 bool is_method, TRAPS) {
2293 // Nothing to do if loaders are the same. 2310 // Nothing to do if loaders are the same.
2294 if (loader1() == loader2()) { 2311 if (loader1() == loader2()) {