1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/share/vm/oops/constantPoolOop.cpp Sat Dec 01 00:00:00 2007 +0000 1.3 @@ -0,0 +1,1269 @@ 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/_constantPoolOop.cpp.incl" 1.30 + 1.31 +klassOop constantPoolOopDesc::klass_at_impl(constantPoolHandle this_oop, int which, TRAPS) { 1.32 + // A resolved constantPool entry will contain a klassOop, otherwise a symbolOop. 1.33 + // It is not safe to rely on the tag bit's here, since we don't have a lock, and the entry and 1.34 + // tag is not updated atomicly. 1.35 + oop entry = *(this_oop->obj_at_addr(which)); 1.36 + if (entry->is_klass()) { 1.37 + // Already resolved - return entry. 1.38 + return (klassOop)entry; 1.39 + } 1.40 + 1.41 + // Acquire lock on constant oop while doing update. After we get the lock, we check if another object 1.42 + // already has updated the object 1.43 + assert(THREAD->is_Java_thread(), "must be a Java thread"); 1.44 + bool do_resolve = false; 1.45 + bool in_error = false; 1.46 + 1.47 + symbolHandle name; 1.48 + Handle loader; 1.49 + { ObjectLocker ol(this_oop, THREAD); 1.50 + 1.51 + if (this_oop->tag_at(which).is_unresolved_klass()) { 1.52 + if (this_oop->tag_at(which).is_unresolved_klass_in_error()) { 1.53 + in_error = true; 1.54 + } else { 1.55 + do_resolve = true; 1.56 + name = symbolHandle(THREAD, this_oop->unresolved_klass_at(which)); 1.57 + loader = Handle(THREAD, instanceKlass::cast(this_oop->pool_holder())->class_loader()); 1.58 + } 1.59 + } 1.60 + } // unlocking constantPool 1.61 + 1.62 + 1.63 + // The original attempt to resolve this constant pool entry failed so find the 1.64 + // original error and throw it again (JVMS 5.4.3). 1.65 + if (in_error) { 1.66 + symbolOop error = SystemDictionary::find_resolution_error(this_oop, which); 1.67 + guarantee(error != (symbolOop)NULL, "tag mismatch with resolution error table"); 1.68 + ResourceMark rm; 1.69 + // exception text will be the class name 1.70 + const char* className = this_oop->unresolved_klass_at(which)->as_C_string(); 1.71 + THROW_MSG_0(error, className); 1.72 + } 1.73 + 1.74 + if (do_resolve) { 1.75 + // this_oop must be unlocked during resolve_or_fail 1.76 + oop protection_domain = Klass::cast(this_oop->pool_holder())->protection_domain(); 1.77 + Handle h_prot (THREAD, protection_domain); 1.78 + klassOop k_oop = SystemDictionary::resolve_or_fail(name, loader, h_prot, true, THREAD); 1.79 + KlassHandle k; 1.80 + if (!HAS_PENDING_EXCEPTION) { 1.81 + k = KlassHandle(THREAD, k_oop); 1.82 + // Do access check for klasses 1.83 + verify_constant_pool_resolve(this_oop, k, THREAD); 1.84 + } 1.85 + 1.86 + // Failed to resolve class. We must record the errors so that subsequent attempts 1.87 + // to resolve this constant pool entry fail with the same error (JVMS 5.4.3). 1.88 + if (HAS_PENDING_EXCEPTION) { 1.89 + ResourceMark rm; 1.90 + symbolHandle error(PENDING_EXCEPTION->klass()->klass_part()->name()); 1.91 + 1.92 + bool throw_orig_error = false; 1.93 + { 1.94 + ObjectLocker ol (this_oop, THREAD); 1.95 + 1.96 + // some other thread has beaten us and has resolved the class. 1.97 + if (this_oop->tag_at(which).is_klass()) { 1.98 + CLEAR_PENDING_EXCEPTION; 1.99 + entry = this_oop->resolved_klass_at(which); 1.100 + return (klassOop)entry; 1.101 + } 1.102 + 1.103 + if (!PENDING_EXCEPTION-> 1.104 + is_a(SystemDictionary::linkageError_klass())) { 1.105 + // Just throw the exception and don't prevent these classes from 1.106 + // being loaded due to virtual machine errors like StackOverflow 1.107 + // and OutOfMemoryError, etc, or if the thread was hit by stop() 1.108 + // Needs clarification to section 5.4.3 of the VM spec (see 6308271) 1.109 + } 1.110 + else if (!this_oop->tag_at(which).is_unresolved_klass_in_error()) { 1.111 + SystemDictionary::add_resolution_error(this_oop, which, error); 1.112 + this_oop->tag_at_put(which, JVM_CONSTANT_UnresolvedClassInError); 1.113 + } else { 1.114 + // some other thread has put the class in error state. 1.115 + error = symbolHandle(SystemDictionary::find_resolution_error(this_oop, which)); 1.116 + assert(!error.is_null(), "checking"); 1.117 + throw_orig_error = true; 1.118 + } 1.119 + } // unlocked 1.120 + 1.121 + if (throw_orig_error) { 1.122 + CLEAR_PENDING_EXCEPTION; 1.123 + ResourceMark rm; 1.124 + const char* className = this_oop->unresolved_klass_at(which)->as_C_string(); 1.125 + THROW_MSG_0(error, className); 1.126 + } 1.127 + 1.128 + return 0; 1.129 + } 1.130 + 1.131 + if (TraceClassResolution && !k()->klass_part()->oop_is_array()) { 1.132 + // skip resolving the constant pool so that this code get's 1.133 + // called the next time some bytecodes refer to this class. 1.134 + ResourceMark rm; 1.135 + int line_number = -1; 1.136 + const char * source_file = NULL; 1.137 + if (JavaThread::current()->has_last_Java_frame()) { 1.138 + // try to identify the method which called this function. 1.139 + vframeStream vfst(JavaThread::current()); 1.140 + if (!vfst.at_end()) { 1.141 + line_number = vfst.method()->line_number_from_bci(vfst.bci()); 1.142 + symbolOop s = instanceKlass::cast(vfst.method()->method_holder())->source_file_name(); 1.143 + if (s != NULL) { 1.144 + source_file = s->as_C_string(); 1.145 + } 1.146 + } 1.147 + } 1.148 + if (k() != this_oop->pool_holder()) { 1.149 + // only print something if the classes are different 1.150 + if (source_file != NULL) { 1.151 + tty->print("RESOLVE %s %s %s:%d\n", 1.152 + instanceKlass::cast(this_oop->pool_holder())->external_name(), 1.153 + instanceKlass::cast(k())->external_name(), source_file, line_number); 1.154 + } else { 1.155 + tty->print("RESOLVE %s %s\n", 1.156 + instanceKlass::cast(this_oop->pool_holder())->external_name(), 1.157 + instanceKlass::cast(k())->external_name()); 1.158 + } 1.159 + } 1.160 + return k(); 1.161 + } else { 1.162 + ObjectLocker ol (this_oop, THREAD); 1.163 + // Only updated constant pool - if it is resolved. 1.164 + do_resolve = this_oop->tag_at(which).is_unresolved_klass(); 1.165 + if (do_resolve) { 1.166 + this_oop->klass_at_put(which, k()); 1.167 + } 1.168 + } 1.169 + } 1.170 + 1.171 + entry = this_oop->resolved_klass_at(which); 1.172 + assert(entry->is_klass(), "must be resolved at this point"); 1.173 + return (klassOop)entry; 1.174 +} 1.175 + 1.176 + 1.177 +// Does not update constantPoolOop - to avoid any exception throwing. Used 1.178 +// by compiler and exception handling. Also used to avoid classloads for 1.179 +// instanceof operations. Returns NULL if the class has not been loaded or 1.180 +// if the verification of constant pool failed 1.181 +klassOop constantPoolOopDesc::klass_at_if_loaded(constantPoolHandle this_oop, int which) { 1.182 + oop entry = *this_oop->obj_at_addr(which); 1.183 + if (entry->is_klass()) { 1.184 + return (klassOop)entry; 1.185 + } else { 1.186 + assert(entry->is_symbol(), "must be either symbol or klass"); 1.187 + Thread *thread = Thread::current(); 1.188 + symbolHandle name (thread, (symbolOop)entry); 1.189 + oop loader = instanceKlass::cast(this_oop->pool_holder())->class_loader(); 1.190 + oop protection_domain = Klass::cast(this_oop->pool_holder())->protection_domain(); 1.191 + Handle h_prot (thread, protection_domain); 1.192 + Handle h_loader (thread, loader); 1.193 + klassOop k = SystemDictionary::find(name, h_loader, h_prot, thread); 1.194 + 1.195 + if (k != NULL) { 1.196 + // Make sure that resolving is legal 1.197 + EXCEPTION_MARK; 1.198 + KlassHandle klass(THREAD, k); 1.199 + // return NULL if verification fails 1.200 + verify_constant_pool_resolve(this_oop, klass, THREAD); 1.201 + if (HAS_PENDING_EXCEPTION) { 1.202 + CLEAR_PENDING_EXCEPTION; 1.203 + return NULL; 1.204 + } 1.205 + return klass(); 1.206 + } else { 1.207 + return k; 1.208 + } 1.209 + } 1.210 +} 1.211 + 1.212 + 1.213 +klassOop constantPoolOopDesc::klass_ref_at_if_loaded(constantPoolHandle this_oop, int which) { 1.214 + return klass_at_if_loaded(this_oop, this_oop->klass_ref_index_at(which)); 1.215 +} 1.216 + 1.217 + 1.218 +// This is an interface for the compiler that allows accessing non-resolved entries 1.219 +// in the constant pool - but still performs the validations tests. Must be used 1.220 +// in a pre-parse of the compiler - to determine what it can do and not do. 1.221 +// Note: We cannot update the ConstantPool from the vm_thread. 1.222 +klassOop constantPoolOopDesc::klass_ref_at_if_loaded_check(constantPoolHandle this_oop, int index, TRAPS) { 1.223 + int which = this_oop->klass_ref_index_at(index); 1.224 + oop entry = *this_oop->obj_at_addr(which); 1.225 + if (entry->is_klass()) { 1.226 + return (klassOop)entry; 1.227 + } else { 1.228 + assert(entry->is_symbol(), "must be either symbol or klass"); 1.229 + symbolHandle name (THREAD, (symbolOop)entry); 1.230 + oop loader = instanceKlass::cast(this_oop->pool_holder())->class_loader(); 1.231 + oop protection_domain = Klass::cast(this_oop->pool_holder())->protection_domain(); 1.232 + Handle h_loader(THREAD, loader); 1.233 + Handle h_prot (THREAD, protection_domain); 1.234 + KlassHandle k(THREAD, SystemDictionary::find(name, h_loader, h_prot, THREAD)); 1.235 + 1.236 + // Do access check for klasses 1.237 + if( k.not_null() ) verify_constant_pool_resolve(this_oop, k, CHECK_NULL); 1.238 + return k(); 1.239 + } 1.240 +} 1.241 + 1.242 + 1.243 +symbolOop constantPoolOopDesc::uncached_name_ref_at(int which) { 1.244 + jint ref_index = name_and_type_at(uncached_name_and_type_ref_index_at(which)); 1.245 + int name_index = extract_low_short_from_int(ref_index); 1.246 + return symbol_at(name_index); 1.247 +} 1.248 + 1.249 + 1.250 +symbolOop constantPoolOopDesc::uncached_signature_ref_at(int which) { 1.251 + jint ref_index = name_and_type_at(uncached_name_and_type_ref_index_at(which)); 1.252 + int signature_index = extract_high_short_from_int(ref_index); 1.253 + return symbol_at(signature_index); 1.254 +} 1.255 + 1.256 + 1.257 +int constantPoolOopDesc::uncached_name_and_type_ref_index_at(int which) { 1.258 + jint ref_index = field_or_method_at(which, true); 1.259 + return extract_high_short_from_int(ref_index); 1.260 +} 1.261 + 1.262 + 1.263 +int constantPoolOopDesc::uncached_klass_ref_index_at(int which) { 1.264 + jint ref_index = field_or_method_at(which, true); 1.265 + return extract_low_short_from_int(ref_index); 1.266 +} 1.267 + 1.268 + 1.269 +void constantPoolOopDesc::verify_constant_pool_resolve(constantPoolHandle this_oop, KlassHandle k, TRAPS) { 1.270 + if (k->oop_is_instance() || k->oop_is_objArray()) { 1.271 + instanceKlassHandle holder (THREAD, this_oop->pool_holder()); 1.272 + klassOop elem_oop = k->oop_is_instance() ? k() : objArrayKlass::cast(k())->bottom_klass(); 1.273 + KlassHandle element (THREAD, elem_oop); 1.274 + 1.275 + // The element type could be a typeArray - we only need the access check if it is 1.276 + // an reference to another class 1.277 + if (element->oop_is_instance()) { 1.278 + LinkResolver::check_klass_accessability(holder, element, CHECK); 1.279 + } 1.280 + } 1.281 +} 1.282 + 1.283 + 1.284 +int constantPoolOopDesc::klass_ref_index_at(int which) { 1.285 + jint ref_index = field_or_method_at(which, false); 1.286 + return extract_low_short_from_int(ref_index); 1.287 +} 1.288 + 1.289 + 1.290 +int constantPoolOopDesc::name_and_type_ref_index_at(int which) { 1.291 + jint ref_index = field_or_method_at(which, false); 1.292 + return extract_high_short_from_int(ref_index); 1.293 +} 1.294 + 1.295 + 1.296 +int constantPoolOopDesc::name_ref_index_at(int which) { 1.297 + jint ref_index = name_and_type_at(which); 1.298 + return extract_low_short_from_int(ref_index); 1.299 +} 1.300 + 1.301 + 1.302 +int constantPoolOopDesc::signature_ref_index_at(int which) { 1.303 + jint ref_index = name_and_type_at(which); 1.304 + return extract_high_short_from_int(ref_index); 1.305 +} 1.306 + 1.307 + 1.308 +klassOop constantPoolOopDesc::klass_ref_at(int which, TRAPS) { 1.309 + return klass_at(klass_ref_index_at(which), CHECK_NULL); 1.310 +} 1.311 + 1.312 + 1.313 +symbolOop constantPoolOopDesc::klass_name_at(int which) { 1.314 + assert(tag_at(which).is_unresolved_klass() || tag_at(which).is_klass(), 1.315 + "Corrupted constant pool"); 1.316 + // A resolved constantPool entry will contain a klassOop, otherwise a symbolOop. 1.317 + // It is not safe to rely on the tag bit's here, since we don't have a lock, and the entry and 1.318 + // tag is not updated atomicly. 1.319 + oop entry = *(obj_at_addr(which)); 1.320 + if (entry->is_klass()) { 1.321 + // Already resolved - return entry's name. 1.322 + return klassOop(entry)->klass_part()->name(); 1.323 + } else { 1.324 + assert(entry->is_symbol(), "must be either symbol or klass"); 1.325 + return (symbolOop)entry; 1.326 + } 1.327 +} 1.328 + 1.329 +symbolOop constantPoolOopDesc::klass_ref_at_noresolve(int which) { 1.330 + jint ref_index = klass_ref_index_at(which); 1.331 + return klass_at_noresolve(ref_index); 1.332 +} 1.333 + 1.334 +char* constantPoolOopDesc::string_at_noresolve(int which) { 1.335 + // Test entry type in case string is resolved while in here. 1.336 + oop entry = *(obj_at_addr(which)); 1.337 + if (entry->is_symbol()) { 1.338 + return ((symbolOop)entry)->as_C_string(); 1.339 + } else { 1.340 + return java_lang_String::as_utf8_string(entry); 1.341 + } 1.342 +} 1.343 + 1.344 + 1.345 +symbolOop constantPoolOopDesc::name_ref_at(int which) { 1.346 + jint ref_index = name_and_type_at(name_and_type_ref_index_at(which)); 1.347 + int name_index = extract_low_short_from_int(ref_index); 1.348 + return symbol_at(name_index); 1.349 +} 1.350 + 1.351 + 1.352 +symbolOop constantPoolOopDesc::signature_ref_at(int which) { 1.353 + jint ref_index = name_and_type_at(name_and_type_ref_index_at(which)); 1.354 + int signature_index = extract_high_short_from_int(ref_index); 1.355 + return symbol_at(signature_index); 1.356 +} 1.357 + 1.358 + 1.359 +BasicType constantPoolOopDesc::basic_type_for_signature_at(int which) { 1.360 + return FieldType::basic_type(symbol_at(which)); 1.361 +} 1.362 + 1.363 + 1.364 +void constantPoolOopDesc::resolve_string_constants_impl(constantPoolHandle this_oop, TRAPS) { 1.365 + for (int index = 1; index < this_oop->length(); index++) { // Index 0 is unused 1.366 + if (this_oop->tag_at(index).is_unresolved_string()) { 1.367 + this_oop->string_at(index, CHECK); 1.368 + } 1.369 + } 1.370 +} 1.371 + 1.372 +oop constantPoolOopDesc::string_at_impl(constantPoolHandle this_oop, int which, TRAPS) { 1.373 + oop entry = *(this_oop->obj_at_addr(which)); 1.374 + if (entry->is_symbol()) { 1.375 + ObjectLocker ol(this_oop, THREAD); 1.376 + if (this_oop->tag_at(which).is_unresolved_string()) { 1.377 + // Intern string 1.378 + symbolOop sym = this_oop->unresolved_string_at(which); 1.379 + entry = StringTable::intern(sym, CHECK_(constantPoolOop(NULL))); 1.380 + this_oop->string_at_put(which, entry); 1.381 + } else { 1.382 + // Another thread beat us and interned string, read string from constant pool 1.383 + entry = this_oop->resolved_string_at(which); 1.384 + } 1.385 + } 1.386 + assert(java_lang_String::is_instance(entry), "must be string"); 1.387 + return entry; 1.388 +} 1.389 + 1.390 + 1.391 +bool constantPoolOopDesc::klass_name_at_matches(instanceKlassHandle k, 1.392 + int which) { 1.393 + // Names are interned, so we can compare symbolOops directly 1.394 + symbolOop cp_name = klass_name_at(which); 1.395 + return (cp_name == k->name()); 1.396 +} 1.397 + 1.398 + 1.399 +int constantPoolOopDesc::pre_resolve_shared_klasses(TRAPS) { 1.400 + ResourceMark rm; 1.401 + int count = 0; 1.402 + for (int index = 1; index < tags()->length(); index++) { // Index 0 is unused 1.403 + if (tag_at(index).is_unresolved_string()) { 1.404 + // Intern string 1.405 + symbolOop sym = unresolved_string_at(index); 1.406 + oop entry = StringTable::intern(sym, CHECK_(-1)); 1.407 + string_at_put(index, entry); 1.408 + } 1.409 + } 1.410 + return count; 1.411 +} 1.412 + 1.413 + 1.414 +// Iterate over symbols which are used as class, field, method names and 1.415 +// signatures (in preparation for writing to the shared archive). 1.416 + 1.417 +void constantPoolOopDesc::shared_symbols_iterate(OopClosure* closure) { 1.418 + for (int index = 1; index < length(); index++) { // Index 0 is unused 1.419 + switch (tag_at(index).value()) { 1.420 + 1.421 + case JVM_CONSTANT_UnresolvedClass: 1.422 + closure->do_oop(obj_at_addr(index)); 1.423 + break; 1.424 + 1.425 + case JVM_CONSTANT_NameAndType: 1.426 + { 1.427 + int i = *int_at_addr(index); 1.428 + closure->do_oop(obj_at_addr((unsigned)i >> 16)); 1.429 + closure->do_oop(obj_at_addr((unsigned)i & 0xffff)); 1.430 + } 1.431 + break; 1.432 + 1.433 + case JVM_CONSTANT_Class: 1.434 + case JVM_CONSTANT_InterfaceMethodref: 1.435 + case JVM_CONSTANT_Fieldref: 1.436 + case JVM_CONSTANT_Methodref: 1.437 + case JVM_CONSTANT_Integer: 1.438 + case JVM_CONSTANT_Float: 1.439 + // Do nothing! Not an oop. 1.440 + // These constant types do not reference symbols at this point. 1.441 + break; 1.442 + 1.443 + case JVM_CONSTANT_String: 1.444 + // Do nothing! Not a symbol. 1.445 + break; 1.446 + 1.447 + case JVM_CONSTANT_UnresolvedString: 1.448 + case JVM_CONSTANT_Utf8: 1.449 + // These constants are symbols, but unless these symbols are 1.450 + // actually to be used for something, we don't want to mark them. 1.451 + break; 1.452 + 1.453 + case JVM_CONSTANT_Long: 1.454 + case JVM_CONSTANT_Double: 1.455 + // Do nothing! Not an oop. (But takes two pool entries.) 1.456 + ++index; 1.457 + break; 1.458 + 1.459 + default: 1.460 + ShouldNotReachHere(); 1.461 + break; 1.462 + } 1.463 + } 1.464 +} 1.465 + 1.466 + 1.467 +// Iterate over the [one] tags array (in preparation for writing to the 1.468 +// shared archive). 1.469 + 1.470 +void constantPoolOopDesc::shared_tags_iterate(OopClosure* closure) { 1.471 + closure->do_oop(tags_addr()); 1.472 +} 1.473 + 1.474 + 1.475 +// Iterate over String objects (in preparation for writing to the shared 1.476 +// archive). 1.477 + 1.478 +void constantPoolOopDesc::shared_strings_iterate(OopClosure* closure) { 1.479 + for (int index = 1; index < length(); index++) { // Index 0 is unused 1.480 + switch (tag_at(index).value()) { 1.481 + 1.482 + case JVM_CONSTANT_UnresolvedClass: 1.483 + case JVM_CONSTANT_NameAndType: 1.484 + // Do nothing! Not a String. 1.485 + break; 1.486 + 1.487 + case JVM_CONSTANT_Class: 1.488 + case JVM_CONSTANT_InterfaceMethodref: 1.489 + case JVM_CONSTANT_Fieldref: 1.490 + case JVM_CONSTANT_Methodref: 1.491 + case JVM_CONSTANT_Integer: 1.492 + case JVM_CONSTANT_Float: 1.493 + // Do nothing! Not an oop. 1.494 + // These constant types do not reference symbols at this point. 1.495 + break; 1.496 + 1.497 + case JVM_CONSTANT_String: 1.498 + closure->do_oop(obj_at_addr(index)); 1.499 + break; 1.500 + 1.501 + case JVM_CONSTANT_UnresolvedString: 1.502 + case JVM_CONSTANT_Utf8: 1.503 + // These constants are symbols, but unless these symbols are 1.504 + // actually to be used for something, we don't want to mark them. 1.505 + break; 1.506 + 1.507 + case JVM_CONSTANT_Long: 1.508 + case JVM_CONSTANT_Double: 1.509 + // Do nothing! Not an oop. (But takes two pool entries.) 1.510 + ++index; 1.511 + break; 1.512 + 1.513 + default: 1.514 + ShouldNotReachHere(); 1.515 + break; 1.516 + } 1.517 + } 1.518 +} 1.519 + 1.520 + 1.521 +// Compare this constant pool's entry at index1 to the constant pool 1.522 +// cp2's entry at index2. 1.523 +bool constantPoolOopDesc::compare_entry_to(int index1, constantPoolHandle cp2, 1.524 + int index2, TRAPS) { 1.525 + 1.526 + jbyte t1 = tag_at(index1).value(); 1.527 + jbyte t2 = cp2->tag_at(index2).value(); 1.528 + 1.529 + 1.530 + // JVM_CONSTANT_UnresolvedClassInError is equal to JVM_CONSTANT_UnresolvedClass 1.531 + // when comparing 1.532 + if (t1 == JVM_CONSTANT_UnresolvedClassInError) { 1.533 + t1 = JVM_CONSTANT_UnresolvedClass; 1.534 + } 1.535 + if (t2 == JVM_CONSTANT_UnresolvedClassInError) { 1.536 + t2 = JVM_CONSTANT_UnresolvedClass; 1.537 + } 1.538 + 1.539 + if (t1 != t2) { 1.540 + // Not the same entry type so there is nothing else to check. Note 1.541 + // that this style of checking will consider resolved/unresolved 1.542 + // class pairs and resolved/unresolved string pairs as different. 1.543 + // From the constantPoolOop API point of view, this is correct 1.544 + // behavior. See constantPoolKlass::merge() to see how this plays 1.545 + // out in the context of constantPoolOop merging. 1.546 + return false; 1.547 + } 1.548 + 1.549 + switch (t1) { 1.550 + case JVM_CONSTANT_Class: 1.551 + { 1.552 + klassOop k1 = klass_at(index1, CHECK_false); 1.553 + klassOop k2 = cp2->klass_at(index2, CHECK_false); 1.554 + if (k1 == k2) { 1.555 + return true; 1.556 + } 1.557 + } break; 1.558 + 1.559 + case JVM_CONSTANT_ClassIndex: 1.560 + { 1.561 + int recur1 = klass_index_at(index1); 1.562 + int recur2 = cp2->klass_index_at(index2); 1.563 + bool match = compare_entry_to(recur1, cp2, recur2, CHECK_false); 1.564 + if (match) { 1.565 + return true; 1.566 + } 1.567 + } break; 1.568 + 1.569 + case JVM_CONSTANT_Double: 1.570 + { 1.571 + jdouble d1 = double_at(index1); 1.572 + jdouble d2 = cp2->double_at(index2); 1.573 + if (d1 == d2) { 1.574 + return true; 1.575 + } 1.576 + } break; 1.577 + 1.578 + case JVM_CONSTANT_Fieldref: 1.579 + case JVM_CONSTANT_InterfaceMethodref: 1.580 + case JVM_CONSTANT_Methodref: 1.581 + { 1.582 + int recur1 = uncached_klass_ref_index_at(index1); 1.583 + int recur2 = cp2->uncached_klass_ref_index_at(index2); 1.584 + bool match = compare_entry_to(recur1, cp2, recur2, CHECK_false); 1.585 + if (match) { 1.586 + recur1 = uncached_name_and_type_ref_index_at(index1); 1.587 + recur2 = cp2->uncached_name_and_type_ref_index_at(index2); 1.588 + match = compare_entry_to(recur1, cp2, recur2, CHECK_false); 1.589 + if (match) { 1.590 + return true; 1.591 + } 1.592 + } 1.593 + } break; 1.594 + 1.595 + case JVM_CONSTANT_Float: 1.596 + { 1.597 + jfloat f1 = float_at(index1); 1.598 + jfloat f2 = cp2->float_at(index2); 1.599 + if (f1 == f2) { 1.600 + return true; 1.601 + } 1.602 + } break; 1.603 + 1.604 + case JVM_CONSTANT_Integer: 1.605 + { 1.606 + jint i1 = int_at(index1); 1.607 + jint i2 = cp2->int_at(index2); 1.608 + if (i1 == i2) { 1.609 + return true; 1.610 + } 1.611 + } break; 1.612 + 1.613 + case JVM_CONSTANT_Long: 1.614 + { 1.615 + jlong l1 = long_at(index1); 1.616 + jlong l2 = cp2->long_at(index2); 1.617 + if (l1 == l2) { 1.618 + return true; 1.619 + } 1.620 + } break; 1.621 + 1.622 + case JVM_CONSTANT_NameAndType: 1.623 + { 1.624 + int recur1 = name_ref_index_at(index1); 1.625 + int recur2 = cp2->name_ref_index_at(index2); 1.626 + bool match = compare_entry_to(recur1, cp2, recur2, CHECK_false); 1.627 + if (match) { 1.628 + recur1 = signature_ref_index_at(index1); 1.629 + recur2 = cp2->signature_ref_index_at(index2); 1.630 + match = compare_entry_to(recur1, cp2, recur2, CHECK_false); 1.631 + if (match) { 1.632 + return true; 1.633 + } 1.634 + } 1.635 + } break; 1.636 + 1.637 + case JVM_CONSTANT_String: 1.638 + { 1.639 + oop s1 = string_at(index1, CHECK_false); 1.640 + oop s2 = cp2->string_at(index2, CHECK_false); 1.641 + if (s1 == s2) { 1.642 + return true; 1.643 + } 1.644 + } break; 1.645 + 1.646 + case JVM_CONSTANT_StringIndex: 1.647 + { 1.648 + int recur1 = string_index_at(index1); 1.649 + int recur2 = cp2->string_index_at(index2); 1.650 + bool match = compare_entry_to(recur1, cp2, recur2, CHECK_false); 1.651 + if (match) { 1.652 + return true; 1.653 + } 1.654 + } break; 1.655 + 1.656 + case JVM_CONSTANT_UnresolvedClass: 1.657 + { 1.658 + symbolOop k1 = unresolved_klass_at(index1); 1.659 + symbolOop k2 = cp2->unresolved_klass_at(index2); 1.660 + if (k1 == k2) { 1.661 + return true; 1.662 + } 1.663 + } break; 1.664 + 1.665 + case JVM_CONSTANT_UnresolvedString: 1.666 + { 1.667 + symbolOop s1 = unresolved_string_at(index1); 1.668 + symbolOop s2 = cp2->unresolved_string_at(index2); 1.669 + if (s1 == s2) { 1.670 + return true; 1.671 + } 1.672 + } break; 1.673 + 1.674 + case JVM_CONSTANT_Utf8: 1.675 + { 1.676 + symbolOop s1 = symbol_at(index1); 1.677 + symbolOop s2 = cp2->symbol_at(index2); 1.678 + if (s1 == s2) { 1.679 + return true; 1.680 + } 1.681 + } break; 1.682 + 1.683 + // Invalid is used as the tag for the second constant pool entry 1.684 + // occupied by JVM_CONSTANT_Double or JVM_CONSTANT_Long. It should 1.685 + // not be seen by itself. 1.686 + case JVM_CONSTANT_Invalid: // fall through 1.687 + 1.688 + default: 1.689 + ShouldNotReachHere(); 1.690 + break; 1.691 + } 1.692 + 1.693 + return false; 1.694 +} // end compare_entry_to() 1.695 + 1.696 + 1.697 +// Copy this constant pool's entries at start_i to end_i (inclusive) 1.698 +// to the constant pool to_cp's entries starting at to_i. A total of 1.699 +// (end_i - start_i) + 1 entries are copied. 1.700 +void constantPoolOopDesc::copy_cp_to(int start_i, int end_i, 1.701 + constantPoolHandle to_cp, int to_i, TRAPS) { 1.702 + 1.703 + int dest_i = to_i; // leave original alone for debug purposes 1.704 + 1.705 + for (int src_i = start_i; src_i <= end_i; /* see loop bottom */ ) { 1.706 + copy_entry_to(src_i, to_cp, dest_i, CHECK); 1.707 + 1.708 + switch (tag_at(src_i).value()) { 1.709 + case JVM_CONSTANT_Double: 1.710 + case JVM_CONSTANT_Long: 1.711 + // double and long take two constant pool entries 1.712 + src_i += 2; 1.713 + dest_i += 2; 1.714 + break; 1.715 + 1.716 + default: 1.717 + // all others take one constant pool entry 1.718 + src_i++; 1.719 + dest_i++; 1.720 + break; 1.721 + } 1.722 + } 1.723 +} // end copy_cp_to() 1.724 + 1.725 + 1.726 +// Copy this constant pool's entry at from_i to the constant pool 1.727 +// to_cp's entry at to_i. 1.728 +void constantPoolOopDesc::copy_entry_to(int from_i, constantPoolHandle to_cp, 1.729 + int to_i, TRAPS) { 1.730 + 1.731 + switch (tag_at(from_i).value()) { 1.732 + case JVM_CONSTANT_Class: 1.733 + { 1.734 + klassOop k = klass_at(from_i, CHECK); 1.735 + to_cp->klass_at_put(to_i, k); 1.736 + } break; 1.737 + 1.738 + case JVM_CONSTANT_ClassIndex: 1.739 + { 1.740 + jint ki = klass_index_at(from_i); 1.741 + to_cp->klass_index_at_put(to_i, ki); 1.742 + } break; 1.743 + 1.744 + case JVM_CONSTANT_Double: 1.745 + { 1.746 + jdouble d = double_at(from_i); 1.747 + to_cp->double_at_put(to_i, d); 1.748 + // double takes two constant pool entries so init second entry's tag 1.749 + to_cp->tag_at_put(to_i + 1, JVM_CONSTANT_Invalid); 1.750 + } break; 1.751 + 1.752 + case JVM_CONSTANT_Fieldref: 1.753 + { 1.754 + int class_index = uncached_klass_ref_index_at(from_i); 1.755 + int name_and_type_index = uncached_name_and_type_ref_index_at(from_i); 1.756 + to_cp->field_at_put(to_i, class_index, name_and_type_index); 1.757 + } break; 1.758 + 1.759 + case JVM_CONSTANT_Float: 1.760 + { 1.761 + jfloat f = float_at(from_i); 1.762 + to_cp->float_at_put(to_i, f); 1.763 + } break; 1.764 + 1.765 + case JVM_CONSTANT_Integer: 1.766 + { 1.767 + jint i = int_at(from_i); 1.768 + to_cp->int_at_put(to_i, i); 1.769 + } break; 1.770 + 1.771 + case JVM_CONSTANT_InterfaceMethodref: 1.772 + { 1.773 + int class_index = uncached_klass_ref_index_at(from_i); 1.774 + int name_and_type_index = uncached_name_and_type_ref_index_at(from_i); 1.775 + to_cp->interface_method_at_put(to_i, class_index, name_and_type_index); 1.776 + } break; 1.777 + 1.778 + case JVM_CONSTANT_Long: 1.779 + { 1.780 + jlong l = long_at(from_i); 1.781 + to_cp->long_at_put(to_i, l); 1.782 + // long takes two constant pool entries so init second entry's tag 1.783 + to_cp->tag_at_put(to_i + 1, JVM_CONSTANT_Invalid); 1.784 + } break; 1.785 + 1.786 + case JVM_CONSTANT_Methodref: 1.787 + { 1.788 + int class_index = uncached_klass_ref_index_at(from_i); 1.789 + int name_and_type_index = uncached_name_and_type_ref_index_at(from_i); 1.790 + to_cp->method_at_put(to_i, class_index, name_and_type_index); 1.791 + } break; 1.792 + 1.793 + case JVM_CONSTANT_NameAndType: 1.794 + { 1.795 + int name_ref_index = name_ref_index_at(from_i); 1.796 + int signature_ref_index = signature_ref_index_at(from_i); 1.797 + to_cp->name_and_type_at_put(to_i, name_ref_index, signature_ref_index); 1.798 + } break; 1.799 + 1.800 + case JVM_CONSTANT_String: 1.801 + { 1.802 + oop s = string_at(from_i, CHECK); 1.803 + to_cp->string_at_put(to_i, s); 1.804 + } break; 1.805 + 1.806 + case JVM_CONSTANT_StringIndex: 1.807 + { 1.808 + jint si = string_index_at(from_i); 1.809 + to_cp->string_index_at_put(to_i, si); 1.810 + } break; 1.811 + 1.812 + case JVM_CONSTANT_UnresolvedClass: 1.813 + { 1.814 + symbolOop k = unresolved_klass_at(from_i); 1.815 + to_cp->unresolved_klass_at_put(to_i, k); 1.816 + } break; 1.817 + 1.818 + case JVM_CONSTANT_UnresolvedClassInError: 1.819 + { 1.820 + symbolOop k = unresolved_klass_at(from_i); 1.821 + to_cp->unresolved_klass_at_put(to_i, k); 1.822 + to_cp->tag_at_put(to_i, JVM_CONSTANT_UnresolvedClassInError); 1.823 + } break; 1.824 + 1.825 + 1.826 + case JVM_CONSTANT_UnresolvedString: 1.827 + { 1.828 + symbolOop s = unresolved_string_at(from_i); 1.829 + to_cp->unresolved_string_at_put(to_i, s); 1.830 + } break; 1.831 + 1.832 + case JVM_CONSTANT_Utf8: 1.833 + { 1.834 + symbolOop s = symbol_at(from_i); 1.835 + to_cp->symbol_at_put(to_i, s); 1.836 + } break; 1.837 + 1.838 + // Invalid is used as the tag for the second constant pool entry 1.839 + // occupied by JVM_CONSTANT_Double or JVM_CONSTANT_Long. It should 1.840 + // not be seen by itself. 1.841 + case JVM_CONSTANT_Invalid: // fall through 1.842 + 1.843 + default: 1.844 + { 1.845 + jbyte bad_value = tag_at(from_i).value(); // leave a breadcrumb 1.846 + ShouldNotReachHere(); 1.847 + } break; 1.848 + } 1.849 +} // end copy_entry_to() 1.850 + 1.851 + 1.852 +// Search constant pool search_cp for an entry that matches this 1.853 +// constant pool's entry at pattern_i. Returns the index of a 1.854 +// matching entry or zero (0) if there is no matching entry. 1.855 +int constantPoolOopDesc::find_matching_entry(int pattern_i, 1.856 + constantPoolHandle search_cp, TRAPS) { 1.857 + 1.858 + // index zero (0) is not used 1.859 + for (int i = 1; i < search_cp->length(); i++) { 1.860 + bool found = compare_entry_to(pattern_i, search_cp, i, CHECK_0); 1.861 + if (found) { 1.862 + return i; 1.863 + } 1.864 + } 1.865 + 1.866 + return 0; // entry not found; return unused index zero (0) 1.867 +} // end find_matching_entry() 1.868 + 1.869 + 1.870 +#ifndef PRODUCT 1.871 + 1.872 +const char* constantPoolOopDesc::printable_name_at(int which) { 1.873 + 1.874 + constantTag tag = tag_at(which); 1.875 + 1.876 + if (tag.is_unresolved_string() || tag.is_string()) { 1.877 + return string_at_noresolve(which); 1.878 + } else if (tag.is_klass() || tag.is_unresolved_klass()) { 1.879 + return klass_name_at(which)->as_C_string(); 1.880 + } else if (tag.is_symbol()) { 1.881 + return symbol_at(which)->as_C_string(); 1.882 + } 1.883 + return ""; 1.884 +} 1.885 + 1.886 +#endif // PRODUCT 1.887 + 1.888 + 1.889 +// JVMTI GetConstantPool support 1.890 + 1.891 +// For temporary use until code is stable. 1.892 +#define DBG(code) 1.893 + 1.894 +static const char* WARN_MSG = "Must not be such entry!"; 1.895 + 1.896 +static void print_cpool_bytes(jint cnt, u1 *bytes) { 1.897 + jint size = 0; 1.898 + u2 idx1, idx2; 1.899 + 1.900 + for (jint idx = 1; idx < cnt; idx++) { 1.901 + jint ent_size = 0; 1.902 + u1 tag = *bytes++; 1.903 + size++; // count tag 1.904 + 1.905 + printf("const #%03d, tag: %02d ", idx, tag); 1.906 + switch(tag) { 1.907 + case JVM_CONSTANT_Invalid: { 1.908 + printf("Invalid"); 1.909 + break; 1.910 + } 1.911 + case JVM_CONSTANT_Unicode: { 1.912 + printf("Unicode %s", WARN_MSG); 1.913 + break; 1.914 + } 1.915 + case JVM_CONSTANT_Utf8: { 1.916 + u2 len = Bytes::get_Java_u2(bytes); 1.917 + char str[128]; 1.918 + if (len > 127) { 1.919 + len = 127; 1.920 + } 1.921 + strncpy(str, (char *) (bytes+2), len); 1.922 + str[len] = '\0'; 1.923 + printf("Utf8 \"%s\"", str); 1.924 + ent_size = 2 + len; 1.925 + break; 1.926 + } 1.927 + case JVM_CONSTANT_Integer: { 1.928 + u4 val = Bytes::get_Java_u4(bytes); 1.929 + printf("int %d", *(int *) &val); 1.930 + ent_size = 4; 1.931 + break; 1.932 + } 1.933 + case JVM_CONSTANT_Float: { 1.934 + u4 val = Bytes::get_Java_u4(bytes); 1.935 + printf("float %5.3ff", *(float *) &val); 1.936 + ent_size = 4; 1.937 + break; 1.938 + } 1.939 + case JVM_CONSTANT_Long: { 1.940 + u8 val = Bytes::get_Java_u8(bytes); 1.941 + printf("long %lldl", *(jlong *) &val); 1.942 + ent_size = 8; 1.943 + idx++; // Long takes two cpool slots 1.944 + break; 1.945 + } 1.946 + case JVM_CONSTANT_Double: { 1.947 + u8 val = Bytes::get_Java_u8(bytes); 1.948 + printf("double %5.3fd", *(jdouble *)&val); 1.949 + ent_size = 8; 1.950 + idx++; // Double takes two cpool slots 1.951 + break; 1.952 + } 1.953 + case JVM_CONSTANT_Class: { 1.954 + idx1 = Bytes::get_Java_u2(bytes); 1.955 + printf("class #%03d", idx1); 1.956 + ent_size = 2; 1.957 + break; 1.958 + } 1.959 + case JVM_CONSTANT_String: { 1.960 + idx1 = Bytes::get_Java_u2(bytes); 1.961 + printf("String #%03d", idx1); 1.962 + ent_size = 2; 1.963 + break; 1.964 + } 1.965 + case JVM_CONSTANT_Fieldref: { 1.966 + idx1 = Bytes::get_Java_u2(bytes); 1.967 + idx2 = Bytes::get_Java_u2(bytes+2); 1.968 + printf("Field #%03d, #%03d", (int) idx1, (int) idx2); 1.969 + ent_size = 4; 1.970 + break; 1.971 + } 1.972 + case JVM_CONSTANT_Methodref: { 1.973 + idx1 = Bytes::get_Java_u2(bytes); 1.974 + idx2 = Bytes::get_Java_u2(bytes+2); 1.975 + printf("Method #%03d, #%03d", idx1, idx2); 1.976 + ent_size = 4; 1.977 + break; 1.978 + } 1.979 + case JVM_CONSTANT_InterfaceMethodref: { 1.980 + idx1 = Bytes::get_Java_u2(bytes); 1.981 + idx2 = Bytes::get_Java_u2(bytes+2); 1.982 + printf("InterfMethod #%03d, #%03d", idx1, idx2); 1.983 + ent_size = 4; 1.984 + break; 1.985 + } 1.986 + case JVM_CONSTANT_NameAndType: { 1.987 + idx1 = Bytes::get_Java_u2(bytes); 1.988 + idx2 = Bytes::get_Java_u2(bytes+2); 1.989 + printf("NameAndType #%03d, #%03d", idx1, idx2); 1.990 + ent_size = 4; 1.991 + break; 1.992 + } 1.993 + case JVM_CONSTANT_ClassIndex: { 1.994 + printf("ClassIndex %s", WARN_MSG); 1.995 + break; 1.996 + } 1.997 + case JVM_CONSTANT_UnresolvedClass: { 1.998 + printf("UnresolvedClass: %s", WARN_MSG); 1.999 + break; 1.1000 + } 1.1001 + case JVM_CONSTANT_UnresolvedClassInError: { 1.1002 + printf("UnresolvedClassInErr: %s", WARN_MSG); 1.1003 + break; 1.1004 + } 1.1005 + case JVM_CONSTANT_StringIndex: { 1.1006 + printf("StringIndex: %s", WARN_MSG); 1.1007 + break; 1.1008 + } 1.1009 + case JVM_CONSTANT_UnresolvedString: { 1.1010 + printf("UnresolvedString: %s", WARN_MSG); 1.1011 + break; 1.1012 + } 1.1013 + } 1.1014 + printf(";\n"); 1.1015 + bytes += ent_size; 1.1016 + size += ent_size; 1.1017 + } 1.1018 + printf("Cpool size: %d\n", size); 1.1019 + fflush(0); 1.1020 + return; 1.1021 +} /* end print_cpool_bytes */ 1.1022 + 1.1023 + 1.1024 +// Returns size of constant pool entry. 1.1025 +jint constantPoolOopDesc::cpool_entry_size(jint idx) { 1.1026 + switch(tag_at(idx).value()) { 1.1027 + case JVM_CONSTANT_Invalid: 1.1028 + case JVM_CONSTANT_Unicode: 1.1029 + return 1; 1.1030 + 1.1031 + case JVM_CONSTANT_Utf8: 1.1032 + return 3 + symbol_at(idx)->utf8_length(); 1.1033 + 1.1034 + case JVM_CONSTANT_Class: 1.1035 + case JVM_CONSTANT_String: 1.1036 + case JVM_CONSTANT_ClassIndex: 1.1037 + case JVM_CONSTANT_UnresolvedClass: 1.1038 + case JVM_CONSTANT_UnresolvedClassInError: 1.1039 + case JVM_CONSTANT_StringIndex: 1.1040 + case JVM_CONSTANT_UnresolvedString: 1.1041 + return 3; 1.1042 + 1.1043 + case JVM_CONSTANT_Integer: 1.1044 + case JVM_CONSTANT_Float: 1.1045 + case JVM_CONSTANT_Fieldref: 1.1046 + case JVM_CONSTANT_Methodref: 1.1047 + case JVM_CONSTANT_InterfaceMethodref: 1.1048 + case JVM_CONSTANT_NameAndType: 1.1049 + return 5; 1.1050 + 1.1051 + case JVM_CONSTANT_Long: 1.1052 + case JVM_CONSTANT_Double: 1.1053 + return 9; 1.1054 + } 1.1055 + assert(false, "cpool_entry_size: Invalid constant pool entry tag"); 1.1056 + return 1; 1.1057 +} /* end cpool_entry_size */ 1.1058 + 1.1059 + 1.1060 +// SymbolHashMap is used to find a constant pool index from a string. 1.1061 +// This function fills in SymbolHashMaps, one for utf8s and one for 1.1062 +// class names, returns size of the cpool raw bytes. 1.1063 +jint constantPoolOopDesc::hash_entries_to(SymbolHashMap *symmap, 1.1064 + SymbolHashMap *classmap) { 1.1065 + jint size = 0; 1.1066 + 1.1067 + for (u2 idx = 1; idx < length(); idx++) { 1.1068 + u2 tag = tag_at(idx).value(); 1.1069 + size += cpool_entry_size(idx); 1.1070 + 1.1071 + switch(tag) { 1.1072 + case JVM_CONSTANT_Utf8: { 1.1073 + symbolOop sym = symbol_at(idx); 1.1074 + symmap->add_entry(sym, idx); 1.1075 + DBG(printf("adding symbol entry %s = %d\n", sym->as_utf8(), idx)); 1.1076 + break; 1.1077 + } 1.1078 + case JVM_CONSTANT_Class: 1.1079 + case JVM_CONSTANT_UnresolvedClass: 1.1080 + case JVM_CONSTANT_UnresolvedClassInError: { 1.1081 + symbolOop sym = klass_name_at(idx); 1.1082 + classmap->add_entry(sym, idx); 1.1083 + DBG(printf("adding class entry %s = %d\n", sym->as_utf8(), idx)); 1.1084 + break; 1.1085 + } 1.1086 + case JVM_CONSTANT_Long: 1.1087 + case JVM_CONSTANT_Double: { 1.1088 + idx++; // Both Long and Double take two cpool slots 1.1089 + break; 1.1090 + } 1.1091 + } 1.1092 + } 1.1093 + return size; 1.1094 +} /* end hash_utf8_entries_to */ 1.1095 + 1.1096 + 1.1097 +// Copy cpool bytes. 1.1098 +// Returns: 1.1099 +// 0, in case of OutOfMemoryError 1.1100 +// -1, in case of internal error 1.1101 +// > 0, count of the raw cpool bytes that have been copied 1.1102 +int constantPoolOopDesc::copy_cpool_bytes(int cpool_size, 1.1103 + SymbolHashMap* tbl, 1.1104 + unsigned char *bytes) { 1.1105 + u2 idx1, idx2; 1.1106 + jint size = 0; 1.1107 + jint cnt = length(); 1.1108 + unsigned char *start_bytes = bytes; 1.1109 + 1.1110 + for (jint idx = 1; idx < cnt; idx++) { 1.1111 + u1 tag = tag_at(idx).value(); 1.1112 + jint ent_size = cpool_entry_size(idx); 1.1113 + 1.1114 + assert(size + ent_size <= cpool_size, "Size mismatch"); 1.1115 + 1.1116 + *bytes = tag; 1.1117 + DBG(printf("#%03hd tag=%03hd, ", idx, tag)); 1.1118 + switch(tag) { 1.1119 + case JVM_CONSTANT_Invalid: { 1.1120 + DBG(printf("JVM_CONSTANT_Invalid")); 1.1121 + break; 1.1122 + } 1.1123 + case JVM_CONSTANT_Unicode: { 1.1124 + assert(false, "Wrong constant pool tag: JVM_CONSTANT_Unicode"); 1.1125 + DBG(printf("JVM_CONSTANT_Unicode")); 1.1126 + break; 1.1127 + } 1.1128 + case JVM_CONSTANT_Utf8: { 1.1129 + symbolOop sym = symbol_at(idx); 1.1130 + char* str = sym->as_utf8(); 1.1131 + // Warning! It's crashing on x86 with len = sym->utf8_length() 1.1132 + int len = (int) strlen(str); 1.1133 + Bytes::put_Java_u2((address) (bytes+1), (u2) len); 1.1134 + for (int i = 0; i < len; i++) { 1.1135 + bytes[3+i] = (u1) str[i]; 1.1136 + } 1.1137 + DBG(printf("JVM_CONSTANT_Utf8: %s ", str)); 1.1138 + break; 1.1139 + } 1.1140 + case JVM_CONSTANT_Integer: { 1.1141 + jint val = int_at(idx); 1.1142 + Bytes::put_Java_u4((address) (bytes+1), *(u4*)&val); 1.1143 + break; 1.1144 + } 1.1145 + case JVM_CONSTANT_Float: { 1.1146 + jfloat val = float_at(idx); 1.1147 + Bytes::put_Java_u4((address) (bytes+1), *(u4*)&val); 1.1148 + break; 1.1149 + } 1.1150 + case JVM_CONSTANT_Long: { 1.1151 + jlong val = long_at(idx); 1.1152 + Bytes::put_Java_u8((address) (bytes+1), *(u8*)&val); 1.1153 + idx++; // Long takes two cpool slots 1.1154 + break; 1.1155 + } 1.1156 + case JVM_CONSTANT_Double: { 1.1157 + jdouble val = double_at(idx); 1.1158 + Bytes::put_Java_u8((address) (bytes+1), *(u8*)&val); 1.1159 + idx++; // Double takes two cpool slots 1.1160 + break; 1.1161 + } 1.1162 + case JVM_CONSTANT_Class: 1.1163 + case JVM_CONSTANT_UnresolvedClass: 1.1164 + case JVM_CONSTANT_UnresolvedClassInError: { 1.1165 + *bytes = JVM_CONSTANT_Class; 1.1166 + symbolOop sym = klass_name_at(idx); 1.1167 + idx1 = tbl->symbol_to_value(sym); 1.1168 + assert(idx1 != 0, "Have not found a hashtable entry"); 1.1169 + Bytes::put_Java_u2((address) (bytes+1), idx1); 1.1170 + DBG(printf("JVM_CONSTANT_Class: idx=#%03hd, %s", idx1, sym->as_utf8())); 1.1171 + break; 1.1172 + } 1.1173 + case JVM_CONSTANT_String: { 1.1174 + unsigned int hash; 1.1175 + char *str = string_at_noresolve(idx); 1.1176 + symbolOop sym = SymbolTable::lookup_only(str, (int) strlen(str), hash); 1.1177 + idx1 = tbl->symbol_to_value(sym); 1.1178 + assert(idx1 != 0, "Have not found a hashtable entry"); 1.1179 + Bytes::put_Java_u2((address) (bytes+1), idx1); 1.1180 + DBG(printf("JVM_CONSTANT_String: idx=#%03hd, %s", idx1, str)); 1.1181 + break; 1.1182 + } 1.1183 + case JVM_CONSTANT_UnresolvedString: { 1.1184 + *bytes = JVM_CONSTANT_String; 1.1185 + symbolOop sym = unresolved_string_at(idx); 1.1186 + idx1 = tbl->symbol_to_value(sym); 1.1187 + assert(idx1 != 0, "Have not found a hashtable entry"); 1.1188 + Bytes::put_Java_u2((address) (bytes+1), idx1); 1.1189 + DBG(char *str = sym->as_utf8()); 1.1190 + DBG(printf("JVM_CONSTANT_UnresolvedString: idx=#%03hd, %s", idx1, str)); 1.1191 + break; 1.1192 + } 1.1193 + case JVM_CONSTANT_Fieldref: 1.1194 + case JVM_CONSTANT_Methodref: 1.1195 + case JVM_CONSTANT_InterfaceMethodref: { 1.1196 + idx1 = uncached_klass_ref_index_at(idx); 1.1197 + idx2 = uncached_name_and_type_ref_index_at(idx); 1.1198 + Bytes::put_Java_u2((address) (bytes+1), idx1); 1.1199 + Bytes::put_Java_u2((address) (bytes+3), idx2); 1.1200 + DBG(printf("JVM_CONSTANT_Methodref: %hd %hd", idx1, idx2)); 1.1201 + break; 1.1202 + } 1.1203 + case JVM_CONSTANT_NameAndType: { 1.1204 + idx1 = name_ref_index_at(idx); 1.1205 + idx2 = signature_ref_index_at(idx); 1.1206 + Bytes::put_Java_u2((address) (bytes+1), idx1); 1.1207 + Bytes::put_Java_u2((address) (bytes+3), idx2); 1.1208 + DBG(printf("JVM_CONSTANT_NameAndType: %hd %hd", idx1, idx2)); 1.1209 + break; 1.1210 + } 1.1211 + case JVM_CONSTANT_ClassIndex: { 1.1212 + *bytes = JVM_CONSTANT_Class; 1.1213 + idx1 = klass_index_at(idx); 1.1214 + Bytes::put_Java_u2((address) (bytes+1), idx1); 1.1215 + DBG(printf("JVM_CONSTANT_ClassIndex: %hd", idx1)); 1.1216 + break; 1.1217 + } 1.1218 + case JVM_CONSTANT_StringIndex: { 1.1219 + *bytes = JVM_CONSTANT_String; 1.1220 + idx1 = string_index_at(idx); 1.1221 + Bytes::put_Java_u2((address) (bytes+1), idx1); 1.1222 + DBG(printf("JVM_CONSTANT_StringIndex: %hd", idx1)); 1.1223 + break; 1.1224 + } 1.1225 + } 1.1226 + DBG(printf("\n")); 1.1227 + bytes += ent_size; 1.1228 + size += ent_size; 1.1229 + } 1.1230 + assert(size == cpool_size, "Size mismatch"); 1.1231 + 1.1232 + // Keep temorarily for debugging until it's stable. 1.1233 + DBG(print_cpool_bytes(cnt, start_bytes)); 1.1234 + return (int)(bytes - start_bytes); 1.1235 +} /* end copy_cpool_bytes */ 1.1236 + 1.1237 + 1.1238 +void SymbolHashMap::add_entry(symbolOop sym, u2 value) { 1.1239 + char *str = sym->as_utf8(); 1.1240 + unsigned int hash = compute_hash(str, sym->utf8_length()); 1.1241 + unsigned int index = hash % table_size(); 1.1242 + 1.1243 + // check if already in map 1.1244 + // we prefer the first entry since it is more likely to be what was used in 1.1245 + // the class file 1.1246 + for (SymbolHashMapEntry *en = bucket(index); en != NULL; en = en->next()) { 1.1247 + assert(en->symbol() != NULL, "SymbolHashMapEntry symbol is NULL"); 1.1248 + if (en->hash() == hash && en->symbol() == sym) { 1.1249 + return; // already there 1.1250 + } 1.1251 + } 1.1252 + 1.1253 + SymbolHashMapEntry* entry = new SymbolHashMapEntry(hash, sym, value); 1.1254 + entry->set_next(bucket(index)); 1.1255 + _buckets[index].set_entry(entry); 1.1256 + assert(entry->symbol() != NULL, "SymbolHashMapEntry symbol is NULL"); 1.1257 +} 1.1258 + 1.1259 +SymbolHashMapEntry* SymbolHashMap::find_entry(symbolOop sym) { 1.1260 + assert(sym != NULL, "SymbolHashMap::find_entry - symbol is NULL"); 1.1261 + char *str = sym->as_utf8(); 1.1262 + int len = sym->utf8_length(); 1.1263 + unsigned int hash = SymbolHashMap::compute_hash(str, len); 1.1264 + unsigned int index = hash % table_size(); 1.1265 + for (SymbolHashMapEntry *en = bucket(index); en != NULL; en = en->next()) { 1.1266 + assert(en->symbol() != NULL, "SymbolHashMapEntry symbol is NULL"); 1.1267 + if (en->hash() == hash && en->symbol() == sym) { 1.1268 + return en; 1.1269 + } 1.1270 + } 1.1271 + return NULL; 1.1272 +}