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 }