< prev index next >

src/share/vm/classfile/stringTable.cpp

Print this page




  73  public:
  74   StableMemoryChecker(const void* region, jint size) {
  75     _region = (address) region;
  76     _size   = size;
  77     sample(_save_buf);
  78   }
  79 
  80   bool verify() {
  81     u1 check_buf[sizeof(_save_buf)];
  82     int check_size = sample(check_buf);
  83     return (0 == memcmp(_save_buf, check_buf, check_size));
  84   }
  85 
  86   void set_region(const void* region) { _region = (address) region; }
  87 };
  88 #endif
  89 
  90 
  91 // --------------------------------------------------------------------------
  92 StringTable* StringTable::_the_table = NULL;
  93 bool StringTable::_ignore_shared_strings = false;
  94 bool StringTable::_needs_rehashing = false;
  95 
  96 volatile int StringTable::_parallel_claimed_idx = 0;
  97 
  98 CompactHashtable<oop, char> StringTable::_shared_table;
  99 
 100 // Pick hashing algorithm
 101 unsigned int StringTable::hash_string(const jchar* s, int len) {
 102   return use_alternate_hashcode() ? alt_hash_string(s, len) :
 103                                     java_lang_String::hash_code(s, len);
 104 }
 105 
 106 unsigned int StringTable::alt_hash_string(const jchar* s, int len) {
 107   return AltHashing::murmur3_32(seed(), s, len);
 108 }
 109 
 110 unsigned int StringTable::hash_string(oop string) {
 111   EXCEPTION_MARK;
 112   if (string == NULL) {
 113     return hash_string((jchar*)NULL, 0);


 661   _dcmdparser.add_dcmd_option(&_verbose);
 662 }
 663 
 664 void StringtableDCmd::execute(DCmdSource source, TRAPS) {
 665   VM_DumpHashtable dumper(output(), VM_DumpHashtable::DumpStrings,
 666                          _verbose.value());
 667   VMThread::execute(&dumper);
 668 }
 669 
 670 int StringtableDCmd::num_arguments() {
 671   ResourceMark rm;
 672   StringtableDCmd* dcmd = new StringtableDCmd(NULL, false);
 673   if (dcmd != NULL) {
 674     DCmdMark mark(dcmd);
 675     return dcmd->_dcmdparser.num_arguments();
 676   } else {
 677     return 0;
 678   }
 679 }
 680 

 681 // Sharing



















 682 bool StringTable::copy_shared_string(GrowableArray<MemRegion> *string_space,
 683                                      CompactStringTableWriter* writer) {
 684 #if INCLUDE_CDS && INCLUDE_ALL_GCS && defined(_LP64) && !defined(_WINDOWS)
 685   assert(UseG1GC, "Only support G1 GC");
 686   assert(UseCompressedOops && UseCompressedClassPointers,
 687          "Only support UseCompressedOops and UseCompressedClassPointers enabled");
 688 
 689   Thread* THREAD = Thread::current();
 690   G1CollectedHeap::heap()->begin_archive_alloc_range();
 691   for (int i = 0; i < the_table()->table_size(); ++i) {
 692     HashtableEntry<oop, mtSymbol>* bucket = the_table()->bucket(i);
 693     for ( ; bucket != NULL; bucket = bucket->next()) {
 694       oop s = bucket->literal();
 695       unsigned int hash = java_lang_String::hash_code(s);
 696       if (hash == 0) {
 697         continue;
 698       }
 699 
 700       // allocate the new 'value' array first
 701       typeArrayOop v = java_lang_String::value(s);
 702       int v_len = v->size();
 703       typeArrayOop new_v;
 704       if (G1CollectedHeap::heap()->is_archive_alloc_too_large(v_len)) {
 705         continue; // skip the current String. The 'value' array is too large to handle
 706       } else {
 707         new_v = (typeArrayOop)G1CollectedHeap::heap()->archive_mem_allocate(v_len);
 708         if (new_v == NULL) {
 709           return false; // allocation failed
 710         }
 711       }
 712       // now allocate the new String object
 713       int s_len = s->size();
 714       oop new_s = (oop)G1CollectedHeap::heap()->archive_mem_allocate(s_len);
 715       if (new_s == NULL) {
 716         return false;
 717       }
 718 
 719       s->identity_hash();
 720       v->identity_hash();
 721 
 722       // copy the objects' data
 723       Copy::aligned_disjoint_words((HeapWord*)s, (HeapWord*)new_s, s_len);
 724       Copy::aligned_disjoint_words((HeapWord*)v, (HeapWord*)new_v, v_len);
 725 
 726       // adjust the pointer to the 'value' field in the new String oop. Also pre-compute and set the
 727       // 'hash' field. That avoids "write" to the shared strings at runtime by the deduplication process.
 728       java_lang_String::set_value_raw(new_s, new_v);
 729       if (java_lang_String::hash(new_s) == 0) {
 730         java_lang_String::set_hash(new_s, hash);
 731       }
 732 
 733       // add to the compact table
 734       writer->add(hash, new_s);
 735 
 736       MetaspaceShared::relocate_klass_ptr(new_s);
 737       MetaspaceShared::relocate_klass_ptr(new_v);
 738     }
 739   }
 740 
 741   G1CollectedHeap::heap()->end_archive_alloc_range(string_space, os::vm_allocation_granularity());
 742   assert(string_space->length() <= 2, "sanity");
 743 #endif
 744   return true;
 745 }
 746 
 747 void StringTable::write_to_archive(GrowableArray<MemRegion> *string_space) {
 748 #if INCLUDE_CDS

 749   _shared_table.reset();
 750   if (!(UseG1GC && UseCompressedOops && UseCompressedClassPointers)) {
 751       log_info(cds)(
 752         "Shared strings are excluded from the archive as UseG1GC, "
 753         "UseCompressedOops and UseCompressedClassPointers are required."
 754         "Current settings: UseG1GC=%s, UseCompressedOops=%s, UseCompressedClassPointers=%s.",
 755         BOOL_TO_STR(UseG1GC), BOOL_TO_STR(UseCompressedOops),
 756         BOOL_TO_STR(UseCompressedClassPointers));
 757   } else {
 758     int num_buckets = the_table()->number_of_entries() /
 759                            SharedSymbolTableBucketSize;
 760     // calculation of num_buckets can result in zero buckets, we need at least one
 761     CompactStringTableWriter writer(num_buckets > 1 ? num_buckets : 1,
 762                                     &MetaspaceShared::stats()->string);
 763 
 764     // Copy the interned strings into the "string space" within the java heap
 765     if (copy_shared_string(string_space, &writer)) {
 766       writer.dump(&_shared_table);
 767     }
 768   }
 769 #endif
 770 }
 771 
 772 void StringTable::serialize(SerializeClosure* soc) {
 773 #if INCLUDE_CDS && defined(_LP64) && !defined(_WINDOWS)
 774   _shared_table.set_type(CompactHashtable<oop, char>::_string_table);
 775   _shared_table.serialize(soc);
 776 
 777   if (soc->writing()) {
 778     _shared_table.reset(); // Sanity. Make sure we don't use the shared table at dump time
 779   } else if (_ignore_shared_strings) {
 780     _shared_table.reset();
 781   }
 782 #endif
 783 }
 784 
 785 void StringTable::shared_oops_do(OopClosure* f) {
 786 #if INCLUDE_CDS && defined(_LP64) && !defined(_WINDOWS)
 787   _shared_table.oops_do(f);
 788 #endif
 789 }

 790 


  73  public:
  74   StableMemoryChecker(const void* region, jint size) {
  75     _region = (address) region;
  76     _size   = size;
  77     sample(_save_buf);
  78   }
  79 
  80   bool verify() {
  81     u1 check_buf[sizeof(_save_buf)];
  82     int check_size = sample(check_buf);
  83     return (0 == memcmp(_save_buf, check_buf, check_size));
  84   }
  85 
  86   void set_region(const void* region) { _region = (address) region; }
  87 };
  88 #endif
  89 
  90 
  91 // --------------------------------------------------------------------------
  92 StringTable* StringTable::_the_table = NULL;
  93 bool StringTable::_shared_string_mapped = false;
  94 bool StringTable::_needs_rehashing = false;
  95 
  96 volatile int StringTable::_parallel_claimed_idx = 0;
  97 
  98 CompactHashtable<oop, char> StringTable::_shared_table;
  99 
 100 // Pick hashing algorithm
 101 unsigned int StringTable::hash_string(const jchar* s, int len) {
 102   return use_alternate_hashcode() ? alt_hash_string(s, len) :
 103                                     java_lang_String::hash_code(s, len);
 104 }
 105 
 106 unsigned int StringTable::alt_hash_string(const jchar* s, int len) {
 107   return AltHashing::murmur3_32(seed(), s, len);
 108 }
 109 
 110 unsigned int StringTable::hash_string(oop string) {
 111   EXCEPTION_MARK;
 112   if (string == NULL) {
 113     return hash_string((jchar*)NULL, 0);


 661   _dcmdparser.add_dcmd_option(&_verbose);
 662 }
 663 
 664 void StringtableDCmd::execute(DCmdSource source, TRAPS) {
 665   VM_DumpHashtable dumper(output(), VM_DumpHashtable::DumpStrings,
 666                          _verbose.value());
 667   VMThread::execute(&dumper);
 668 }
 669 
 670 int StringtableDCmd::num_arguments() {
 671   ResourceMark rm;
 672   StringtableDCmd* dcmd = new StringtableDCmd(NULL, false);
 673   if (dcmd != NULL) {
 674     DCmdMark mark(dcmd);
 675     return dcmd->_dcmdparser.num_arguments();
 676   } else {
 677     return 0;
 678   }
 679 }
 680 
 681 #if INCLUDE_CDS_JAVA_HEAP
 682 // Sharing
 683 oop StringTable::create_archived_string(oop s, Thread* THREAD) {
 684   assert(DumpSharedSpaces, "this function is only used with -Xshare:dump");
 685 
 686   oop new_s = NULL;
 687   typeArrayOop v = java_lang_String::value(s);
 688   typeArrayOop new_v = (typeArrayOop)MetaspaceShared::archive_heap_object(v, THREAD);
 689   if (new_v == NULL) {
 690     return NULL;
 691   }
 692   new_s = MetaspaceShared::archive_heap_object(s, THREAD);
 693   if (new_s == NULL) {
 694     return NULL;
 695   }
 696 
 697   // adjust the pointer to the 'value' field in the new String oop
 698   java_lang_String::set_value_raw(new_s, new_v);
 699   return new_s;
 700 }
 701 
 702 bool StringTable::copy_shared_string(GrowableArray<MemRegion> *string_space,
 703                                      CompactStringTableWriter* writer) {
 704   assert(MetaspaceShared::is_heap_object_archiving_allowed(), "must be");



 705 
 706   Thread* THREAD = Thread::current();
 707   G1CollectedHeap::heap()->begin_archive_alloc_range();
 708   for (int i = 0; i < the_table()->table_size(); ++i) {
 709     HashtableEntry<oop, mtSymbol>* bucket = the_table()->bucket(i);
 710     for ( ; bucket != NULL; bucket = bucket->next()) {
 711       oop s = bucket->literal();
 712       unsigned int hash = java_lang_String::hash_code(s);
 713       if (hash == 0) {
 714         continue;
 715       }
 716 
 717       java_lang_String::set_hash(s, hash);
 718       oop new_s = create_archived_string(s, THREAD);













 719       if (new_s == NULL) {
 720         continue;
 721       }
 722 
 723       // set the archived string in bucket
 724       bucket->set_literal(new_s);











 725 
 726       // add to the compact table
 727       writer->add(hash, new_s);



 728     }
 729   }
 730 
 731   G1CollectedHeap::heap()->end_archive_alloc_range(string_space, os::vm_allocation_granularity());
 732   assert(string_space->length() <= 2, "sanity");

 733   return true;
 734 }
 735 
 736 void StringTable::write_to_archive(GrowableArray<MemRegion> *string_space) {
 737   assert(MetaspaceShared::is_heap_object_archiving_allowed(), "must be");
 738 
 739   _shared_table.reset();








 740   int num_buckets = the_table()->number_of_entries() /
 741                          SharedSymbolTableBucketSize;
 742   // calculation of num_buckets can result in zero buckets, we need at least one
 743   CompactStringTableWriter writer(num_buckets > 1 ? num_buckets : 1,
 744                                   &MetaspaceShared::stats()->string);
 745 
 746   // Copy the interned strings into the "string space" within the java heap
 747   if (copy_shared_string(string_space, &writer)) {
 748     writer.dump(&_shared_table);
 749   }


 750 }
 751 
 752 void StringTable::serialize(SerializeClosure* soc) {

 753   _shared_table.set_type(CompactHashtable<oop, char>::_string_table);
 754   _shared_table.serialize(soc);
 755 
 756   if (soc->writing()) {
 757     _shared_table.reset(); // Sanity. Make sure we don't use the shared table at dump time
 758   } else if (!_shared_string_mapped) {
 759     _shared_table.reset();
 760   }

 761 }
 762 
 763 void StringTable::shared_oops_do(OopClosure* f) {

 764   _shared_table.oops_do(f);

 765 }
 766 #endif //INCLUDE_CDS_JAVA_HEAP
 767 
< prev index next >