From c075680fb76b319ec1d1570a69564ab588cf8f2c Mon Sep 17 00:00:00 2001 From: acorn Date: Mon, 30 Jan 2012 23:27:30 -0500 Subject: [PATCH] 7114376: Make system dictionary hashtable bucket array size configurable Summary: 7u4 new experimental flag -XX:PredictedClassLoadedCount=# Reviewed-by: dholmes, phh, dcubed --- .../hotspot/memory/LoaderConstraintTable.java | 11 +------- .../jvm/hotspot/memory/SystemDictionary.java | 8 +----- src/share/vm/classfile/dictionary.cpp | 5 ++-- src/share/vm/classfile/systemDictionary.cpp | 28 +++++++++++++++---- src/share/vm/classfile/systemDictionary.hpp | 14 ++++++++-- src/share/vm/runtime/globals.hpp | 3 ++ src/share/vm/runtime/vmStructs.cpp | 9 +----- src/share/vm/utilities/hashtable.hpp | 4 +-- 8 files changed, 46 insertions(+), 36 deletions(-) diff --git a/agent/src/share/classes/sun/jvm/hotspot/memory/LoaderConstraintTable.java b/agent/src/share/classes/sun/jvm/hotspot/memory/LoaderConstraintTable.java index 582789ac7..14d6c566b 100644 --- a/agent/src/share/classes/sun/jvm/hotspot/memory/LoaderConstraintTable.java +++ b/agent/src/share/classes/sun/jvm/hotspot/memory/LoaderConstraintTable.java @@ -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) { diff --git a/agent/src/share/classes/sun/jvm/hotspot/memory/SystemDictionary.java b/agent/src/share/classes/sun/jvm/hotspot/memory/SystemDictionary.java index c999ff1a8..11adb3cf1 100644 --- a/agent/src/share/classes/sun/jvm/hotspot/memory/SystemDictionary.java +++ b/agent/src/share/classes/sun/jvm/hotspot/memory/SystemDictionary.java @@ -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); } diff --git a/src/share/vm/classfile/dictionary.cpp b/src/share/vm/classfile/dictionary.cpp index b15446c6f..4458f46d7 100644 --- a/src/share/vm/classfile/dictionary.cpp +++ b/src/share/vm/classfile/dictionary.cpp @@ -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"); diff --git a/src/share/vm/classfile/systemDictionary.cpp b/src/share/vm/classfile/systemDictionary.cpp index 88ccc91b7..04bb9d9f5 100644 --- a/src/share/vm/classfile/systemDictionary.cpp +++ b/src/share/vm/classfile/systemDictionary.cpp @@ -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); diff --git a/src/share/vm/classfile/systemDictionary.hpp b/src/share/vm/classfile/systemDictionary.hpp index 528ecafbc..3abc5054d 100644 --- a/src/share/vm/classfile/systemDictionary.hpp +++ b/src/share/vm/classfile/systemDictionary.hpp @@ -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; diff --git a/src/share/vm/runtime/globals.hpp b/src/share/vm/runtime/globals.hpp index b6d4ec94e..0785459b4 100644 --- a/src/share/vm/runtime/globals.hpp +++ b/src/share/vm/runtime/globals.hpp @@ -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 " \ diff --git a/src/share/vm/runtime/vmStructs.cpp b/src/share/vm/runtime/vmStructs.cpp index eb765f0cf..65da74a81 100644 --- a/src/share/vm/runtime/vmStructs.cpp +++ b/src/share/vm/runtime/vmStructs.cpp @@ -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 */ \ /***********************************/ \ diff --git a/src/share/vm/utilities/hashtable.hpp b/src/share/vm/utilities/hashtable.hpp index a4f0e9012..527470938 100644 --- a/src/share/vm/utilities/hashtable.hpp +++ b/src/share/vm/utilities/hashtable.hpp @@ -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); -- GitLab