1 /* 2 * Copyright (c) 1997, 2015, 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 "memory/allocation.inline.hpp" 29 #include "utilities/hashtable.hpp" 30 31 template <class T, class N> class CompactHashtable; 32 class CompactHashtableWriter; 33 class FileMapInfo; 34 35 class StringTable : public RehashableHashtable<oop, mtSymbol> { 36 friend class VMStructs; 37 friend class Symbol; 38 39 private: 40 // The string table 41 static StringTable* _the_table; 42 43 // Shared string table 44 static CompactHashtable<oop, char> _shared_table; 45 static bool _ignore_shared_strings; 46 47 // Set if one bucket is out of balance due to hash algorithm deficiency 48 static bool _needs_rehashing; 49 50 // Claimed high water mark for parallel chunked scanning 51 static volatile int _parallel_claimed_idx; 52 53 static oop intern(Handle string_or_null, jchar* chars, int length, TRAPS); 54 oop basic_add(int index, Handle string_or_null, jchar* name, int len, 55 unsigned int hashValue, TRAPS); 56 57 oop lookup_in_main_table(int index, jchar* chars, int length, unsigned int hashValue); 58 static oop lookup_shared(jchar* name, int len); 59 60 // Apply the give oop closure to the entries to the buckets 61 // in the range [start_idx, end_idx). 62 static void buckets_oops_do(OopClosure* f, int start_idx, int end_idx); 63 // Unlink or apply the give oop closure to the entries to the buckets 64 // in the range [start_idx, end_idx). 65 static void buckets_unlink_or_oops_do(BoolObjectClosure* is_alive, OopClosure* f, int start_idx, int end_idx, int* processed, int* removed); 66 67 StringTable() : RehashableHashtable<oop, mtSymbol>((int)StringTableSize, 68 sizeof (HashtableEntry<oop, mtSymbol>)) {} 69 70 StringTable(HashtableBucket<mtSymbol>* t, int number_of_entries) 71 : RehashableHashtable<oop, mtSymbol>((int)StringTableSize, sizeof (HashtableEntry<oop, mtSymbol>), t, 72 number_of_entries) {} 73 public: 74 // The string table 75 static StringTable* the_table() { return _the_table; } 76 77 // Size of one bucket in the string table. Used when checking for rollover. 78 static uint bucket_size() { return sizeof(HashtableBucket<mtSymbol>); } 79 80 static void create_table() { 81 assert(_the_table == NULL, "One string table allowed."); 82 _the_table = new StringTable(); 83 } 84 85 // GC support 86 // Delete pointers to otherwise-unreachable objects. 87 static void unlink_or_oops_do(BoolObjectClosure* cl, OopClosure* f) { 88 int processed = 0; 89 int removed = 0; 90 unlink_or_oops_do(cl, f, &processed, &removed); 91 } 92 static void unlink(BoolObjectClosure* cl) { 93 int processed = 0; 94 int removed = 0; 95 unlink_or_oops_do(cl, NULL, &processed, &removed); 96 } 97 static void unlink_or_oops_do(BoolObjectClosure* cl, OopClosure* f, int* processed, int* removed); 98 static void unlink(BoolObjectClosure* cl, int* processed, int* removed) { 99 unlink_or_oops_do(cl, NULL, processed, removed); 100 } 101 // Serially invoke "f->do_oop" on the locations of all oops in the table. 102 static void oops_do(OopClosure* f); 103 104 // Possibly parallel versions of the above 105 static void possibly_parallel_unlink_or_oops_do(BoolObjectClosure* cl, OopClosure* f, int* processed, int* removed); 106 static void possibly_parallel_unlink(BoolObjectClosure* cl, int* processed, int* removed) { 107 possibly_parallel_unlink_or_oops_do(cl, NULL, processed, removed); 108 } 109 static void possibly_parallel_oops_do(OopClosure* f); 110 111 // Hashing algorithm, used as the hash value used by the 112 // StringTable for bucket selection and comparison (stored in the 113 // HashtableEntry structures). This is used in the String.intern() method. 114 template<typename T> static unsigned int hash_string(const T* s, int len); 115 116 // Internal test. 117 static void test_alt_hash() PRODUCT_RETURN; 118 119 // Probing 120 static oop lookup(Symbol* symbol); 121 static oop lookup(jchar* chars, int length); 122 123 // Interning 124 static oop intern(Symbol* symbol, TRAPS); 125 static oop intern(oop string, TRAPS); 126 static oop intern(const char *utf8_string, TRAPS); 127 128 // Debugging 129 static void verify(); 130 static void dump(outputStream* st, bool verbose=false); 131 132 enum VerifyMesgModes { 133 _verify_quietly = 0, 134 _verify_with_mesgs = 1 135 }; 136 137 enum VerifyRetTypes { 138 _verify_pass = 0, 139 _verify_fail_continue = 1, 140 _verify_fail_done = 2 141 }; 142 143 static VerifyRetTypes compare_entries(int bkt1, int e_cnt1, 144 HashtableEntry<oop, mtSymbol>* e_ptr1, 145 int bkt2, int e_cnt2, 146 HashtableEntry<oop, mtSymbol>* e_ptr2); 147 static VerifyRetTypes verify_entry(int bkt, int e_cnt, 148 HashtableEntry<oop, mtSymbol>* e_ptr, 149 VerifyMesgModes mesg_mode); 150 static int verify_and_compare_entries(); 151 152 // Sharing 153 static void ignore_shared_strings(bool v) { _ignore_shared_strings = v; } 154 static bool shared_string_ignored() { return _ignore_shared_strings; } 155 static void shared_oops_do(OopClosure* f); 156 static bool copy_shared_string(GrowableArray<MemRegion> *string_space, 157 CompactHashtableWriter* ch_table); 158 static bool copy_compact_table(char** top, char* end, GrowableArray<MemRegion> *string_space, 159 size_t* space_size); 160 static const char* init_shared_table(FileMapInfo *mapinfo, char* buffer); 161 static void reverse() { 162 the_table()->Hashtable<oop, mtSymbol>::reverse(); 163 } 164 165 // Rehash the symbol table if it gets out of balance 166 static void rehash_table(); 167 static bool needs_rehashing() { return _needs_rehashing; } 168 169 // Parallel chunked scanning 170 static void clear_parallel_claimed_index() { _parallel_claimed_idx = 0; } 171 static int parallel_claimed_index() { return _parallel_claimed_idx; } 172 }; 173 #endif // SHARE_VM_CLASSFILE_STRINGTABLE_HPP