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()) { |