提交 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,
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.
......
......@@ -334,33 +334,6 @@ klassOop LoaderConstraintTable::find_constrained_klass(symbolHandle name,
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) {
......
......@@ -66,9 +66,6 @@ public:
// 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
......
......@@ -2164,9 +2164,8 @@ klassOop SystemDictionary::find_constrained_instance_or_array_klass(
// 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,
......@@ -2176,8 +2175,9 @@ klassOop SystemDictionary::find_constrained_instance_or_array_klass(
} 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);
}
......@@ -2195,22 +2195,38 @@ bool SystemDictionary::add_loader_constraint(symbolHandle class_name,
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);
MutexLocker mu_s(SystemDictionary_lock, THREAD);
// Better never do a GC while we're holding these oops
No_Safepoint_Verifier nosafepoint;
// 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,
klass2, class_loader2);
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);
}
}
......@@ -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
// 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) {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册