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);