src/share/vm/utilities/hashtable.cpp

Fri, 07 Nov 2008 09:29:38 -0800

author
kvn
date
Fri, 07 Nov 2008 09:29:38 -0800
changeset 855
a1980da045cc
parent 435
a61af66fc99e
child 867
275a3b7ff0d6
permissions
-rw-r--r--

6462850: generate biased locking code in C2 ideal graph
Summary: Inline biased locking code in C2 ideal graph during macro nodes expansion
Reviewed-by: never

duke@435 1 /*
duke@435 2 * Copyright 2003-2005 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 # include "incls/_precompiled.incl"
duke@435 26 # include "incls/_hashtable.cpp.incl"
duke@435 27
duke@435 28 HS_DTRACE_PROBE_DECL4(hs_private, hashtable__new_entry,
duke@435 29 void*, unsigned int, oop, void*);
duke@435 30
duke@435 31 // This is a generic hashtable, designed to be used for the symbol
duke@435 32 // and string tables.
duke@435 33 //
duke@435 34 // It is implemented as an open hash table with a fixed number of buckets.
duke@435 35 //
duke@435 36 // %note:
duke@435 37 // - HashtableEntrys are allocated in blocks to reduce the space overhead.
duke@435 38
duke@435 39 BasicHashtableEntry* BasicHashtable::new_entry(unsigned int hashValue) {
duke@435 40 BasicHashtableEntry* entry;
duke@435 41
duke@435 42 if (_free_list) {
duke@435 43 entry = _free_list;
duke@435 44 _free_list = _free_list->next();
duke@435 45 } else {
duke@435 46 const int block_size = 500;
duke@435 47 if (_first_free_entry == _end_block) {
duke@435 48 int len = _entry_size * block_size;
duke@435 49 _first_free_entry = NEW_C_HEAP_ARRAY(char, len);
duke@435 50 _end_block = _first_free_entry + len;
duke@435 51 }
duke@435 52 entry = (BasicHashtableEntry*)_first_free_entry;
duke@435 53 _first_free_entry += _entry_size;
duke@435 54 }
duke@435 55
duke@435 56 entry->set_hash(hashValue);
duke@435 57 return entry;
duke@435 58 }
duke@435 59
duke@435 60
duke@435 61 HashtableEntry* Hashtable::new_entry(unsigned int hashValue, oop obj) {
duke@435 62 HashtableEntry* entry;
duke@435 63
duke@435 64 entry = (HashtableEntry*)BasicHashtable::new_entry(hashValue);
duke@435 65 entry->set_literal(obj); // clears literal string field
duke@435 66 HS_DTRACE_PROBE4(hs_private, hashtable__new_entry,
duke@435 67 this, hashValue, obj, entry);
duke@435 68 return entry;
duke@435 69 }
duke@435 70
duke@435 71
duke@435 72 // GC support
duke@435 73
duke@435 74 void Hashtable::unlink(BoolObjectClosure* is_alive) {
duke@435 75 // Readers of the table are unlocked, so we should only be removing
duke@435 76 // entries at a safepoint.
duke@435 77 assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint");
duke@435 78 for (int i = 0; i < table_size(); ++i) {
duke@435 79 for (HashtableEntry** p = bucket_addr(i); *p != NULL; ) {
duke@435 80 HashtableEntry* entry = *p;
duke@435 81 if (entry->is_shared()) {
duke@435 82 break;
duke@435 83 }
duke@435 84 assert(entry->literal() != NULL, "just checking");
duke@435 85 if (is_alive->do_object_b(entry->literal())) {
duke@435 86 p = entry->next_addr();
duke@435 87 } else {
duke@435 88 *p = entry->next();
duke@435 89 free_entry(entry);
duke@435 90 }
duke@435 91 }
duke@435 92 }
duke@435 93 }
duke@435 94
duke@435 95
duke@435 96 void Hashtable::oops_do(OopClosure* f) {
duke@435 97 for (int i = 0; i < table_size(); ++i) {
duke@435 98 HashtableEntry** p = bucket_addr(i);
duke@435 99 HashtableEntry* entry = bucket(i);
duke@435 100 while (entry != NULL) {
duke@435 101 f->do_oop(entry->literal_addr());
duke@435 102
duke@435 103 // Did the closure remove the literal from the table?
duke@435 104 if (entry->literal() == NULL) {
duke@435 105 assert(!entry->is_shared(), "immutable hashtable entry?");
duke@435 106 *p = entry->next();
duke@435 107 free_entry(entry);
duke@435 108 } else {
duke@435 109 p = entry->next_addr();
duke@435 110 }
duke@435 111 entry = (HashtableEntry*)HashtableEntry::make_ptr(*p);
duke@435 112 }
duke@435 113 }
duke@435 114 }
duke@435 115
duke@435 116
duke@435 117 // Reverse the order of elements in the hash buckets.
duke@435 118
duke@435 119 void BasicHashtable::reverse() {
duke@435 120
duke@435 121 for (int i = 0; i < _table_size; ++i) {
duke@435 122 BasicHashtableEntry* new_list = NULL;
duke@435 123 BasicHashtableEntry* p = bucket(i);
duke@435 124 while (p != NULL) {
duke@435 125 BasicHashtableEntry* next = p->next();
duke@435 126 p->set_next(new_list);
duke@435 127 new_list = p;
duke@435 128 p = next;
duke@435 129 }
duke@435 130 *bucket_addr(i) = new_list;
duke@435 131 }
duke@435 132 }
duke@435 133
duke@435 134
duke@435 135 // Copy the table to the shared space.
duke@435 136
duke@435 137 void BasicHashtable::copy_table(char** top, char* end) {
duke@435 138
duke@435 139 // Dump the hash table entries.
duke@435 140
duke@435 141 intptr_t *plen = (intptr_t*)(*top);
duke@435 142 *top += sizeof(*plen);
duke@435 143
duke@435 144 int i;
duke@435 145 for (i = 0; i < _table_size; ++i) {
duke@435 146 for (BasicHashtableEntry** p = _buckets[i].entry_addr();
duke@435 147 *p != NULL;
duke@435 148 p = (*p)->next_addr()) {
duke@435 149 if (*top + entry_size() > end) {
duke@435 150 warning("\nThe shared miscellaneous data space is not large "
duke@435 151 "enough to \npreload requested classes. Use "
duke@435 152 "-XX:SharedMiscDataSize= to increase \nthe initial "
duke@435 153 "size of the miscellaneous data space.\n");
duke@435 154 exit(2);
duke@435 155 }
duke@435 156 *p = (BasicHashtableEntry*)memcpy(*top, *p, entry_size());
duke@435 157 *top += entry_size();
duke@435 158 }
duke@435 159 }
duke@435 160 *plen = (char*)(*top) - (char*)plen - sizeof(*plen);
duke@435 161
duke@435 162 // Set the shared bit.
duke@435 163
duke@435 164 for (i = 0; i < _table_size; ++i) {
duke@435 165 for (BasicHashtableEntry* p = bucket(i); p != NULL; p = p->next()) {
duke@435 166 p->set_shared();
duke@435 167 }
duke@435 168 }
duke@435 169 }
duke@435 170
duke@435 171
duke@435 172
duke@435 173 // Reverse the order of elements in the hash buckets.
duke@435 174
duke@435 175 void Hashtable::reverse(void* boundary) {
duke@435 176
duke@435 177 for (int i = 0; i < table_size(); ++i) {
duke@435 178 HashtableEntry* high_list = NULL;
duke@435 179 HashtableEntry* low_list = NULL;
duke@435 180 HashtableEntry* last_low_entry = NULL;
duke@435 181 HashtableEntry* p = bucket(i);
duke@435 182 while (p != NULL) {
duke@435 183 HashtableEntry* next = p->next();
duke@435 184 if ((void*)p->literal() >= boundary) {
duke@435 185 p->set_next(high_list);
duke@435 186 high_list = p;
duke@435 187 } else {
duke@435 188 p->set_next(low_list);
duke@435 189 low_list = p;
duke@435 190 if (last_low_entry == NULL) {
duke@435 191 last_low_entry = p;
duke@435 192 }
duke@435 193 }
duke@435 194 p = next;
duke@435 195 }
duke@435 196 if (low_list != NULL) {
duke@435 197 *bucket_addr(i) = low_list;
duke@435 198 last_low_entry->set_next(high_list);
duke@435 199 } else {
duke@435 200 *bucket_addr(i) = high_list;
duke@435 201 }
duke@435 202 }
duke@435 203 }
duke@435 204
duke@435 205
duke@435 206 // Dump the hash table buckets.
duke@435 207
duke@435 208 void BasicHashtable::copy_buckets(char** top, char* end) {
duke@435 209 intptr_t len = _table_size * sizeof(HashtableBucket);
duke@435 210 *(intptr_t*)(*top) = len;
duke@435 211 *top += sizeof(intptr_t);
duke@435 212
duke@435 213 *(intptr_t*)(*top) = _number_of_entries;
duke@435 214 *top += sizeof(intptr_t);
duke@435 215
duke@435 216 if (*top + len > end) {
duke@435 217 warning("\nThe shared miscellaneous data space is not large "
duke@435 218 "enough to \npreload requested classes. Use "
duke@435 219 "-XX:SharedMiscDataSize= to increase \nthe initial "
duke@435 220 "size of the miscellaneous data space.\n");
duke@435 221 exit(2);
duke@435 222 }
duke@435 223 _buckets = (HashtableBucket*)memcpy(*top, _buckets, len);
duke@435 224 *top += len;
duke@435 225 }
duke@435 226
duke@435 227
duke@435 228 #ifndef PRODUCT
duke@435 229
duke@435 230 void Hashtable::print() {
duke@435 231 ResourceMark rm;
duke@435 232
duke@435 233 for (int i = 0; i < table_size(); i++) {
duke@435 234 HashtableEntry* entry = bucket(i);
duke@435 235 while(entry != NULL) {
duke@435 236 tty->print("%d : ", i);
duke@435 237 entry->literal()->print();
duke@435 238 tty->cr();
duke@435 239 entry = entry->next();
duke@435 240 }
duke@435 241 }
duke@435 242 }
duke@435 243
duke@435 244
duke@435 245 void BasicHashtable::verify() {
duke@435 246 int count = 0;
duke@435 247 for (int i = 0; i < table_size(); i++) {
duke@435 248 for (BasicHashtableEntry* p = bucket(i); p != NULL; p = p->next()) {
duke@435 249 ++count;
duke@435 250 }
duke@435 251 }
duke@435 252 assert(count == number_of_entries(), "number of hashtable entries incorrect");
duke@435 253 }
duke@435 254
duke@435 255
duke@435 256 #endif // PRODUCT
duke@435 257
duke@435 258
duke@435 259 #ifdef ASSERT
duke@435 260
duke@435 261 void BasicHashtable::verify_lookup_length(double load) {
duke@435 262 if ((double)_lookup_length / (double)_lookup_count > load * 2.0) {
duke@435 263 warning("Performance bug: SystemDictionary lookup_count=%d "
duke@435 264 "lookup_length=%d average=%lf load=%f",
duke@435 265 _lookup_count, _lookup_length,
duke@435 266 (double) _lookup_length / _lookup_count, load);
duke@435 267 }
duke@435 268 }
duke@435 269
duke@435 270 #endif

mercurial