Mercurial > hg > truffle
comparison src/share/vm/classfile/dictionary.cpp @ 2177:3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
Summary: move symbols from permgen into C heap and reference count them
Reviewed-by: never, acorn, jmasa, stefank
author | coleenp |
---|---|
date | Thu, 27 Jan 2011 16:11:27 -0800 |
parents | f95d63e2154a |
children | 1d1603768966 |
comparison
equal
deleted
inserted
replaced
2176:27e4ea99855d | 2177:3582bf76420e |
---|---|
34 DictionaryEntry* Dictionary::_current_class_entry = NULL; | 34 DictionaryEntry* Dictionary::_current_class_entry = NULL; |
35 int Dictionary::_current_class_index = 0; | 35 int Dictionary::_current_class_index = 0; |
36 | 36 |
37 | 37 |
38 Dictionary::Dictionary(int table_size) | 38 Dictionary::Dictionary(int table_size) |
39 : TwoOopHashtable(table_size, sizeof(DictionaryEntry)) { | 39 : TwoOopHashtable<klassOop>(table_size, sizeof(DictionaryEntry)) { |
40 _current_class_index = 0; | 40 _current_class_index = 0; |
41 _current_class_entry = NULL; | 41 _current_class_entry = NULL; |
42 }; | 42 }; |
43 | 43 |
44 | 44 |
45 | 45 |
46 Dictionary::Dictionary(int table_size, HashtableBucket* t, | 46 Dictionary::Dictionary(int table_size, HashtableBucket* t, |
47 int number_of_entries) | 47 int number_of_entries) |
48 : TwoOopHashtable(table_size, sizeof(DictionaryEntry), t, number_of_entries) { | 48 : TwoOopHashtable<klassOop>(table_size, sizeof(DictionaryEntry), t, number_of_entries) { |
49 _current_class_index = 0; | 49 _current_class_index = 0; |
50 _current_class_entry = NULL; | 50 _current_class_entry = NULL; |
51 }; | 51 }; |
52 | 52 |
53 | 53 |
54 DictionaryEntry* Dictionary::new_entry(unsigned int hash, klassOop klass, | 54 DictionaryEntry* Dictionary::new_entry(unsigned int hash, klassOop klass, |
55 oop loader) { | 55 oop loader) { |
56 DictionaryEntry* entry; | 56 DictionaryEntry* entry; |
57 entry = (DictionaryEntry*)Hashtable::new_entry(hash, klass); | 57 entry = (DictionaryEntry*)Hashtable<klassOop>::new_entry(hash, klass); |
58 entry->set_loader(loader); | 58 entry->set_loader(loader); |
59 entry->set_pd_set(NULL); | 59 entry->set_pd_set(NULL); |
60 return entry; | 60 return entry; |
61 } | 61 } |
62 | 62 |
63 | 63 |
64 DictionaryEntry* Dictionary::new_entry() { | 64 DictionaryEntry* Dictionary::new_entry() { |
65 DictionaryEntry* entry = (DictionaryEntry*)Hashtable::new_entry(0L, NULL); | 65 DictionaryEntry* entry = (DictionaryEntry*)Hashtable<klassOop>::new_entry(0L, NULL); |
66 entry->set_loader(NULL); | 66 entry->set_loader(NULL); |
67 entry->set_pd_set(NULL); | 67 entry->set_pd_set(NULL); |
68 return entry; | 68 return entry; |
69 } | 69 } |
70 | 70 |
74 while (entry->pd_set() != NULL) { | 74 while (entry->pd_set() != NULL) { |
75 ProtectionDomainEntry* to_delete = entry->pd_set(); | 75 ProtectionDomainEntry* to_delete = entry->pd_set(); |
76 entry->set_pd_set(to_delete->next()); | 76 entry->set_pd_set(to_delete->next()); |
77 delete to_delete; | 77 delete to_delete; |
78 } | 78 } |
79 Hashtable::free_entry(entry); | 79 Hashtable<klassOop>::free_entry(entry); |
80 } | 80 } |
81 | 81 |
82 | 82 |
83 bool DictionaryEntry::contains_protection_domain(oop protection_domain) const { | 83 bool DictionaryEntry::contains_protection_domain(oop protection_domain) const { |
84 #ifdef ASSERT | 84 #ifdef ASSERT |
296 // Follow all system classes and temporary placeholders in dictionary | 296 // Follow all system classes and temporary placeholders in dictionary |
297 for (int index = 0; index < table_size(); index++) { | 297 for (int index = 0; index < table_size(); index++) { |
298 for (DictionaryEntry *probe = bucket(index); | 298 for (DictionaryEntry *probe = bucket(index); |
299 probe != NULL; | 299 probe != NULL; |
300 probe = probe->next()) { | 300 probe = probe->next()) { |
301 oop e = probe->klass(); | 301 klassOop e = probe->klass(); |
302 oop class_loader = probe->loader(); | 302 oop class_loader = probe->loader(); |
303 if (is_strongly_reachable(class_loader, e)) { | 303 if (is_strongly_reachable(class_loader, e)) { |
304 blk->do_oop((oop*)probe->klass_addr()); | 304 blk->do_oop((oop*)probe->klass_addr()); |
305 if (class_loader != NULL) { | 305 if (class_loader != NULL) { |
306 blk->do_oop(probe->loader_addr()); | 306 blk->do_oop(probe->loader_addr()); |
419 // Readers of the SystemDictionary aren't always locked, so _buckets | 419 // Readers of the SystemDictionary aren't always locked, so _buckets |
420 // is volatile. The store of the next field in the constructor is | 420 // is volatile. The store of the next field in the constructor is |
421 // also cast to volatile; we do this to ensure store order is maintained | 421 // also cast to volatile; we do this to ensure store order is maintained |
422 // by the compilers. | 422 // by the compilers. |
423 | 423 |
424 void Dictionary::add_klass(symbolHandle class_name, Handle class_loader, | 424 void Dictionary::add_klass(Symbol* class_name, Handle class_loader, |
425 KlassHandle obj) { | 425 KlassHandle obj) { |
426 assert_locked_or_safepoint(SystemDictionary_lock); | 426 assert_locked_or_safepoint(SystemDictionary_lock); |
427 assert(obj() != NULL, "adding NULL obj"); | 427 assert(obj() != NULL, "adding NULL obj"); |
428 assert(Klass::cast(obj())->name() == class_name(), "sanity check on name"); | 428 assert(Klass::cast(obj())->name() == class_name, "sanity check on name"); |
429 | 429 |
430 unsigned int hash = compute_hash(class_name, class_loader); | 430 unsigned int hash = compute_hash(class_name, class_loader); |
431 int index = hash_to_index(hash); | 431 int index = hash_to_index(hash); |
432 DictionaryEntry* entry = new_entry(hash, obj(), class_loader()); | 432 DictionaryEntry* entry = new_entry(hash, obj(), class_loader()); |
433 add_entry(index, entry); | 433 add_entry(index, entry); |
442 // be updated in an MT-safe manner). | 442 // be updated in an MT-safe manner). |
443 // | 443 // |
444 // Callers should be aware that an entry could be added just after | 444 // Callers should be aware that an entry could be added just after |
445 // _buckets[index] is read here, so the caller will not see the new entry. | 445 // _buckets[index] is read here, so the caller will not see the new entry. |
446 DictionaryEntry* Dictionary::get_entry(int index, unsigned int hash, | 446 DictionaryEntry* Dictionary::get_entry(int index, unsigned int hash, |
447 symbolHandle class_name, | 447 Symbol* class_name, |
448 Handle class_loader) { | 448 Handle class_loader) { |
449 symbolOop name_ = class_name(); | 449 oop loader = class_loader(); |
450 oop loader_ = class_loader(); | |
451 debug_only(_lookup_count++); | 450 debug_only(_lookup_count++); |
452 for (DictionaryEntry* entry = bucket(index); | 451 for (DictionaryEntry* entry = bucket(index); |
453 entry != NULL; | 452 entry != NULL; |
454 entry = entry->next()) { | 453 entry = entry->next()) { |
455 if (entry->hash() == hash && entry->equals(name_, loader_)) { | 454 if (entry->hash() == hash && entry->equals(class_name, loader)) { |
456 return entry; | 455 return entry; |
457 } | 456 } |
458 debug_only(_lookup_length++); | 457 debug_only(_lookup_length++); |
459 } | 458 } |
460 return NULL; | 459 return NULL; |
461 } | 460 } |
462 | 461 |
463 | 462 |
464 klassOop Dictionary::find(int index, unsigned int hash, symbolHandle name, | 463 klassOop Dictionary::find(int index, unsigned int hash, Symbol* name, |
465 Handle loader, Handle protection_domain, TRAPS) { | 464 Handle loader, Handle protection_domain, TRAPS) { |
466 DictionaryEntry* entry = get_entry(index, hash, name, loader); | 465 DictionaryEntry* entry = get_entry(index, hash, name, loader); |
467 if (entry != NULL && entry->is_valid_protection_domain(protection_domain)) { | 466 if (entry != NULL && entry->is_valid_protection_domain(protection_domain)) { |
468 return entry->klass(); | 467 return entry->klass(); |
469 } else { | 468 } else { |
471 } | 470 } |
472 } | 471 } |
473 | 472 |
474 | 473 |
475 klassOop Dictionary::find_class(int index, unsigned int hash, | 474 klassOop Dictionary::find_class(int index, unsigned int hash, |
476 symbolHandle name, Handle loader) { | 475 Symbol* name, Handle loader) { |
477 assert_locked_or_safepoint(SystemDictionary_lock); | 476 assert_locked_or_safepoint(SystemDictionary_lock); |
478 assert (index == index_for(name, loader), "incorrect index?"); | 477 assert (index == index_for(name, loader), "incorrect index?"); |
479 | 478 |
480 DictionaryEntry* entry = get_entry(index, hash, name, loader); | 479 DictionaryEntry* entry = get_entry(index, hash, name, loader); |
481 return (entry != NULL) ? entry->klass() : (klassOop)NULL; | 480 return (entry != NULL) ? entry->klass() : (klassOop)NULL; |
484 | 483 |
485 // Variant of find_class for shared classes. No locking required, as | 484 // Variant of find_class for shared classes. No locking required, as |
486 // that table is static. | 485 // that table is static. |
487 | 486 |
488 klassOop Dictionary::find_shared_class(int index, unsigned int hash, | 487 klassOop Dictionary::find_shared_class(int index, unsigned int hash, |
489 symbolHandle name) { | 488 Symbol* name) { |
490 assert (index == index_for(name, Handle()), "incorrect index?"); | 489 assert (index == index_for(name, Handle()), "incorrect index?"); |
491 | 490 |
492 DictionaryEntry* entry = get_entry(index, hash, name, Handle()); | 491 DictionaryEntry* entry = get_entry(index, hash, name, Handle()); |
493 return (entry != NULL) ? entry->klass() : (klassOop)NULL; | 492 return (entry != NULL) ? entry->klass() : (klassOop)NULL; |
494 } | 493 } |
496 | 495 |
497 void Dictionary::add_protection_domain(int index, unsigned int hash, | 496 void Dictionary::add_protection_domain(int index, unsigned int hash, |
498 instanceKlassHandle klass, | 497 instanceKlassHandle klass, |
499 Handle loader, Handle protection_domain, | 498 Handle loader, Handle protection_domain, |
500 TRAPS) { | 499 TRAPS) { |
501 symbolHandle klass_name(THREAD, klass->name()); | 500 Symbol* klass_name = klass->name(); |
502 DictionaryEntry* entry = get_entry(index, hash, klass_name, loader); | 501 DictionaryEntry* entry = get_entry(index, hash, klass_name, loader); |
503 | 502 |
504 assert(entry != NULL,"entry must be present, we just created it"); | 503 assert(entry != NULL,"entry must be present, we just created it"); |
505 assert(protection_domain() != NULL, | 504 assert(protection_domain() != NULL, |
506 "real protection domain should be present"); | 505 "real protection domain should be present"); |
511 "now protection domain should be present"); | 510 "now protection domain should be present"); |
512 } | 511 } |
513 | 512 |
514 | 513 |
515 bool Dictionary::is_valid_protection_domain(int index, unsigned int hash, | 514 bool Dictionary::is_valid_protection_domain(int index, unsigned int hash, |
516 symbolHandle name, | 515 Symbol* name, |
517 Handle loader, | 516 Handle loader, |
518 Handle protection_domain) { | 517 Handle protection_domain) { |
519 DictionaryEntry* entry = get_entry(index, hash, name, loader); | 518 DictionaryEntry* entry = get_entry(index, hash, name, loader); |
520 return entry->is_valid_protection_domain(protection_domain); | 519 return entry->is_valid_protection_domain(protection_domain); |
521 } | 520 } |
543 | 542 |
544 while (master_list != NULL) { | 543 while (master_list != NULL) { |
545 DictionaryEntry* p = master_list; | 544 DictionaryEntry* p = master_list; |
546 master_list = master_list->next(); | 545 master_list = master_list->next(); |
547 p->set_next(NULL); | 546 p->set_next(NULL); |
548 symbolHandle class_name (thread, instanceKlass::cast((klassOop)(p->klass()))->name()); | 547 Symbol* class_name = instanceKlass::cast((klassOop)(p->klass()))->name(); |
549 unsigned int hash = compute_hash(class_name, Handle(thread, p->loader())); | 548 unsigned int hash = compute_hash(class_name, Handle(thread, p->loader())); |
550 int index = hash_to_index(hash); | 549 int index = hash_to_index(hash); |
551 p->set_hash(hash); | 550 p->set_hash(hash); |
552 p->set_next(bucket(index)); | 551 p->set_next(bucket(index)); |
553 set_entry(index, p); | 552 set_entry(index, p); |
554 } | 553 } |
555 } | 554 } |
556 | 555 |
557 SymbolPropertyTable::SymbolPropertyTable(int table_size) | 556 SymbolPropertyTable::SymbolPropertyTable(int table_size) |
558 : Hashtable(table_size, sizeof(SymbolPropertyEntry)) | 557 : Hashtable<Symbol*>(table_size, sizeof(SymbolPropertyEntry)) |
559 { | 558 { |
560 } | 559 } |
561 SymbolPropertyTable::SymbolPropertyTable(int table_size, HashtableBucket* t, | 560 SymbolPropertyTable::SymbolPropertyTable(int table_size, HashtableBucket* t, |
562 int number_of_entries) | 561 int number_of_entries) |
563 : Hashtable(table_size, sizeof(SymbolPropertyEntry), t, number_of_entries) | 562 : Hashtable<Symbol*>(table_size, sizeof(SymbolPropertyEntry), t, number_of_entries) |
564 { | 563 { |
565 } | 564 } |
566 | 565 |
567 | 566 |
568 SymbolPropertyEntry* SymbolPropertyTable::find_entry(int index, unsigned int hash, | 567 SymbolPropertyEntry* SymbolPropertyTable::find_entry(int index, unsigned int hash, |
569 symbolHandle sym, | 568 Symbol* sym, |
570 intptr_t sym_mode) { | 569 intptr_t sym_mode) { |
571 assert(index == index_for(sym, sym_mode), "incorrect index?"); | 570 assert(index == index_for(sym, sym_mode), "incorrect index?"); |
572 for (SymbolPropertyEntry* p = bucket(index); p != NULL; p = p->next()) { | 571 for (SymbolPropertyEntry* p = bucket(index); p != NULL; p = p->next()) { |
573 if (p->hash() == hash && p->symbol() == sym() && p->symbol_mode() == sym_mode) { | 572 if (p->hash() == hash && p->symbol() == sym && p->symbol_mode() == sym_mode) { |
574 return p; | 573 return p; |
575 } | 574 } |
576 } | 575 } |
577 return NULL; | 576 return NULL; |
578 } | 577 } |
579 | 578 |
580 | 579 |
581 SymbolPropertyEntry* SymbolPropertyTable::add_entry(int index, unsigned int hash, | 580 SymbolPropertyEntry* SymbolPropertyTable::add_entry(int index, unsigned int hash, |
582 symbolHandle sym, intptr_t sym_mode) { | 581 Symbol* sym, intptr_t sym_mode) { |
583 assert_locked_or_safepoint(SystemDictionary_lock); | 582 assert_locked_or_safepoint(SystemDictionary_lock); |
584 assert(index == index_for(sym, sym_mode), "incorrect index?"); | 583 assert(index == index_for(sym, sym_mode), "incorrect index?"); |
585 assert(find_entry(index, hash, sym, sym_mode) == NULL, "no double entry"); | 584 assert(find_entry(index, hash, sym, sym_mode) == NULL, "no double entry"); |
586 | 585 |
587 SymbolPropertyEntry* p = new_entry(hash, sym(), sym_mode); | 586 SymbolPropertyEntry* p = new_entry(hash, sym, sym_mode); |
588 Hashtable::add_entry(index, p); | 587 Hashtable<Symbol*>::add_entry(index, p); |
589 return p; | 588 return p; |
590 } | 589 } |
591 | 590 |
592 | 591 |
593 void SymbolPropertyTable::oops_do(OopClosure* f) { | 592 void SymbolPropertyTable::oops_do(OopClosure* f) { |
594 for (int index = 0; index < table_size(); index++) { | 593 for (int index = 0; index < table_size(); index++) { |
595 for (SymbolPropertyEntry* p = bucket(index); p != NULL; p = p->next()) { | 594 for (SymbolPropertyEntry* p = bucket(index); p != NULL; p = p->next()) { |
596 f->do_oop((oop*) p->symbol_addr()); | |
597 if (p->property_oop() != NULL) { | 595 if (p->property_oop() != NULL) { |
598 f->do_oop(p->property_oop_addr()); | 596 f->do_oop(p->property_oop_addr()); |
599 } | 597 } |
600 } | 598 } |
601 } | 599 } |