30 #include "classfile/systemDictionary.hpp" |
30 #include "classfile/systemDictionary.hpp" |
31 #include "gc/shared/collectedHeap.inline.hpp" |
31 #include "gc/shared/collectedHeap.inline.hpp" |
32 #include "gc/shared/gcLocker.inline.hpp" |
32 #include "gc/shared/gcLocker.inline.hpp" |
33 #include "memory/allocation.inline.hpp" |
33 #include "memory/allocation.inline.hpp" |
34 #include "memory/filemap.hpp" |
34 #include "memory/filemap.hpp" |
|
35 #include "memory/metaspaceClosure.hpp" |
35 #include "memory/resourceArea.hpp" |
36 #include "memory/resourceArea.hpp" |
36 #include "oops/oop.inline.hpp" |
37 #include "oops/oop.inline.hpp" |
37 #include "runtime/atomic.hpp" |
38 #include "runtime/atomic.hpp" |
38 #include "runtime/mutexLocker.hpp" |
39 #include "runtime/mutexLocker.hpp" |
39 #include "services/diagnosticCommand.hpp" |
40 #include "services/diagnosticCommand.hpp" |
55 assert (len <= Symbol::max_length(), "should be checked by caller"); |
56 assert (len <= Symbol::max_length(), "should be checked by caller"); |
56 |
57 |
57 Symbol* sym; |
58 Symbol* sym; |
58 |
59 |
59 if (DumpSharedSpaces) { |
60 if (DumpSharedSpaces) { |
60 // Allocate all symbols to CLD shared metaspace |
61 c_heap = false; |
61 sym = new (len, ClassLoaderData::the_null_class_loader_data(), THREAD) Symbol(name, len, PERM_REFCOUNT); |
62 } |
62 } else if (c_heap) { |
63 if (c_heap) { |
63 // refcount starts as 1 |
64 // refcount starts as 1 |
64 sym = new (len, THREAD) Symbol(name, len, 1); |
65 sym = new (len, THREAD) Symbol(name, len, 1); |
65 assert(sym != NULL, "new should call vm_exit_out_of_memory if C_HEAP is exhausted"); |
66 assert(sym != NULL, "new should call vm_exit_out_of_memory if C_HEAP is exhausted"); |
66 } else { |
67 } else { |
67 // Allocate to global arena |
68 // Allocate to global arena |
89 for (int i = 0; i < n; i++) { |
90 for (int i = 0; i < n; i++) { |
90 for (HashtableEntry<Symbol*, mtSymbol>* p = the_table()->bucket(i); |
91 for (HashtableEntry<Symbol*, mtSymbol>* p = the_table()->bucket(i); |
91 p != NULL; |
92 p != NULL; |
92 p = p->next()) { |
93 p = p->next()) { |
93 cl->do_symbol(p->literal_addr()); |
94 cl->do_symbol(p->literal_addr()); |
|
95 } |
|
96 } |
|
97 } |
|
98 |
|
99 void SymbolTable::metaspace_pointers_do(MetaspaceClosure* it) { |
|
100 assert(DumpSharedSpaces, "called only during dump time"); |
|
101 const int n = the_table()->table_size(); |
|
102 for (int i = 0; i < n; i++) { |
|
103 for (HashtableEntry<Symbol*, mtSymbol>* p = the_table()->bucket(i); |
|
104 p != NULL; |
|
105 p = p->next()) { |
|
106 it->push(p->literal_addr()); |
94 } |
107 } |
95 } |
108 } |
96 } |
109 } |
97 |
110 |
98 int SymbolTable::_symbols_removed = 0; |
111 int SymbolTable::_symbols_removed = 0; |
566 } |
579 } |
567 } |
580 } |
568 } |
581 } |
569 } |
582 } |
570 |
583 |
571 void SymbolTable::serialize(SerializeClosure* soc) { |
584 void SymbolTable::write_to_archive() { |
572 #if INCLUDE_CDS |
585 #if INCLUDE_CDS |
573 _shared_table.reset(); |
586 _shared_table.reset(); |
574 if (soc->writing()) { |
587 |
575 int num_buckets = the_table()->number_of_entries() / |
588 int num_buckets = the_table()->number_of_entries() / |
576 SharedSymbolTableBucketSize; |
589 SharedSymbolTableBucketSize; |
577 CompactSymbolTableWriter writer(num_buckets, |
590 CompactSymbolTableWriter writer(num_buckets, |
578 &MetaspaceShared::stats()->symbol); |
591 &MetaspaceShared::stats()->symbol); |
579 for (int i = 0; i < the_table()->table_size(); ++i) { |
592 for (int i = 0; i < the_table()->table_size(); ++i) { |
585 writer.add(fixed_hash, s); |
598 writer.add(fixed_hash, s); |
586 } |
599 } |
587 } |
600 } |
588 |
601 |
589 writer.dump(&_shared_table); |
602 writer.dump(&_shared_table); |
590 } |
603 |
591 |
|
592 _shared_table.set_type(CompactHashtable<Symbol*, char>::_symbol_table); |
|
593 _shared_table.serialize(soc); |
|
594 |
|
595 if (soc->writing()) { |
|
596 // Verify table is correct |
604 // Verify table is correct |
597 Symbol* sym = vmSymbols::java_lang_Object(); |
605 Symbol* sym = vmSymbols::java_lang_Object(); |
598 const char* name = (const char*)sym->bytes(); |
606 const char* name = (const char*)sym->bytes(); |
599 int len = sym->utf8_length(); |
607 int len = sym->utf8_length(); |
600 unsigned int hash = hash_symbol(name, len); |
608 unsigned int hash = hash_symbol(name, len); |
601 assert(sym == _shared_table.lookup(name, hash, len), "sanity"); |
609 assert(sym == _shared_table.lookup(name, hash, len), "sanity"); |
602 |
610 #endif |
|
611 } |
|
612 |
|
613 void SymbolTable::serialize(SerializeClosure* soc) { |
|
614 #if INCLUDE_CDS |
|
615 _shared_table.set_type(CompactHashtable<Symbol*, char>::_symbol_table); |
|
616 _shared_table.serialize(soc); |
|
617 |
|
618 if (soc->writing()) { |
603 // Sanity. Make sure we don't use the shared table at dump time |
619 // Sanity. Make sure we don't use the shared table at dump time |
604 _shared_table.reset(); |
620 _shared_table.reset(); |
605 } |
621 } |
606 #endif |
622 #endif |
607 } |
623 } |