Changeset 406 for trunk/openjdk/hotspot
- Timestamp:
- Dec 21, 2012, 10:37:13 AM (13 years ago)
- Location:
- trunk/openjdk
- Files:
-
- 29 edited
- 6 copied
Legend:
- Unmodified
- Added
- Removed
-
trunk/openjdk
- Property svn:mergeinfo changed
/branches/vendor/oracle/openjdk6/b27 (added) merged: 405 /branches/vendor/oracle/openjdk6/current merged: 404
- Property svn:mergeinfo changed
-
trunk/openjdk/hotspot/make/linux/Makefile
r309 r406 231 231 # Disable this check by setting DISABLE_HOTSPOT_OS_VERSION_CHECK=ok. 232 232 233 SUPPORTED_OS_VERSION = 2.4% 2.5% 2.6% 2.7%233 SUPPORTED_OS_VERSION = 2.4% 2.5% 2.6% 3% 234 234 OS_VERSION := $(shell uname -r) 235 235 EMPTY_IF_NOT_SUPPORTED = $(filter $(SUPPORTED_OS_VERSION),$(OS_VERSION)) -
trunk/openjdk/hotspot/src/os_cpu/os2_x86/vm/os2_x86_32.s
- Property svn:mergeinfo changed
/branches/vendor/oracle/openjdk6/b27/hotspot/src/os_cpu/os2_x86/vm/os2_x86_32.s (added) merged: 405 /branches/vendor/oracle/openjdk6/current/hotspot/src/os_cpu/os2_x86/vm/os2_x86_32.s merged: 387-404
- Property svn:mergeinfo changed
-
trunk/openjdk/hotspot/src/share/vm/ci/ciField.cpp
r309 r406 1 1 /* 2 * Copyright (c) 1999, 201 0, Oracle and/or its affiliates. All rights reserved.2 * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved. 3 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 4 * … … 68 68 // ------------------------------------------------------------------ 69 69 // ciField::ciField 70 ciField::ciField(ciInstanceKlass* klass, int index): _known_to_link_with (NULL) {70 ciField::ciField(ciInstanceKlass* klass, int index): _known_to_link_with_put(NULL), _known_to_link_with_get(NULL) { 71 71 ASSERT_IN_VM; 72 72 CompilerThread *thread = CompilerThread::current(); … … 144 144 } 145 145 146 ciField::ciField(fieldDescriptor *fd): _known_to_link_with (NULL) {146 ciField::ciField(fieldDescriptor *fd): _known_to_link_with_put(NULL), _known_to_link_with_get(NULL) { 147 147 ASSERT_IN_VM; 148 148 … … 313 313 Bytecodes::Code bc) { 314 314 VM_ENTRY_MARK; 315 assert(bc == Bytecodes::_getstatic || bc == Bytecodes::_putstatic || 316 bc == Bytecodes::_getfield || bc == Bytecodes::_putfield, 317 "unexpected bytecode"); 318 315 319 if (_offset == -1) { 316 320 // at creation we couldn't link to our holder so we need to … … 320 324 } 321 325 322 if (_known_to_link_with == accessing_klass) { 323 return true; 326 // Check for static/nonstatic mismatch 327 bool is_static = (bc == Bytecodes::_getstatic || bc == Bytecodes::_putstatic); 328 if (is_static != this->is_static()) { 329 return false; 330 } 331 332 // Get and put can have different accessibility rules 333 bool is_put = (bc == Bytecodes::_putfield || bc == Bytecodes::_putstatic); 334 if (is_put) { 335 if (_known_to_link_with_put == accessing_klass) { 336 return true; 337 } 338 } else { 339 if (_known_to_link_with_get == accessing_klass) { 340 return true; 341 } 324 342 } 325 343 … … 332 350 333 351 // update the hit-cache, unless there is a problem with memory scoping: 334 if (accessing_klass->is_shared() || !is_shared()) 335 _known_to_link_with = accessing_klass; 352 if (accessing_klass->is_shared() || !is_shared()) { 353 if (is_put) { 354 _known_to_link_with_put = accessing_klass; 355 } else { 356 _known_to_link_with_get = accessing_klass; 357 } 358 } 336 359 337 360 return true; -
trunk/openjdk/hotspot/src/share/vm/ci/ciField.hpp
r309 r406 1 1 /* 2 * Copyright (c) 1999, 201 0, Oracle and/or its affiliates. All rights reserved.2 * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved. 3 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 4 * … … 50 50 int _offset; 51 51 bool _is_constant; 52 ciInstanceKlass* _known_to_link_with; 52 ciInstanceKlass* _known_to_link_with_put; 53 ciInstanceKlass* _known_to_link_with_get; 53 54 ciConstant _constant_value; 54 55 -
trunk/openjdk/hotspot/src/share/vm/classfile/javaClasses.cpp
r309 r406 277 277 } 278 278 return result; 279 } 280 281 unsigned int java_lang_String::to_hash(oop java_string) { 282 int length = java_lang_String::length(java_string); 283 // Zero length string will hash to zero with String.toHash() function. 284 if (length == 0) return 0; 285 286 typeArrayOop value = java_lang_String::value(java_string); 287 int offset = java_lang_String::offset(java_string); 288 return java_lang_String::to_hash(value->char_at_addr(offset), length); 289 } 290 291 unsigned int java_lang_String::hash_string(oop java_string) { 292 int length = java_lang_String::length(java_string); 293 // Zero length string doesn't hash necessarily hash to zero. 294 if (length == 0) { 295 return StringTable::hash_string(NULL, 0); 296 } 297 298 typeArrayOop value = java_lang_String::value(java_string); 299 int offset = java_lang_String::offset(java_string); 300 return StringTable::hash_string(value->char_at_addr(offset), length); 279 301 } 280 302 -
trunk/openjdk/hotspot/src/share/vm/classfile/javaClasses.hpp
r309 r406 109 109 static char* as_platform_dependent_str(Handle java_string, TRAPS); 110 110 static jchar* as_unicode_string(oop java_string, int& length); 111 112 // Compute the hash value for a java.lang.String object which would 113 // contain the characters passed in. 114 // 115 // As the hash value used by the String object itself, in 116 // String.hashCode(). This value is normally calculated in Java code 117 // in the String.hashCode method(), but is precomputed for String 118 // objects in the shared archive file. 119 // hash P(31) from Kernighan & Ritchie 120 // 121 // For this reason, THIS ALGORITHM MUST MATCH String.toHash(). 122 template <typename T> static unsigned int to_hash(T* s, int len) { 123 unsigned int h = 0; 124 while (len-- > 0) { 125 h = 31*h + (unsigned int) *s; 126 s++; 127 } 128 return h; 129 } 130 static unsigned int to_hash(oop java_string); 131 132 // This is the string hash code used by the StringTable, which may be 133 // the same as String.toHash or an alternate hash code. 134 static unsigned int hash_string(oop java_string); 111 135 112 136 static bool equals(oop java_string, jchar* chars, int len); -
trunk/openjdk/hotspot/src/share/vm/classfile/symbolTable.cpp
r309 r406 24 24 25 25 #include "precompiled.hpp" 26 #include "classfile/altHashing.hpp" 26 27 #include "classfile/javaClasses.hpp" 27 28 #include "classfile/symbolTable.hpp" … … 35 36 #include "runtime/mutexLocker.hpp" 36 37 #include "utilities/hashtable.inline.hpp" 38 #include "utilities/numberSeq.hpp" 37 39 38 40 // -------------------------------------------------------------------------- 39 41 40 42 SymbolTable* SymbolTable::_the_table = NULL; 43 bool SymbolTable::_needs_rehashing = false; 44 45 // Create a new table and using alternate hash code, populate the new table 46 // with the existing strings. Set flag to use the alternate hash code afterwards. 47 void SymbolTable::rehash_table() { 48 49 assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint"); 50 // This should never happen with -Xshare:dump but it might in testing mode. 51 if (DumpSharedSpaces) return; 52 // Create a new symbol table 53 SymbolTable* new_table = new SymbolTable(); 54 55 the_table()->move_to(new_table); 56 57 // Delete the table and buckets (entries are reused in new table). 58 delete _the_table; 59 // Don't check if we need rehashing until the table gets unbalanced again. 60 // Then rehash with a new global seed. 61 _needs_rehashing = false; 62 _the_table = new_table; 63 } 41 64 42 65 // Lookup a symbol in a bucket. … … 44 67 symbolOop SymbolTable::lookup(int index, const char* name, 45 68 int len, unsigned int hash) { 69 int count = 0; 46 70 for (HashtableEntry* e = bucket(index); e != NULL; e = e->next()) { 71 count++; 47 72 if (e->hash() == hash) { 48 73 symbolOop sym = symbolOop(e->literal()); … … 52 77 } 53 78 } 79 // If the bucket size is too deep check if this hash code is insufficient. 80 if (count >= BasicHashtable::rehash_count && !needs_rehashing()) { 81 _needs_rehashing = check_rehash_table(count); 82 } 54 83 return NULL; 84 } 85 86 // Pick hashing algorithm. 87 unsigned int SymbolTable::hash_symbol(const char* s, int len) { 88 return the_table()->use_alternate_hashcode() ? 89 AltHashing::murmur3_32(the_table()->seed(), (const jbyte*)s, len) : 90 java_lang_String::to_hash(s, len); 55 91 } 56 92 … … 72 108 if (s != NULL) return s; 73 109 110 // We assume that lookup() has been called already, that it failed, 111 // and symbol was not found. We create the symbol here. 112 symbolKlass* sk = (symbolKlass*) Universe::symbolKlassObj()->klass_part(); 113 symbolOop s_oop = sk->allocate_symbol((u1*)name, len, CHECK_NULL); 114 symbolHandle sym (THREAD, s_oop); 115 116 // Allocation must be done before grabbing the SymbolTable_lock lock 117 MutexLocker ml(SymbolTable_lock, THREAD); 118 74 119 // Otherwise, add to symbol to table 75 return the_table()->basic_add( index, (u1*)name, len, hashValue, CHECK_NULL);120 return the_table()->basic_add(sym, index, (u1*)name, len, hashValue, CHECK_NULL); 76 121 } 77 122 … … 109 154 // ResourceMark. 110 155 111 return the_table()->basic_add(index, (u1*)buffer, len, hashValue, CHECK_NULL); 156 // We assume that lookup() has been called already, that it failed, 157 // and symbol was not found. We create the symbol here. 158 symbolKlass* sk = (symbolKlass*) Universe::symbolKlassObj()->klass_part(); 159 symbolOop s_oop = sk->allocate_symbol((u1*)buffer, len, CHECK_NULL); 160 symbolHandle newsym (THREAD, s_oop); 161 162 // Allocation must be done before grabbing the SymbolTable_lock lock 163 MutexLocker ml(SymbolTable_lock, THREAD); 164 165 return the_table()->basic_add(newsym, index, (u1*)buffer, len, hashValue, CHECK_NULL); 112 166 } 113 167 … … 157 211 const char** names, int* lengths, int* cp_indices, 158 212 unsigned int* hashValues, TRAPS) { 159 SymbolTable* table = the_table(); 160 bool added = table->basic_add(cp, names_count, names, lengths, 161 cp_indices, hashValues, CHECK); 162 if (!added) { 213 214 symbolKlass* sk = (symbolKlass*) Universe::symbolKlassObj()->klass_part(); 215 symbolOop sym_oops[symbol_alloc_batch_size]; 216 bool allocated = sk->allocate_symbols(names_count, names, lengths, 217 sym_oops, CHECK); 218 if (!allocated) { 163 219 // do it the hard way 164 220 for (int i=0; i<names_count; i++) { 221 assert(!Universe::heap()->is_in_reserved(names[i]) || GC_locker::is_active(), 222 "proposed name of symbol must be stable"); 223 224 // We assume that lookup() has been called already, that it failed, 225 // and symbol was not found. We create the symbol here. 226 symbolKlass* sk = (symbolKlass*) Universe::symbolKlassObj()->klass_part(); 227 symbolOop s_oop = sk->allocate_symbol((u1*)names[i], lengths[i], CHECK); 228 symbolHandle sym (THREAD, s_oop); 229 230 // Allocation must be done before grabbing the SymbolTable_lock lock 231 MutexLocker ml(SymbolTable_lock, THREAD); 232 233 SymbolTable* table = the_table(); 165 234 int index = table->hash_to_index(hashValues[i]); 166 symbolOop s ym = table->basic_add(index, (u1*)names[i], lengths[i],235 symbolOop s = table->basic_add(sym, index, (u1*)names[i], lengths[i], 167 236 hashValues[i], CHECK); 168 cp->symbol_at_put(cp_indices[i], sym); 169 } 170 } 171 } 172 173 symbolOop SymbolTable::basic_add(int index, u1 *name, int len, 174 unsigned int hashValue, TRAPS) { 175 assert(!Universe::heap()->is_in_reserved(name) || GC_locker::is_active(), 176 "proposed name of symbol must be stable"); 177 178 // We assume that lookup() has been called already, that it failed, 179 // and symbol was not found. We create the symbol here. 180 symbolKlass* sk = (symbolKlass*) Universe::symbolKlassObj()->klass_part(); 181 symbolOop s_oop = sk->allocate_symbol(name, len, CHECK_NULL); 182 symbolHandle sym (THREAD, s_oop); 183 184 // Allocation must be done before grapping the SymbolTable_lock lock 237 cp->symbol_at_put(cp_indices[i], s); 238 } 239 return; 240 } 241 242 symbolHandle syms[symbol_alloc_batch_size]; 243 for (int i=0; i<names_count; i++) { 244 syms[i] = symbolHandle(THREAD, sym_oops[i]); 245 } 246 247 // Allocation must be done before grabbing the SymbolTable_lock lock 185 248 MutexLocker ml(SymbolTable_lock, THREAD); 186 249 250 SymbolTable* table = the_table(); 251 bool added = table->basic_add(syms, cp, names_count, names, lengths, 252 cp_indices, hashValues, CHECK); 253 assert(added, "should always return true"); 254 } 255 256 symbolOop SymbolTable::basic_add(symbolHandle sym, int index_arg, u1 *name, int len, 257 unsigned int hashValue_arg, TRAPS) { 258 // Cannot hit a safepoint in this function because the "this" pointer can move. 259 No_Safepoint_Verifier nsv; 260 187 261 assert(sym->equals((char*)name, len), "symbol must be properly initialized"); 262 263 // Check if the symbol table has been rehashed, if so, need to recalculate 264 // the hash value and index. 265 unsigned int hashValue; 266 int index; 267 if (use_alternate_hashcode()) { 268 hashValue = hash_symbol((const char*)name, len); 269 index = hash_to_index(hashValue); 270 } else { 271 hashValue = hashValue_arg; 272 index = index_arg; 273 } 188 274 189 275 // Since look-up was done lock-free, we need to check if another … … 202 288 } 203 289 204 bool SymbolTable::basic_add(constantPoolHandle cp, int names_count, 290 bool SymbolTable::basic_add(symbolHandle* syms, 291 constantPoolHandle cp, int names_count, 205 292 const char** names, int* lengths, 206 293 int* cp_indices, unsigned int* hashValues, 207 294 TRAPS) { 208 symbolKlass* sk = (symbolKlass*) Universe::symbolKlassObj()->klass_part(); 209 symbolOop sym_oops[symbol_alloc_batch_size]; 210 bool allocated = sk->allocate_symbols(names_count, names, lengths, 211 sym_oops, CHECK_false); 212 if (!allocated) { 213 return false; 214 } 215 symbolHandle syms[symbol_alloc_batch_size]; 216 int i; 217 for (i=0; i<names_count; i++) { 218 syms[i] = symbolHandle(THREAD, sym_oops[i]); 219 } 220 221 // Allocation must be done before grabbing the SymbolTable_lock lock 222 MutexLocker ml(SymbolTable_lock, THREAD); 223 224 for (i=0; i<names_count; i++) { 295 // Cannot hit a safepoint in this function because the "this" pointer can move. 296 No_Safepoint_Verifier nsv; 297 298 for (int i=0; i<names_count; i++) { 225 299 assert(syms[i]->equals(names[i], lengths[i]), "symbol must be properly initialized"); 300 // Check if the symbol table has been rehashed, if so, need to recalculate 301 // the hash value. 302 unsigned int hashValue; 303 if (use_alternate_hashcode()) { 304 hashValue = hash_symbol(names[i], lengths[i]); 305 } else { 306 hashValue = hashValues[i]; 307 } 226 308 // Since look-up was done lock-free, we need to check if another 227 309 // thread beat us in the race to insert the symbol. 228 int index = hash_to_index(hashValue s[i]);229 symbolOop test = lookup(index, names[i], lengths[i], hashValue s[i]);310 int index = hash_to_index(hashValue); 311 symbolOop test = lookup(index, names[i], lengths[i], hashValue); 230 312 if (test != NULL) { 231 313 // A race occurred and another thread introduced the symbol, this one … … 234 316 } else { 235 317 symbolOop sym = syms[i](); 236 HashtableEntry* entry = new_entry(hashValue s[i], sym);318 HashtableEntry* entry = new_entry(hashValue, sym); 237 319 add_entry(index, entry); 238 320 cp->symbol_at_put(cp_indices[i], sym); 239 321 } 240 322 } 241 242 return true; 243 } 244 323 return true; // always returns true 324 } 245 325 246 326 void SymbolTable::verify() { … … 252 332 s->verify(); 253 333 guarantee(s->is_perm(), "symbol not in permspace"); 254 unsigned int h = hash_symbol((c har*)s->bytes(), s->utf8_length());334 unsigned int h = hash_symbol((const char*)s->bytes(), s->utf8_length()); 255 335 guarantee(p->hash() == h, "broken hash in symbol table entry"); 256 336 guarantee(the_table()->hash_to_index(h) == i, … … 260 340 } 261 341 342 void SymbolTable::dump(outputStream* st) { 343 NumberSeq summary; 344 for (int i = 0; i < the_table()->table_size(); ++i) { 345 int count = 0; 346 for (HashtableEntry* e = the_table()->bucket(i); 347 e != NULL; e = e->next()) { 348 count++; 349 } 350 summary.add((double)count); 351 } 352 st->print_cr("SymbolTable statistics:"); 353 st->print_cr("Number of buckets : %7d", summary.num()); 354 st->print_cr("Average bucket size : %7.0f", summary.avg()); 355 st->print_cr("Variance of bucket size : %7.0f", summary.variance()); 356 st->print_cr("Std. dev. of bucket size: %7.0f", summary.sd()); 357 st->print_cr("Maximum bucket size : %7.0f", summary.maximum()); 358 } 262 359 263 360 //--------------------------------------------------------------------------- … … 322 419 results_length, out_of_range); 323 420 } 324 325 421 #endif // PRODUCT 326 422 … … 368 464 369 465 370 // Compute the hash value for a java.lang.String object which would371 // contain the characters passed in. This hash value is used for at372 // least two purposes.373 //374 // (a) As the hash value used by the StringTable for bucket selection375 // and comparison (stored in the HashtableEntry structures). This376 // is used in the String.intern() method.377 //378 // (b) As the hash value used by the String object itself, in379 // String.hashCode(). This value is normally calculate in Java code380 // in the String.hashCode method(), but is precomputed for String381 // objects in the shared archive file.382 //383 // For this reason, THIS ALGORITHM MUST MATCH String.hashCode().384 385 int StringTable::hash_string(jchar* s, int len) {386 unsigned h = 0;387 while (len-- > 0) {388 h = 31*h + (unsigned) *s;389 s++;390 }391 return h;392 }393 394 395 466 StringTable* StringTable::_the_table = NULL; 467 468 bool StringTable::_needs_rehashing = false; 469 470 // Pick hashing algorithm 471 unsigned int StringTable::hash_string(const jchar* s, int len) { 472 return the_table()->use_alternate_hashcode() ? AltHashing::murmur3_32(the_table()->seed(), s, len) : 473 java_lang_String::to_hash(s, len); 474 } 396 475 397 476 oop StringTable::lookup(int index, jchar* name, 398 477 int len, unsigned int hash) { 478 int count = 0; 399 479 for (HashtableEntry* l = bucket(index); l != NULL; l = l->next()) { 480 count++; 400 481 if (l->hash() == hash) { 401 482 if (java_lang_String::equals(l->literal(), name, len)) { … … 404 485 } 405 486 } 487 // If the bucket size is too deep check if this hash code is insufficient. 488 if (count >= BasicHashtable::rehash_count && !needs_rehashing()) { 489 _needs_rehashing = check_rehash_table(count); 490 } 406 491 return NULL; 407 492 } 408 493 409 494 410 oop StringTable::basic_add(int index, Handle string_or_null, jchar* name, 411 int len, unsigned int hashValue, TRAPS) { 412 debug_only(StableMemoryChecker smc(name, len * sizeof(name[0]))); 413 assert(!Universe::heap()->is_in_reserved(name) || GC_locker::is_active(), 414 "proposed name of symbol must be stable"); 415 416 Handle string; 417 // try to reuse the string if possible 418 if (!string_or_null.is_null() && string_or_null()->is_perm()) { 419 string = string_or_null; 420 } else { 421 string = java_lang_String::create_tenured_from_unicode(name, len, CHECK_NULL); 422 } 423 424 // Allocation must be done before grapping the SymbolTable_lock lock 425 MutexLocker ml(StringTable_lock, THREAD); 495 oop StringTable::basic_add(int index_arg, Handle string, jchar* name, 496 int len, unsigned int hashValue_arg, TRAPS) { 497 498 // Cannot hit a safepoint in this function because the "this" pointer can move. 499 No_Safepoint_Verifier nsv; 426 500 427 501 assert(java_lang_String::equals(string(), name, len), 428 502 "string must be properly initialized"); 503 504 // Check if the symbol table has been rehashed, if so, need to recalculate 505 // the hash value and index before second lookup. 506 unsigned int hashValue; 507 int index; 508 if (use_alternate_hashcode()) { 509 hashValue = hash_string(name, len); 510 index = hash_to_index(hashValue); 511 } else { 512 hashValue = hashValue_arg; 513 index = index_arg; 514 } 429 515 430 516 // Since look-up was done lock-free, we need to check if another … … 457 543 unsigned int hashValue = hash_string(name, len); 458 544 int index = the_table()->hash_to_index(hashValue); 459 oop string = the_table()->lookup(index, name, len, hashValue);545 oop found_string = the_table()->lookup(index, name, len, hashValue); 460 546 461 547 // Found 462 if (string != NULL) return string; 548 if (found_string != NULL) return found_string; 549 550 debug_only(StableMemoryChecker smc(name, len * sizeof(name[0]))); 551 assert(!Universe::heap()->is_in_reserved(name) || GC_locker::is_active(), 552 "proposed name of symbol must be stable"); 553 554 Handle string; 555 // try to reuse the string if possible 556 if (!string_or_null.is_null() && string_or_null()->is_perm()) { 557 string = string_or_null; 558 } else { 559 string = java_lang_String::create_tenured_from_unicode(name, len, CHECK_NULL); 560 } 561 562 // Allocation must be done before grabbing the StringTable_lock lock 563 MutexLocker ml(StringTable_lock, THREAD); 463 564 464 565 // Otherwise, add to symbol to table 465 return the_table()->basic_add(index, string _or_null, name, len,566 return the_table()->basic_add(index, string, name, len, 466 567 hashValue, CHECK_NULL); 467 568 } … … 518 619 } 519 620 } 621 622 void StringTable::dump(outputStream* st) { 623 NumberSeq summary; 624 for (int i = 0; i < the_table()->table_size(); ++i) { 625 HashtableEntry* p = the_table()->bucket(i); 626 int count = 0; 627 for ( ; p != NULL; p = p->next()) { 628 count++; 629 } 630 summary.add((double)count); 631 } 632 st->print_cr("StringTable statistics:"); 633 st->print_cr("Number of buckets : %7d", summary.num()); 634 st->print_cr("Average bucket size : %7.0f", summary.avg()); 635 st->print_cr("Variance of bucket size : %7.0f", summary.variance()); 636 st->print_cr("Std. dev. of bucket size: %7.0f", summary.sd()); 637 st->print_cr("Maximum bucket size : %7.0f", summary.maximum()); 638 } 639 640 641 // Create a new table and using alternate hash code, populate the new table 642 // with the existing strings. Set flag to use the alternate hash code afterwards. 643 void StringTable::rehash_table() { 644 assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint"); 645 // This should never happen with -Xshare:dump but it might in testing mode. 646 if (DumpSharedSpaces) return; 647 StringTable* new_table = new StringTable(); 648 649 // Rehash the table 650 the_table()->move_to(new_table); 651 652 // Delete the table and buckets (entries are reused in new table). 653 delete _the_table; 654 // Don't check if we need rehashing until the table gets unbalanced again. 655 // Then rehash with a new global seed. 656 _needs_rehashing = false; 657 _the_table = new_table; 658 } -
trunk/openjdk/hotspot/src/share/vm/classfile/symbolTable.hpp
r309 r406 41 41 42 42 class BoolObjectClosure; 43 class outputStream; 43 44 44 45 … … 50 51 static SymbolTable* _the_table; 51 52 53 // Set if one bucket is out of balance due to hash algorithm deficiency 54 static bool _needs_rehashing; 55 52 56 // Adding elements 53 symbolOop basic_add( int index, u1* name, int len,57 symbolOop basic_add(symbolHandle sym, int index, u1* name, int len, 54 58 unsigned int hashValue, TRAPS); 55 bool basic_add( constantPoolHandle cp, int names_count,59 bool basic_add(symbolHandle* syms, constantPoolHandle cp, int names_count, 56 60 const char** names, int* lengths, int* cp_indices, 57 61 unsigned int* hashValues, TRAPS); … … 62 66 }; 63 67 68 static unsigned int hash_symbol(const char* s, int len); 69 64 70 symbolOop lookup(int index, const char* name, int len, unsigned int hash); 65 71 … … 70 76 : Hashtable(symbol_table_size, sizeof (HashtableEntry), t, 71 77 number_of_entries) {} 72 73 78 74 79 public: … … 138 143 // Debugging 139 144 static void verify(); 145 static void dump(outputStream* st); 140 146 141 147 // Sharing … … 149 155 ((Hashtable*)the_table())->reverse(boundary); 150 156 } 157 158 // Rehash the symbol table if it gets out of balance 159 static void rehash_table(); 160 static bool needs_rehashing() { return _needs_rehashing; } 151 161 }; 152 162 … … 159 169 static StringTable* _the_table; 160 170 171 // Set if one bucket is out of balance due to hash algorithm deficiency 172 static bool _needs_rehashing; 173 161 174 static oop intern(Handle string_or_null, jchar* chars, int length, TRAPS); 162 oop basic_add(int index, Handle string _or_null, jchar* name, int len,175 oop basic_add(int index, Handle string, jchar* name, int len, 163 176 unsigned int hashValue, TRAPS); 164 177 … … 193 206 } 194 207 195 196 static int hash_string(jchar* s, int len);197 198 199 208 // GC support 200 209 // Delete pointers to otherwise-unreachable objects. … … 208 217 } 209 218 219 // Hashing algorithm, used as the hash value used by the 220 // StringTable for bucket selection and comparison (stored in the 221 // HashtableEntry structures). This is used in the String.intern() method. 222 static unsigned int hash_string(const jchar* s, int len); 223 224 // Internal test. 225 static void test_alt_hash() PRODUCT_RETURN; 226 210 227 // Probing 211 228 static oop lookup(symbolOop symbol); … … 218 235 // Debugging 219 236 static void verify(); 237 static void dump(outputStream* st); 220 238 221 239 // Sharing … … 229 247 ((BasicHashtable*)the_table())->reverse(); 230 248 } 249 250 // Rehash the symbol table if it gets out of balance 251 static void rehash_table(); 252 static bool needs_rehashing() { return _needs_rehashing; } 231 253 }; 232 233 254 #endif // SHARE_VM_CLASSFILE_SYMBOLTABLE_HPP -
trunk/openjdk/hotspot/src/share/vm/classfile/verifier.cpp
r309 r406 1872 1872 VerificationType::reference_check(), CHECK_VERIFY(this)); 1873 1873 if (type == VerificationType::uninitialized_this_type()) { 1874 // The method must be an <init> method of either this class, or one of its1875 // superclasses1874 // The method must be an <init> method of this class or its superclass 1875 klassOop superk = current_class()->super(); 1876 1876 if (ref_class_type.name() != current_class()->name() && 1877 !name_in_supers(ref_class_type.name(), current_class())) {1877 ref_class_type.name() != superk->klass_part()->name()) { 1878 1878 verify_error(bci, "Bad <init> method call"); 1879 1879 return; -
trunk/openjdk/hotspot/src/share/vm/compiler/compilerOracle.cpp
r309 r406 552 552 553 553 static const char* cc_file() { 554 if (CompileCommandFile == NULL) 554 #ifdef ASSERT 555 if (CompileCommandFile == NULL) { 555 556 return ".hotspot_compiler"; 557 } 558 #endif 556 559 return CompileCommandFile; 557 560 } 561 562 bool CompilerOracle::has_command_file() { 563 return cc_file() != NULL; 564 } 565 558 566 bool CompilerOracle::_quiet = false; 559 567 560 568 void CompilerOracle::parse_from_file() { 569 assert(has_command_file(), "command file must be specified"); 561 570 FILE* stream = fopen(cc_file(), "rt"); 562 571 if (stream == NULL) return; … … 565 574 int pos = 0; 566 575 int c = getc(stream); 567 while(c != EOF ) {576 while(c != EOF && pos < (int)(sizeof(token)-1)) { 568 577 if (c == '\n') { 569 578 token[pos++] = '\0'; … … 586 595 const char* sp = str; 587 596 int c = *sp++; 588 while (c != '\0' ) {597 while (c != '\0' && pos < (int)(sizeof(token)-1)) { 589 598 if (c == '\n') { 590 599 token[pos++] = '\0'; … … 601 610 602 611 void CompilerOracle::append_comment_to_file(const char* message) { 612 assert(has_command_file(), "command file must be specified"); 603 613 fileStream stream(fopen(cc_file(), "at")); 604 614 stream.print("# "); … … 611 621 612 622 void CompilerOracle::append_exclude_to_file(methodHandle method) { 623 assert(has_command_file(), "command file must be specified"); 613 624 fileStream stream(fopen(cc_file(), "at")); 614 625 stream.print("exclude "); … … 625 636 CompilerOracle::parse_from_string(CompileCommand, CompilerOracle::parse_from_line); 626 637 CompilerOracle::parse_from_string(CompileOnly, CompilerOracle::parse_compile_only); 627 CompilerOracle::parse_from_file(); 638 if (CompilerOracle::has_command_file()) { 639 CompilerOracle::parse_from_file(); 640 } 628 641 if (lists[PrintCommand] != NULL) { 629 642 if (PrintAssembly) { -
trunk/openjdk/hotspot/src/share/vm/compiler/compilerOracle.hpp
r309 r406 39 39 40 40 public: 41 42 // True if the command file has been specified or is implicit 43 static bool has_command_file(); 44 41 45 // Reads from file and adds to lists 42 46 static void parse_from_file(); -
trunk/openjdk/hotspot/src/share/vm/memory/dump.cpp
r309 r406 63 63 // the hash can be shared. 64 64 // 65 // NOTE THAT the algorithm in StringTable::hash_string() MUST MATCHthe66 // algorithm in java.lang.String. hashCode().65 // NOTE THAT we have to call java_lang_String::to_hash() to match the 66 // algorithm in java.lang.String.toHash(). 67 67 68 68 class StringHashCodeClosure: public OopClosure { … … 89 89 int offset = java_lang_String::offset(obj); 90 90 jchar* s = value->char_at_addr(offset); 91 hash = StringTable::hash_string(s, length);91 hash = java_lang_String::to_hash(s, length); 92 92 } 93 93 obj->int_field_put(hash_offset, hash); -
trunk/openjdk/hotspot/src/share/vm/opto/addnode.cpp
r309 r406 34 34 35 35 // Portions of code courtesy of Clifford Click 36 37 #define MAXFLOAT ((float)3.40282346638528860e+38)38 36 39 37 // Classic Add functionality. This covers all the usual 'add' behaviors for -
trunk/openjdk/hotspot/src/share/vm/opto/loopTransform.cpp
r390 r406 2722 2722 _igvn.register_new_node_with_optimizer(result_mem); 2723 2723 2724 /* Disable following optimization until proper fix (add missing checks). 2725 2724 2726 // If this fill is tightly coupled to an allocation and overwrites 2725 2727 // the whole body, allow it to take over the zeroing. … … 2745 2747 } 2746 2748 } 2749 */ 2747 2750 2748 2751 // Redirect the old control and memory edges that are outside the loop. -
trunk/openjdk/hotspot/src/share/vm/opto/loopnode.cpp
r309 r406 1 1 /* 2 * Copyright (c) 1998, 201 0, Oracle and/or its affiliates. All rights reserved.2 * Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved. 3 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 4 * … … 547 547 Node* expr, Node** trunc1, Node** trunc2, const TypeInt** trunc_type) { 548 548 // Quick cutouts: 549 if (expr == NULL || expr->req() != 3) return false;549 if (expr == NULL || expr->req() != 3) return NULL; 550 550 551 551 Node *t1 = NULL; -
trunk/openjdk/hotspot/src/share/vm/opto/runtime.cpp
r309 r406 805 805 tty->print_cr("# Method where it happened %s.%s ", Klass::cast(method->method_holder())->name()->as_C_string(), method->name()->as_C_string()); 806 806 tty->print_cr("#"); 807 if (ShowMessageBoxOnError && UpdateHotSpotCompilerFileOnError) { 807 if (ShowMessageBoxOnError && UpdateHotSpotCompilerFileOnError && 808 CompilerOracle::has_command_file()) { 808 809 const char* title = "HotSpot Runtime Error"; 809 810 const char* question = "Do you want to exclude compilation of this method in future runs?"; -
trunk/openjdk/hotspot/src/share/vm/prims/jniCheck.cpp
r309 r406 102 102 NativeReportJNIFatalError(thr, warn_wrong_jnienv); \ 103 103 } \ 104 __ENTRY(result_type, header, thr)104 VM_ENTRY_BASE(result_type, header, thr) 105 105 106 106 -
trunk/openjdk/hotspot/src/share/vm/prims/jvmtiEnter.xsl
r309 r406 427 427 <xsl:text>ThreadInVMfromNative __tiv(current_thread);</xsl:text> 428 428 <xsl:value-of select="$space"/> 429 <xsl:text> __ENTRY(jvmtiError, </xsl:text>429 <xsl:text>VM_ENTRY_BASE(jvmtiError, </xsl:text> 430 430 <xsl:apply-templates select="." mode="functionid"/> 431 431 <xsl:text> , current_thread)</xsl:text> -
trunk/openjdk/hotspot/src/share/vm/prims/jvmtiEnv.cpp
r309 r406 171 171 172 172 ThreadInVMfromNative __tiv(current_thread); 173 __ENTRY(jvmtiError, JvmtiEnv::GetThreadLocalStorage , current_thread)173 VM_ENTRY_BASE(jvmtiError, JvmtiEnv::GetThreadLocalStorage , current_thread) 174 174 debug_only(VMNativeEntryWrapper __vew;) 175 175 -
trunk/openjdk/hotspot/src/share/vm/prims/jvmtiExport.cpp
r390 r406 374 374 // transition code: native to VM 375 375 ThreadInVMfromNative __tiv(current_thread); 376 __ENTRY(jvmtiEnv*, JvmtiExport::get_jvmti_interface, current_thread)376 VM_ENTRY_BASE(jvmtiEnv*, JvmtiExport::get_jvmti_interface, current_thread) 377 377 debug_only(VMNativeEntryWrapper __vew;) 378 378 -
trunk/openjdk/hotspot/src/share/vm/runtime/arguments.cpp
r309 r406 1 1 /* 2 * Copyright (c) 1997, 201 1, Oracle and/or its affiliates. All rights reserved.2 * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. 3 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 4 * … … 843 843 844 844 int c = getc(stream); 845 while(c != EOF ) {845 while(c != EOF && pos < (int)(sizeof(token)-1)) { 846 846 if (in_white_space) { 847 847 if (in_comment) { … … 2969 2969 } 2970 2970 2971 #ifdef ASSERT 2971 2972 // Parse default .hotspotrc settings file 2972 2973 if (!settings_file_specified) { … … 2975 2976 } 2976 2977 } 2978 #endif 2977 2979 2978 2980 if (PrintVMOptions) { -
trunk/openjdk/hotspot/src/share/vm/runtime/globals.hpp
r390 r406 2512 2512 "use heavyweight instead of lightweight Java monitors") \ 2513 2513 \ 2514 product(bool, PrintStringTableStatistics, false, \ 2515 "print statistics about the StringTable and SymbolTable") \ 2516 \ 2514 2517 notproduct(bool, PrintSymbolTableSizeHistogram, false, \ 2515 2518 "print histogram of the symbol table") \ -
trunk/openjdk/hotspot/src/share/vm/runtime/init.cpp
r309 r406 24 24 25 25 #include "precompiled.hpp" 26 #include "classfile/symbolTable.hpp" 26 27 #include "code/icBuffer.hpp" 27 28 #include "gc_interface/collectedHeap.hpp" … … 154 155 SafepointSynchronize::print_stat_on_exit(); 155 156 } 157 if (PrintStringTableStatistics) { 158 SymbolTable::dump(tty); 159 StringTable::dump(tty); 160 } 156 161 ostream_exit(); 157 162 } -
trunk/openjdk/hotspot/src/share/vm/runtime/interfaceSupport.hpp
r309 r406 70 70 }; 71 71 72 // InterfaceSupport provides functionality used by the __LEAF and __ENTRY73 // macros. These macros are used to guard entry points into the VM and74 // perform checks upon leave of the VM.72 // InterfaceSupport provides functionality used by the VM_LEAF_BASE and 73 // VM_ENTRY_BASE macros. These macros are used to guard entry points into 74 // the VM and perform checks upon leave of the VM. 75 75 76 76 … … 424 424 // LEAF routines do not lock, GC or throw exceptions 425 425 426 #define __LEAF(result_type, header)\426 #define VM_LEAF_BASE(result_type, header) \ 427 427 TRACE_CALL(result_type, header) \ 428 428 debug_only(NoHandleMark __hm;) \ … … 432 432 // ENTRY routines may lock, GC and throw exceptions 433 433 434 #define __ENTRY(result_type, header, thread)\434 #define VM_ENTRY_BASE(result_type, header, thread) \ 435 435 TRACE_CALL(result_type, header) \ 436 436 HandleMarkCleaner __hm(thread); \ … … 441 441 // QUICK_ENTRY routines behave like ENTRY but without a handle mark 442 442 443 #define __QUICK_ENTRY(result_type, header, thread)\443 #define VM_QUICK_ENTRY_BASE(result_type, header, thread) \ 444 444 TRACE_CALL(result_type, header) \ 445 445 debug_only(NoHandleMark __hm;) \ … … 454 454 result_type header { \ 455 455 ThreadInVMfromJava __tiv(thread); \ 456 __ENTRY(result_type, header, thread)\456 VM_ENTRY_BASE(result_type, header, thread) \ 457 457 debug_only(VMEntryWrapper __vew;) 458 458 … … 460 460 #define IRT_LEAF(result_type, header) \ 461 461 result_type header { \ 462 __LEAF(result_type, header)\462 VM_LEAF_BASE(result_type, header) \ 463 463 debug_only(No_Safepoint_Verifier __nspv(true);) 464 464 … … 467 467 result_type header { \ 468 468 ThreadInVMfromJavaNoAsyncException __tiv(thread); \ 469 __ENTRY(result_type, header, thread)\469 VM_ENTRY_BASE(result_type, header, thread) \ 470 470 debug_only(VMEntryWrapper __vew;) 471 471 … … 478 478 nmethodLocker _nmlock(nm); \ 479 479 ThreadInVMfromJavaNoAsyncException __tiv(thread); \ 480 __ENTRY(result_type, header, thread)480 VM_ENTRY_BASE(result_type, header, thread) 481 481 482 482 #define IRT_END } … … 488 488 result_type header { \ 489 489 ThreadInVMfromJava __tiv(thread); \ 490 __ENTRY(result_type, header, thread)\490 VM_ENTRY_BASE(result_type, header, thread) \ 491 491 debug_only(VMEntryWrapper __vew;) 492 492 … … 494 494 #define JRT_LEAF(result_type, header) \ 495 495 result_type header { \ 496 __LEAF(result_type, header)\496 VM_LEAF_BASE(result_type, header) \ 497 497 debug_only(JRT_Leaf_Verifier __jlv;) 498 498 … … 501 501 result_type header { \ 502 502 ThreadInVMfromJavaNoAsyncException __tiv(thread); \ 503 __ENTRY(result_type, header, thread)\503 VM_ENTRY_BASE(result_type, header, thread) \ 504 504 debug_only(VMEntryWrapper __vew;) 505 505 … … 534 534 ThreadInVMfromNative __tiv(thread); \ 535 535 debug_only(VMNativeEntryWrapper __vew;) \ 536 __ENTRY(result_type, header, thread)536 VM_ENTRY_BASE(result_type, header, thread) 537 537 538 538 539 539 // Ensure that the VMNativeEntryWrapper constructor, which can cause 540 // a GC, is called outside the NoHandleMark (set via __QUICK_ENTRY).540 // a GC, is called outside the NoHandleMark (set via VM_QUICK_ENTRY_BASE). 541 541 #define JNI_QUICK_ENTRY(result_type, header) \ 542 542 extern "C" { \ … … 546 546 ThreadInVMfromNative __tiv(thread); \ 547 547 debug_only(VMNativeEntryWrapper __vew;) \ 548 __QUICK_ENTRY(result_type, header, thread)548 VM_QUICK_ENTRY_BASE(result_type, header, thread) 549 549 550 550 … … 554 554 JavaThread* thread=JavaThread::thread_from_jni_environment(env); \ 555 555 assert( !VerifyJNIEnvThread || (thread == Thread::current()), "JNIEnv is only valid in same thread"); \ 556 __LEAF(result_type, header)556 VM_LEAF_BASE(result_type, header) 557 557 558 558 … … 570 570 ThreadInVMfromNative __tiv(thread); \ 571 571 debug_only(VMNativeEntryWrapper __vew;) \ 572 __ENTRY(result_type, header, thread)572 VM_ENTRY_BASE(result_type, header, thread) 573 573 574 574 … … 579 579 ThreadInVMfromNative __tiv(thread); \ 580 580 debug_only(VMNativeEntryWrapper __vew;) \ 581 __ENTRY(result_type, header, thread)581 VM_ENTRY_BASE(result_type, header, thread) 582 582 583 583 … … 588 588 ThreadInVMfromNative __tiv(thread); \ 589 589 debug_only(VMNativeEntryWrapper __vew;) \ 590 __QUICK_ENTRY(result_type, header, thread)590 VM_QUICK_ENTRY_BASE(result_type, header, thread) 591 591 592 592 … … 595 595 result_type JNICALL header { \ 596 596 VM_Exit::block_if_vm_exited(); \ 597 __LEAF(result_type, header)597 VM_LEAF_BASE(result_type, header) 598 598 599 599 -
trunk/openjdk/hotspot/src/share/vm/runtime/safepoint.cpp
r309 r406 24 24 25 25 #include "precompiled.hpp" 26 #include "classfile/symbolTable.hpp" 26 27 #include "classfile/systemDictionary.hpp" 27 28 #include "code/codeCache.hpp" … … 502 503 } 503 504 504 TraceTime t4("sweeping nmethods", TraceSafepointCleanupTime); 505 NMethodSweeper::scan_stacks(); 505 { 506 TraceTime t4("sweeping nmethods", TraceSafepointCleanupTime); 507 NMethodSweeper::scan_stacks(); 508 } 509 510 if (SymbolTable::needs_rehashing()) { 511 TraceTime t5("rehashing symbol table", TraceSafepointCleanupTime); 512 SymbolTable::rehash_table(); 513 } 514 515 if (StringTable::needs_rehashing()) { 516 TraceTime t6("rehashing string table", TraceSafepointCleanupTime); 517 StringTable::rehash_table(); 518 } 506 519 } 507 520 -
trunk/openjdk/hotspot/src/share/vm/utilities/hashtable.cpp
r309 r406 1 /* 2 * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. 1 /* * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved. 3 2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 3 * … … 24 23 25 24 #include "precompiled.hpp" 25 #include "classfile/altHashing.hpp" 26 #include "classfile/javaClasses.hpp" 26 27 #include "memory/allocation.inline.hpp" 28 #include "memory/filemap.hpp" 27 29 #include "memory/resourceArea.hpp" 28 30 #include "oops/oop.inline.hpp" … … 70 72 HashtableEntry* Hashtable::new_entry(unsigned int hashValue, oop obj) { 71 73 HashtableEntry* entry; 72 73 74 entry = (HashtableEntry*)BasicHashtable::new_entry(hashValue); 74 75 entry->set_literal(obj); // clears literal string field … … 86 87 assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint"); 87 88 for (int i = 0; i < table_size(); ++i) { 88 for (HashtableEntry** p = bucket_addr(i); *p != NULL; ) { 89 HashtableEntry* entry = *p; 90 if (entry->is_shared()) { 89 HashtableEntry** p = bucket_addr(i); 90 HashtableEntry* entry = bucket(i); 91 while (entry != NULL) { 92 // Shared entries are normally at the end of the bucket and if we run into 93 // a shared entry, then there is nothing more to remove. However, if we 94 // have rehashed the table, then the shared entries are no longer at the 95 // end of the bucket. 96 if (entry->is_shared() && !use_alternate_hashcode()) { 91 97 break; 92 98 } 93 99 assert(entry->literal() != NULL, "just checking"); 94 if ( is_alive->do_object_b(entry->literal())) {100 if (entry->is_shared() || is_alive->do_object_b(entry->literal())) { 95 101 p = entry->next_addr(); 96 102 } else { … … 98 104 free_entry(entry); 99 105 } 106 entry = (HashtableEntry*)HashtableEntry::make_ptr(*p); 100 107 } 101 108 } … … 120 127 entry = (HashtableEntry*)HashtableEntry::make_ptr(*p); 121 128 } 129 } 130 } 131 132 133 // Check to see if the hashtable is unbalanced. The caller set a flag to 134 // rehash at the next safepoint. If this bucket is 60 times greater than the 135 // expected average bucket length, it's an unbalanced hashtable. 136 // This is somewhat an arbitrary heuristic but if one bucket gets to 137 // rehash_count which is currently 100, there's probably something wrong. 138 139 bool BasicHashtable::check_rehash_table(int count) { 140 assert(table_size() != 0, "underflow"); 141 if (count > (((double)number_of_entries()/(double)table_size())*rehash_multiple)) { 142 // Set a flag for the next safepoint, which should be at some guaranteed 143 // safepoint interval. 144 return true; 145 } 146 return false; 147 } 148 149 unsigned int Hashtable::new_hash(oop string) { 150 ResourceMark rm; 151 int length; 152 if (java_lang_String::is_instance(string)) { 153 jchar* chars = java_lang_String::as_unicode_string(string, length); 154 // Use alternate hashing algorithm on the string 155 return AltHashing::murmur3_32(seed(), chars, length); 156 } else { 157 // Use alternate hashing algorithm on this symbol. 158 symbolOop symOop = (symbolOop) string; 159 return AltHashing::murmur3_32(seed(), (const jbyte*)symOop->bytes(), symOop->utf8_length()); 160 } 161 } 162 163 // Create a new table and using alternate hash code, populate the new table 164 // with the existing elements. This can be used to change the hash code 165 // and could in the future change the size of the table. 166 167 void Hashtable::move_to(Hashtable* new_table) { 168 // Initialize the global seed for hashing. 169 assert(new_table->seed() == 0, "should be zero"); 170 _seed = AltHashing::compute_seed(); 171 assert(seed() != 0, "shouldn't be zero"); 172 new_table->set_seed(_seed); 173 174 int saved_entry_count = this->number_of_entries(); 175 176 // Iterate through the table and create a new entry for the new table 177 for (int i = 0; i < new_table->table_size(); ++i) { 178 for (HashtableEntry* p = bucket(i); p != NULL; ) { 179 HashtableEntry* next = p->next(); 180 oop string = p->literal(); 181 // Use alternate hashing algorithm on the symbol in the first table 182 unsigned int hashValue = new_hash(string); 183 // Get a new index relative to the new table (can also change size) 184 int index = new_table->hash_to_index(hashValue); 185 p->set_hash(hashValue); 186 // Keep the shared bit in the Hashtable entry to indicate that this entry 187 // can't be deleted. The shared bit is the LSB in the _next field so 188 // walking the hashtable past these entries requires 189 // BasicHashtableEntry::make_ptr() call. 190 bool keep_shared = p->is_shared(); 191 unlink_entry(p); 192 new_table->add_entry(index, p); 193 if (keep_shared) { 194 p->set_shared(); 195 } 196 p = next; 197 } 198 } 199 // give the new table the free list as well 200 new_table->copy_freelist(this); 201 assert(new_table->number_of_entries() == saved_entry_count, "lost entry on dictionary copy?"); 202 203 // Destroy memory used by the buckets in the hashtable. The memory 204 // for the elements has been used in a new table and is not 205 // destroyed. The memory reuse will benefit resizing the SystemDictionary 206 // to avoid a memory allocation spike at safepoint. 207 free_buckets(); 208 } 209 210 void BasicHashtable::free_buckets() { 211 if (NULL != _buckets) { 212 // Don't delete the buckets in the shared space. They aren't 213 // allocated by os::malloc 214 if (!UseSharedSpaces || 215 !FileMapInfo::current_info()->is_in_shared_space(_buckets)) { 216 FREE_C_HEAP_ARRAY(HashtableBucket, _buckets); 217 } 218 _buckets = NULL; 122 219 } 123 220 } -
trunk/openjdk/hotspot/src/share/vm/utilities/hashtable.hpp
r309 r406 178 178 #endif 179 179 180 enum { 181 rehash_count = 100, 182 rehash_multiple = 60 183 }; 184 180 185 void initialize(int table_size, int entry_size, int number_of_entries); 181 186 … … 193 198 BasicHashtableEntry* new_entry(unsigned int hashValue); 194 199 200 // Check that the table is unbalanced 201 bool check_rehash_table(int count); 202 203 // Used when moving the entry to another table 204 // Clean up links, but do not add to free_list 205 void unlink_entry(BasicHashtableEntry* entry) { 206 entry->set_next(NULL); 207 --_number_of_entries; 208 } 209 210 // Move over freelist and free block for allocation 211 void copy_freelist(BasicHashtable* src) { 212 _free_list = src->_free_list; 213 src->_free_list = NULL; 214 _first_free_entry = src->_first_free_entry; 215 src->_first_free_entry = NULL; 216 _end_block = src->_end_block; 217 src->_end_block = NULL; 218 } 219 220 // Free the buckets in this hashtable 221 void free_buckets(); 222 195 223 public: 196 224 void set_entry(int index, BasicHashtableEntry* entry); … … 211 239 public: 212 240 Hashtable(int table_size, int entry_size) 213 : BasicHashtable(table_size, entry_size) { }241 : BasicHashtable(table_size, entry_size), _seed(0) { } 214 242 215 243 Hashtable(int table_size, int entry_size, 216 244 HashtableBucket* buckets, int number_of_entries) 217 : BasicHashtable(table_size, entry_size, buckets, number_of_entries) { }245 : BasicHashtable(table_size, entry_size, buckets, number_of_entries), _seed(0) { } 218 246 219 247 // Invoke "f->do_oop" on the locations of all oops in the table. … … 235 263 protected: 236 264 237 static unsigned int hash_symbol(const char* s, int len);238 239 265 unsigned int compute_hash(symbolHandle name) { 240 266 return (unsigned int) name->identity_hash(); … … 257 283 return (HashtableEntry**)BasicHashtable::bucket_addr(i); 258 284 } 285 286 // Function to move these elements into the new table. 287 void move_to(Hashtable* new_table); 288 bool use_alternate_hashcode() { return _seed != 0; } 289 jint seed() { return _seed; } 290 void set_seed(jint seed) { _seed = seed; } 291 292 private: 293 jint _seed; 294 295 unsigned int new_hash(oop string); 259 296 }; 260 297 -
trunk/openjdk/hotspot/src/share/vm/utilities/hashtable.inline.hpp
r309 r406 30 30 31 31 // Inline function definitions for hashtable.hpp. 32 33 34 // --------------------------------------------------------------------------35 // Hash function36 37 // We originally used hashpjw, but hash P(31) gives just as good results38 // and is slighly faster. We would like a hash function that looks at every39 // character, since package names have large common prefixes, and also because40 // hash_or_fail does error checking while iterating.41 42 // hash P(31) from Kernighan & Ritchie43 44 inline unsigned int Hashtable::hash_symbol(const char* s, int len) {45 unsigned int h = 0;46 while (len-- > 0) {47 h = 31*h + (unsigned) *s;48 s++;49 }50 return h;51 }52 53 32 54 33 // --------------------------------------------------------------------------
Note:
See TracChangeset
for help on using the changeset viewer.