1 /*
2  * Copyright (c) 1997, 2018, 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_VM_CLASSFILE_STRINGTABLE_HPP
26 #define SHARE_VM_CLASSFILE_STRINGTABLE_HPP
27 
28 #include "gc/shared/oopStorage.hpp"
29 #include "gc/shared/oopStorageParState.hpp"
30 #include "memory/allocation.hpp"
31 #include "memory/padded.hpp"
32 #include "oops/oop.hpp"
33 #include "oops/weakHandle.hpp"
34 #include "utilities/concurrentHashTable.hpp"
35 
36 template <class T, class N> class CompactHashtable;
37 class CompactStringTableWriter;
38 class SerializeClosure;
39 
40 class StringTable;
41 class StringTableConfig;
42 typedef ConcurrentHashTable<WeakHandle<vm_string_table_data>,
43                             StringTableConfig, mtSymbol> StringTableHash;
44 
45 class StringTableCreateEntry;
46 
47 class StringTable : public CHeapObj<mtSymbol>{
48   friend class VMStructs;
49   friend class Symbol;
50   friend class StringTableConfig;
51   friend class StringTableCreateEntry;
52 
53 private:
54   void grow(JavaThread* jt);
55   void clean_dead_entries(JavaThread* jt);
56 
57   // The string table
58   static StringTable* _the_table;
59   // Shared string table
60   static CompactHashtable<oop, char> _shared_table;
61   static bool _shared_string_mapped;
62   static bool _alt_hash;
63 private:
64 
65    // Set if one bucket is out of balance due to hash algorithm deficiency
66   StringTableHash* _local_table;
67   size_t _current_size;
68   volatile bool _has_work;
69   volatile bool _needs_rehashing;
70 
71   OopStorage* _weak_handles;
72 
73   volatile size_t _items;
74   DEFINE_PAD_MINUS_SIZE(1, DEFAULT_CACHE_LINE_SIZE, sizeof(volatile size_t));
75   volatile size_t _uncleaned_items;
76   DEFINE_PAD_MINUS_SIZE(2, DEFAULT_CACHE_LINE_SIZE, sizeof(volatile size_t));
77 
78   double get_load_factor();
79   double get_dead_factor();
80 
81   void check_concurrent_work();
82   void trigger_concurrent_work();
83 
84   static size_t item_added();
85   static void item_removed();
86   size_t add_items_to_clean(size_t ndead);
87 
88   StringTable();
89 
90   static oop intern(Handle string_or_null_h, jchar* name, int len, TRAPS);
91   oop do_intern(Handle string_or_null, jchar* name, int len, uintx hash, TRAPS);
92   oop do_lookup(jchar* name, int len, uintx hash);
93 
94   void concurrent_work(JavaThread* jt);
95   void print_table_statistics(outputStream* st, const char* table_name);
96 
97   void try_rehash_table();
98   bool do_rehash();
99 
100  public:
101   // The string table
the_table()102   static StringTable* the_table() { return _the_table; }
103   size_t table_size(Thread* thread = NULL);
104 
weak_storage()105   static OopStorage* weak_storage() { return the_table()->_weak_handles; }
106 
create_table()107   static void create_table() {
108     assert(_the_table == NULL, "One string table allowed.");
109     _the_table = new StringTable();
110   }
111 
112   static void do_concurrent_work(JavaThread* jt);
has_work()113   static bool has_work() { return the_table()->_has_work; }
114 
115   // GC support
116 
117   // Must be called before a parallel walk where strings might die.
reset_dead_counter()118   static void reset_dead_counter() {
119     the_table()->_uncleaned_items = 0;
120   }
121   // After the parallel walk this method must be called to trigger
122   // cleaning. Note it might trigger a resize instead.
finish_dead_counter()123   static void finish_dead_counter() {
124     the_table()->check_concurrent_work();
125   }
126 
127   // If GC uses ParState directly it should add the number of cleared
128   // strings to this method.
inc_dead_counter(size_t ndead)129   static void inc_dead_counter(size_t ndead) {
130     the_table()->add_items_to_clean(ndead);
131   }
132 
133   //   Delete pointers to otherwise-unreachable objects.
unlink(BoolObjectClosure * cl)134   static void unlink(BoolObjectClosure* cl) {
135     unlink_or_oops_do(cl);
136   }
137   static void unlink_or_oops_do(BoolObjectClosure* is_alive, OopClosure* f = NULL,
138                                 int* processed = NULL, int* removed = NULL);
139 
140   // Serially invoke "f->do_oop" on the locations of all oops in the table.
141   static void oops_do(OopClosure* f);
142 
143   // Possibly parallel versions of the above
144   static void possibly_parallel_unlink(
145      OopStorage::ParState<false /* concurrent */, false /* const*/>* par_state_string,
146      BoolObjectClosure* cl, int* processed, int* removed);
147   static void possibly_parallel_oops_do(
148      OopStorage::ParState<false /* concurrent */, false /* const*/>* par_state_string,
149      OopClosure* f);
150 
151   // Probing
152   static oop lookup(Symbol* symbol);
153   static oop lookup(jchar* chars, int length);
154 
155   // Interning
156   static oop intern(Symbol* symbol, TRAPS);
157   static oop intern(oop string, TRAPS);
158   static oop intern(const char *utf8_string, TRAPS);
159 
160   // Rehash the string table if it gets out of balance
161   static void rehash_table();
needs_rehashing()162   static bool needs_rehashing()
163     { return StringTable::the_table()->_needs_rehashing; }
164 
165   // Sharing
166  private:
167   oop lookup_shared(jchar* name, int len, unsigned int hash) NOT_CDS_JAVA_HEAP_RETURN_(NULL);
168   static void copy_shared_string_table(CompactStringTableWriter* ch_table) NOT_CDS_JAVA_HEAP_RETURN;
169  public:
170   static oop create_archived_string(oop s, Thread* THREAD) NOT_CDS_JAVA_HEAP_RETURN_(NULL);
set_shared_string_mapped()171   static void set_shared_string_mapped() { _shared_string_mapped = true; }
shared_string_mapped()172   static bool shared_string_mapped()     { return _shared_string_mapped; }
173   static void shared_oops_do(OopClosure* f) NOT_CDS_JAVA_HEAP_RETURN;
174   static void write_to_archive() NOT_CDS_JAVA_HEAP_RETURN;
175   static void serialize(SerializeClosure* soc) NOT_CDS_JAVA_HEAP_RETURN;
176 
177   // Jcmd
178   static void dump(outputStream* st, bool verbose=false);
179   // Debugging
180   static size_t verify_and_compare_entries();
181   static void verify();
182 };
183 
184 #endif // SHARE_VM_CLASSFILE_STRINGTABLE_HPP
185