src/share/vm/classfile/symbolTable.cpp

changeset 3682
fc9d8850ab8b
parent 3427
94ec88ca68e2
child 3865
e9140bf80b4a
     1.1 --- a/src/share/vm/classfile/symbolTable.cpp	Thu Mar 15 13:37:13 2012 +0100
     1.2 +++ b/src/share/vm/classfile/symbolTable.cpp	Fri Mar 23 11:16:05 2012 -0400
     1.3 @@ -1,5 +1,5 @@
     1.4  /*
     1.5 - * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
     1.6 + * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
     1.7   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     1.8   *
     1.9   * This code is free software; you can redistribute it and/or modify it
    1.10 @@ -27,6 +27,7 @@
    1.11  #include "classfile/symbolTable.hpp"
    1.12  #include "classfile/systemDictionary.hpp"
    1.13  #include "gc_interface/collectedHeap.inline.hpp"
    1.14 +#include "memory/allocation.inline.hpp"
    1.15  #include "memory/filemap.hpp"
    1.16  #include "memory/gcLocker.inline.hpp"
    1.17  #include "oops/oop.inline.hpp"
    1.18 @@ -37,34 +38,35 @@
    1.19  // --------------------------------------------------------------------------
    1.20  
    1.21  SymbolTable* SymbolTable::_the_table = NULL;
    1.22 +// Static arena for symbols that are not deallocated
    1.23 +Arena* SymbolTable::_arena = NULL;
    1.24  
    1.25 -Symbol* SymbolTable::allocate_symbol(const u1* name, int len, TRAPS) {
    1.26 +Symbol* SymbolTable::allocate_symbol(const u1* name, int len, bool c_heap, TRAPS) {
    1.27    // Don't allow symbols to be created which cannot fit in a Symbol*.
    1.28    if (len > Symbol::max_length()) {
    1.29      THROW_MSG_0(vmSymbols::java_lang_InternalError(),
    1.30                  "name is too long to represent");
    1.31    }
    1.32 -  Symbol* sym = new (len) Symbol(name, len);
    1.33 +  Symbol* sym;
    1.34 +  // Allocate symbols in the C heap when dumping shared spaces in case there
    1.35 +  // are temporary symbols we can remove.
    1.36 +  if (c_heap || DumpSharedSpaces) {
    1.37 +    // refcount starts as 1
    1.38 +    sym = new (len, THREAD) Symbol(name, len, 1);
    1.39 +  } else {
    1.40 +    sym = new (len, arena(), THREAD) Symbol(name, len, -1);
    1.41 +  }
    1.42    assert(sym != NULL, "new should call vm_exit_out_of_memory if C_HEAP is exhausted");
    1.43    return sym;
    1.44  }
    1.45  
    1.46 -bool SymbolTable::allocate_symbols(int names_count, const u1** names,
    1.47 -                                   int* lengths, Symbol** syms, TRAPS) {
    1.48 -  for (int i = 0; i< names_count; i++) {
    1.49 -    if (lengths[i] > Symbol::max_length()) {
    1.50 -      THROW_MSG_0(vmSymbols::java_lang_InternalError(),
    1.51 -                  "name is too long to represent");
    1.52 -    }
    1.53 +void SymbolTable::initialize_symbols(int arena_alloc_size) {
    1.54 +  // Initialize the arena for global symbols, size passed in depends on CDS.
    1.55 +  if (arena_alloc_size == 0) {
    1.56 +    _arena = new Arena();
    1.57 +  } else {
    1.58 +    _arena = new Arena(arena_alloc_size);
    1.59    }
    1.60 -
    1.61 -  for (int i = 0; i< names_count; i++) {
    1.62 -    int len = lengths[i];
    1.63 -    syms[i] = new (len) Symbol(names[i], len);
    1.64 -    assert(syms[i] != NULL, "new should call vm_exit_out_of_memory if "
    1.65 -                            "C_HEAP is exhausted");
    1.66 -  }
    1.67 -  return true;
    1.68  }
    1.69  
    1.70  // Call function for all symbols in the symbol table.
    1.71 @@ -83,8 +85,7 @@
    1.72  int SymbolTable::symbols_counted = 0;
    1.73  
    1.74  // Remove unreferenced symbols from the symbol table
    1.75 -// This is done late during GC.  This doesn't use the hash table unlink because
    1.76 -// it assumes that the literals are oops.
    1.77 +// This is done late during GC.
    1.78  void SymbolTable::unlink() {
    1.79    int removed = 0;
    1.80    int total = 0;
    1.81 @@ -156,7 +157,7 @@
    1.82    if (s != NULL) return s;
    1.83  
    1.84    // Otherwise, add to symbol to table
    1.85 -  return the_table()->basic_add(index, (u1*)name, len, hashValue, CHECK_NULL);
    1.86 +  return the_table()->basic_add(index, (u1*)name, len, hashValue, true, CHECK_NULL);
    1.87  }
    1.88  
    1.89  Symbol* SymbolTable::lookup(const Symbol* sym, int begin, int end, TRAPS) {
    1.90 @@ -192,7 +193,7 @@
    1.91    // We can't include the code in No_Safepoint_Verifier because of the
    1.92    // ResourceMark.
    1.93  
    1.94 -  return the_table()->basic_add(index, (u1*)buffer, len, hashValue, CHECK_NULL);
    1.95 +  return the_table()->basic_add(index, (u1*)buffer, len, hashValue, true, CHECK_NULL);
    1.96  }
    1.97  
    1.98  Symbol* SymbolTable::lookup_only(const char* name, int len,
    1.99 @@ -256,71 +257,81 @@
   1.100    }
   1.101  }
   1.102  
   1.103 -void SymbolTable::add(constantPoolHandle cp, int names_count,
   1.104 +void SymbolTable::add(Handle class_loader, constantPoolHandle cp,
   1.105 +                      int names_count,
   1.106                        const char** names, int* lengths, int* cp_indices,
   1.107                        unsigned int* hashValues, TRAPS) {
   1.108    SymbolTable* table = the_table();
   1.109 -  bool added = table->basic_add(cp, names_count, names, lengths,
   1.110 +  bool added = table->basic_add(class_loader, cp, names_count, names, lengths,
   1.111                                  cp_indices, hashValues, CHECK);
   1.112    if (!added) {
   1.113      // do it the hard way
   1.114      for (int i=0; i<names_count; i++) {
   1.115        int index = table->hash_to_index(hashValues[i]);
   1.116 -      Symbol* sym = table->basic_add(index, (u1*)names[i], lengths[i],
   1.117 -                                       hashValues[i], CHECK);
   1.118 +      bool c_heap = class_loader() != NULL;
   1.119 +      Symbol* sym = table->basic_add(index, (u1*)names[i], lengths[i], hashValues[i], c_heap, CHECK);
   1.120        cp->symbol_at_put(cp_indices[i], sym);
   1.121      }
   1.122    }
   1.123  }
   1.124  
   1.125 +Symbol* SymbolTable::new_permanent_symbol(const char* name, TRAPS) {
   1.126 +  unsigned int hash;
   1.127 +  Symbol* result = SymbolTable::lookup_only((char*)name, (int)strlen(name), hash);
   1.128 +  if (result != NULL) {
   1.129 +    return result;
   1.130 +  }
   1.131 +  SymbolTable* table = the_table();
   1.132 +  int index = table->hash_to_index(hash);
   1.133 +  return table->basic_add(index, (u1*)name, (int)strlen(name), hash, false, THREAD);
   1.134 +}
   1.135 +
   1.136  Symbol* SymbolTable::basic_add(int index, u1 *name, int len,
   1.137 -                                 unsigned int hashValue, TRAPS) {
   1.138 +                               unsigned int hashValue, bool c_heap, TRAPS) {
   1.139    assert(!Universe::heap()->is_in_reserved(name) || GC_locker::is_active(),
   1.140           "proposed name of symbol must be stable");
   1.141  
   1.142 -  // We assume that lookup() has been called already, that it failed,
   1.143 -  // and symbol was not found.  We create the symbol here.
   1.144 -  Symbol* sym = allocate_symbol(name, len, CHECK_NULL);
   1.145 -
   1.146 -  // Allocation must be done before grabbing the SymbolTable_lock lock
   1.147 +  // Grab SymbolTable_lock first.
   1.148    MutexLocker ml(SymbolTable_lock, THREAD);
   1.149  
   1.150 -  assert(sym->equals((char*)name, len), "symbol must be properly initialized");
   1.151 -
   1.152    // Since look-up was done lock-free, we need to check if another
   1.153    // thread beat us in the race to insert the symbol.
   1.154 -
   1.155    Symbol* test = lookup(index, (char*)name, len, hashValue);
   1.156    if (test != NULL) {
   1.157 -    // A race occurred and another thread introduced the symbol, this one
   1.158 -    // will be dropped and collected.
   1.159 -    delete sym;
   1.160 +    // A race occurred and another thread introduced the symbol.
   1.161      assert(test->refcount() != 0, "lookup should have incremented the count");
   1.162      return test;
   1.163    }
   1.164  
   1.165 +  // Create a new symbol.
   1.166 +  Symbol* sym = allocate_symbol(name, len, c_heap, CHECK_NULL);
   1.167 +  assert(sym->equals((char*)name, len), "symbol must be properly initialized");
   1.168 +
   1.169    HashtableEntry<Symbol*>* entry = new_entry(hashValue, sym);
   1.170 -  sym->increment_refcount();
   1.171    add_entry(index, entry);
   1.172    return sym;
   1.173  }
   1.174  
   1.175 -bool SymbolTable::basic_add(constantPoolHandle cp, int names_count,
   1.176 +// This version of basic_add adds symbols in batch from the constant pool
   1.177 +// parsing.
   1.178 +bool SymbolTable::basic_add(Handle class_loader, constantPoolHandle cp,
   1.179 +                            int names_count,
   1.180                              const char** names, int* lengths,
   1.181                              int* cp_indices, unsigned int* hashValues,
   1.182                              TRAPS) {
   1.183 -  Symbol* syms[symbol_alloc_batch_size];
   1.184 -  bool allocated = allocate_symbols(names_count, (const u1**)names, lengths,
   1.185 -                                    syms, CHECK_false);
   1.186 -  if (!allocated) {
   1.187 -    return false;
   1.188 +
   1.189 +  // Check symbol names are not too long.  If any are too long, don't add any.
   1.190 +  for (int i = 0; i< names_count; i++) {
   1.191 +    if (lengths[i] > Symbol::max_length()) {
   1.192 +      THROW_MSG_0(vmSymbols::java_lang_InternalError(),
   1.193 +                  "name is too long to represent");
   1.194 +    }
   1.195    }
   1.196  
   1.197 -  // Allocation must be done before grabbing the SymbolTable_lock lock
   1.198 +  // Hold SymbolTable_lock through the symbol creation
   1.199    MutexLocker ml(SymbolTable_lock, THREAD);
   1.200  
   1.201    for (int i=0; i<names_count; i++) {
   1.202 -    assert(syms[i]->equals(names[i], lengths[i]), "symbol must be properly initialized");
   1.203      // Since look-up was done lock-free, we need to check if another
   1.204      // thread beat us in the race to insert the symbol.
   1.205      int index = hash_to_index(hashValues[i]);
   1.206 @@ -330,16 +341,17 @@
   1.207        // will be dropped and collected. Use test instead.
   1.208        cp->symbol_at_put(cp_indices[i], test);
   1.209        assert(test->refcount() != 0, "lookup should have incremented the count");
   1.210 -      delete syms[i];
   1.211      } else {
   1.212 -      Symbol* sym = syms[i];
   1.213 +      // Create a new symbol.  The null class loader is never unloaded so these
   1.214 +      // are allocated specially in a permanent arena.
   1.215 +      bool c_heap = class_loader() != NULL;
   1.216 +      Symbol* sym = allocate_symbol((const u1*)names[i], lengths[i], c_heap, CHECK_(false));
   1.217 +      assert(sym->equals(names[i], lengths[i]), "symbol must be properly initialized");  // why wouldn't it be???
   1.218        HashtableEntry<Symbol*>* entry = new_entry(hashValues[i], sym);
   1.219 -      sym->increment_refcount();  // increment refcount in external hashtable
   1.220        add_entry(index, entry);
   1.221        cp->symbol_at_put(cp_indices[i], sym);
   1.222      }
   1.223    }
   1.224 -
   1.225    return true;
   1.226  }
   1.227  
   1.228 @@ -406,6 +418,8 @@
   1.229            ((float)symbols_removed/(float)symbols_counted)* 100);
   1.230    }
   1.231    tty->print_cr("Reference counts         %5d", Symbol::_total_count);
   1.232 +  tty->print_cr("Symbol arena size        %5d used %5d",
   1.233 +                 arena()->size_in_bytes(), arena()->used());
   1.234    tty->print_cr("Histogram of symbol length:");
   1.235    tty->print_cr("%8s %5d", "Total  ", total);
   1.236    tty->print_cr("%8s %5d", "Maximum", max_symbols);

mercurial