提交 93cefacc 编写于 作者: A acorn

6893504: LinkageError for bootstrap duplicate class definitions.

Reviewed-by: kamg, xlu
上级 6652bf0c
...@@ -99,6 +99,15 @@ bool SystemDictionary::is_parallelCapable(Handle class_loader) { ...@@ -99,6 +99,15 @@ bool SystemDictionary::is_parallelCapable(Handle class_loader) {
return java_lang_Class::parallelCapable(class_loader()); return java_lang_Class::parallelCapable(class_loader());
} }
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// ParallelDefineClass flag does not apply to bootclass loader
bool SystemDictionary::is_parallelDefine(Handle class_loader) {
if (class_loader.is_null()) return false;
if (AllowParallelDefineClass && java_lang_Class::parallelCapable(class_loader())) {
return true;
}
return false;
}
// ----------------------------------------------------------------------------
// Resolving of classes // Resolving of classes
// Forwards to resolve_or_null // Forwards to resolve_or_null
...@@ -724,13 +733,13 @@ klassOop SystemDictionary::resolve_instance_class_or_null(symbolHandle class_nam ...@@ -724,13 +733,13 @@ klassOop SystemDictionary::resolve_instance_class_or_null(symbolHandle class_nam
// Do actual loading // Do actual loading
k = load_instance_class(name, class_loader, THREAD); k = load_instance_class(name, class_loader, THREAD);
// For UnsyncloadClass and AllowParallelDefineClass only: // For UnsyncloadClass only
// If they got a linkageError, check if a parallel class load succeeded. // If they got a linkageError, check if a parallel class load succeeded.
// If it did, then for bytecode resolution the specification requires // If it did, then for bytecode resolution the specification requires
// that we return the same result we did for the other thread, i.e. the // that we return the same result we did for the other thread, i.e. the
// successfully loaded instanceKlass // successfully loaded instanceKlass
// Should not get here for classloaders that support parallelism // Should not get here for classloaders that support parallelism
// with the new cleaner mechanism // with the new cleaner mechanism, even with AllowParallelDefineClass
// Bootstrap goes through here to allow for an extra guarantee check // Bootstrap goes through here to allow for an extra guarantee check
if (UnsyncloadClass || (class_loader.is_null())) { if (UnsyncloadClass || (class_loader.is_null())) {
if (k.is_null() && HAS_PENDING_EXCEPTION if (k.is_null() && HAS_PENDING_EXCEPTION
...@@ -1483,14 +1492,17 @@ void SystemDictionary::define_instance_class(instanceKlassHandle k, TRAPS) { ...@@ -1483,14 +1492,17 @@ void SystemDictionary::define_instance_class(instanceKlassHandle k, TRAPS) {
} }
// Support parallel classloading // Support parallel classloading
// Initial implementation for bootstrap classloader // All parallel class loaders, including bootstrap classloader
// For custom class loaders that support parallel classloading, // lock a placeholder entry for this class/class_loader pair
// to allow parallel defines of different classes for this class loader
// With AllowParallelDefine flag==true, in case they do not synchronize around // With AllowParallelDefine flag==true, in case they do not synchronize around
// FindLoadedClass/DefineClass, calls, we check for parallel // FindLoadedClass/DefineClass, calls, we check for parallel
// loading for them, wait if a defineClass is in progress // loading for them, wait if a defineClass is in progress
// and return the initial requestor's results // and return the initial requestor's results
// This flag does not apply to the bootstrap classloader.
// With AllowParallelDefine flag==false, call through to define_instance_class // With AllowParallelDefine flag==false, call through to define_instance_class
// which will throw LinkageError: duplicate class definition. // which will throw LinkageError: duplicate class definition.
// False is the requested default.
// For better performance, the class loaders should synchronize // For better performance, the class loaders should synchronize
// findClass(), i.e. FindLoadedClass/DefineClassIfAbsent or they // findClass(), i.e. FindLoadedClass/DefineClassIfAbsent or they
// potentially waste time reading and parsing the bytestream. // potentially waste time reading and parsing the bytestream.
...@@ -1511,10 +1523,12 @@ instanceKlassHandle SystemDictionary::find_or_define_instance_class(symbolHandle ...@@ -1511,10 +1523,12 @@ instanceKlassHandle SystemDictionary::find_or_define_instance_class(symbolHandle
{ {
MutexLocker mu(SystemDictionary_lock, THREAD); MutexLocker mu(SystemDictionary_lock, THREAD);
// First check if class already defined // First check if class already defined
if (UnsyncloadClass || (is_parallelDefine(class_loader))) {
klassOop check = find_class(d_index, d_hash, name_h, class_loader); klassOop check = find_class(d_index, d_hash, name_h, class_loader);
if (check != NULL) { if (check != NULL) {
return(instanceKlassHandle(THREAD, check)); return(instanceKlassHandle(THREAD, check));
} }
}
// Acquire define token for this class/classloader // Acquire define token for this class/classloader
symbolHandle nullsymbolHandle; symbolHandle nullsymbolHandle;
...@@ -1529,7 +1543,7 @@ instanceKlassHandle SystemDictionary::find_or_define_instance_class(symbolHandle ...@@ -1529,7 +1543,7 @@ instanceKlassHandle SystemDictionary::find_or_define_instance_class(symbolHandle
// Only special cases allow parallel defines and can use other thread's results // Only special cases allow parallel defines and can use other thread's results
// Other cases fall through, and may run into duplicate defines // Other cases fall through, and may run into duplicate defines
// caught by finding an entry in the SystemDictionary // caught by finding an entry in the SystemDictionary
if ((UnsyncloadClass || AllowParallelDefineClass) && (probe->instanceKlass() != NULL)) { if ((UnsyncloadClass || is_parallelDefine(class_loader)) && (probe->instanceKlass() != NULL)) {
probe->remove_seen_thread(THREAD, PlaceholderTable::DEFINE_CLASS); probe->remove_seen_thread(THREAD, PlaceholderTable::DEFINE_CLASS);
placeholders()->find_and_remove(p_index, p_hash, name_h, class_loader, THREAD); placeholders()->find_and_remove(p_index, p_hash, name_h, class_loader, THREAD);
SystemDictionary_lock->notify_all(); SystemDictionary_lock->notify_all();
......
...@@ -578,6 +578,7 @@ private: ...@@ -578,6 +578,7 @@ private:
static Handle compute_loader_lock_object(Handle class_loader, TRAPS); static Handle compute_loader_lock_object(Handle class_loader, TRAPS);
static void check_loader_lock_contention(Handle loader_lock, TRAPS); static void check_loader_lock_contention(Handle loader_lock, TRAPS);
static bool is_parallelCapable(Handle class_loader); static bool is_parallelCapable(Handle class_loader);
static bool is_parallelDefine(Handle class_loader);
static klassOop find_shared_class(symbolHandle class_name); static klassOop find_shared_class(symbolHandle class_name);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册