7150058: Allocate symbols from null boot loader to an arena for NMT

Fri, 23 Mar 2012 11:16:05 -0400

author
coleenp
date
Fri, 23 Mar 2012 11:16:05 -0400
changeset 3682
fc9d8850ab8b
parent 3681
51612f0c0a79
child 3683
a4ee440d71cc

7150058: Allocate symbols from null boot loader to an arena for NMT
Summary: Move symbol allocation to an arena so NMT doesn't have to track them at startup.
Reviewed-by: never, kamg, zgu

src/share/vm/classfile/classFileParser.cpp file | annotate | diff | comparison | revisions
src/share/vm/classfile/classFileParser.hpp file | annotate | diff | comparison | revisions
src/share/vm/classfile/symbolTable.cpp file | annotate | diff | comparison | revisions
src/share/vm/classfile/symbolTable.hpp file | annotate | diff | comparison | revisions
src/share/vm/classfile/vmSymbols.cpp file | annotate | diff | comparison | revisions
src/share/vm/memory/dump.cpp file | annotate | diff | comparison | revisions
src/share/vm/oops/objArrayKlassKlass.cpp file | annotate | diff | comparison | revisions
src/share/vm/oops/symbol.cpp file | annotate | diff | comparison | revisions
src/share/vm/oops/symbol.hpp file | annotate | diff | comparison | revisions
src/share/vm/oops/typeArrayKlass.cpp file | annotate | diff | comparison | revisions
src/share/vm/runtime/globals.hpp file | annotate | diff | comparison | revisions
     1.1 --- a/src/share/vm/classfile/classFileParser.cpp	Thu Mar 15 13:37:13 2012 +0100
     1.2 +++ b/src/share/vm/classfile/classFileParser.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 @@ -81,7 +81,7 @@
    1.11  #define JAVA_7_VERSION                    51
    1.12  
    1.13  
    1.14 -void ClassFileParser::parse_constant_pool_entries(constantPoolHandle cp, int length, TRAPS) {
    1.15 +void ClassFileParser::parse_constant_pool_entries(Handle class_loader, constantPoolHandle cp, int length, TRAPS) {
    1.16    // Use a local copy of ClassFileStream. It helps the C++ compiler to optimize
    1.17    // this function (_current can be allocated in a register, with scalar
    1.18    // replacement of aggregates). The _current pointer is copied back to
    1.19 @@ -272,7 +272,7 @@
    1.20              indices[names_count] = index;
    1.21              hashValues[names_count++] = hash;
    1.22              if (names_count == SymbolTable::symbol_alloc_batch_size) {
    1.23 -              SymbolTable::new_symbols(cp, names_count, names, lengths, indices, hashValues, CHECK);
    1.24 +              SymbolTable::new_symbols(class_loader, cp, names_count, names, lengths, indices, hashValues, CHECK);
    1.25                names_count = 0;
    1.26              }
    1.27            } else {
    1.28 @@ -289,7 +289,7 @@
    1.29  
    1.30    // Allocate the remaining symbols
    1.31    if (names_count > 0) {
    1.32 -    SymbolTable::new_symbols(cp, names_count, names, lengths, indices, hashValues, CHECK);
    1.33 +    SymbolTable::new_symbols(class_loader, cp, names_count, names, lengths, indices, hashValues, CHECK);
    1.34    }
    1.35  
    1.36    // Copy _current pointer of local copy back to stream().
    1.37 @@ -318,7 +318,7 @@
    1.38  
    1.39  bool inline valid_cp_range(int index, int length) { return (index > 0 && index < length); }
    1.40  
    1.41 -constantPoolHandle ClassFileParser::parse_constant_pool(TRAPS) {
    1.42 +constantPoolHandle ClassFileParser::parse_constant_pool(Handle class_loader, TRAPS) {
    1.43    ClassFileStream* cfs = stream();
    1.44    constantPoolHandle nullHandle;
    1.45  
    1.46 @@ -337,7 +337,7 @@
    1.47    ConstantPoolCleaner cp_in_error(cp); // set constant pool to be cleaned up.
    1.48  
    1.49    // parsing constant pool entries
    1.50 -  parse_constant_pool_entries(cp, length, CHECK_(nullHandle));
    1.51 +  parse_constant_pool_entries(class_loader, cp, length, CHECK_(nullHandle));
    1.52  
    1.53    int index = 1;  // declared outside of loops for portability
    1.54  
    1.55 @@ -2758,7 +2758,7 @@
    1.56    _relax_verify = Verifier::relax_verify_for(class_loader());
    1.57  
    1.58    // Constant pool
    1.59 -  constantPoolHandle cp = parse_constant_pool(CHECK_(nullHandle));
    1.60 +  constantPoolHandle cp = parse_constant_pool(class_loader, CHECK_(nullHandle));
    1.61    ConstantPoolCleaner error_handler(cp); // set constant pool to be cleaned up.
    1.62  
    1.63    int cp_size = cp->length();
     2.1 --- a/src/share/vm/classfile/classFileParser.hpp	Thu Mar 15 13:37:13 2012 +0100
     2.2 +++ b/src/share/vm/classfile/classFileParser.hpp	Fri Mar 23 11:16:05 2012 -0400
     2.3 @@ -1,5 +1,5 @@
     2.4  /*
     2.5 - * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
     2.6 + * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
     2.7   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     2.8   *
     2.9   * This code is free software; you can redistribute it and/or modify it
    2.10 @@ -68,9 +68,10 @@
    2.11    void set_stream(ClassFileStream* st)             { _stream = st; }
    2.12  
    2.13    // Constant pool parsing
    2.14 -  void parse_constant_pool_entries(constantPoolHandle cp, int length, TRAPS);
    2.15 +  void parse_constant_pool_entries(Handle class_loader,
    2.16 +                                   constantPoolHandle cp, int length, TRAPS);
    2.17  
    2.18 -  constantPoolHandle parse_constant_pool(TRAPS);
    2.19 +  constantPoolHandle parse_constant_pool(Handle class_loader, TRAPS);
    2.20  
    2.21    // Interface parsing
    2.22    objArrayHandle parse_interfaces(constantPoolHandle cp,
     3.1 --- a/src/share/vm/classfile/symbolTable.cpp	Thu Mar 15 13:37:13 2012 +0100
     3.2 +++ b/src/share/vm/classfile/symbolTable.cpp	Fri Mar 23 11:16:05 2012 -0400
     3.3 @@ -1,5 +1,5 @@
     3.4  /*
     3.5 - * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
     3.6 + * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
     3.7   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     3.8   *
     3.9   * This code is free software; you can redistribute it and/or modify it
    3.10 @@ -27,6 +27,7 @@
    3.11  #include "classfile/symbolTable.hpp"
    3.12  #include "classfile/systemDictionary.hpp"
    3.13  #include "gc_interface/collectedHeap.inline.hpp"
    3.14 +#include "memory/allocation.inline.hpp"
    3.15  #include "memory/filemap.hpp"
    3.16  #include "memory/gcLocker.inline.hpp"
    3.17  #include "oops/oop.inline.hpp"
    3.18 @@ -37,34 +38,35 @@
    3.19  // --------------------------------------------------------------------------
    3.20  
    3.21  SymbolTable* SymbolTable::_the_table = NULL;
    3.22 +// Static arena for symbols that are not deallocated
    3.23 +Arena* SymbolTable::_arena = NULL;
    3.24  
    3.25 -Symbol* SymbolTable::allocate_symbol(const u1* name, int len, TRAPS) {
    3.26 +Symbol* SymbolTable::allocate_symbol(const u1* name, int len, bool c_heap, TRAPS) {
    3.27    // Don't allow symbols to be created which cannot fit in a Symbol*.
    3.28    if (len > Symbol::max_length()) {
    3.29      THROW_MSG_0(vmSymbols::java_lang_InternalError(),
    3.30                  "name is too long to represent");
    3.31    }
    3.32 -  Symbol* sym = new (len) Symbol(name, len);
    3.33 +  Symbol* sym;
    3.34 +  // Allocate symbols in the C heap when dumping shared spaces in case there
    3.35 +  // are temporary symbols we can remove.
    3.36 +  if (c_heap || DumpSharedSpaces) {
    3.37 +    // refcount starts as 1
    3.38 +    sym = new (len, THREAD) Symbol(name, len, 1);
    3.39 +  } else {
    3.40 +    sym = new (len, arena(), THREAD) Symbol(name, len, -1);
    3.41 +  }
    3.42    assert(sym != NULL, "new should call vm_exit_out_of_memory if C_HEAP is exhausted");
    3.43    return sym;
    3.44  }
    3.45  
    3.46 -bool SymbolTable::allocate_symbols(int names_count, const u1** names,
    3.47 -                                   int* lengths, Symbol** syms, TRAPS) {
    3.48 -  for (int i = 0; i< names_count; i++) {
    3.49 -    if (lengths[i] > Symbol::max_length()) {
    3.50 -      THROW_MSG_0(vmSymbols::java_lang_InternalError(),
    3.51 -                  "name is too long to represent");
    3.52 -    }
    3.53 +void SymbolTable::initialize_symbols(int arena_alloc_size) {
    3.54 +  // Initialize the arena for global symbols, size passed in depends on CDS.
    3.55 +  if (arena_alloc_size == 0) {
    3.56 +    _arena = new Arena();
    3.57 +  } else {
    3.58 +    _arena = new Arena(arena_alloc_size);
    3.59    }
    3.60 -
    3.61 -  for (int i = 0; i< names_count; i++) {
    3.62 -    int len = lengths[i];
    3.63 -    syms[i] = new (len) Symbol(names[i], len);
    3.64 -    assert(syms[i] != NULL, "new should call vm_exit_out_of_memory if "
    3.65 -                            "C_HEAP is exhausted");
    3.66 -  }
    3.67 -  return true;
    3.68  }
    3.69  
    3.70  // Call function for all symbols in the symbol table.
    3.71 @@ -83,8 +85,7 @@
    3.72  int SymbolTable::symbols_counted = 0;
    3.73  
    3.74  // Remove unreferenced symbols from the symbol table
    3.75 -// This is done late during GC.  This doesn't use the hash table unlink because
    3.76 -// it assumes that the literals are oops.
    3.77 +// This is done late during GC.
    3.78  void SymbolTable::unlink() {
    3.79    int removed = 0;
    3.80    int total = 0;
    3.81 @@ -156,7 +157,7 @@
    3.82    if (s != NULL) return s;
    3.83  
    3.84    // Otherwise, add to symbol to table
    3.85 -  return the_table()->basic_add(index, (u1*)name, len, hashValue, CHECK_NULL);
    3.86 +  return the_table()->basic_add(index, (u1*)name, len, hashValue, true, CHECK_NULL);
    3.87  }
    3.88  
    3.89  Symbol* SymbolTable::lookup(const Symbol* sym, int begin, int end, TRAPS) {
    3.90 @@ -192,7 +193,7 @@
    3.91    // We can't include the code in No_Safepoint_Verifier because of the
    3.92    // ResourceMark.
    3.93  
    3.94 -  return the_table()->basic_add(index, (u1*)buffer, len, hashValue, CHECK_NULL);
    3.95 +  return the_table()->basic_add(index, (u1*)buffer, len, hashValue, true, CHECK_NULL);
    3.96  }
    3.97  
    3.98  Symbol* SymbolTable::lookup_only(const char* name, int len,
    3.99 @@ -256,71 +257,81 @@
   3.100    }
   3.101  }
   3.102  
   3.103 -void SymbolTable::add(constantPoolHandle cp, int names_count,
   3.104 +void SymbolTable::add(Handle class_loader, constantPoolHandle cp,
   3.105 +                      int names_count,
   3.106                        const char** names, int* lengths, int* cp_indices,
   3.107                        unsigned int* hashValues, TRAPS) {
   3.108    SymbolTable* table = the_table();
   3.109 -  bool added = table->basic_add(cp, names_count, names, lengths,
   3.110 +  bool added = table->basic_add(class_loader, cp, names_count, names, lengths,
   3.111                                  cp_indices, hashValues, CHECK);
   3.112    if (!added) {
   3.113      // do it the hard way
   3.114      for (int i=0; i<names_count; i++) {
   3.115        int index = table->hash_to_index(hashValues[i]);
   3.116 -      Symbol* sym = table->basic_add(index, (u1*)names[i], lengths[i],
   3.117 -                                       hashValues[i], CHECK);
   3.118 +      bool c_heap = class_loader() != NULL;
   3.119 +      Symbol* sym = table->basic_add(index, (u1*)names[i], lengths[i], hashValues[i], c_heap, CHECK);
   3.120        cp->symbol_at_put(cp_indices[i], sym);
   3.121      }
   3.122    }
   3.123  }
   3.124  
   3.125 +Symbol* SymbolTable::new_permanent_symbol(const char* name, TRAPS) {
   3.126 +  unsigned int hash;
   3.127 +  Symbol* result = SymbolTable::lookup_only((char*)name, (int)strlen(name), hash);
   3.128 +  if (result != NULL) {
   3.129 +    return result;
   3.130 +  }
   3.131 +  SymbolTable* table = the_table();
   3.132 +  int index = table->hash_to_index(hash);
   3.133 +  return table->basic_add(index, (u1*)name, (int)strlen(name), hash, false, THREAD);
   3.134 +}
   3.135 +
   3.136  Symbol* SymbolTable::basic_add(int index, u1 *name, int len,
   3.137 -                                 unsigned int hashValue, TRAPS) {
   3.138 +                               unsigned int hashValue, bool c_heap, TRAPS) {
   3.139    assert(!Universe::heap()->is_in_reserved(name) || GC_locker::is_active(),
   3.140           "proposed name of symbol must be stable");
   3.141  
   3.142 -  // We assume that lookup() has been called already, that it failed,
   3.143 -  // and symbol was not found.  We create the symbol here.
   3.144 -  Symbol* sym = allocate_symbol(name, len, CHECK_NULL);
   3.145 -
   3.146 -  // Allocation must be done before grabbing the SymbolTable_lock lock
   3.147 +  // Grab SymbolTable_lock first.
   3.148    MutexLocker ml(SymbolTable_lock, THREAD);
   3.149  
   3.150 -  assert(sym->equals((char*)name, len), "symbol must be properly initialized");
   3.151 -
   3.152    // Since look-up was done lock-free, we need to check if another
   3.153    // thread beat us in the race to insert the symbol.
   3.154 -
   3.155    Symbol* test = lookup(index, (char*)name, len, hashValue);
   3.156    if (test != NULL) {
   3.157 -    // A race occurred and another thread introduced the symbol, this one
   3.158 -    // will be dropped and collected.
   3.159 -    delete sym;
   3.160 +    // A race occurred and another thread introduced the symbol.
   3.161      assert(test->refcount() != 0, "lookup should have incremented the count");
   3.162      return test;
   3.163    }
   3.164  
   3.165 +  // Create a new symbol.
   3.166 +  Symbol* sym = allocate_symbol(name, len, c_heap, CHECK_NULL);
   3.167 +  assert(sym->equals((char*)name, len), "symbol must be properly initialized");
   3.168 +
   3.169    HashtableEntry<Symbol*>* entry = new_entry(hashValue, sym);
   3.170 -  sym->increment_refcount();
   3.171    add_entry(index, entry);
   3.172    return sym;
   3.173  }
   3.174  
   3.175 -bool SymbolTable::basic_add(constantPoolHandle cp, int names_count,
   3.176 +// This version of basic_add adds symbols in batch from the constant pool
   3.177 +// parsing.
   3.178 +bool SymbolTable::basic_add(Handle class_loader, constantPoolHandle cp,
   3.179 +                            int names_count,
   3.180                              const char** names, int* lengths,
   3.181                              int* cp_indices, unsigned int* hashValues,
   3.182                              TRAPS) {
   3.183 -  Symbol* syms[symbol_alloc_batch_size];
   3.184 -  bool allocated = allocate_symbols(names_count, (const u1**)names, lengths,
   3.185 -                                    syms, CHECK_false);
   3.186 -  if (!allocated) {
   3.187 -    return false;
   3.188 +
   3.189 +  // Check symbol names are not too long.  If any are too long, don't add any.
   3.190 +  for (int i = 0; i< names_count; i++) {
   3.191 +    if (lengths[i] > Symbol::max_length()) {
   3.192 +      THROW_MSG_0(vmSymbols::java_lang_InternalError(),
   3.193 +                  "name is too long to represent");
   3.194 +    }
   3.195    }
   3.196  
   3.197 -  // Allocation must be done before grabbing the SymbolTable_lock lock
   3.198 +  // Hold SymbolTable_lock through the symbol creation
   3.199    MutexLocker ml(SymbolTable_lock, THREAD);
   3.200  
   3.201    for (int i=0; i<names_count; i++) {
   3.202 -    assert(syms[i]->equals(names[i], lengths[i]), "symbol must be properly initialized");
   3.203      // Since look-up was done lock-free, we need to check if another
   3.204      // thread beat us in the race to insert the symbol.
   3.205      int index = hash_to_index(hashValues[i]);
   3.206 @@ -330,16 +341,17 @@
   3.207        // will be dropped and collected. Use test instead.
   3.208        cp->symbol_at_put(cp_indices[i], test);
   3.209        assert(test->refcount() != 0, "lookup should have incremented the count");
   3.210 -      delete syms[i];
   3.211      } else {
   3.212 -      Symbol* sym = syms[i];
   3.213 +      // Create a new symbol.  The null class loader is never unloaded so these
   3.214 +      // are allocated specially in a permanent arena.
   3.215 +      bool c_heap = class_loader() != NULL;
   3.216 +      Symbol* sym = allocate_symbol((const u1*)names[i], lengths[i], c_heap, CHECK_(false));
   3.217 +      assert(sym->equals(names[i], lengths[i]), "symbol must be properly initialized");  // why wouldn't it be???
   3.218        HashtableEntry<Symbol*>* entry = new_entry(hashValues[i], sym);
   3.219 -      sym->increment_refcount();  // increment refcount in external hashtable
   3.220        add_entry(index, entry);
   3.221        cp->symbol_at_put(cp_indices[i], sym);
   3.222      }
   3.223    }
   3.224 -
   3.225    return true;
   3.226  }
   3.227  
   3.228 @@ -406,6 +418,8 @@
   3.229            ((float)symbols_removed/(float)symbols_counted)* 100);
   3.230    }
   3.231    tty->print_cr("Reference counts         %5d", Symbol::_total_count);
   3.232 +  tty->print_cr("Symbol arena size        %5d used %5d",
   3.233 +                 arena()->size_in_bytes(), arena()->used());
   3.234    tty->print_cr("Histogram of symbol length:");
   3.235    tty->print_cr("%8s %5d", "Total  ", total);
   3.236    tty->print_cr("%8s %5d", "Maximum", max_symbols);
     4.1 --- a/src/share/vm/classfile/symbolTable.hpp	Thu Mar 15 13:37:13 2012 +0100
     4.2 +++ b/src/share/vm/classfile/symbolTable.hpp	Fri Mar 23 11:16:05 2012 -0400
     4.3 @@ -1,5 +1,5 @@
     4.4  /*
     4.5 - * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
     4.6 + * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
     4.7   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4.8   *
     4.9   * This code is free software; you can redistribute it and/or modify it
    4.10 @@ -82,24 +82,24 @@
    4.11    static int symbols_removed;
    4.12    static int symbols_counted;
    4.13  
    4.14 -  Symbol* allocate_symbol(const u1* name, int len, TRAPS);   // Assumes no characters larger than 0x7F
    4.15 -  bool allocate_symbols(int names_count, const u1** names, int* lengths, Symbol** syms, TRAPS);
    4.16 +  Symbol* allocate_symbol(const u1* name, int len, bool c_heap, TRAPS); // Assumes no characters larger than 0x7F
    4.17  
    4.18    // Adding elements
    4.19 -  Symbol* basic_add(int index, u1* name, int len,
    4.20 -                      unsigned int hashValue, TRAPS);
    4.21 -  bool basic_add(constantPoolHandle cp, int names_count,
    4.22 +  Symbol* basic_add(int index, u1* name, int len, unsigned int hashValue,
    4.23 +                    bool c_heap, TRAPS);
    4.24 +
    4.25 +  bool basic_add(Handle class_loader, constantPoolHandle cp, int names_count,
    4.26                   const char** names, int* lengths, int* cp_indices,
    4.27                   unsigned int* hashValues, TRAPS);
    4.28  
    4.29 -  static void new_symbols(constantPoolHandle cp, int names_count,
    4.30 +  static void new_symbols(Handle class_loader, constantPoolHandle cp,
    4.31 +                          int names_count,
    4.32                            const char** name, int* lengths,
    4.33                            int* cp_indices, unsigned int* hashValues,
    4.34                            TRAPS) {
    4.35 -    add(cp, names_count, name, lengths, cp_indices, hashValues, THREAD);
    4.36 +    add(class_loader, cp, names_count, name, lengths, cp_indices, hashValues, THREAD);
    4.37    }
    4.38  
    4.39 -
    4.40    // Table size
    4.41    enum {
    4.42      symbol_table_size = 20011
    4.43 @@ -114,10 +114,16 @@
    4.44      : Hashtable<Symbol*>(symbol_table_size, sizeof (HashtableEntry<Symbol*>), t,
    4.45                  number_of_entries) {}
    4.46  
    4.47 +  // Arena for permanent symbols (null class loader) that are never unloaded
    4.48 +  static Arena*  _arena;
    4.49 +  static Arena* arena() { return _arena; }  // called for statistics
    4.50  
    4.51 +  static void initialize_symbols(int arena_alloc_size = 0);
    4.52  public:
    4.53    enum {
    4.54 -    symbol_alloc_batch_size = 8
    4.55 +    symbol_alloc_batch_size = 8,
    4.56 +    // Pick initial size based on java -version size measurements
    4.57 +    symbol_alloc_arena_size = 360*K
    4.58    };
    4.59  
    4.60    // The symbol table
    4.61 @@ -126,6 +132,7 @@
    4.62    static void create_table() {
    4.63      assert(_the_table == NULL, "One symbol table allowed.");
    4.64      _the_table = new SymbolTable();
    4.65 +    initialize_symbols(symbol_alloc_arena_size);
    4.66    }
    4.67  
    4.68    static void create_table(HashtableBucket* t, int length,
    4.69 @@ -134,6 +141,9 @@
    4.70      assert(length == symbol_table_size * sizeof(HashtableBucket),
    4.71             "bad shared symbol size.");
    4.72      _the_table = new SymbolTable(t, number_of_entries);
    4.73 +    // if CDS give symbol table a default arena size since most symbols
    4.74 +    // are already allocated in the shared misc section.
    4.75 +    initialize_symbols();
    4.76    }
    4.77  
    4.78    static Symbol* lookup(const char* name, int len, TRAPS);
    4.79 @@ -151,7 +161,7 @@
    4.80    static Symbol* lookup_unicode(const jchar* name, int len, TRAPS);
    4.81    static Symbol* lookup_only_unicode(const jchar* name, int len, unsigned int& hash);
    4.82  
    4.83 -  static void add(constantPoolHandle cp, int names_count,
    4.84 +  static void add(Handle class_loader, constantPoolHandle cp, int names_count,
    4.85                    const char** names, int* lengths, int* cp_indices,
    4.86                    unsigned int* hashValues, TRAPS);
    4.87  
    4.88 @@ -174,6 +184,9 @@
    4.89      return lookup(sym, begin, end, THREAD);
    4.90    }
    4.91  
    4.92 +  // Create a symbol in the arena for symbols that are not deleted
    4.93 +  static Symbol* new_permanent_symbol(const char* name, TRAPS);
    4.94 +
    4.95    // Symbol lookup
    4.96    static Symbol* lookup(int index, const char* name, int len, TRAPS);
    4.97  
     5.1 --- a/src/share/vm/classfile/vmSymbols.cpp	Thu Mar 15 13:37:13 2012 +0100
     5.2 +++ b/src/share/vm/classfile/vmSymbols.cpp	Fri Mar 23 11:16:05 2012 -0400
     5.3 @@ -1,5 +1,5 @@
     5.4  /*
     5.5 - * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
     5.6 + * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
     5.7   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     5.8   *
     5.9   * This code is free software; you can redistribute it and/or modify it
    5.10 @@ -79,7 +79,7 @@
    5.11    if (!UseSharedSpaces) {
    5.12      const char* string = &vm_symbol_bodies[0];
    5.13      for (int index = (int)FIRST_SID; index < (int)SID_LIMIT; index++) {
    5.14 -      Symbol* sym = SymbolTable::new_symbol(string, CHECK);
    5.15 +      Symbol* sym = SymbolTable::new_permanent_symbol(string, CHECK);
    5.16        _symbols[index] = sym;
    5.17        string += strlen(string); // skip string body
    5.18        string += 1;              // skip trailing null
    5.19 @@ -128,7 +128,7 @@
    5.20      // Spot-check correspondence between strings, symbols, and enums:
    5.21      assert(_symbols[NO_SID] == NULL, "must be");
    5.22      const char* str = "java/lang/Object";
    5.23 -    TempNewSymbol jlo = SymbolTable::new_symbol(str, CHECK);
    5.24 +    TempNewSymbol jlo = SymbolTable::new_permanent_symbol(str, CHECK);
    5.25      assert(strncmp(str, (char*)jlo->base(), jlo->utf8_length()) == 0, "");
    5.26      assert(jlo == java_lang_Object(), "");
    5.27      SID sid = VM_SYMBOL_ENUM_NAME(java_lang_Object);
    5.28 @@ -147,7 +147,7 @@
    5.29      // The string "format" happens (at the moment) not to be a vmSymbol,
    5.30      // though it is a method name in java.lang.String.
    5.31      str = "format";
    5.32 -    TempNewSymbol fmt = SymbolTable::new_symbol(str, CHECK);
    5.33 +    TempNewSymbol fmt = SymbolTable::new_permanent_symbol(str, CHECK);
    5.34      sid = find_sid(fmt);
    5.35      assert(sid == NO_SID, "symbol index works (negative test)");
    5.36    }
     6.1 --- a/src/share/vm/memory/dump.cpp	Thu Mar 15 13:37:13 2012 +0100
     6.2 +++ b/src/share/vm/memory/dump.cpp	Fri Mar 23 11:16:05 2012 -0400
     6.3 @@ -1,5 +1,5 @@
     6.4  /*
     6.5 - * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
     6.6 + * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
     6.7   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     6.8   *
     6.9   * This code is free software; you can redistribute it and/or modify it
    6.10 @@ -1490,12 +1490,11 @@
    6.11  
    6.12      // sun.io.Converters
    6.13      static const char obj_array_sig[] = "[[Ljava/lang/Object;";
    6.14 -    SymbolTable::lookup(obj_array_sig, (int)strlen(obj_array_sig), THREAD);
    6.15 +    (void)SymbolTable::new_permanent_symbol(obj_array_sig, THREAD);
    6.16  
    6.17      // java.util.HashMap
    6.18      static const char map_entry_array_sig[] = "[Ljava/util/Map$Entry;";
    6.19 -    SymbolTable::lookup(map_entry_array_sig, (int)strlen(map_entry_array_sig),
    6.20 -                        THREAD);
    6.21 +    (void)SymbolTable::new_permanent_symbol(map_entry_array_sig, THREAD);
    6.22  
    6.23      tty->print("Loading classes to share ... ");
    6.24      while ((fgets(class_name, sizeof class_name, file)) != NULL) {
    6.25 @@ -1514,7 +1513,7 @@
    6.26        computed_jsum = jsum(computed_jsum, class_name, (const int)name_len - 1);
    6.27  
    6.28        // Got a class name - load it.
    6.29 -      TempNewSymbol class_name_symbol = SymbolTable::new_symbol(class_name, THREAD);
    6.30 +      Symbol* class_name_symbol = SymbolTable::new_permanent_symbol(class_name, THREAD);
    6.31        guarantee(!HAS_PENDING_EXCEPTION, "Exception creating a symbol.");
    6.32        klassOop klass = SystemDictionary::resolve_or_null(class_name_symbol,
    6.33                                                           THREAD);
     7.1 --- a/src/share/vm/oops/objArrayKlassKlass.cpp	Thu Mar 15 13:37:13 2012 +0100
     7.2 +++ b/src/share/vm/oops/objArrayKlassKlass.cpp	Fri Mar 23 11:16:05 2012 -0400
     7.3 @@ -1,5 +1,5 @@
     7.4  /*
     7.5 - * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
     7.6 + * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
     7.7   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     7.8   *
     7.9   * This code is free software; you can redistribute it and/or modify it
    7.10 @@ -137,7 +137,7 @@
    7.11        new_str[idx++] = ';';
    7.12      }
    7.13      new_str[idx++] = '\0';
    7.14 -    name = SymbolTable::new_symbol(new_str, CHECK_0);
    7.15 +    name = SymbolTable::new_permanent_symbol(new_str, CHECK_0);
    7.16      if (element_klass->oop_is_instance()) {
    7.17        instanceKlass* ik = instanceKlass::cast(element_klass());
    7.18        ik->set_array_name(name);
     8.1 --- a/src/share/vm/oops/symbol.cpp	Thu Mar 15 13:37:13 2012 +0100
     8.2 +++ b/src/share/vm/oops/symbol.cpp	Fri Mar 23 11:16:05 2012 -0400
     8.3 @@ -1,5 +1,5 @@
     8.4  /*
     8.5 - * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
     8.6 + * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
     8.7   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     8.8   *
     8.9   * This code is free software; you can redistribute it and/or modify it
    8.10 @@ -29,15 +29,25 @@
    8.11  #include "runtime/os.hpp"
    8.12  #include "memory/allocation.inline.hpp"
    8.13  
    8.14 -Symbol::Symbol(const u1* name, int length) : _refcount(0), _length(length) {
    8.15 +Symbol::Symbol(const u1* name, int length, int refcount) : _refcount(refcount), _length(length) {
    8.16    _identity_hash = os::random();
    8.17    for (int i = 0; i < _length; i++) {
    8.18      byte_at_put(i, name[i]);
    8.19    }
    8.20  }
    8.21  
    8.22 -void* Symbol::operator new(size_t size, int len) {
    8.23 -  return (void *) AllocateHeap(object_size(len) * HeapWordSize, "symbol");
    8.24 +void* Symbol::operator new(size_t sz, int len, TRAPS) {
    8.25 +  int alloc_size = object_size(len)*HeapWordSize;
    8.26 +  address res = (address) AllocateHeap(alloc_size, "symbol");
    8.27 +  DEBUG_ONLY(set_allocation_type(res, ResourceObj::C_HEAP);)
    8.28 +  return res;
    8.29 +}
    8.30 +
    8.31 +void* Symbol::operator new(size_t sz, int len, Arena* arena, TRAPS) {
    8.32 +  int alloc_size = object_size(len)*HeapWordSize;
    8.33 +  address res = (address)arena->Amalloc(alloc_size);
    8.34 +  DEBUG_ONLY(set_allocation_type(res, ResourceObj::ARENA);)
    8.35 +  return res;
    8.36  }
    8.37  
    8.38  // ------------------------------------------------------------------
    8.39 @@ -206,26 +216,5 @@
    8.40    }
    8.41  }
    8.42  
    8.43 -void Symbol::increment_refcount() {
    8.44 -  // Only increment the refcount if positive.  If negative either
    8.45 -  // overflow has occurred or it is a permanent symbol in a read only
    8.46 -  // shared archive.
    8.47 -  if (_refcount >= 0) {
    8.48 -    Atomic::inc(&_refcount);
    8.49 -    NOT_PRODUCT(Atomic::inc(&_total_count);)
    8.50 -  }
    8.51 -}
    8.52 -
    8.53 -void Symbol::decrement_refcount() {
    8.54 -  if (_refcount >= 0) {
    8.55 -    Atomic::dec(&_refcount);
    8.56 -#ifdef ASSERT
    8.57 -    if (_refcount < 0) {
    8.58 -      print();
    8.59 -      assert(false, "reference count underflow for symbol");
    8.60 -    }
    8.61 -#endif
    8.62 -  }
    8.63 -}
    8.64 -
    8.65 +// SymbolTable prints this in its statistics
    8.66  NOT_PRODUCT(int Symbol::_total_count = 0;)
     9.1 --- a/src/share/vm/oops/symbol.hpp	Thu Mar 15 13:37:13 2012 +0100
     9.2 +++ b/src/share/vm/oops/symbol.hpp	Fri Mar 23 11:16:05 2012 -0400
     9.3 @@ -1,5 +1,5 @@
     9.4  /*
     9.5 - * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
     9.6 + * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
     9.7   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     9.8   *
     9.9   * This code is free software; you can redistribute it and/or modify it
    9.10 @@ -27,6 +27,7 @@
    9.11  
    9.12  #include "utilities/utf8.hpp"
    9.13  #include "memory/allocation.hpp"
    9.14 +#include "runtime/atomic.hpp"
    9.15  
    9.16  // A Symbol is a canonicalized string.
    9.17  // All Symbols reside in global SymbolTable and are reference counted.
    9.18 @@ -95,7 +96,7 @@
    9.19  // TempNewSymbol (passed in as a parameter) so the reference count on its symbol
    9.20  // will be decremented when it goes out of scope.
    9.21  
    9.22 -class Symbol : public CHeapObj {
    9.23 +class Symbol : public ResourceObj {
    9.24    friend class VMStructs;
    9.25    friend class SymbolTable;
    9.26    friend class MoveSymbols;
    9.27 @@ -111,7 +112,7 @@
    9.28    };
    9.29  
    9.30    static int object_size(int length) {
    9.31 -    size_t size = heap_word_size(sizeof(Symbol) + length);
    9.32 +    size_t size = heap_word_size(sizeof(Symbol) + (length > 0 ? length - 1 : 0));
    9.33      return align_object_size(size);
    9.34    }
    9.35  
    9.36 @@ -120,28 +121,25 @@
    9.37      _body[index] = value;
    9.38    }
    9.39  
    9.40 -  Symbol(const u1* name, int length);
    9.41 -  void* operator new(size_t size, int len);
    9.42 +  Symbol(const u1* name, int length, int refcount);
    9.43 +  void* operator new(size_t size, int len, TRAPS);
    9.44 +  void* operator new(size_t size, int len, Arena* arena, TRAPS);
    9.45  
    9.46   public:
    9.47    // Low-level access (used with care, since not GC-safe)
    9.48    const jbyte* base() const { return &_body[0]; }
    9.49  
    9.50 -  int object_size() { return object_size(utf8_length()); }
    9.51 +  int object_size()         { return object_size(utf8_length()); }
    9.52  
    9.53    // Returns the largest size symbol we can safely hold.
    9.54 -  static int max_length() {
    9.55 -    return max_symbol_length;
    9.56 -  }
    9.57 +  static int max_length()   { return max_symbol_length; }
    9.58  
    9.59 -  int identity_hash() {
    9.60 -    return _identity_hash;
    9.61 -  }
    9.62 +  int identity_hash()       { return _identity_hash; }
    9.63  
    9.64    // Reference counting.  See comments above this class for when to use.
    9.65 -  int refcount() const { return _refcount; }
    9.66 -  void increment_refcount();
    9.67 -  void decrement_refcount();
    9.68 +  int refcount() const      { return _refcount; }
    9.69 +  inline void increment_refcount();
    9.70 +  inline void decrement_refcount();
    9.71  
    9.72    int byte_at(int index) const {
    9.73      assert(index >=0 && index < _length, "symbol index overflow");
    9.74 @@ -220,4 +218,26 @@
    9.75   return (((uintptr_t)this < (uintptr_t)other) ? -1
    9.76     : ((uintptr_t)this == (uintptr_t) other) ? 0 : 1);
    9.77  }
    9.78 +
    9.79 +inline void Symbol::increment_refcount() {
    9.80 +  // Only increment the refcount if positive.  If negative either
    9.81 +  // overflow has occurred or it is a permanent symbol in a read only
    9.82 +  // shared archive.
    9.83 +  if (_refcount >= 0) {
    9.84 +    Atomic::inc(&_refcount);
    9.85 +    NOT_PRODUCT(Atomic::inc(&_total_count);)
    9.86 +  }
    9.87 +}
    9.88 +
    9.89 +inline void Symbol::decrement_refcount() {
    9.90 +  if (_refcount >= 0) {
    9.91 +    Atomic::dec(&_refcount);
    9.92 +#ifdef ASSERT
    9.93 +    if (_refcount < 0) {
    9.94 +      print();
    9.95 +      assert(false, "reference count underflow for symbol");
    9.96 +    }
    9.97 +#endif
    9.98 +  }
    9.99 +}
   9.100  #endif // SHARE_VM_OOPS_SYMBOL_HPP
    10.1 --- a/src/share/vm/oops/typeArrayKlass.cpp	Thu Mar 15 13:37:13 2012 +0100
    10.2 +++ b/src/share/vm/oops/typeArrayKlass.cpp	Fri Mar 23 11:16:05 2012 -0400
    10.3 @@ -55,7 +55,7 @@
    10.4  
    10.5    Symbol* sym = NULL;
    10.6    if (name_str != NULL) {
    10.7 -    sym = SymbolTable::new_symbol(name_str, CHECK_NULL);
    10.8 +    sym = SymbolTable::new_permanent_symbol(name_str, CHECK_NULL);
    10.9    }
   10.10    KlassHandle klassklass (THREAD, Universe::typeArrayKlassKlassObj());
   10.11  
    11.1 --- a/src/share/vm/runtime/globals.hpp	Thu Mar 15 13:37:13 2012 +0100
    11.2 +++ b/src/share/vm/runtime/globals.hpp	Fri Mar 23 11:16:05 2012 -0400
    11.3 @@ -3807,7 +3807,7 @@
    11.4    product(uintx, SharedReadOnlySize,   10*M,                                \
    11.5            "Size of read-only space in permanent generation (in bytes)")     \
    11.6                                                                              \
    11.7 -  product(uintx, SharedMiscDataSize,    NOT_LP64(4*M) LP64_ONLY(5*M),       \
    11.8 +  product(uintx, SharedMiscDataSize, NOT_LP64(4*M) LP64_ONLY(5*M) NOT_PRODUCT(+1*M),       \
    11.9            "Size of the shared data area adjacent to the heap (in bytes)")   \
   11.10                                                                              \
   11.11    product(uintx, SharedMiscCodeSize,    4*M,                                \

mercurial