1 #ifdef USE_PRAGMA_IDENT_SRC 2 #pragma ident "@(#)constantPoolOop.cpp 1.104 07/05/05 17:06:01 JVM" 3 #endif 4 /* 5 * Copyright 1997-2008 Sun Microsystems, Inc. All Rights Reserved. 6 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 7 * 8 * This code is free software; you can redistribute it and/or modify it 9 * under the terms of the GNU General Public License version 2 only, as 10 * published by the Free Software Foundation. 11 * 12 * This code is distributed in the hope that it will be useful, but WITHOUT 13 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 14 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 15 * version 2 for more details (a copy is included in the LICENSE file that 16 * accompanied this code). 17 * 18 * You should have received a copy of the GNU General Public License version 19 * 2 along with this work; if not, write to the Free Software Foundation, 20 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 21 * 22 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, 23 * CA 95054 USA or visit www.sun.com if you need additional information or 24 * have any questions. 25 * 26 */ 27 28 # include "incls/_precompiled.incl" 29 # include "incls/_constantPoolOop.cpp.incl" 30 31 void constantPoolOopDesc::set_flag_at(FlagBit fb) { 32 const int MAX_STATE_CHANGES = 2; 33 for (int i = MAX_STATE_CHANGES + 10; i > 0; i--) { 34 int oflags = _flags; 35 int nflags = oflags | (1 << (int)fb); 36 if (Atomic::cmpxchg(nflags, &_flags, oflags) == oflags) 37 return; 38 } 39 assert(false, "failed to cmpxchg flags"); 40 _flags |= (1 << (int)fb); // better than nothing 41 } 42 43 klassOop constantPoolOopDesc::klass_at_impl(constantPoolHandle this_oop, int which, TRAPS) { 44 // A resolved constantPool entry will contain a klassOop, otherwise a symbolOop. 45 // It is not safe to rely on the tag bit's here, since we don't have a lock, and the entry and 46 // tag is not updated atomicly. 47 oop entry = *(this_oop->obj_at_addr(which)); 48 if (entry->is_klass()) { 49 // Already resolved - return entry. 50 return (klassOop)entry; 51 } 52 53 // Acquire lock on constant oop while doing update. After we get the lock, we check if another object 54 // already has updated the object 55 assert(THREAD->is_Java_thread(), "must be a Java thread"); 56 bool do_resolve = false; 57 bool in_error = false; 58 59 symbolHandle name; 60 Handle loader; 61 { ObjectLocker ol(this_oop, THREAD); 62 63 if (this_oop->tag_at(which).is_unresolved_klass()) { 64 if (this_oop->tag_at(which).is_unresolved_klass_in_error()) { 65 in_error = true; 66 } else { 67 do_resolve = true; 68 name = symbolHandle(THREAD, this_oop->unresolved_klass_at(which)); 69 loader = Handle(THREAD, instanceKlass::cast(this_oop->pool_holder())->class_loader()); 70 } 71 } 72 } // unlocking constantPool 73 74 75 // The original attempt to resolve this constant pool entry failed so find the 76 // original error and throw it again (JVMS 5.4.3). 77 if (in_error) { 78 symbolOop error = SystemDictionary::find_resolution_error(this_oop, which); 79 guarantee(error != (symbolOop)NULL, "tag mismatch with resolution error table"); 80 ResourceMark rm; 81 // exception text will be the class name 82 const char* className = this_oop->unresolved_klass_at(which)->as_C_string(); 83 THROW_MSG_0(error, className); 84 } 85 86 if (do_resolve) { 87 // this_oop must be unlocked during resolve_or_fail 88 oop protection_domain = Klass::cast(this_oop->pool_holder())->protection_domain(); 89 Handle h_prot (THREAD, protection_domain); 90 klassOop k_oop = SystemDictionary::resolve_or_fail(name, loader, h_prot, true, THREAD); 91 KlassHandle k; 92 if (!HAS_PENDING_EXCEPTION) { 93 k = KlassHandle(THREAD, k_oop); 94 // Do access check for klasses 95 verify_constant_pool_resolve(this_oop, k, THREAD); 96 } 97 98 // Failed to resolve class. We must record the errors so that subsequent attempts 99 // to resolve this constant pool entry fail with the same error (JVMS 5.4.3). 100 if (HAS_PENDING_EXCEPTION) { 101 ResourceMark rm; 102 symbolHandle error(PENDING_EXCEPTION->klass()->klass_part()->name()); 103 104 bool throw_orig_error = false; 105 { 106 ObjectLocker ol (this_oop, THREAD); 107 108 // some other thread has beaten us and has resolved the class. 109 if (this_oop->tag_at(which).is_klass()) { 110 CLEAR_PENDING_EXCEPTION; 111 entry = this_oop->resolved_klass_at(which); 112 return (klassOop)entry; 113 } 114 115 if (!PENDING_EXCEPTION-> 116 is_a(SystemDictionary::linkageError_klass())) { 117 // Just throw the exception and don't prevent these classes from 118 // being loaded due to virtual machine errors like StackOverflow 119 // and OutOfMemoryError, etc, or if the thread was hit by stop() 120 // Needs clarification to section 5.4.3 of the VM spec (see 6308271) 121 } 122 else if (!this_oop->tag_at(which).is_unresolved_klass_in_error()) { 123 SystemDictionary::add_resolution_error(this_oop, which, error); 124 this_oop->tag_at_put(which, JVM_CONSTANT_UnresolvedClassInError); 125 } else { 126 // some other thread has put the class in error state. 127 error = symbolHandle(SystemDictionary::find_resolution_error(this_oop, which)); 128 assert(!error.is_null(), "checking"); 129 throw_orig_error = true; 130 } 131 } // unlocked 132 133 if (throw_orig_error) { 134 CLEAR_PENDING_EXCEPTION; 135 ResourceMark rm; 136 const char* className = this_oop->unresolved_klass_at(which)->as_C_string(); 137 THROW_MSG_0(error, className); 138 } 139 140 return 0; 141 } 142 143 if (TraceClassResolution && !k()->klass_part()->oop_is_array()) { 144 // skip resolving the constant pool so that this code get's 145 // called the next time some bytecodes refer to this class. 146 ResourceMark rm; 147 int line_number = -1; 148 const char * source_file = NULL; 149 if (JavaThread::current()->has_last_Java_frame()) { 150 // try to identify the method which called this function. 151 vframeStream vfst(JavaThread::current()); 152 if (!vfst.at_end()) { 153 line_number = vfst.method()->line_number_from_bci(vfst.bci()); 154 symbolOop s = instanceKlass::cast(vfst.method()->method_holder())->source_file_name(); 155 if (s != NULL) { 156 source_file = s->as_C_string(); 157 } 158 } 159 } 160 if (k() != this_oop->pool_holder()) { 161 // only print something if the classes are different 162 if (source_file != NULL) { 163 tty->print("RESOLVE %s %s %s:%d\n", 164 instanceKlass::cast(this_oop->pool_holder())->external_name(), 165 instanceKlass::cast(k())->external_name(), source_file, line_number); 166 } else { 167 tty->print("RESOLVE %s %s\n", 168 instanceKlass::cast(this_oop->pool_holder())->external_name(), 169 instanceKlass::cast(k())->external_name()); 170 } 171 } 172 return k(); 173 } else { 174 ObjectLocker ol (this_oop, THREAD); 175 // Only updated constant pool - if it is resolved. 176 do_resolve = this_oop->tag_at(which).is_unresolved_klass(); 177 if (do_resolve) { 178 this_oop->klass_at_put(which, k()); 179 } 180 } 181 } 182 183 entry = this_oop->resolved_klass_at(which); 184 assert(entry->is_klass(), "must be resolved at this point"); 185 return (klassOop)entry; 186 } 187 188 189 // Does not update constantPoolOop - to avoid any exception throwing. Used 190 // by compiler and exception handling. Also used to avoid classloads for 191 // instanceof operations. Returns NULL if the class has not been loaded or 192 // if the verification of constant pool failed 193 klassOop constantPoolOopDesc::klass_at_if_loaded(constantPoolHandle this_oop, int which) { 194 oop entry = *this_oop->obj_at_addr(which); 195 if (entry->is_klass()) { 196 return (klassOop)entry; 197 } else { 198 assert(entry->is_symbol(), "must be either symbol or klass"); 199 Thread *thread = Thread::current(); 200 symbolHandle name (thread, (symbolOop)entry); 201 oop loader = instanceKlass::cast(this_oop->pool_holder())->class_loader(); 202 oop protection_domain = Klass::cast(this_oop->pool_holder())->protection_domain(); 203 Handle h_prot (thread, protection_domain); 204 Handle h_loader (thread, loader); 205 klassOop k = SystemDictionary::find(name, h_loader, h_prot, thread); 206 207 if (k != NULL) { 208 // Make sure that resolving is legal 209 EXCEPTION_MARK; 210 KlassHandle klass(THREAD, k); 211 // return NULL if verification fails 212 verify_constant_pool_resolve(this_oop, klass, THREAD); 213 if (HAS_PENDING_EXCEPTION) { 214 CLEAR_PENDING_EXCEPTION; 215 return NULL; 216 } 217 return klass(); 218 } else { 219 return k; 220 } 221 } 222 } 223 224 225 klassOop constantPoolOopDesc::klass_ref_at_if_loaded(constantPoolHandle this_oop, int which) { 226 return klass_at_if_loaded(this_oop, this_oop->klass_ref_index_at(which)); 227 } 228 229 230 // This is an interface for the compiler that allows accessing non-resolved entries 231 // in the constant pool - but still performs the validations tests. Must be used 232 // in a pre-parse of the compiler - to determine what it can do and not do. 233 // Note: We cannot update the ConstantPool from the vm_thread. 234 klassOop constantPoolOopDesc::klass_ref_at_if_loaded_check(constantPoolHandle this_oop, int index, TRAPS) { 235 int which = this_oop->klass_ref_index_at(index); 236 oop entry = *this_oop->obj_at_addr(which); 237 if (entry->is_klass()) { 238 return (klassOop)entry; 239 } else { 240 assert(entry->is_symbol(), "must be either symbol or klass"); 241 symbolHandle name (THREAD, (symbolOop)entry); 242 oop loader = instanceKlass::cast(this_oop->pool_holder())->class_loader(); 243 oop protection_domain = Klass::cast(this_oop->pool_holder())->protection_domain(); 244 Handle h_loader(THREAD, loader); 245 Handle h_prot (THREAD, protection_domain); 246 KlassHandle k(THREAD, SystemDictionary::find(name, h_loader, h_prot, THREAD)); 247 248 // Do access check for klasses 249 if( k.not_null() ) verify_constant_pool_resolve(this_oop, k, CHECK_NULL); 250 return k(); 251 } 252 } 253 254 255 symbolOop constantPoolOopDesc::uncached_name_ref_at(int which) { 256 jint ref_index = name_and_type_at(uncached_name_and_type_ref_index_at(which)); 257 int name_index = extract_low_short_from_int(ref_index); 258 return symbol_at(name_index); 259 } 260 261 262 symbolOop constantPoolOopDesc::uncached_signature_ref_at(int which) { 263 jint ref_index = name_and_type_at(uncached_name_and_type_ref_index_at(which)); 264 int signature_index = extract_high_short_from_int(ref_index); 265 return symbol_at(signature_index); 266 } 267 268 269 int constantPoolOopDesc::uncached_name_and_type_ref_index_at(int which) { 270 jint ref_index = field_or_method_at(which, true); 271 return extract_high_short_from_int(ref_index); 272 } 273 274 275 int constantPoolOopDesc::uncached_klass_ref_index_at(int which) { 276 jint ref_index = field_or_method_at(which, true); 277 return extract_low_short_from_int(ref_index); 278 } 279 280 281 void constantPoolOopDesc::verify_constant_pool_resolve(constantPoolHandle this_oop, KlassHandle k, TRAPS) { 282 if (k->oop_is_instance() || k->oop_is_objArray()) { 283 instanceKlassHandle holder (THREAD, this_oop->pool_holder()); 284 klassOop elem_oop = k->oop_is_instance() ? k() : objArrayKlass::cast(k())->bottom_klass(); 285 KlassHandle element (THREAD, elem_oop); 286 287 // The element type could be a typeArray - we only need the access check if it is 288 // an reference to another class 289 if (element->oop_is_instance()) { 290 LinkResolver::check_klass_accessability(holder, element, CHECK); 291 } 292 } 293 } 294 295 296 int constantPoolOopDesc::klass_ref_index_at(int which) { 297 jint ref_index = field_or_method_at(which, false); 298 return extract_low_short_from_int(ref_index); 299 } 300 301 302 int constantPoolOopDesc::name_and_type_ref_index_at(int which) { 303 jint ref_index = field_or_method_at(which, false); 304 return extract_high_short_from_int(ref_index); 305 } 306 307 308 int constantPoolOopDesc::name_ref_index_at(int which) { 309 jint ref_index = name_and_type_at(which); 310 return extract_low_short_from_int(ref_index); 311 } 312 313 314 int constantPoolOopDesc::signature_ref_index_at(int which) { 315 jint ref_index = name_and_type_at(which); 316 return extract_high_short_from_int(ref_index); 317 } 318 319 320 klassOop constantPoolOopDesc::klass_ref_at(int which, TRAPS) { 321 return klass_at(klass_ref_index_at(which), CHECK_NULL); 322 } 323 324 325 symbolOop constantPoolOopDesc::klass_name_at(int which) { 326 assert(tag_at(which).is_unresolved_klass() || tag_at(which).is_klass(), 327 "Corrupted constant pool"); 328 // A resolved constantPool entry will contain a klassOop, otherwise a symbolOop. 329 // It is not safe to rely on the tag bit's here, since we don't have a lock, and the entry and 330 // tag is not updated atomicly. 331 oop entry = *(obj_at_addr(which)); 332 if (entry->is_klass()) { 333 // Already resolved - return entry's name. 334 return klassOop(entry)->klass_part()->name(); 335 } else { 336 assert(entry->is_symbol(), "must be either symbol or klass"); 337 return (symbolOop)entry; 338 } 339 } 340 341 symbolOop constantPoolOopDesc::klass_ref_at_noresolve(int which) { 342 jint ref_index = klass_ref_index_at(which); 343 return klass_at_noresolve(ref_index); 344 } 345 346 char* constantPoolOopDesc::string_at_noresolve(int which) { 347 // Test entry type in case string is resolved while in here. 348 oop entry = *(obj_at_addr(which)); 349 if (entry->is_symbol()) { 350 return ((symbolOop)entry)->as_C_string(); 351 } else if (java_lang_String::is_instance(entry)) { 352 return java_lang_String::as_utf8_string(entry); 353 } else { 354 return (char*)"<pseudo-string>"; 355 } 356 } 357 358 359 symbolOop constantPoolOopDesc::name_ref_at(int which) { 360 jint ref_index = name_and_type_at(name_and_type_ref_index_at(which)); 361 int name_index = extract_low_short_from_int(ref_index); 362 return symbol_at(name_index); 363 } 364 365 366 symbolOop constantPoolOopDesc::signature_ref_at(int which) { 367 jint ref_index = name_and_type_at(name_and_type_ref_index_at(which)); 368 int signature_index = extract_high_short_from_int(ref_index); 369 return symbol_at(signature_index); 370 } 371 372 373 BasicType constantPoolOopDesc::basic_type_for_signature_at(int which) { 374 return FieldType::basic_type(symbol_at(which)); 375 } 376 377 378 void constantPoolOopDesc::resolve_string_constants_impl(constantPoolHandle this_oop, TRAPS) { 379 for (int index = 1; index < this_oop->length(); index++) { // Index 0 is unused 380 if (this_oop->tag_at(index).is_unresolved_string()) { 381 this_oop->string_at(index, CHECK); 382 } 383 } 384 } 385 386 oop constantPoolOopDesc::string_at_impl(constantPoolHandle this_oop, int which, TRAPS) { 387 oop entry = *(this_oop->obj_at_addr(which)); 388 if (entry->is_symbol()) { 389 ObjectLocker ol(this_oop, THREAD); 390 if (this_oop->tag_at(which).is_unresolved_string()) { 391 // Intern string 392 symbolOop sym = this_oop->unresolved_string_at(which); 393 entry = StringTable::intern(sym, CHECK_(constantPoolOop(NULL))); 394 this_oop->string_at_put(which, entry); 395 } else { 396 // Another thread beat us and interned string, read string from constant pool 397 entry = this_oop->resolved_string_at(which); 398 } 399 } 400 assert(java_lang_String::is_instance(entry), "must be string"); 401 return entry; 402 } 403 404 405 bool constantPoolOopDesc::is_pseudo_string_at(int which) { 406 oop entry = *(obj_at_addr(which)); 407 if (entry->is_symbol()) 408 // Not yet resolved, but it will resolve to a string. 409 return false; 410 else if (java_lang_String::is_instance(entry)) 411 return false; // actually, it might be a non-interned or non-perm string 412 else 413 // truly pseudo 414 return true; 415 } 416 417 418 bool constantPoolOopDesc::klass_name_at_matches(instanceKlassHandle k, 419 int which) { 420 // Names are interned, so we can compare symbolOops directly 421 symbolOop cp_name = klass_name_at(which); 422 return (cp_name == k->name()); 423 } 424 425 426 int constantPoolOopDesc::pre_resolve_shared_klasses(TRAPS) { 427 ResourceMark rm; 428 int count = 0; 429 for (int index = 1; index < tags()->length(); index++) { // Index 0 is unused 430 if (tag_at(index).is_unresolved_string()) { 431 // Intern string 432 symbolOop sym = unresolved_string_at(index); 433 oop entry = StringTable::intern(sym, CHECK_(-1)); 434 string_at_put(index, entry); 435 } 436 } 437 return count; 438 } 439 440 441 // Iterate over symbols which are used as class, field, method names and 442 // signatures (in preparation for writing to the shared archive). 443 444 void constantPoolOopDesc::shared_symbols_iterate(OopClosure* closure) { 445 for (int index = 1; index < length(); index++) { // Index 0 is unused 446 switch (tag_at(index).value()) { 447 448 case JVM_CONSTANT_UnresolvedClass: 449 closure->do_oop(obj_at_addr(index)); 450 break; 451 452 case JVM_CONSTANT_NameAndType: 453 { 454 int i = *int_at_addr(index); 455 closure->do_oop(obj_at_addr((unsigned)i >> 16)); 456 closure->do_oop(obj_at_addr((unsigned)i & 0xffff)); 457 } 458 break; 459 460 case JVM_CONSTANT_Class: 461 case JVM_CONSTANT_InterfaceMethodref: 462 case JVM_CONSTANT_Fieldref: 463 case JVM_CONSTANT_Methodref: 464 case JVM_CONSTANT_Integer: 465 case JVM_CONSTANT_Float: 466 // Do nothing! Not an oop. 467 // These constant types do not reference symbols at this point. 468 break; 469 470 case JVM_CONSTANT_String: 471 // Do nothing! Not a symbol. 472 break; 473 474 case JVM_CONSTANT_UnresolvedString: 475 case JVM_CONSTANT_Utf8: 476 // These constants are symbols, but unless these symbols are 477 // actually to be used for something, we don't want to mark them. 478 break; 479 480 case JVM_CONSTANT_Long: 481 case JVM_CONSTANT_Double: 482 // Do nothing! Not an oop. (But takes two pool entries.) 483 ++index; 484 break; 485 486 default: 487 ShouldNotReachHere(); 488 break; 489 } 490 } 491 } 492 493 494 // Iterate over the [one] tags array (in preparation for writing to the 495 // shared archive). 496 497 void constantPoolOopDesc::shared_tags_iterate(OopClosure* closure) { 498 closure->do_oop(tags_addr()); 499 } 500 501 502 // Iterate over String objects (in preparation for writing to the shared 503 // archive). 504 505 void constantPoolOopDesc::shared_strings_iterate(OopClosure* closure) { 506 for (int index = 1; index < length(); index++) { // Index 0 is unused 507 switch (tag_at(index).value()) { 508 509 case JVM_CONSTANT_UnresolvedClass: 510 case JVM_CONSTANT_NameAndType: 511 // Do nothing! Not a String. 512 break; 513 514 case JVM_CONSTANT_Class: 515 case JVM_CONSTANT_InterfaceMethodref: 516 case JVM_CONSTANT_Fieldref: 517 case JVM_CONSTANT_Methodref: 518 case JVM_CONSTANT_Integer: 519 case JVM_CONSTANT_Float: 520 // Do nothing! Not an oop. 521 // These constant types do not reference symbols at this point. 522 break; 523 524 case JVM_CONSTANT_String: 525 closure->do_oop(obj_at_addr(index)); 526 break; 527 528 case JVM_CONSTANT_UnresolvedString: 529 case JVM_CONSTANT_Utf8: 530 // These constants are symbols, but unless these symbols are 531 // actually to be used for something, we don't want to mark them. 532 break; 533 534 case JVM_CONSTANT_Long: 535 case JVM_CONSTANT_Double: 536 // Do nothing! Not an oop. (But takes two pool entries.) 537 ++index; 538 break; 539 540 default: 541 ShouldNotReachHere(); 542 break; 543 } 544 } 545 } 546 547 548 // Compare this constant pool's entry at index1 to the constant pool 549 // cp2's entry at index2. 550 bool constantPoolOopDesc::compare_entry_to(int index1, constantPoolHandle cp2, 551 int index2, TRAPS) { 552 553 jbyte t1 = tag_at(index1).value(); 554 jbyte t2 = cp2->tag_at(index2).value(); 555 556 557 // JVM_CONSTANT_UnresolvedClassInError is equal to JVM_CONSTANT_UnresolvedClass 558 // when comparing 559 if (t1 == JVM_CONSTANT_UnresolvedClassInError) { 560 t1 = JVM_CONSTANT_UnresolvedClass; 561 } 562 if (t2 == JVM_CONSTANT_UnresolvedClassInError) { 563 t2 = JVM_CONSTANT_UnresolvedClass; 564 } 565 566 if (t1 != t2) { 567 // Not the same entry type so there is nothing else to check. Note 568 // that this style of checking will consider resolved/unresolved 569 // class pairs and resolved/unresolved string pairs as different. 570 // From the constantPoolOop API point of view, this is correct 571 // behavior. See constantPoolKlass::merge() to see how this plays 572 // out in the context of constantPoolOop merging. 573 return false; 574 } 575 576 switch (t1) { 577 case JVM_CONSTANT_Class: 578 { 579 klassOop k1 = klass_at(index1, CHECK_false); 580 klassOop k2 = cp2->klass_at(index2, CHECK_false); 581 if (k1 == k2) { 582 return true; 583 } 584 } break; 585 586 case JVM_CONSTANT_ClassIndex: 587 { 588 int recur1 = klass_index_at(index1); 589 int recur2 = cp2->klass_index_at(index2); 590 bool match = compare_entry_to(recur1, cp2, recur2, CHECK_false); 591 if (match) { 592 return true; 593 } 594 } break; 595 596 case JVM_CONSTANT_Double: 597 { 598 jdouble d1 = double_at(index1); 599 jdouble d2 = cp2->double_at(index2); 600 if (d1 == d2) { 601 return true; 602 } 603 } break; 604 605 case JVM_CONSTANT_Fieldref: 606 case JVM_CONSTANT_InterfaceMethodref: 607 case JVM_CONSTANT_Methodref: 608 { 609 int recur1 = uncached_klass_ref_index_at(index1); 610 int recur2 = cp2->uncached_klass_ref_index_at(index2); 611 bool match = compare_entry_to(recur1, cp2, recur2, CHECK_false); 612 if (match) { 613 recur1 = uncached_name_and_type_ref_index_at(index1); 614 recur2 = cp2->uncached_name_and_type_ref_index_at(index2); 615 match = compare_entry_to(recur1, cp2, recur2, CHECK_false); 616 if (match) { 617 return true; 618 } 619 } 620 } break; 621 622 case JVM_CONSTANT_Float: 623 { 624 jfloat f1 = float_at(index1); 625 jfloat f2 = cp2->float_at(index2); 626 if (f1 == f2) { 627 return true; 628 } 629 } break; 630 631 case JVM_CONSTANT_Integer: 632 { 633 jint i1 = int_at(index1); 634 jint i2 = cp2->int_at(index2); 635 if (i1 == i2) { 636 return true; 637 } 638 } break; 639 640 case JVM_CONSTANT_Long: 641 { 642 jlong l1 = long_at(index1); 643 jlong l2 = cp2->long_at(index2); 644 if (l1 == l2) { 645 return true; 646 } 647 } break; 648 649 case JVM_CONSTANT_NameAndType: 650 { 651 int recur1 = name_ref_index_at(index1); 652 int recur2 = cp2->name_ref_index_at(index2); 653 bool match = compare_entry_to(recur1, cp2, recur2, CHECK_false); 654 if (match) { 655 recur1 = signature_ref_index_at(index1); 656 recur2 = cp2->signature_ref_index_at(index2); 657 match = compare_entry_to(recur1, cp2, recur2, CHECK_false); 658 if (match) { 659 return true; 660 } 661 } 662 } break; 663 664 case JVM_CONSTANT_String: 665 { 666 oop s1 = string_at(index1, CHECK_false); 667 oop s2 = cp2->string_at(index2, CHECK_false); 668 if (s1 == s2) { 669 return true; 670 } 671 } break; 672 673 case JVM_CONSTANT_StringIndex: 674 { 675 int recur1 = string_index_at(index1); 676 int recur2 = cp2->string_index_at(index2); 677 bool match = compare_entry_to(recur1, cp2, recur2, CHECK_false); 678 if (match) { 679 return true; 680 } 681 } break; 682 683 case JVM_CONSTANT_UnresolvedClass: 684 { 685 symbolOop k1 = unresolved_klass_at(index1); 686 symbolOop k2 = cp2->unresolved_klass_at(index2); 687 if (k1 == k2) { 688 return true; 689 } 690 } break; 691 692 case JVM_CONSTANT_UnresolvedString: 693 { 694 symbolOop s1 = unresolved_string_at(index1); 695 symbolOop s2 = cp2->unresolved_string_at(index2); 696 if (s1 == s2) { 697 return true; 698 } 699 } break; 700 701 case JVM_CONSTANT_Utf8: 702 { 703 symbolOop s1 = symbol_at(index1); 704 symbolOop s2 = cp2->symbol_at(index2); 705 if (s1 == s2) { 706 return true; 707 } 708 } break; 709 710 // Invalid is used as the tag for the second constant pool entry 711 // occupied by JVM_CONSTANT_Double or JVM_CONSTANT_Long. It should 712 // not be seen by itself. 713 case JVM_CONSTANT_Invalid: // fall through 714 715 default: 716 ShouldNotReachHere(); 717 break; 718 } 719 720 return false; 721 } // end compare_entry_to() 722 723 724 // Copy this constant pool's entries at start_i to end_i (inclusive) 725 // to the constant pool to_cp's entries starting at to_i. A total of 726 // (end_i - start_i) + 1 entries are copied. 727 void constantPoolOopDesc::copy_cp_to(int start_i, int end_i, 728 constantPoolHandle to_cp, int to_i, TRAPS) { 729 730 int dest_i = to_i; // leave original alone for debug purposes 731 732 for (int src_i = start_i; src_i <= end_i; /* see loop bottom */ ) { 733 copy_entry_to(src_i, to_cp, dest_i, CHECK); 734 735 switch (tag_at(src_i).value()) { 736 case JVM_CONSTANT_Double: 737 case JVM_CONSTANT_Long: 738 // double and long take two constant pool entries 739 src_i += 2; 740 dest_i += 2; 741 break; 742 743 default: 744 // all others take one constant pool entry 745 src_i++; 746 dest_i++; 747 break; 748 } 749 } 750 } // end copy_cp_to() 751 752 753 // Copy this constant pool's entry at from_i to the constant pool 754 // to_cp's entry at to_i. 755 void constantPoolOopDesc::copy_entry_to(int from_i, constantPoolHandle to_cp, 756 int to_i, TRAPS) { 757 758 switch (tag_at(from_i).value()) { 759 case JVM_CONSTANT_Class: 760 { 761 klassOop k = klass_at(from_i, CHECK); 762 to_cp->klass_at_put(to_i, k); 763 } break; 764 765 case JVM_CONSTANT_ClassIndex: 766 { 767 jint ki = klass_index_at(from_i); 768 to_cp->klass_index_at_put(to_i, ki); 769 } break; 770 771 case JVM_CONSTANT_Double: 772 { 773 jdouble d = double_at(from_i); 774 to_cp->double_at_put(to_i, d); 775 // double takes two constant pool entries so init second entry's tag 776 to_cp->tag_at_put(to_i + 1, JVM_CONSTANT_Invalid); 777 } break; 778 779 case JVM_CONSTANT_Fieldref: 780 { 781 int class_index = uncached_klass_ref_index_at(from_i); 782 int name_and_type_index = uncached_name_and_type_ref_index_at(from_i); 783 to_cp->field_at_put(to_i, class_index, name_and_type_index); 784 } break; 785 786 case JVM_CONSTANT_Float: 787 { 788 jfloat f = float_at(from_i); 789 to_cp->float_at_put(to_i, f); 790 } break; 791 792 case JVM_CONSTANT_Integer: 793 { 794 jint i = int_at(from_i); 795 to_cp->int_at_put(to_i, i); 796 } break; 797 798 case JVM_CONSTANT_InterfaceMethodref: 799 { 800 int class_index = uncached_klass_ref_index_at(from_i); 801 int name_and_type_index = uncached_name_and_type_ref_index_at(from_i); 802 to_cp->interface_method_at_put(to_i, class_index, name_and_type_index); 803 } break; 804 805 case JVM_CONSTANT_Long: 806 { 807 jlong l = long_at(from_i); 808 to_cp->long_at_put(to_i, l); 809 // long takes two constant pool entries so init second entry's tag 810 to_cp->tag_at_put(to_i + 1, JVM_CONSTANT_Invalid); 811 } break; 812 813 case JVM_CONSTANT_Methodref: 814 { 815 int class_index = uncached_klass_ref_index_at(from_i); 816 int name_and_type_index = uncached_name_and_type_ref_index_at(from_i); 817 to_cp->method_at_put(to_i, class_index, name_and_type_index); 818 } break; 819 820 case JVM_CONSTANT_NameAndType: 821 { 822 int name_ref_index = name_ref_index_at(from_i); 823 int signature_ref_index = signature_ref_index_at(from_i); 824 to_cp->name_and_type_at_put(to_i, name_ref_index, signature_ref_index); 825 } break; 826 827 case JVM_CONSTANT_String: 828 { 829 oop s = string_at(from_i, CHECK); 830 to_cp->string_at_put(to_i, s); 831 } break; 832 833 case JVM_CONSTANT_StringIndex: 834 { 835 jint si = string_index_at(from_i); 836 to_cp->string_index_at_put(to_i, si); 837 } break; 838 839 case JVM_CONSTANT_UnresolvedClass: 840 { 841 symbolOop k = unresolved_klass_at(from_i); 842 to_cp->unresolved_klass_at_put(to_i, k); 843 } break; 844 845 case JVM_CONSTANT_UnresolvedClassInError: 846 { 847 symbolOop k = unresolved_klass_at(from_i); 848 to_cp->unresolved_klass_at_put(to_i, k); 849 to_cp->tag_at_put(to_i, JVM_CONSTANT_UnresolvedClassInError); 850 } break; 851 852 853 case JVM_CONSTANT_UnresolvedString: 854 { 855 symbolOop s = unresolved_string_at(from_i); 856 to_cp->unresolved_string_at_put(to_i, s); 857 } break; 858 859 case JVM_CONSTANT_Utf8: 860 { 861 symbolOop s = symbol_at(from_i); 862 to_cp->symbol_at_put(to_i, s); 863 } break; 864 865 // Invalid is used as the tag for the second constant pool entry 866 // occupied by JVM_CONSTANT_Double or JVM_CONSTANT_Long. It should 867 // not be seen by itself. 868 case JVM_CONSTANT_Invalid: // fall through 869 870 default: 871 { 872 jbyte bad_value = tag_at(from_i).value(); // leave a breadcrumb 873 ShouldNotReachHere(); 874 } break; 875 } 876 } // end copy_entry_to() 877 878 879 // Search constant pool search_cp for an entry that matches this 880 // constant pool's entry at pattern_i. Returns the index of a 881 // matching entry or zero (0) if there is no matching entry. 882 int constantPoolOopDesc::find_matching_entry(int pattern_i, 883 constantPoolHandle search_cp, TRAPS) { 884 885 // index zero (0) is not used 886 for (int i = 1; i < search_cp->length(); i++) { 887 bool found = compare_entry_to(pattern_i, search_cp, i, CHECK_0); 888 if (found) { 889 return i; 890 } 891 } 892 893 return 0; // entry not found; return unused index zero (0) 894 } // end find_matching_entry() 895 896 897 #ifndef PRODUCT 898 899 const char* constantPoolOopDesc::printable_name_at(int which) { 900 901 constantTag tag = tag_at(which); 902 903 if (tag.is_unresolved_string() || tag.is_string()) { 904 return string_at_noresolve(which); 905 } else if (tag.is_klass() || tag.is_unresolved_klass()) { 906 return klass_name_at(which)->as_C_string(); 907 } else if (tag.is_symbol()) { 908 return symbol_at(which)->as_C_string(); 909 } 910 return ""; 911 } 912 913 #endif // PRODUCT 914 915 916 // JVMTI GetConstantPool support 917 918 // For temporary use until code is stable. 919 #define DBG(code) 920 921 static const char* WARN_MSG = "Must not be such entry!"; 922 923 static void print_cpool_bytes(jint cnt, u1 *bytes) { 924 jint size = 0; 925 u2 idx1, idx2; 926 927 for (jint idx = 1; idx < cnt; idx++) { 928 jint ent_size = 0; 929 u1 tag = *bytes++; 930 size++; // count tag 931 932 printf("const #%03d, tag: %02d ", idx, tag); 933 switch(tag) { 934 case JVM_CONSTANT_Invalid: { 935 printf("Invalid"); 936 break; 937 } 938 case JVM_CONSTANT_Unicode: { 939 printf("Unicode %s", WARN_MSG); 940 break; 941 } 942 case JVM_CONSTANT_Utf8: { 943 u2 len = Bytes::get_Java_u2(bytes); 944 char str[128]; 945 if (len > 127) { 946 len = 127; 947 } 948 strncpy(str, (char *) (bytes+2), len); 949 str[len] = '\0'; 950 printf("Utf8 \"%s\"", str); 951 ent_size = 2 + len; 952 break; 953 } 954 case JVM_CONSTANT_Integer: { 955 u4 val = Bytes::get_Java_u4(bytes); 956 printf("int %d", *(int *) &val); 957 ent_size = 4; 958 break; 959 } 960 case JVM_CONSTANT_Float: { 961 u4 val = Bytes::get_Java_u4(bytes); 962 printf("float %5.3ff", *(float *) &val); 963 ent_size = 4; 964 break; 965 } 966 case JVM_CONSTANT_Long: { 967 u8 val = Bytes::get_Java_u8(bytes); 968 printf("long "INT64_FORMAT, *(jlong *) &val); 969 ent_size = 8; 970 idx++; // Long takes two cpool slots 971 break; 972 } 973 case JVM_CONSTANT_Double: { 974 u8 val = Bytes::get_Java_u8(bytes); 975 printf("double %5.3fd", *(jdouble *)&val); 976 ent_size = 8; 977 idx++; // Double takes two cpool slots 978 break; 979 } 980 case JVM_CONSTANT_Class: { 981 idx1 = Bytes::get_Java_u2(bytes); 982 printf("class #%03d", idx1); 983 ent_size = 2; 984 break; 985 } 986 case JVM_CONSTANT_String: { 987 idx1 = Bytes::get_Java_u2(bytes); 988 printf("String #%03d", idx1); 989 ent_size = 2; 990 break; 991 } 992 case JVM_CONSTANT_Fieldref: { 993 idx1 = Bytes::get_Java_u2(bytes); 994 idx2 = Bytes::get_Java_u2(bytes+2); 995 printf("Field #%03d, #%03d", (int) idx1, (int) idx2); 996 ent_size = 4; 997 break; 998 } 999 case JVM_CONSTANT_Methodref: { 1000 idx1 = Bytes::get_Java_u2(bytes); 1001 idx2 = Bytes::get_Java_u2(bytes+2); 1002 printf("Method #%03d, #%03d", idx1, idx2); 1003 ent_size = 4; 1004 break; 1005 } 1006 case JVM_CONSTANT_InterfaceMethodref: { 1007 idx1 = Bytes::get_Java_u2(bytes); 1008 idx2 = Bytes::get_Java_u2(bytes+2); 1009 printf("InterfMethod #%03d, #%03d", idx1, idx2); 1010 ent_size = 4; 1011 break; 1012 } 1013 case JVM_CONSTANT_NameAndType: { 1014 idx1 = Bytes::get_Java_u2(bytes); 1015 idx2 = Bytes::get_Java_u2(bytes+2); 1016 printf("NameAndType #%03d, #%03d", idx1, idx2); 1017 ent_size = 4; 1018 break; 1019 } 1020 case JVM_CONSTANT_ClassIndex: { 1021 printf("ClassIndex %s", WARN_MSG); 1022 break; 1023 } 1024 case JVM_CONSTANT_UnresolvedClass: { 1025 printf("UnresolvedClass: %s", WARN_MSG); 1026 break; 1027 } 1028 case JVM_CONSTANT_UnresolvedClassInError: { 1029 printf("UnresolvedClassInErr: %s", WARN_MSG); 1030 break; 1031 } 1032 case JVM_CONSTANT_StringIndex: { 1033 printf("StringIndex: %s", WARN_MSG); 1034 break; 1035 } 1036 case JVM_CONSTANT_UnresolvedString: { 1037 printf("UnresolvedString: %s", WARN_MSG); 1038 break; 1039 } 1040 } 1041 printf(";\n"); 1042 bytes += ent_size; 1043 size += ent_size; 1044 } 1045 printf("Cpool size: %d\n", size); 1046 fflush(0); 1047 return; 1048 } /* end print_cpool_bytes */ 1049 1050 1051 // Returns size of constant pool entry. 1052 jint constantPoolOopDesc::cpool_entry_size(jint idx) { 1053 switch(tag_at(idx).value()) { 1054 case JVM_CONSTANT_Invalid: 1055 case JVM_CONSTANT_Unicode: 1056 return 1; 1057 1058 case JVM_CONSTANT_Utf8: 1059 return 3 + symbol_at(idx)->utf8_length(); 1060 1061 case JVM_CONSTANT_Class: 1062 case JVM_CONSTANT_String: 1063 case JVM_CONSTANT_ClassIndex: 1064 case JVM_CONSTANT_UnresolvedClass: 1065 case JVM_CONSTANT_UnresolvedClassInError: 1066 case JVM_CONSTANT_StringIndex: 1067 case JVM_CONSTANT_UnresolvedString: 1068 return 3; 1069 1070 case JVM_CONSTANT_Integer: 1071 case JVM_CONSTANT_Float: 1072 case JVM_CONSTANT_Fieldref: 1073 case JVM_CONSTANT_Methodref: 1074 case JVM_CONSTANT_InterfaceMethodref: 1075 case JVM_CONSTANT_NameAndType: 1076 return 5; 1077 1078 case JVM_CONSTANT_Long: 1079 case JVM_CONSTANT_Double: 1080 return 9; 1081 } 1082 assert(false, "cpool_entry_size: Invalid constant pool entry tag"); 1083 return 1; 1084 } /* end cpool_entry_size */ 1085 1086 1087 // SymbolHashMap is used to find a constant pool index from a string. 1088 // This function fills in SymbolHashMaps, one for utf8s and one for 1089 // class names, returns size of the cpool raw bytes. 1090 jint constantPoolOopDesc::hash_entries_to(SymbolHashMap *symmap, 1091 SymbolHashMap *classmap) { 1092 jint size = 0; 1093 1094 for (u2 idx = 1; idx < length(); idx++) { 1095 u2 tag = tag_at(idx).value(); 1096 size += cpool_entry_size(idx); 1097 1098 switch(tag) { 1099 case JVM_CONSTANT_Utf8: { 1100 symbolOop sym = symbol_at(idx); 1101 symmap->add_entry(sym, idx); 1102 DBG(printf("adding symbol entry %s = %d\n", sym->as_utf8(), idx)); 1103 break; 1104 } 1105 case JVM_CONSTANT_Class: 1106 case JVM_CONSTANT_UnresolvedClass: 1107 case JVM_CONSTANT_UnresolvedClassInError: { 1108 symbolOop sym = klass_name_at(idx); 1109 classmap->add_entry(sym, idx); 1110 DBG(printf("adding class entry %s = %d\n", sym->as_utf8(), idx)); 1111 break; 1112 } 1113 case JVM_CONSTANT_Long: 1114 case JVM_CONSTANT_Double: { 1115 idx++; // Both Long and Double take two cpool slots 1116 break; 1117 } 1118 } 1119 } 1120 return size; 1121 } /* end hash_utf8_entries_to */ 1122 1123 1124 // Copy cpool bytes. 1125 // Returns: 1126 // 0, in case of OutOfMemoryError 1127 // -1, in case of internal error 1128 // > 0, count of the raw cpool bytes that have been copied 1129 int constantPoolOopDesc::copy_cpool_bytes(int cpool_size, 1130 SymbolHashMap* tbl, 1131 unsigned char *bytes) { 1132 u2 idx1, idx2; 1133 jint size = 0; 1134 jint cnt = length(); 1135 unsigned char *start_bytes = bytes; 1136 1137 for (jint idx = 1; idx < cnt; idx++) { 1138 u1 tag = tag_at(idx).value(); 1139 jint ent_size = cpool_entry_size(idx); 1140 1141 assert(size + ent_size <= cpool_size, "Size mismatch"); 1142 1143 *bytes = tag; 1144 DBG(printf("#%03hd tag=%03hd, ", idx, tag)); 1145 switch(tag) { 1146 case JVM_CONSTANT_Invalid: { 1147 DBG(printf("JVM_CONSTANT_Invalid")); 1148 break; 1149 } 1150 case JVM_CONSTANT_Unicode: { 1151 assert(false, "Wrong constant pool tag: JVM_CONSTANT_Unicode"); 1152 DBG(printf("JVM_CONSTANT_Unicode")); 1153 break; 1154 } 1155 case JVM_CONSTANT_Utf8: { 1156 symbolOop sym = symbol_at(idx); 1157 char* str = sym->as_utf8(); 1158 // Warning! It's crashing on x86 with len = sym->utf8_length() 1159 int len = (int) strlen(str); 1160 Bytes::put_Java_u2((address) (bytes+1), (u2) len); 1161 for (int i = 0; i < len; i++) { 1162 bytes[3+i] = (u1) str[i]; 1163 } 1164 DBG(printf("JVM_CONSTANT_Utf8: %s ", str)); 1165 break; 1166 } 1167 case JVM_CONSTANT_Integer: { 1168 jint val = int_at(idx); 1169 Bytes::put_Java_u4((address) (bytes+1), *(u4*)&val); 1170 break; 1171 } 1172 case JVM_CONSTANT_Float: { 1173 jfloat val = float_at(idx); 1174 Bytes::put_Java_u4((address) (bytes+1), *(u4*)&val); 1175 break; 1176 } 1177 case JVM_CONSTANT_Long: { 1178 jlong val = long_at(idx); 1179 Bytes::put_Java_u8((address) (bytes+1), *(u8*)&val); 1180 idx++; // Long takes two cpool slots 1181 break; 1182 } 1183 case JVM_CONSTANT_Double: { 1184 jdouble val = double_at(idx); 1185 Bytes::put_Java_u8((address) (bytes+1), *(u8*)&val); 1186 idx++; // Double takes two cpool slots 1187 break; 1188 } 1189 case JVM_CONSTANT_Class: 1190 case JVM_CONSTANT_UnresolvedClass: 1191 case JVM_CONSTANT_UnresolvedClassInError: { 1192 *bytes = JVM_CONSTANT_Class; 1193 symbolOop sym = klass_name_at(idx); 1194 idx1 = tbl->symbol_to_value(sym); 1195 assert(idx1 != 0, "Have not found a hashtable entry"); 1196 Bytes::put_Java_u2((address) (bytes+1), idx1); 1197 DBG(printf("JVM_CONSTANT_Class: idx=#%03hd, %s", idx1, sym->as_utf8())); 1198 break; 1199 } 1200 case JVM_CONSTANT_String: { 1201 unsigned int hash; 1202 char *str = string_at_noresolve(idx); 1203 symbolOop sym = SymbolTable::lookup_only(str, (int) strlen(str), hash); 1204 idx1 = tbl->symbol_to_value(sym); 1205 assert(idx1 != 0, "Have not found a hashtable entry"); 1206 Bytes::put_Java_u2((address) (bytes+1), idx1); 1207 DBG(printf("JVM_CONSTANT_String: idx=#%03hd, %s", idx1, str)); 1208 break; 1209 } 1210 case JVM_CONSTANT_UnresolvedString: { 1211 *bytes = JVM_CONSTANT_String; 1212 symbolOop sym = unresolved_string_at(idx); 1213 idx1 = tbl->symbol_to_value(sym); 1214 assert(idx1 != 0, "Have not found a hashtable entry"); 1215 Bytes::put_Java_u2((address) (bytes+1), idx1); 1216 DBG(char *str = sym->as_utf8()); 1217 DBG(printf("JVM_CONSTANT_UnresolvedString: idx=#%03hd, %s", idx1, str)); 1218 break; 1219 } 1220 case JVM_CONSTANT_Fieldref: 1221 case JVM_CONSTANT_Methodref: 1222 case JVM_CONSTANT_InterfaceMethodref: { 1223 idx1 = uncached_klass_ref_index_at(idx); 1224 idx2 = uncached_name_and_type_ref_index_at(idx); 1225 Bytes::put_Java_u2((address) (bytes+1), idx1); 1226 Bytes::put_Java_u2((address) (bytes+3), idx2); 1227 DBG(printf("JVM_CONSTANT_Methodref: %hd %hd", idx1, idx2)); 1228 break; 1229 } 1230 case JVM_CONSTANT_NameAndType: { 1231 idx1 = name_ref_index_at(idx); 1232 idx2 = signature_ref_index_at(idx); 1233 Bytes::put_Java_u2((address) (bytes+1), idx1); 1234 Bytes::put_Java_u2((address) (bytes+3), idx2); 1235 DBG(printf("JVM_CONSTANT_NameAndType: %hd %hd", idx1, idx2)); 1236 break; 1237 } 1238 case JVM_CONSTANT_ClassIndex: { 1239 *bytes = JVM_CONSTANT_Class; 1240 idx1 = klass_index_at(idx); 1241 Bytes::put_Java_u2((address) (bytes+1), idx1); 1242 DBG(printf("JVM_CONSTANT_ClassIndex: %hd", idx1)); 1243 break; 1244 } 1245 case JVM_CONSTANT_StringIndex: { 1246 *bytes = JVM_CONSTANT_String; 1247 idx1 = string_index_at(idx); 1248 Bytes::put_Java_u2((address) (bytes+1), idx1); 1249 DBG(printf("JVM_CONSTANT_StringIndex: %hd", idx1)); 1250 break; 1251 } 1252 } 1253 DBG(printf("\n")); 1254 bytes += ent_size; 1255 size += ent_size; 1256 } 1257 assert(size == cpool_size, "Size mismatch"); 1258 1259 // Keep temorarily for debugging until it's stable. 1260 DBG(print_cpool_bytes(cnt, start_bytes)); 1261 return (int)(bytes - start_bytes); 1262 } /* end copy_cpool_bytes */ 1263 1264 1265 void SymbolHashMap::add_entry(symbolOop sym, u2 value) { 1266 char *str = sym->as_utf8(); 1267 unsigned int hash = compute_hash(str, sym->utf8_length()); 1268 unsigned int index = hash % table_size(); 1269 1270 // check if already in map 1271 // we prefer the first entry since it is more likely to be what was used in 1272 // the class file 1273 for (SymbolHashMapEntry *en = bucket(index); en != NULL; en = en->next()) { 1274 assert(en->symbol() != NULL, "SymbolHashMapEntry symbol is NULL"); 1275 if (en->hash() == hash && en->symbol() == sym) { 1276 return; // already there 1277 } 1278 } 1279 1280 SymbolHashMapEntry* entry = new SymbolHashMapEntry(hash, sym, value); 1281 entry->set_next(bucket(index)); 1282 _buckets[index].set_entry(entry); 1283 assert(entry->symbol() != NULL, "SymbolHashMapEntry symbol is NULL"); 1284 } 1285 1286 SymbolHashMapEntry* SymbolHashMap::find_entry(symbolOop sym) { 1287 assert(sym != NULL, "SymbolHashMap::find_entry - symbol is NULL"); 1288 char *str = sym->as_utf8(); 1289 int len = sym->utf8_length(); 1290 unsigned int hash = SymbolHashMap::compute_hash(str, len); 1291 unsigned int index = hash % table_size(); 1292 for (SymbolHashMapEntry *en = bucket(index); en != NULL; en = en->next()) { 1293 assert(en->symbol() != NULL, "SymbolHashMapEntry symbol is NULL"); 1294 if (en->hash() == hash && en->symbol() == sym) { 1295 return en; 1296 } 1297 } 1298 return NULL; 1299 }