--- a/hotspot/src/share/vm/classfile/systemDictionary.cpp Tue Nov 24 11:49:42 2009 -0800
+++ b/hotspot/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();
--- a/hotspot/src/share/vm/classfile/systemDictionary.hpp Tue Nov 24 11:49:42 2009 -0800
+++ b/hotspot/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);
--- a/hotspot/src/share/vm/runtime/arguments.cpp Tue Nov 24 11:49:42 2009 -0800
+++ b/hotspot/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);
}
}