# HG changeset patch # User kamg # Date 1259157822 18000 # Node ID e1fb452ad9498d6e6f299145d1a9856f10d358dc # Parent de44705e6b336c220f461250d48b87b203f7ced8# Parent 1920bd911283807fdd4273ab8df06eb5577288cb Merge diff -r de44705e6b33 -r e1fb452ad949 src/share/vm/classfile/systemDictionary.cpp --- a/src/share/vm/classfile/systemDictionary.cpp Tue Nov 24 11:49:42 2009 -0800 +++ b/src/share/vm/classfile/systemDictionary.cpp Wed Nov 25 09:03:42 2009 -0500 @@ -99,6 +99,15 @@ 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 // Forwards to resolve_or_null @@ -724,13 +733,13 @@ // Do actual loading 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 it did, then for bytecode resolution the specification requires // that we return the same result we did for the other thread, i.e. the // successfully loaded instanceKlass // 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 if (UnsyncloadClass || (class_loader.is_null())) { if (k.is_null() && HAS_PENDING_EXCEPTION @@ -1483,14 +1492,17 @@ } // Support parallel classloading -// Initial implementation for bootstrap classloader -// For custom class loaders that support parallel classloading, +// All parallel class loaders, including bootstrap classloader +// 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 // FindLoadedClass/DefineClass, calls, we check for parallel // loading for them, wait if a defineClass is in progress // 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 // which will throw LinkageError: duplicate class definition. +// False is the requested default. // For better performance, the class loaders should synchronize // findClass(), i.e. FindLoadedClass/DefineClassIfAbsent or they // potentially waste time reading and parsing the bytestream. @@ -1511,9 +1523,11 @@ { MutexLocker mu(SystemDictionary_lock, THREAD); // First check if class already defined - klassOop check = find_class(d_index, d_hash, name_h, class_loader); - if (check != NULL) { - return(instanceKlassHandle(THREAD, check)); + if (UnsyncloadClass || (is_parallelDefine(class_loader))) { + klassOop check = find_class(d_index, d_hash, name_h, class_loader); + if (check != NULL) { + return(instanceKlassHandle(THREAD, check)); + } } // Acquire define token for this class/classloader @@ -1529,7 +1543,7 @@ // Only special cases allow parallel defines and can use other thread's results // Other cases fall through, and may run into duplicate defines // 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); placeholders()->find_and_remove(p_index, p_hash, name_h, class_loader, THREAD); SystemDictionary_lock->notify_all(); diff -r de44705e6b33 -r e1fb452ad949 src/share/vm/classfile/systemDictionary.hpp --- a/src/share/vm/classfile/systemDictionary.hpp Tue Nov 24 11:49:42 2009 -0800 +++ b/src/share/vm/classfile/systemDictionary.hpp Wed Nov 25 09:03:42 2009 -0500 @@ -577,6 +577,7 @@ static Handle compute_loader_lock_object(Handle class_loader, TRAPS); static void check_loader_lock_contention(Handle loader_lock, TRAPS); static bool is_parallelCapable(Handle class_loader); + static bool is_parallelDefine(Handle class_loader); static klassOop find_shared_class(symbolHandle class_name); diff -r de44705e6b33 -r e1fb452ad949 src/share/vm/runtime/arguments.cpp --- a/src/share/vm/runtime/arguments.cpp Tue Nov 24 11:49:42 2009 -0800 +++ b/src/share/vm/runtime/arguments.cpp Wed Nov 25 09:03:42 2009 -0500 @@ -1378,9 +1378,15 @@ // or -Xms, then set it as fraction of the size of physical memory, // respecting the maximum and minimum sizes of the heap. if (FLAG_IS_DEFAULT(InitialHeapSize)) { + julong reasonable_minimum = (julong)(OldSize + NewSize); + + reasonable_minimum = MIN2(reasonable_minimum, (julong)MaxHeapSize); + + reasonable_minimum = os::allocatable_physical_memory(reasonable_minimum); + julong reasonable_initial = phys_mem / InitialRAMFraction; - reasonable_initial = MAX2(reasonable_initial, (julong)(OldSize + NewSize)); + reasonable_initial = MAX2(reasonable_initial, reasonable_minimum); reasonable_initial = MIN2(reasonable_initial, (julong)MaxHeapSize); reasonable_initial = os::allocatable_physical_memory(reasonable_initial); @@ -1388,14 +1394,10 @@ if (PrintGCDetails && Verbose) { // Cannot use gclog_or_tty yet. tty->print_cr(" Initial heap size " SIZE_FORMAT, (uintx)reasonable_initial); + tty->print_cr(" Minimum heap size " SIZE_FORMAT, (uintx)reasonable_minimum); } FLAG_SET_ERGO(uintx, InitialHeapSize, (uintx)reasonable_initial); - - // Subsequent ergonomics code may expect min_heap_size to be set - // if InitialHeapSize is. Use whatever the current values are - // for OldSize and NewSize, whether or not they were set on the - // command line. - set_min_heap_size(OldSize + NewSize); + set_min_heap_size((uintx)reasonable_minimum); } }