src/share/vm/utilities/hashtable.inline.hpp

Thu, 20 Nov 2008 16:56:09 -0800

author
ysr
date
Thu, 20 Nov 2008 16:56:09 -0800
changeset 888
c96030fff130
parent 435
a61af66fc99e
child 1907
c18cbe5936b8
permissions
-rw-r--r--

6684579: SoftReference processing can be made more efficient
Summary: For current soft-ref clearing policies, we can decide at marking time if a soft-reference will definitely not be cleared, postponing the decision of whether it will definitely be cleared to the final reference processing phase. This can be especially beneficial in the case of concurrent collectors where the marking is usually concurrent but reference processing is usually not.
Reviewed-by: jmasa

duke@435 1 /*
duke@435 2 * Copyright 2003 Sun Microsystems, Inc. All Rights Reserved.
duke@435 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
duke@435 4 *
duke@435 5 * This code is free software; you can redistribute it and/or modify it
duke@435 6 * under the terms of the GNU General Public License version 2 only, as
duke@435 7 * published by the Free Software Foundation.
duke@435 8 *
duke@435 9 * This code is distributed in the hope that it will be useful, but WITHOUT
duke@435 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
duke@435 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
duke@435 12 * version 2 for more details (a copy is included in the LICENSE file that
duke@435 13 * accompanied this code).
duke@435 14 *
duke@435 15 * You should have received a copy of the GNU General Public License version
duke@435 16 * 2 along with this work; if not, write to the Free Software Foundation,
duke@435 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
duke@435 18 *
duke@435 19 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
duke@435 20 * CA 95054 USA or visit www.sun.com if you need additional information or
duke@435 21 * have any questions.
duke@435 22 *
duke@435 23 */
duke@435 24
duke@435 25 // Inline function definitions for hashtable.hpp.
duke@435 26
duke@435 27
duke@435 28 // --------------------------------------------------------------------------
duke@435 29 // Hash function
duke@435 30
duke@435 31 // We originally used hashpjw, but hash P(31) gives just as good results
duke@435 32 // and is slighly faster. We would like a hash function that looks at every
duke@435 33 // character, since package names have large common prefixes, and also because
duke@435 34 // hash_or_fail does error checking while iterating.
duke@435 35
duke@435 36 // hash P(31) from Kernighan & Ritchie
duke@435 37
duke@435 38 inline unsigned int Hashtable::hash_symbol(const char* s, int len) {
duke@435 39 unsigned int h = 0;
duke@435 40 while (len-- > 0) {
duke@435 41 h = 31*h + (unsigned) *s;
duke@435 42 s++;
duke@435 43 }
duke@435 44 return h;
duke@435 45 }
duke@435 46
duke@435 47
duke@435 48 // --------------------------------------------------------------------------
duke@435 49
duke@435 50 // Initialize a table.
duke@435 51
duke@435 52 inline BasicHashtable::BasicHashtable(int table_size, int entry_size) {
duke@435 53 // Called on startup, no locking needed
duke@435 54 initialize(table_size, entry_size, 0);
duke@435 55 _buckets = NEW_C_HEAP_ARRAY(HashtableBucket, table_size);
duke@435 56 for (int index = 0; index < _table_size; index++) {
duke@435 57 _buckets[index].clear();
duke@435 58 }
duke@435 59 }
duke@435 60
duke@435 61
duke@435 62 inline BasicHashtable::BasicHashtable(int table_size, int entry_size,
duke@435 63 HashtableBucket* buckets,
duke@435 64 int number_of_entries) {
duke@435 65 // Called on startup, no locking needed
duke@435 66 initialize(table_size, entry_size, number_of_entries);
duke@435 67 _buckets = buckets;
duke@435 68 }
duke@435 69
duke@435 70
duke@435 71 inline void BasicHashtable::initialize(int table_size, int entry_size,
duke@435 72 int number_of_entries) {
duke@435 73 // Called on startup, no locking needed
duke@435 74 _table_size = table_size;
duke@435 75 _entry_size = entry_size;
duke@435 76 _free_list = NULL;
duke@435 77 _first_free_entry = NULL;
duke@435 78 _end_block = NULL;
duke@435 79 _number_of_entries = number_of_entries;
duke@435 80 #ifdef ASSERT
duke@435 81 _lookup_count = 0;
duke@435 82 _lookup_length = 0;
duke@435 83 #endif
duke@435 84 }
duke@435 85
duke@435 86
duke@435 87 // The following method is MT-safe and may be used with caution.
duke@435 88 inline BasicHashtableEntry* BasicHashtable::bucket(int i) {
duke@435 89 return _buckets[i].get_entry();
duke@435 90 }
duke@435 91
duke@435 92
duke@435 93 inline void HashtableBucket::set_entry(BasicHashtableEntry* l) {
duke@435 94 // Warning: Preserve store ordering. The SystemDictionary is read
duke@435 95 // without locks. The new SystemDictionaryEntry must be
duke@435 96 // complete before other threads can be allowed to see it
duke@435 97 // via a store to _buckets[index].
duke@435 98 OrderAccess::release_store_ptr(&_entry, l);
duke@435 99 }
duke@435 100
duke@435 101
duke@435 102 inline BasicHashtableEntry* HashtableBucket::get_entry() const {
duke@435 103 // Warning: Preserve load ordering. The SystemDictionary is read
duke@435 104 // without locks. The new SystemDictionaryEntry must be
duke@435 105 // complete before other threads can be allowed to see it
duke@435 106 // via a store to _buckets[index].
duke@435 107 return (BasicHashtableEntry*) OrderAccess::load_ptr_acquire(&_entry);
duke@435 108 }
duke@435 109
duke@435 110
duke@435 111 inline void BasicHashtable::set_entry(int index, BasicHashtableEntry* entry) {
duke@435 112 _buckets[index].set_entry(entry);
duke@435 113 }
duke@435 114
duke@435 115
duke@435 116 inline void BasicHashtable::add_entry(int index, BasicHashtableEntry* entry) {
duke@435 117 entry->set_next(bucket(index));
duke@435 118 _buckets[index].set_entry(entry);
duke@435 119 ++_number_of_entries;
duke@435 120 }
duke@435 121
duke@435 122 inline void BasicHashtable::free_entry(BasicHashtableEntry* entry) {
duke@435 123 entry->set_next(_free_list);
duke@435 124 _free_list = entry;
duke@435 125 --_number_of_entries;
duke@435 126 }

mercurial