19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
23 */
24
25 #include "precompiled.hpp"
26 #include "classfile/altHashing.hpp"
27 #include "classfile/compactHashtable.hpp"
28 #include "classfile/javaClasses.inline.hpp"
29 #include "classfile/stringTable.hpp"
30 #include "classfile/systemDictionary.hpp"
31 #include "gc/shared/collectedHeap.hpp"
32 #include "gc/shared/oopStorage.inline.hpp"
33 #include "gc/shared/oopStorageParState.inline.hpp"
34 #include "logging/log.hpp"
35 #include "logging/logStream.hpp"
36 #include "memory/allocation.inline.hpp"
37 #include "memory/filemap.hpp"
38 #include "memory/heapShared.inline.hpp"
39 #include "memory/metaspaceShared.inline.hpp"
40 #include "memory/resourceArea.hpp"
41 #include "memory/universe.hpp"
42 #include "oops/access.inline.hpp"
43 #include "oops/oop.inline.hpp"
44 #include "oops/typeArrayOop.inline.hpp"
45 #include "oops/weakHandle.inline.hpp"
46 #include "runtime/atomic.hpp"
47 #include "runtime/handles.inline.hpp"
48 #include "runtime/mutexLocker.hpp"
49 #include "runtime/safepointVerifiers.hpp"
50 #include "runtime/timerTrace.hpp"
51 #include "runtime/interfaceSupport.inline.hpp"
52 #include "services/diagnosticCommand.hpp"
53 #include "utilities/concurrentHashTable.inline.hpp"
54 #include "utilities/concurrentHashTableTasks.inline.hpp"
55 #include "utilities/macros.hpp"
56
57 // We prefer short chains of avg 2
58 #define PREF_AVG_LIST_LEN 2
59 // 2^24 is max size
781 StringtableDCmd* dcmd = new StringtableDCmd(NULL, false);
782 if (dcmd != NULL) {
783 DCmdMark mark(dcmd);
784 return dcmd->_dcmdparser.num_arguments();
785 } else {
786 return 0;
787 }
788 }
789
790 // Sharing
791 #if INCLUDE_CDS_JAVA_HEAP
792 oop StringTable::lookup_shared(const jchar* name, int len, unsigned int hash) {
793 assert(hash == java_lang_String::hash_code(name, len),
794 "hash must be computed using java_lang_String::hash_code");
795 return _shared_table.lookup(name, hash, len);
796 }
797
798 oop StringTable::create_archived_string(oop s, Thread* THREAD) {
799 assert(DumpSharedSpaces, "this function is only used with -Xshare:dump");
800
801 if (MetaspaceShared::is_archive_object(s)) {
802 return s;
803 }
804
805 oop new_s = NULL;
806 typeArrayOop v = java_lang_String::value_no_keepalive(s);
807 typeArrayOop new_v =
808 (typeArrayOop)MetaspaceShared::archive_heap_object(v, THREAD);
809 if (new_v == NULL) {
810 return NULL;
811 }
812 new_s = MetaspaceShared::archive_heap_object(s, THREAD);
813 if (new_s == NULL) {
814 return NULL;
815 }
816
817 // adjust the pointer to the 'value' field in the new String oop
818 java_lang_String::set_value_raw(new_s, new_v);
819 return new_s;
820 }
821
822 class CompactStringTableWriter: public CompactHashtableWriter {
823 public:
824 CompactStringTableWriter(int num_entries, CompactHashtableStats* stats) :
825 CompactHashtableWriter(num_entries, stats) {}
826 void add(unsigned int hash, oop string) {
827 CompactHashtableWriter::add(hash, CompressedOops::encode(string));
828 }
829 };
830
831 struct CopyToArchive : StackObj {
832 CompactStringTableWriter* _writer;
838 }
839 unsigned int hash = java_lang_String::hash_code(s);
840 if (hash == 0) {
841 return true;
842 }
843
844 java_lang_String::set_hash(s, hash);
845 oop new_s = StringTable::create_archived_string(s, Thread::current());
846 if (new_s == NULL) {
847 return true;
848 }
849
850 val->replace(new_s);
851 // add to the compact table
852 _writer->add(hash, new_s);
853 return true;
854 }
855 };
856
857 void StringTable::copy_shared_string_table(CompactStringTableWriter* writer) {
858 assert(MetaspaceShared::is_heap_object_archiving_allowed(), "must be");
859
860 CopyToArchive copy(writer);
861 StringTable::the_table()->_local_table->do_scan(Thread::current(), copy);
862 }
863
864 void StringTable::write_to_archive() {
865 assert(MetaspaceShared::is_heap_object_archiving_allowed(), "must be");
866
867 _shared_table.reset();
868 int num_buckets = the_table()->_items_count / SharedSymbolTableBucketSize;
869 // calculation of num_buckets can result in zero buckets, we need at least one
870 CompactStringTableWriter writer(num_buckets > 1 ? num_buckets : 1,
871 &MetaspaceShared::stats()->string);
872
873 // Copy the interned strings into the "string space" within the java heap
874 copy_shared_string_table(&writer);
875 writer.dump(&_shared_table, "string");
876 }
877
878 void StringTable::serialize(SerializeClosure* soc) {
879 _shared_table.serialize(soc);
880
881 if (soc->writing()) {
882 // Sanity. Make sure we don't use the shared table at dump time
883 _shared_table.reset();
884 } else if (!_shared_string_mapped) {
885 _shared_table.reset();
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
23 */
24
25 #include "precompiled.hpp"
26 #include "classfile/altHashing.hpp"
27 #include "classfile/compactHashtable.hpp"
28 #include "classfile/javaClasses.inline.hpp"
29 #include "classfile/stringTable.hpp"
30 #include "classfile/systemDictionary.hpp"
31 #include "gc/shared/collectedHeap.hpp"
32 #include "gc/shared/oopStorage.inline.hpp"
33 #include "gc/shared/oopStorageParState.inline.hpp"
34 #include "logging/log.hpp"
35 #include "logging/logStream.hpp"
36 #include "memory/allocation.inline.hpp"
37 #include "memory/filemap.hpp"
38 #include "memory/heapShared.inline.hpp"
39 #include "memory/resourceArea.hpp"
40 #include "memory/universe.hpp"
41 #include "oops/access.inline.hpp"
42 #include "oops/oop.inline.hpp"
43 #include "oops/typeArrayOop.inline.hpp"
44 #include "oops/weakHandle.inline.hpp"
45 #include "runtime/atomic.hpp"
46 #include "runtime/handles.inline.hpp"
47 #include "runtime/mutexLocker.hpp"
48 #include "runtime/safepointVerifiers.hpp"
49 #include "runtime/timerTrace.hpp"
50 #include "runtime/interfaceSupport.inline.hpp"
51 #include "services/diagnosticCommand.hpp"
52 #include "utilities/concurrentHashTable.inline.hpp"
53 #include "utilities/concurrentHashTableTasks.inline.hpp"
54 #include "utilities/macros.hpp"
55
56 // We prefer short chains of avg 2
57 #define PREF_AVG_LIST_LEN 2
58 // 2^24 is max size
780 StringtableDCmd* dcmd = new StringtableDCmd(NULL, false);
781 if (dcmd != NULL) {
782 DCmdMark mark(dcmd);
783 return dcmd->_dcmdparser.num_arguments();
784 } else {
785 return 0;
786 }
787 }
788
789 // Sharing
790 #if INCLUDE_CDS_JAVA_HEAP
791 oop StringTable::lookup_shared(const jchar* name, int len, unsigned int hash) {
792 assert(hash == java_lang_String::hash_code(name, len),
793 "hash must be computed using java_lang_String::hash_code");
794 return _shared_table.lookup(name, hash, len);
795 }
796
797 oop StringTable::create_archived_string(oop s, Thread* THREAD) {
798 assert(DumpSharedSpaces, "this function is only used with -Xshare:dump");
799
800 if (HeapShared::is_archived_object(s)) {
801 return s;
802 }
803
804 oop new_s = NULL;
805 typeArrayOop v = java_lang_String::value_no_keepalive(s);
806 typeArrayOop new_v = (typeArrayOop)HeapShared::archive_heap_object(v, THREAD);
807 if (new_v == NULL) {
808 return NULL;
809 }
810 new_s = HeapShared::archive_heap_object(s, THREAD);
811 if (new_s == NULL) {
812 return NULL;
813 }
814
815 // adjust the pointer to the 'value' field in the new String oop
816 java_lang_String::set_value_raw(new_s, new_v);
817 return new_s;
818 }
819
820 class CompactStringTableWriter: public CompactHashtableWriter {
821 public:
822 CompactStringTableWriter(int num_entries, CompactHashtableStats* stats) :
823 CompactHashtableWriter(num_entries, stats) {}
824 void add(unsigned int hash, oop string) {
825 CompactHashtableWriter::add(hash, CompressedOops::encode(string));
826 }
827 };
828
829 struct CopyToArchive : StackObj {
830 CompactStringTableWriter* _writer;
836 }
837 unsigned int hash = java_lang_String::hash_code(s);
838 if (hash == 0) {
839 return true;
840 }
841
842 java_lang_String::set_hash(s, hash);
843 oop new_s = StringTable::create_archived_string(s, Thread::current());
844 if (new_s == NULL) {
845 return true;
846 }
847
848 val->replace(new_s);
849 // add to the compact table
850 _writer->add(hash, new_s);
851 return true;
852 }
853 };
854
855 void StringTable::copy_shared_string_table(CompactStringTableWriter* writer) {
856 assert(HeapShared::is_heap_object_archiving_allowed(), "must be");
857
858 CopyToArchive copy(writer);
859 StringTable::the_table()->_local_table->do_scan(Thread::current(), copy);
860 }
861
862 void StringTable::write_to_archive() {
863 assert(HeapShared::is_heap_object_archiving_allowed(), "must be");
864
865 _shared_table.reset();
866 int num_buckets = the_table()->_items_count / SharedSymbolTableBucketSize;
867 // calculation of num_buckets can result in zero buckets, we need at least one
868 CompactStringTableWriter writer(num_buckets > 1 ? num_buckets : 1,
869 &MetaspaceShared::stats()->string);
870
871 // Copy the interned strings into the "string space" within the java heap
872 copy_shared_string_table(&writer);
873 writer.dump(&_shared_table, "string");
874 }
875
876 void StringTable::serialize(SerializeClosure* soc) {
877 _shared_table.serialize(soc);
878
879 if (soc->writing()) {
880 // Sanity. Make sure we don't use the shared table at dump time
881 _shared_table.reset();
882 } else if (!_shared_string_mapped) {
883 _shared_table.reset();
|