7114376: Make system dictionary hashtable bucket array size configurable
7u4 new experimental flag -XX:PredictedClassLoadedCount=# Reviewed-by: dholmes, phh, dcubed
This commit is contained in:
parent
d5546e27cf
commit
ce074f86c3
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2003, 2012 Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -42,15 +42,6 @@ public class LoaderConstraintTable extends TwoOopHashtable {
|
||||
|
||||
private static synchronized void initialize(TypeDataBase db) {
|
||||
Type type = db.lookupType("LoaderConstraintTable");
|
||||
nofBuckets = db.lookupIntConstant("LoaderConstraintTable::_nof_buckets").intValue();
|
||||
}
|
||||
|
||||
// Fields
|
||||
private static int nofBuckets;
|
||||
|
||||
// Accessors
|
||||
public static int getNumOfBuckets() {
|
||||
return nofBuckets;
|
||||
}
|
||||
|
||||
public LoaderConstraintTable(Address addr) {
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -36,7 +36,6 @@ public class SystemDictionary {
|
||||
private static AddressField placeholdersField;
|
||||
private static AddressField loaderConstraintTableField;
|
||||
private static sun.jvm.hotspot.types.OopField javaSystemLoaderField;
|
||||
private static int nofBuckets;
|
||||
|
||||
private static sun.jvm.hotspot.types.OopField objectKlassField;
|
||||
private static sun.jvm.hotspot.types.OopField classLoaderKlassField;
|
||||
@ -62,7 +61,6 @@ public class SystemDictionary {
|
||||
placeholdersField = type.getAddressField("_placeholders");
|
||||
loaderConstraintTableField = type.getAddressField("_loader_constraints");
|
||||
javaSystemLoaderField = type.getOopField("_java_system_loader");
|
||||
nofBuckets = db.lookupIntConstant("SystemDictionary::_nof_buckets").intValue();
|
||||
|
||||
objectKlassField = type.getOopField(WK_KLASS("Object_klass"));
|
||||
classLoaderKlassField = type.getOopField(WK_KLASS("ClassLoader_klass"));
|
||||
@ -142,10 +140,6 @@ public class SystemDictionary {
|
||||
return newOop(javaSystemLoaderField.getValue());
|
||||
}
|
||||
|
||||
public static int getNumOfBuckets() {
|
||||
return nofBuckets;
|
||||
}
|
||||
|
||||
private static Oop newOop(OopHandle handle) {
|
||||
return VM.getVM().getObjectHeap().newOop(handle);
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -618,7 +618,8 @@ void Dictionary::print() {
|
||||
ResourceMark rm;
|
||||
HandleMark hm;
|
||||
|
||||
tty->print_cr("Java system dictionary (classes=%d)", number_of_entries());
|
||||
tty->print_cr("Java system dictionary (table_size=%d, classes=%d)",
|
||||
table_size(), number_of_entries());
|
||||
tty->print_cr("^ indicates that initiating loader is different from "
|
||||
"defining loader");
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -64,6 +64,9 @@ SymbolPropertyTable* SystemDictionary::_invoke_method_table = NULL;
|
||||
|
||||
|
||||
int SystemDictionary::_number_of_modifications = 0;
|
||||
int SystemDictionary::_sdgeneration = 0;
|
||||
const int SystemDictionary::_primelist[_prime_array_size] = {1009,2017,4049,5051,10103,
|
||||
20201,40423,99991};
|
||||
|
||||
oop SystemDictionary::_system_loader_lock_obj = NULL;
|
||||
|
||||
@ -1178,8 +1181,8 @@ void SystemDictionary::set_shared_dictionary(HashtableBucket* t, int length,
|
||||
|
||||
klassOop SystemDictionary::find_shared_class(Symbol* class_name) {
|
||||
if (shared_dictionary() != NULL) {
|
||||
unsigned int d_hash = dictionary()->compute_hash(class_name, Handle());
|
||||
int d_index = dictionary()->hash_to_index(d_hash);
|
||||
unsigned int d_hash = shared_dictionary()->compute_hash(class_name, Handle());
|
||||
int d_index = shared_dictionary()->hash_to_index(d_hash);
|
||||
return shared_dictionary()->find_shared_class(d_index, d_hash, class_name);
|
||||
} else {
|
||||
return NULL;
|
||||
@ -1750,7 +1753,21 @@ void SystemDictionary::placeholders_do(OopClosure* blk) {
|
||||
placeholders()->oops_do(blk);
|
||||
}
|
||||
|
||||
|
||||
// Calculate a "good" systemdictionary size based
|
||||
// on predicted or current loaded classes count
|
||||
int SystemDictionary::calculate_systemdictionary_size(int classcount) {
|
||||
int newsize = _old_default_sdsize;
|
||||
if ((classcount > 0) && !DumpSharedSpaces) {
|
||||
int desiredsize = classcount/_average_depth_goal;
|
||||
for (newsize = _primelist[_sdgeneration]; _sdgeneration < _prime_array_size -1;
|
||||
newsize = _primelist[++_sdgeneration]) {
|
||||
if (desiredsize <= newsize) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return newsize;
|
||||
}
|
||||
bool SystemDictionary::do_unloading(BoolObjectClosure* is_alive) {
|
||||
bool result = dictionary()->do_unloading(is_alive);
|
||||
constraints()->purge_loader_constraints(is_alive);
|
||||
@ -1873,7 +1890,8 @@ void SystemDictionary::initialize(TRAPS) {
|
||||
// Allocate arrays
|
||||
assert(dictionary() == NULL,
|
||||
"SystemDictionary should only be initialized once");
|
||||
_dictionary = new Dictionary(_nof_buckets);
|
||||
_sdgeneration = 0;
|
||||
_dictionary = new Dictionary(calculate_systemdictionary_size(PredictedLoadedClassCount));
|
||||
_placeholders = new PlaceholderTable(_nof_buckets);
|
||||
_number_of_modifications = 0;
|
||||
_loader_constraints = new LoaderConstraintTable(_loader_constraint_size);
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -346,6 +346,8 @@ public:
|
||||
// loaders. Returns "true" iff something was unloaded.
|
||||
static bool do_unloading(BoolObjectClosure* is_alive);
|
||||
|
||||
static int calculate_systemdictionary_size(int loadedclasses);
|
||||
|
||||
// Applies "f->do_oop" to all root oops in the system dictionary.
|
||||
static void oops_do(OopClosure* f);
|
||||
|
||||
@ -538,12 +540,20 @@ public:
|
||||
_loader_constraint_size = 107, // number of entries in constraint table
|
||||
_resolution_error_size = 107, // number of entries in resolution error table
|
||||
_invoke_method_size = 139, // number of entries in invoke method table
|
||||
_nof_buckets = 1009 // number of buckets in hash table
|
||||
_nof_buckets = 1009, // number of buckets in hash table for placeholders
|
||||
_old_default_sdsize = 1009, // backward compat for system dictionary size
|
||||
_prime_array_size = 8, // array of primes for system dictionary size
|
||||
_average_depth_goal = 3 // goal for lookup length
|
||||
};
|
||||
|
||||
|
||||
// Static variables
|
||||
|
||||
// hashtable sizes for system dictionary to allow growth
|
||||
// prime numbers for system dictionary size
|
||||
static int _sdgeneration;
|
||||
static const int _primelist[_prime_array_size];
|
||||
|
||||
// Hashtable holding loaded classes.
|
||||
static Dictionary* _dictionary;
|
||||
|
||||
|
@ -1042,6 +1042,9 @@ class CommandLineFlags {
|
||||
notproduct(bool, PrintSystemDictionaryAtExit, false, \
|
||||
"Prints the system dictionary at exit") \
|
||||
\
|
||||
experimental(intx, PredictedLoadedClassCount, 0, \
|
||||
"Experimental: Tune loaded class cache starting size.") \
|
||||
\
|
||||
diagnostic(bool, UnsyncloadClass, false, \
|
||||
"Unstable: VM calls loadClass unsynchronized. Custom " \
|
||||
"class loader must call VM synchronized for findClass " \
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -2261,13 +2261,6 @@ static inline uint64_t cast_uint64_t(size_t x)
|
||||
\
|
||||
declare_constant(SymbolTable::symbol_table_size) \
|
||||
\
|
||||
/********************/ \
|
||||
/* SystemDictionary */ \
|
||||
/********************/ \
|
||||
\
|
||||
declare_constant(SystemDictionary::_loader_constraint_size) \
|
||||
declare_constant(SystemDictionary::_nof_buckets) \
|
||||
\
|
||||
/***********************************/ \
|
||||
/* LoaderConstraintTable constants */ \
|
||||
/***********************************/ \
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -183,7 +183,6 @@ protected:
|
||||
|
||||
// Accessor
|
||||
int entry_size() const { return _entry_size; }
|
||||
int table_size() { return _table_size; }
|
||||
|
||||
// The following method is MT-safe and may be used with caution.
|
||||
BasicHashtableEntry* bucket(int i);
|
||||
@ -195,6 +194,7 @@ protected:
|
||||
BasicHashtableEntry* new_entry(unsigned int hashValue);
|
||||
|
||||
public:
|
||||
int table_size() { return _table_size; }
|
||||
void set_entry(int index, BasicHashtableEntry* entry);
|
||||
|
||||
void add_entry(int index, BasicHashtableEntry* entry);
|
||||
|
Loading…
Reference in New Issue
Block a user