提交 8172591f 编写于 作者: A acorn

6626217: Fixed loader constraint array handling

Summary: Loader constraints track array elements, not arrays themselves.
Reviewed-by: dcubed, kevinw
上级 589c0d91
...@@ -375,30 +375,6 @@ ciKlass* ciEnv::get_klass_by_name_impl(ciKlass* accessing_klass, ...@@ -375,30 +375,6 @@ ciKlass* ciEnv::get_klass_by_name_impl(ciKlass* accessing_klass,
return get_object(found_klass)->as_klass(); 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; if (require_local) return NULL;
// Not yet loaded into the VM, or not governed by loader constraints. // Not yet loaded into the VM, or not governed by loader constraints.
// Make a CI representative for it. // Make a CI representative for it.
......
...@@ -334,33 +334,6 @@ klassOop LoaderConstraintTable::find_constrained_klass(symbolHandle name, ...@@ -334,33 +334,6 @@ klassOop LoaderConstraintTable::find_constrained_klass(symbolHandle name,
return NULL; 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( void LoaderConstraintTable::ensure_loader_constraint_capacity(
LoaderConstraintEntry *p, LoaderConstraintEntry *p,
int nfree) { int nfree) {
......
...@@ -66,9 +66,6 @@ public: ...@@ -66,9 +66,6 @@ public:
// bool is_method, TRAPS) // bool is_method, TRAPS)
klassOop find_constrained_klass(symbolHandle name, Handle loader); klassOop find_constrained_klass(symbolHandle name, Handle loader);
klassOop find_constrained_elem_klass(symbolHandle name, symbolHandle elem_name,
Handle loader, TRAPS);
// Class loader constraints // Class loader constraints
......
...@@ -2164,9 +2164,8 @@ klassOop SystemDictionary::find_constrained_instance_or_array_klass( ...@@ -2164,9 +2164,8 @@ klassOop SystemDictionary::find_constrained_instance_or_array_klass(
// a loader constraint that would require this loader to return the // a loader constraint that would require this loader to return the
// klass that is already loaded. // klass that is already loaded.
if (FieldType::is_array(class_name())) { if (FieldType::is_array(class_name())) {
// Array classes are hard because their klassOops are not kept in the // For array classes, their klassOops are not kept in the
// constraint table. The array klass may be constrained, but the elem class // constraint table. The element klassOops are.
// may not be.
jint dimension; jint dimension;
symbolOop object_key; symbolOop object_key;
BasicType t = FieldType::get_array_info(class_name(), &dimension, BasicType t = FieldType::get_array_info(class_name(), &dimension,
...@@ -2176,8 +2175,9 @@ klassOop SystemDictionary::find_constrained_instance_or_array_klass( ...@@ -2176,8 +2175,9 @@ klassOop SystemDictionary::find_constrained_instance_or_array_klass(
} else { } else {
symbolHandle elem_name(THREAD, object_key); symbolHandle elem_name(THREAD, object_key);
MutexLocker mu(SystemDictionary_lock, THREAD); 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) { if (klass != NULL) {
klass = Klass::cast(klass)->array_klass_or_null(dimension); klass = Klass::cast(klass)->array_klass_or_null(dimension);
} }
...@@ -2195,22 +2195,38 @@ bool SystemDictionary::add_loader_constraint(symbolHandle class_name, ...@@ -2195,22 +2195,38 @@ bool SystemDictionary::add_loader_constraint(symbolHandle class_name,
Handle class_loader1, Handle class_loader1,
Handle class_loader2, Handle class_loader2,
Thread* THREAD) { 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); 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); int d_index2 = dictionary()->hash_to_index(d_hash2);
{ {
MutexLocker mu_s(SystemDictionary_lock, THREAD); MutexLocker mu_s(SystemDictionary_lock, THREAD);
// Better never do a GC while we're holding these oops // Better never do a GC while we're holding these oops
No_Safepoint_Verifier nosafepoint; No_Safepoint_Verifier nosafepoint;
klassOop klass1 = find_class(d_index1, d_hash1, class_name, class_loader1); klassOop klass1 = find_class(d_index1, d_hash1, constraint_name, class_loader1);
klassOop klass2 = find_class(d_index2, d_hash2, class_name, class_loader2); klassOop klass2 = find_class(d_index2, d_hash2, constraint_name, class_loader2);
return constraints()->add_entry(class_name, klass1, class_loader1, return constraints()->add_entry(constraint_name, klass1, class_loader1,
klass2, class_loader2); klass2, class_loader2);
} }
} }
...@@ -2287,6 +2303,7 @@ symbolOop SystemDictionary::find_resolution_error(constantPoolHandle pool, int w ...@@ -2287,6 +2303,7 @@ symbolOop SystemDictionary::find_resolution_error(constantPoolHandle pool, int w
// Returns the name of the type that failed a loader constraint check, or // 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 // NULL if no constraint failed. The returned C string needs cleaning up
// with a ResourceMark in the caller. No exception except OOME is thrown. // 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, char* SystemDictionary::check_signature_loaders(symbolHandle signature,
Handle loader1, Handle loader2, Handle loader1, Handle loader2,
bool is_method, TRAPS) { bool is_method, TRAPS) {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册