< prev index next >

src/hotspot/share/classfile/symbolTable.cpp

Print this page

@@ -22,15 +22,16 @@
  *
  */
 
 #include "precompiled.hpp"
 #include "classfile/altHashing.hpp"
-#include "classfile/compactHashtable.inline.hpp"
+#include "classfile/compactHashtable.hpp"
 #include "classfile/javaClasses.hpp"
 #include "classfile/symbolTable.hpp"
 #include "memory/allocation.inline.hpp"
 #include "memory/metaspaceClosure.hpp"
+#include "memory/metaspaceShared.hpp"
 #include "memory/resourceArea.hpp"
 #include "oops/oop.inline.hpp"
 #include "runtime/atomic.hpp"
 #include "runtime/interfaceSupport.inline.hpp"
 #include "runtime/timerTrace.hpp"

@@ -54,12 +55,31 @@
 #define CLEAN_DEAD_HIGH_WATER_MARK  0.0
 
 #define ON_STACK_BUFFER_LENGTH 128
 
 // --------------------------------------------------------------------------
+inline Symbol* read_symbol_from_compact_hashtable(address base_address, u4 offset) {
+  return (Symbol*)(base_address + offset);
+}
+
+inline bool symbol_equals_compact_hashtable_entry(Symbol* value, const char* key, int len) {
+  if (value->equals(key, len)) {
+    assert(value->refcount() == PERM_REFCOUNT, "must be shared");
+    return true;
+  } else {
+    return false;
+  }
+}
+
+static CompactHashtable<
+  const char*, Symbol*,
+  read_symbol_from_compact_hashtable,
+  symbol_equals_compact_hashtable_entry
+> _shared_table;
+
+// --------------------------------------------------------------------------
 SymbolTable* SymbolTable::_the_table = NULL;
-CompactHashtable<Symbol*, char> SymbolTable::_shared_table;
 volatile bool SymbolTable::_alt_hash = false;
 volatile bool SymbolTable::_lookup_shared_first = false;
 // Static arena for symbols that are not deallocated
 Arena* SymbolTable::_arena = NULL;
 

@@ -222,14 +242,24 @@
     _cl->do_symbol(value);
     return true;
   };
 };
 
+class SharedSymbolIterator {
+  SymbolClosure* _symbol_closure;
+public:
+  SharedSymbolIterator(SymbolClosure* f) : _symbol_closure(f) {}
+  void do_value(Symbol* symbol) {
+    _symbol_closure->do_symbol(&symbol);
+  }
+};
+
 // Call function for all symbols in the symbol table.
 void SymbolTable::symbols_do(SymbolClosure *cl) {
   // all symbols from shared table
-  _shared_table.symbols_do(cl);
+  SharedSymbolIterator iter(cl);
+  _shared_table.iterate(&iter);
 
   // all symbols from the dynamic table
   SymbolsDo sd(cl);
   if (!SymbolTable::the_table()->_local_table->try_scan(Thread::current(), sd)) {
     log_info(stringtable)("symbols_do unavailable at this moment");

@@ -595,10 +625,26 @@
     }
   }
 }
 
 #if INCLUDE_CDS
+class CompactSymbolTableWriter: public CompactHashtableWriter {
+public:
+  CompactSymbolTableWriter(int num_buckets, CompactHashtableStats* stats) :
+    CompactHashtableWriter(num_buckets, stats) {}
+  void add(unsigned int hash, Symbol *symbol) {
+    uintx deltax = MetaspaceShared::object_delta(symbol);
+    // When the symbols are stored into the archive, we already check that
+    // they won't be more than MAX_SHARED_DELTA from the base address, or
+    // else the dumping would have been aborted.
+    assert(deltax <= MAX_SHARED_DELTA, "must not be");
+    u4 delta = u4(deltax);
+
+    CompactHashtableWriter::add(hash, delta);
+  }
+};
+
 struct CopyToArchive : StackObj {
   CompactSymbolTableWriter* _writer;
   CopyToArchive(CompactSymbolTableWriter* writer) : _writer(writer) {}
   bool operator()(Symbol** value) {
     assert(value != NULL, "expected valid value");

@@ -611,11 +657,10 @@
     assert(fixed_hash == hash_symbol((const char*)sym->bytes(), sym->utf8_length(), false),
            "must not rehash during dumping");
 
     // add to the compact table
     _writer->add(fixed_hash, sym);
-
     return true;
   }
 };
 
 void SymbolTable::copy_shared_symbol_table(CompactSymbolTableWriter* writer) {

@@ -629,22 +674,21 @@
   int num_buckets = (int)(SymbolTable::the_table()->_items_count / SharedSymbolTableBucketSize);
   // calculation of num_buckets can result in zero buckets, we need at least one
   CompactSymbolTableWriter writer(num_buckets > 1 ? num_buckets : 1,
                                   &MetaspaceShared::stats()->symbol);
   copy_shared_symbol_table(&writer);
-  writer.dump(&_shared_table);
+  writer.dump(&_shared_table, "symbol");
 
   // Verify table is correct
   Symbol* sym = vmSymbols::java_lang_Object();
   const char* name = (const char*)sym->bytes();
   int len = sym->utf8_length();
   unsigned int hash = hash_symbol(name, len, SymbolTable::_alt_hash);
   assert(sym == _shared_table.lookup(name, hash, len), "sanity");
 }
 
 void SymbolTable::serialize(SerializeClosure* soc) {
-  _shared_table.set_type(CompactHashtable<Symbol*, char>::_symbol_table);
   _shared_table.serialize(soc);
 
   if (soc->writing()) {
     // Sanity. Make sure we don't use the shared table at dump time
     _shared_table.reset();
< prev index next >