1 /*
   2  * Copyright (c) 1997, 2010, 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_SYMBOLTABLE_HPP
  26 #define SHARE_VM_CLASSFILE_SYMBOLTABLE_HPP
  27 
  28 #include "memory/allocation.inline.hpp"
  29 #include "oops/symbolOop.hpp"
  30 #include "utilities/hashtable.hpp"
  31 
  32 // The symbol table holds all symbolOops and corresponding interned strings.
  33 // symbolOops and literal strings should be canonicalized.
  34 //
  35 // The interned strings are created lazily.
  36 //
  37 // It is implemented as an open hash table with a fixed number of buckets.
  38 //
  39 // %note:
  40 //  - symbolTableEntrys are allocated in blocks to reduce the space overhead.
  41 
  42 class BoolObjectClosure;
  43 
  44 
  45 class SymbolTable : public Hashtable {
  46   friend class VMStructs;
  47 
  48 private:
  49   // The symbol table
  50   static SymbolTable* _the_table;
  51 
  52   // Adding elements
  53   symbolOop basic_add(int index, u1* name, int len,
  54                       unsigned int hashValue, TRAPS);
  55   bool basic_add(constantPoolHandle cp, int names_count,
  56                  const char** names, int* lengths, int* cp_indices,
  57                  unsigned int* hashValues, TRAPS);
  58 
  59   // Table size
  60   enum {
  61     symbol_table_size = 20011
  62   };
  63 
  64   symbolOop lookup(int index, const char* name, int len, unsigned int hash);
  65 
  66   SymbolTable()
  67     : Hashtable(symbol_table_size, sizeof (HashtableEntry)) {}
  68 
  69   SymbolTable(HashtableBucket* t, int number_of_entries)
  70     : Hashtable(symbol_table_size, sizeof (HashtableEntry), t,
  71                 number_of_entries) {}
  72 
  73 
  74 public:
  75   enum {
  76     symbol_alloc_batch_size = 8
  77   };
  78 
  79   // The symbol table
  80   static SymbolTable* the_table() { return _the_table; }
  81 
  82   static void create_table() {
  83     assert(_the_table == NULL, "One symbol table allowed.");
  84     _the_table = new SymbolTable();
  85   }
  86 
  87   static void create_table(HashtableBucket* t, int length,
  88                            int number_of_entries) {
  89     assert(_the_table == NULL, "One symbol table allowed.");
  90     assert(length == symbol_table_size * sizeof(HashtableBucket),
  91            "bad shared symbol size.");
  92     _the_table = new SymbolTable(t, number_of_entries);
  93   }
  94 
  95   static symbolOop lookup(const char* name, int len, TRAPS);
  96   // lookup only, won't add. Also calculate hash.
  97   static symbolOop lookup_only(const char* name, int len, unsigned int& hash);
  98   // Only copy to C string to be added if lookup failed.
  99   static symbolOop lookup(symbolHandle sym, int begin, int end, TRAPS);
 100 
 101   // jchar (utf16) version of lookups
 102   static symbolOop lookup_unicode(const jchar* name, int len, TRAPS);
 103   static symbolOop lookup_only_unicode(const jchar* name, int len, unsigned int& hash);
 104 
 105   static void add(constantPoolHandle cp, int names_count,
 106                   const char** names, int* lengths, int* cp_indices,
 107                   unsigned int* hashValues, TRAPS);
 108 
 109   // GC support
 110   //   Delete pointers to otherwise-unreachable objects.
 111   static void unlink(BoolObjectClosure* cl) {
 112     the_table()->Hashtable::unlink(cl);
 113   }
 114 
 115   // Invoke "f->do_oop" on the locations of all oops in the table.
 116   static void oops_do(OopClosure* f) {
 117     the_table()->Hashtable::oops_do(f);
 118   }
 119 
 120   // Symbol lookup
 121   static symbolOop lookup(int index, const char* name, int len, TRAPS);
 122 
 123   // Needed for preloading classes in signatures when compiling.
 124   // Returns the symbol is already present in symbol table, otherwise
 125   // NULL.  NO ALLOCATION IS GUARANTEED!
 126   static symbolOop probe(const char* name, int len) {
 127     unsigned int ignore_hash;
 128     return lookup_only(name, len, ignore_hash);
 129   }
 130   static symbolOop probe_unicode(const jchar* name, int len) {
 131     unsigned int ignore_hash;
 132     return lookup_only_unicode(name, len, ignore_hash);
 133   }
 134 
 135   // Histogram
 136   static void print_histogram()     PRODUCT_RETURN;
 137 
 138   // Debugging
 139   static void verify();
 140 
 141   // Sharing
 142   static void copy_buckets(char** top, char*end) {
 143     the_table()->Hashtable::copy_buckets(top, end);
 144   }
 145   static void copy_table(char** top, char*end) {
 146     the_table()->Hashtable::copy_table(top, end);
 147   }
 148   static void reverse(void* boundary = NULL) {
 149     ((Hashtable*)the_table())->reverse(boundary);
 150   }
 151 };
 152 
 153 
 154 class StringTable : public Hashtable {
 155   friend class VMStructs;
 156 
 157 private:
 158   // The string table
 159   static StringTable* _the_table;
 160 
 161   static oop intern(Handle string_or_null, jchar* chars, int length, TRAPS);
 162   oop basic_add(int index, Handle string_or_null, jchar* name, int len,
 163                 unsigned int hashValue, TRAPS);
 164 
 165   // Table size
 166   enum {
 167     string_table_size = 1009
 168   };
 169 
 170   oop lookup(int index, jchar* chars, int length, unsigned int hashValue);
 171 
 172   StringTable() : Hashtable(string_table_size, sizeof (HashtableEntry)) {}
 173 
 174   StringTable(HashtableBucket* t, int number_of_entries)
 175     : Hashtable(string_table_size, sizeof (HashtableEntry), t,
 176                 number_of_entries) {}
 177 
 178 public:
 179   // The string table
 180   static StringTable* the_table() { return _the_table; }
 181 
 182   static void create_table() {
 183     assert(_the_table == NULL, "One string table allowed.");
 184     _the_table = new StringTable();
 185   }
 186 
 187   static void create_table(HashtableBucket* t, int length,
 188                            int number_of_entries) {
 189     assert(_the_table == NULL, "One string table allowed.");
 190     assert(length == string_table_size * sizeof(HashtableBucket),
 191            "bad shared string size.");
 192     _the_table = new StringTable(t, number_of_entries);
 193   }
 194 
 195 
 196   static int hash_string(jchar* s, int len);
 197 
 198 
 199   // GC support
 200   //   Delete pointers to otherwise-unreachable objects.
 201   static void unlink(BoolObjectClosure* cl) {
 202     the_table()->Hashtable::unlink(cl);
 203   }
 204 
 205   // Invoke "f->do_oop" on the locations of all oops in the table.
 206   static void oops_do(OopClosure* f) {
 207     the_table()->Hashtable::oops_do(f);
 208   }
 209 
 210   // Probing
 211   static oop lookup(symbolOop symbol);
 212 
 213   // Interning
 214   static oop intern(symbolOop symbol, TRAPS);
 215   static oop intern(oop string, TRAPS);
 216   static oop intern(const char *utf8_string, TRAPS);
 217 
 218   // Debugging
 219   static void verify();
 220 
 221   // Sharing
 222   static void copy_buckets(char** top, char*end) {
 223     the_table()->Hashtable::copy_buckets(top, end);
 224   }
 225   static void copy_table(char** top, char*end) {
 226     the_table()->Hashtable::copy_table(top, end);
 227   }
 228   static void reverse() {
 229     ((BasicHashtable*)the_table())->reverse();
 230   }
 231 };
 232 
 233 #endif // SHARE_VM_CLASSFILE_SYMBOLTABLE_HPP