1 /*
2  * Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved.
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * This code is free software; you can redistribute it and/or modify it
6  * under the terms of the GNU General Public License version 2 only, as
7  * published by the Free Software Foundation.
8  *
9  * This code is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12  * version 2 for more details (a copy is included in the LICENSE file that
13  * accompanied this code).
14  *
15  * You should have received a copy of the GNU General Public License version
16  * 2 along with this work; if not, write to the Free Software Foundation,
17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18  *
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 #ifndef SHARE_CLASSFILE_STRINGTABLE_HPP
26 #define SHARE_CLASSFILE_STRINGTABLE_HPP
27 
28 #include "gc/shared/oopStorage.hpp"
29 #include "memory/allocation.hpp"
30 #include "memory/padded.hpp"
31 #include "oops/oop.hpp"
32 #include "oops/weakHandle.hpp"
33 #include "utilities/tableStatistics.hpp"
34 
35 class CompactHashtableWriter;
36 class SerializeClosure;
37 
38 class StringTable;
39 class StringTableConfig;
40 class StringTableCreateEntry;
41 
42 class StringTable : public CHeapObj<mtSymbol>{
43   friend class VMStructs;
44   friend class Symbol;
45   friend class StringTableConfig;
46   friend class StringTableCreateEntry;
47 
48   static volatile bool _has_work;
49   static volatile size_t _uncleaned_items_count;
50 
51   // Set if one bucket is out of balance due to hash algorithm deficiency
52   static volatile bool _needs_rehashing;
53 
54   static OopStorage* _weak_handles;
55 
56   static void grow(JavaThread* jt);
57   static void clean_dead_entries(JavaThread* jt);
58 
59   static double get_load_factor();
60   static double get_dead_factor();
61 
62   static void check_concurrent_work();
63   static void trigger_concurrent_work();
64 
65   static size_t item_added();
66   static void item_removed();
67   static size_t add_items_to_clean(size_t ndead);
68 
69   static oop intern(Handle string_or_null_h, const jchar* name, int len, TRAPS);
70   static oop do_intern(Handle string_or_null, const jchar* name, int len, uintx hash, TRAPS);
71   static oop do_lookup(const jchar* name, int len, uintx hash);
72 
73   static void print_table_statistics(outputStream* st, const char* table_name);
74 
75   static bool do_rehash();
76 
77  public:
78   static size_t table_size();
79   static TableStatistics get_table_statistics();
80 
weak_storage()81   static OopStorage* weak_storage() { return _weak_handles; }
82 
83   static void create_table();
84 
85   static void do_concurrent_work(JavaThread* jt);
has_work()86   static bool has_work() { return _has_work; }
87 
88   // GC support
89 
90   // Must be called before a parallel walk where strings might die.
reset_dead_counter()91   static void reset_dead_counter() { _uncleaned_items_count = 0; }
92 
93   // After the parallel walk this method must be called to trigger
94   // cleaning. Note it might trigger a resize instead.
finish_dead_counter()95   static void finish_dead_counter() { check_concurrent_work(); }
96 
97   // If GC uses ParState directly it should add the number of cleared
98   // strings to this method.
inc_dead_counter(size_t ndead)99   static void inc_dead_counter(size_t ndead) { add_items_to_clean(ndead); }
100 
101   // Serially invoke "f->do_oop" on the locations of all oops in the table.
102   // Used by JFR leak profiler.  TODO: it should find these oops through
103   // the WeakProcessor.
104   static void oops_do(OopClosure* f);
105 
106   // Probing
107   static oop lookup(Symbol* symbol);
108   static oop lookup(const jchar* chars, int length);
109 
110   // Interning
111   static oop intern(Symbol* symbol, TRAPS);
112   static oop intern(oop string, TRAPS);
113   static oop intern(const char *utf8_string, TRAPS);
114 
115   // Rehash the string table if it gets out of balance
116   static void rehash_table();
needs_rehashing()117   static bool needs_rehashing() { return _needs_rehashing; }
update_needs_rehash(bool rehash)118   static inline void update_needs_rehash(bool rehash) {
119     if (rehash) {
120       _needs_rehashing = true;
121     }
122   }
123 
124   // Sharing
125  private:
126   static oop lookup_shared(const jchar* name, int len, unsigned int hash) NOT_CDS_JAVA_HEAP_RETURN_(NULL);
127   static void copy_shared_string_table(CompactHashtableWriter* ch_table) NOT_CDS_JAVA_HEAP_RETURN;
128  public:
129   static oop create_archived_string(oop s, Thread* THREAD) NOT_CDS_JAVA_HEAP_RETURN_(NULL);
130   static void shared_oops_do(OopClosure* f) NOT_CDS_JAVA_HEAP_RETURN;
131   static void write_to_archive() NOT_CDS_JAVA_HEAP_RETURN;
132   static void serialize_shared_table_header(SerializeClosure* soc) NOT_CDS_JAVA_HEAP_RETURN;
133 
134   // Jcmd
135   static void dump(outputStream* st, bool verbose=false);
136   // Debugging
137   static size_t verify_and_compare_entries();
138   static void verify();
139 };
140 
141 #endif // SHARE_CLASSFILE_STRINGTABLE_HPP
142