Fri, 23 Mar 2012 11:16:05 -0400
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
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, \