1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/share/vm/oops/symbolKlass.cpp Sat Dec 01 00:00:00 2007 +0000 1.3 @@ -0,0 +1,232 @@ 1.4 +/* 1.5 + * Copyright 1997-2006 Sun Microsystems, Inc. All Rights Reserved. 1.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 1.7 + * 1.8 + * This code is free software; you can redistribute it and/or modify it 1.9 + * under the terms of the GNU General Public License version 2 only, as 1.10 + * published by the Free Software Foundation. 1.11 + * 1.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 1.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 1.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 1.15 + * version 2 for more details (a copy is included in the LICENSE file that 1.16 + * accompanied this code). 1.17 + * 1.18 + * You should have received a copy of the GNU General Public License version 1.19 + * 2 along with this work; if not, write to the Free Software Foundation, 1.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 1.21 + * 1.22 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, 1.23 + * CA 95054 USA or visit www.sun.com if you need additional information or 1.24 + * have any questions. 1.25 + * 1.26 + */ 1.27 + 1.28 +# include "incls/_precompiled.incl" 1.29 +# include "incls/_symbolKlass.cpp.incl" 1.30 + 1.31 +symbolOop symbolKlass::allocate_symbol(u1* name, int len, TRAPS) { 1.32 + // Don't allow symbol oops to be created which cannot fit in a symbolOop. 1.33 + if (len > symbolOopDesc::max_length()) { 1.34 + THROW_MSG_0(vmSymbols::java_lang_InternalError(), 1.35 + "name is too long to represent"); 1.36 + } 1.37 + int size = symbolOopDesc::object_size(len); 1.38 + symbolKlassHandle h_k(THREAD, as_klassOop()); 1.39 + symbolOop sym = (symbolOop) 1.40 + CollectedHeap::permanent_obj_allocate(h_k, size, CHECK_NULL); 1.41 + assert(!sym->is_parsable(), "not expecting parsability yet."); 1.42 + No_Safepoint_Verifier no_safepoint; 1.43 + sym->set_utf8_length(len); 1.44 + for (int i = 0; i < len; i++) { 1.45 + sym->byte_at_put(i, name[i]); 1.46 + } 1.47 + // Let the first emptySymbol be created and 1.48 + // ensure only one is ever created. 1.49 + assert(sym->is_parsable() || Universe::emptySymbol() == NULL, 1.50 + "should be parsable here."); 1.51 + return sym; 1.52 +} 1.53 + 1.54 +bool symbolKlass::allocate_symbols(int names_count, const char** names, 1.55 + int* lengths, symbolOop* sym_oops, TRAPS) { 1.56 + if (UseConcMarkSweepGC || UseParallelGC) { 1.57 + // Concurrent GC needs to mark all the allocated symbol oops after 1.58 + // the remark phase which isn't done below (except the first symbol oop). 1.59 + // So return false which will let the symbols be allocated one by one. 1.60 + // The parallel collector uses an object start array to find the 1.61 + // start of objects on a dirty card. The object start array is not 1.62 + // updated for the start of each symbol so is not precise. During 1.63 + // object array verification this causes a verification failure. 1.64 + // In a product build this causes extra searching for the start of 1.65 + // a symbol. As with the concurrent collector a return of false will 1.66 + // cause each symbol to be allocated separately and in the case 1.67 + // of the parallel collector will cause the object 1.68 + // start array to be updated. 1.69 + return false; 1.70 + } 1.71 + 1.72 + assert(names_count > 0, "can't allocate 0 symbols"); 1.73 + 1.74 + int total_size = 0; 1.75 + int i, sizes[SymbolTable::symbol_alloc_batch_size]; 1.76 + for (i=0; i<names_count; i++) { 1.77 + int len = lengths[i]; 1.78 + if (len > symbolOopDesc::max_length()) { 1.79 + return false; 1.80 + } 1.81 + int sz = symbolOopDesc::object_size(len); 1.82 + sizes[i] = sz * HeapWordSize; 1.83 + total_size += sz; 1.84 + } 1.85 + symbolKlassHandle h_k(THREAD, as_klassOop()); 1.86 + HeapWord* base = Universe::heap()->permanent_mem_allocate(total_size); 1.87 + if (base == NULL) { 1.88 + return false; 1.89 + } 1.90 + 1.91 + // CAN'T take any safepoint during the initialization of the symbol oops ! 1.92 + No_Safepoint_Verifier nosafepoint; 1.93 + 1.94 + klassOop sk = h_k(); 1.95 + int pos = 0; 1.96 + for (i=0; i<names_count; i++) { 1.97 + symbolOop s = (symbolOop) (((char*)base) + pos); 1.98 + s->set_mark(markOopDesc::prototype()); 1.99 + s->set_klass(sk); 1.100 + s->set_utf8_length(lengths[i]); 1.101 + const char* name = names[i]; 1.102 + for (int j=0; j<lengths[i]; j++) { 1.103 + s->byte_at_put(j, name[j]); 1.104 + } 1.105 + 1.106 + assert(s->is_parsable(), "should be parsable here."); 1.107 + 1.108 + sym_oops[i] = s; 1.109 + pos += sizes[i]; 1.110 + } 1.111 + return true; 1.112 +} 1.113 + 1.114 +klassOop symbolKlass::create_klass(TRAPS) { 1.115 + symbolKlass o; 1.116 + KlassHandle h_this_klass(THREAD, Universe::klassKlassObj()); 1.117 + KlassHandle k = base_create_klass(h_this_klass, header_size(), o.vtbl_value(), CHECK_NULL); 1.118 + // Make sure size calculation is right 1.119 + assert(k()->size() == align_object_size(header_size()), "wrong size for object"); 1.120 +// java_lang_Class::create_mirror(k, CHECK_NULL); // Allocate mirror 1.121 + return k(); 1.122 +} 1.123 + 1.124 +int symbolKlass::oop_size(oop obj) const { 1.125 + assert(obj->is_symbol(),"must be a symbol"); 1.126 + symbolOop s = symbolOop(obj); 1.127 + int size = s->object_size(); 1.128 + return size; 1.129 +} 1.130 + 1.131 +bool symbolKlass::oop_is_parsable(oop obj) const { 1.132 + assert(obj->is_symbol(),"must be a symbol"); 1.133 + symbolOop s = symbolOop(obj); 1.134 + return s->object_is_parsable(); 1.135 +} 1.136 + 1.137 +void symbolKlass::oop_follow_contents(oop obj) { 1.138 + assert (obj->is_symbol(), "object must be symbol"); 1.139 + // Performance tweak: We skip iterating over the klass pointer since we 1.140 + // know that Universe::symbolKlassObj never moves. 1.141 + // Note: do not follow next link here (see SymbolTable::follow_contents) 1.142 +} 1.143 + 1.144 +#ifndef SERIALGC 1.145 +void symbolKlass::oop_follow_contents(ParCompactionManager* cm, oop obj) { 1.146 + assert (obj->is_symbol(), "object must be symbol"); 1.147 + // Performance tweak: We skip iterating over the klass pointer since we 1.148 + // know that Universe::symbolKlassObj never moves. 1.149 + // Note: do not follow next link here (see SymbolTable::follow_contents) 1.150 +} 1.151 +#endif // SERIALGC 1.152 + 1.153 +int symbolKlass::oop_oop_iterate(oop obj, OopClosure* blk) { 1.154 + assert(obj->is_symbol(), "object must be symbol"); 1.155 + symbolOop s = symbolOop(obj); 1.156 + // Get size before changing pointers. 1.157 + // Don't call size() or oop_size() since that is a virtual call. 1.158 + int size = s->object_size(); 1.159 + // Performance tweak: We skip iterating over the klass pointer since we 1.160 + // know that Universe::symbolKlassObj never moves. 1.161 + return size; 1.162 +} 1.163 + 1.164 + 1.165 +int symbolKlass::oop_oop_iterate_m(oop obj, OopClosure* blk, MemRegion mr) { 1.166 + assert(obj->is_symbol(), "object must be symbol"); 1.167 + symbolOop s = symbolOop(obj); 1.168 + // Get size before changing pointers. 1.169 + // Don't call size() or oop_size() since that is a virtual call. 1.170 + int size = s->object_size(); 1.171 + // Performance tweak: We skip iterating over the klass pointer since we 1.172 + // know that Universe::symbolKlassObj never moves. 1.173 + return size; 1.174 +} 1.175 + 1.176 + 1.177 +int symbolKlass::oop_adjust_pointers(oop obj) { 1.178 + assert(obj->is_symbol(), "should be symbol"); 1.179 + symbolOop s = symbolOop(obj); 1.180 + // Get size before changing pointers. 1.181 + // Don't call size() or oop_size() since that is a virtual call. 1.182 + int size = s->object_size(); 1.183 + // Performance tweak: We skip iterating over the klass pointer since we 1.184 + // know that Universe::symbolKlassObj never moves. 1.185 + return size; 1.186 +} 1.187 + 1.188 + 1.189 +#ifndef SERIALGC 1.190 +void symbolKlass::oop_copy_contents(PSPromotionManager* pm, oop obj) { 1.191 + assert(obj->is_symbol(), "should be symbol"); 1.192 +} 1.193 + 1.194 +void symbolKlass::oop_push_contents(PSPromotionManager* pm, oop obj) { 1.195 + assert(obj->is_symbol(), "should be symbol"); 1.196 +} 1.197 + 1.198 +int symbolKlass::oop_update_pointers(ParCompactionManager* cm, oop obj) { 1.199 + assert(obj->is_symbol(), "should be symbol"); 1.200 + return symbolOop(obj)->object_size(); 1.201 +} 1.202 + 1.203 +int symbolKlass::oop_update_pointers(ParCompactionManager* cm, oop obj, 1.204 + HeapWord* beg_addr, HeapWord* end_addr) { 1.205 + assert(obj->is_symbol(), "should be symbol"); 1.206 + return symbolOop(obj)->object_size(); 1.207 +} 1.208 +#endif // SERIALGC 1.209 + 1.210 +#ifndef PRODUCT 1.211 +// Printing 1.212 + 1.213 +void symbolKlass::oop_print_on(oop obj, outputStream* st) { 1.214 + st->print("Symbol: '"); 1.215 + symbolOop sym = symbolOop(obj); 1.216 + for (int i = 0; i < sym->utf8_length(); i++) { 1.217 + st->print("%c", sym->byte_at(i)); 1.218 + } 1.219 + st->print("'"); 1.220 +} 1.221 + 1.222 +void symbolKlass::oop_print_value_on(oop obj, outputStream* st) { 1.223 + symbolOop sym = symbolOop(obj); 1.224 + st->print("'"); 1.225 + for (int i = 0; i < sym->utf8_length(); i++) { 1.226 + st->print("%c", sym->byte_at(i)); 1.227 + } 1.228 + st->print("'"); 1.229 +} 1.230 + 1.231 +#endif //PRODUCT 1.232 + 1.233 +const char* symbolKlass::internal_name() const { 1.234 + return "{symbol}"; 1.235 +}