1 /* 2 * Copyright (c) 1999, 2025, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 * 23 */ 24 25 #include "ci/ciField.hpp" 26 #include "ci/ciInstance.hpp" 27 #include "ci/ciInstanceKlass.hpp" 28 #include "ci/ciUtilities.inline.hpp" 29 #include "classfile/javaClasses.hpp" 30 #include "classfile/vmClasses.hpp" 31 #include "memory/allocation.hpp" 32 #include "memory/allocation.inline.hpp" 33 #include "memory/resourceArea.hpp" 34 #include "oops/instanceKlass.inline.hpp" 35 #include "oops/klass.inline.hpp" 36 #include "oops/oop.inline.hpp" 37 #include "oops/fieldStreams.inline.hpp" 38 #include "runtime/fieldDescriptor.inline.hpp" 39 #include "runtime/handles.inline.hpp" 40 #include "runtime/jniHandles.inline.hpp" 41 42 // ciInstanceKlass 43 // 44 // This class represents a Klass* in the HotSpot virtual machine 45 // whose Klass part in an InstanceKlass. 46 47 48 // ------------------------------------------------------------------ 49 // ciInstanceKlass::ciInstanceKlass 50 // 51 // Loaded instance klass. 52 ciInstanceKlass::ciInstanceKlass(Klass* k) : 53 ciKlass(k) 54 { 55 assert(get_Klass()->is_instance_klass(), "wrong type"); 56 assert(get_instanceKlass()->is_loaded(), "must be at least loaded"); 57 InstanceKlass* ik = get_instanceKlass(); 58 59 AccessFlags access_flags = ik->access_flags(); 60 _flags = ciFlags(access_flags); 61 _has_finalizer = ik->has_finalizer(); 62 _has_subklass = flags().is_final() ? subklass_false : subklass_unknown; 63 _init_state = ik->init_state(); 64 _has_nonstatic_fields = ik->has_nonstatic_fields(); 65 _has_nonstatic_concrete_methods = ik->has_nonstatic_concrete_methods(); 66 _is_hidden = ik->is_hidden(); 67 _is_record = ik->is_record(); 68 _nonstatic_fields = nullptr; // initialized lazily by compute_nonstatic_fields: 69 _has_injected_fields = -1; 70 _implementor = nullptr; // we will fill these lazily 71 _transitive_interfaces = nullptr; 72 73 // Ensure that the metadata wrapped by the ciMetadata is kept alive by GC. 74 // This is primarily useful for metadata which is considered as weak roots 75 // by the GC but need to be strong roots if reachable from a current compilation. 76 // InstanceKlass are created for both weak and strong metadata. Ensuring this metadata 77 // alive covers the cases where there are weak roots without performance cost. 78 oop holder = ik->klass_holder(); 79 if (ik->class_loader_data()->has_class_mirror_holder()) { 80 // Though ciInstanceKlass records class loader oop, it's not enough to keep 81 // non-strong hidden classes alive (loader == nullptr). Klass holder should 82 // be used instead. It is enough to record a ciObject, since cached elements are never removed 83 // during ciObjectFactory lifetime. ciObjectFactory itself is created for 84 // every compilation and lives for the whole duration of the compilation. 85 assert(holder != nullptr, "holder of hidden class is the mirror which is never null"); 86 (void)CURRENT_ENV->get_object(holder); 87 } 88 89 JavaThread *thread = JavaThread::current(); 90 if (ciObjectFactory::is_initialized()) { 91 _loader = JNIHandles::make_local(thread, ik->class_loader()); 92 _is_shared = false; 93 } else { 94 Handle h_loader(thread, ik->class_loader()); 95 _loader = JNIHandles::make_global(h_loader); 96 _is_shared = true; 97 } 98 99 _has_trusted_loader = compute_has_trusted_loader(); 100 101 // Lazy fields get filled in only upon request. 102 _super = nullptr; 103 _java_mirror = nullptr; 104 105 if (is_shared()) { 106 if (k != vmClasses::Object_klass()) { 107 super(); 108 } 109 //compute_nonstatic_fields(); // done outside of constructor 110 } 111 112 _field_cache = nullptr; 113 } 114 115 // Version for unloaded classes: 116 ciInstanceKlass::ciInstanceKlass(ciSymbol* name, 117 jobject loader) 118 : ciKlass(name, T_OBJECT) 119 { 120 assert(name->char_at(0) != JVM_SIGNATURE_ARRAY, "not an instance klass"); 121 _init_state = (InstanceKlass::ClassState)0; 122 _has_nonstatic_fields = false; 123 _nonstatic_fields = nullptr; 124 _has_injected_fields = -1; 125 _is_hidden = false; 126 _is_record = false; 127 _loader = loader; 128 _is_shared = false; 129 _super = nullptr; 130 _java_mirror = nullptr; 131 _field_cache = nullptr; 132 _has_trusted_loader = compute_has_trusted_loader(); 133 } 134 135 136 137 // ------------------------------------------------------------------ 138 // ciInstanceKlass::compute_shared_is_initialized 139 void ciInstanceKlass::compute_shared_init_state() { 140 GUARDED_VM_ENTRY( 141 InstanceKlass* ik = get_instanceKlass(); 142 _init_state = ik->init_state(); 143 ) 144 } 145 146 // ------------------------------------------------------------------ 147 // ciInstanceKlass::compute_shared_has_subklass 148 bool ciInstanceKlass::compute_shared_has_subklass() { 149 GUARDED_VM_ENTRY( 150 InstanceKlass* ik = get_instanceKlass(); 151 _has_subklass = ik->subklass() != nullptr ? subklass_true : subklass_false; 152 return _has_subklass == subklass_true; 153 ) 154 } 155 156 // ------------------------------------------------------------------ 157 // ciInstanceKlass::loader 158 oop ciInstanceKlass::loader() { 159 ASSERT_IN_VM; 160 return JNIHandles::resolve(_loader); 161 } 162 163 // ------------------------------------------------------------------ 164 // ciInstanceKlass::loader_handle 165 jobject ciInstanceKlass::loader_handle() { 166 return _loader; 167 } 168 169 // ------------------------------------------------------------------ 170 // ciInstanceKlass::field_cache 171 // 172 // Get the field cache associated with this klass. 173 ciConstantPoolCache* ciInstanceKlass::field_cache() { 174 if (is_shared()) { 175 return nullptr; 176 } 177 if (_field_cache == nullptr) { 178 assert(!is_java_lang_Object(), "Object has no fields"); 179 Arena* arena = CURRENT_ENV->arena(); 180 _field_cache = new (arena) ciConstantPoolCache(arena, 5); 181 } 182 return _field_cache; 183 } 184 185 // ------------------------------------------------------------------ 186 // ciInstanceKlass::get_canonical_holder 187 // 188 ciInstanceKlass* ciInstanceKlass::get_canonical_holder(int offset) { 189 #ifdef ASSERT 190 if (!(offset >= 0 && offset < layout_helper_size_in_bytes())) { 191 tty->print("*** get_canonical_holder(%d) on ", offset); 192 this->print(); 193 tty->print_cr(" ***"); 194 }; 195 assert(offset >= 0 && offset < layout_helper_size_in_bytes(), "offset must be tame"); 196 #endif 197 198 if (offset < instanceOopDesc::base_offset_in_bytes()) { 199 // All header offsets belong properly to java/lang/Object. 200 return CURRENT_ENV->Object_klass(); 201 } 202 203 ciInstanceKlass* self = this; 204 assert(self->is_loaded(), "must be loaded to access field info"); 205 ciField* field = self->get_field_by_offset(offset, false); 206 if (field != nullptr) { 207 return field->holder(); 208 } else { 209 for (;;) { 210 assert(self->is_loaded(), "must be loaded to have size"); 211 ciInstanceKlass* super = self->super(); 212 if (super == nullptr || 213 super->nof_nonstatic_fields() == 0 || 214 super->layout_helper_size_in_bytes() <= offset) { 215 return self; 216 } else { 217 self = super; // return super->get_canonical_holder(offset) 218 } 219 } 220 } 221 } 222 223 // ------------------------------------------------------------------ 224 // ciInstanceKlass::is_java_lang_Object 225 // 226 // Is this klass java.lang.Object? 227 bool ciInstanceKlass::is_java_lang_Object() const { 228 return equals(CURRENT_ENV->Object_klass()); 229 } 230 231 // ------------------------------------------------------------------ 232 // ciInstanceKlass::uses_default_loader 233 bool ciInstanceKlass::uses_default_loader() const { 234 // Note: We do not need to resolve the handle or enter the VM 235 // in order to test null-ness. 236 return _loader == nullptr; 237 } 238 239 // ------------------------------------------------------------------ 240 241 /** 242 * Return basic type of boxed value for box klass or T_OBJECT if not. 243 */ 244 BasicType ciInstanceKlass::box_klass_type() const { 245 if (uses_default_loader() && is_loaded()) { 246 return vmClasses::box_klass_type(get_Klass()); 247 } else { 248 return T_OBJECT; 249 } 250 } 251 252 /** 253 * Is this boxing klass? 254 */ 255 bool ciInstanceKlass::is_box_klass() const { 256 return is_java_primitive(box_klass_type()); 257 } 258 259 /** 260 * Is this boxed value offset? 261 */ 262 bool ciInstanceKlass::is_boxed_value_offset(int offset) const { 263 BasicType bt = box_klass_type(); 264 return is_java_primitive(bt) && 265 (offset == java_lang_boxing_object::value_offset(bt)); 266 } 267 268 // ------------------------------------------------------------------ 269 // ciInstanceKlass::is_in_package 270 // 271 // Is this klass in the given package? 272 bool ciInstanceKlass::is_in_package(const char* packagename, int len) { 273 // To avoid class loader mischief, this test always rejects application classes. 274 if (!uses_default_loader()) 275 return false; 276 GUARDED_VM_ENTRY( 277 return is_in_package_impl(packagename, len); 278 ) 279 } 280 281 bool ciInstanceKlass::is_in_package_impl(const char* packagename, int len) { 282 ASSERT_IN_VM; 283 284 // If packagename contains trailing '/' exclude it from the 285 // prefix-test since we test for it explicitly. 286 if (packagename[len - 1] == '/') 287 len--; 288 289 if (!name()->starts_with(packagename, len)) 290 return false; 291 292 // Test if the class name is something like "java/lang". 293 if ((len + 1) > name()->utf8_length()) 294 return false; 295 296 // Test for trailing '/' 297 if (name()->char_at(len) != '/') 298 return false; 299 300 // Make sure it's not actually in a subpackage: 301 if (name()->index_of_at(len+1, "/", 1) >= 0) 302 return false; 303 304 return true; 305 } 306 307 // ------------------------------------------------------------------ 308 // ciInstanceKlass::print_impl 309 // 310 // Implementation of the print method. 311 void ciInstanceKlass::print_impl(outputStream* st) { 312 ciKlass::print_impl(st); 313 GUARDED_VM_ENTRY(st->print(" loader=" INTPTR_FORMAT, p2i(loader()));) 314 if (is_loaded()) { 315 st->print(" initialized=%s finalized=%s subklass=%s size=%d flags=", 316 bool_to_str(is_initialized()), 317 bool_to_str(has_finalizer()), 318 bool_to_str(has_subklass()), 319 layout_helper()); 320 321 _flags.print_klass_flags(); 322 323 if (_super) { 324 st->print(" super="); 325 _super->print_name(); 326 } 327 if (_java_mirror) { 328 st->print(" mirror=PRESENT"); 329 } 330 } 331 } 332 333 // ------------------------------------------------------------------ 334 // ciInstanceKlass::super 335 // 336 // Get the superklass of this klass. 337 ciInstanceKlass* ciInstanceKlass::super() { 338 assert(is_loaded(), "must be loaded"); 339 if (_super == nullptr && !is_java_lang_Object()) { 340 GUARDED_VM_ENTRY( 341 Klass* super_klass = get_instanceKlass()->super(); 342 _super = CURRENT_ENV->get_instance_klass(super_klass); 343 ) 344 } 345 return _super; 346 } 347 348 // ------------------------------------------------------------------ 349 // ciInstanceKlass::java_mirror 350 // 351 // Get the instance of java.lang.Class corresponding to this klass. 352 // Cache it on this->_java_mirror. 353 ciInstance* ciInstanceKlass::java_mirror() { 354 if (is_shared()) { 355 return ciKlass::java_mirror(); 356 } 357 if (_java_mirror == nullptr) { 358 _java_mirror = ciKlass::java_mirror(); 359 } 360 return _java_mirror; 361 } 362 363 // ------------------------------------------------------------------ 364 // ciInstanceKlass::unique_concrete_subklass 365 ciInstanceKlass* ciInstanceKlass::unique_concrete_subklass() { 366 if (!is_loaded()) return nullptr; // No change if class is not loaded 367 if (!is_abstract()) return nullptr; // Only applies to abstract classes. 368 if (!has_subklass()) return nullptr; // Must have at least one subklass. 369 VM_ENTRY_MARK; 370 InstanceKlass* ik = get_instanceKlass(); 371 Klass* up = ik->up_cast_abstract(); 372 assert(up->is_instance_klass(), "must be InstanceKlass"); 373 if (ik == up) { 374 return nullptr; 375 } 376 return CURRENT_THREAD_ENV->get_instance_klass(up); 377 } 378 379 // ------------------------------------------------------------------ 380 // ciInstanceKlass::has_finalizable_subclass 381 bool ciInstanceKlass::has_finalizable_subclass() { 382 if (!is_loaded()) return true; 383 VM_ENTRY_MARK; 384 return Dependencies::find_finalizable_subclass(get_instanceKlass()) != nullptr; 385 } 386 387 // ------------------------------------------------------------------ 388 // ciInstanceKlass::contains_field_offset 389 bool ciInstanceKlass::contains_field_offset(int offset) { 390 VM_ENTRY_MARK; 391 return get_instanceKlass()->contains_field_offset(offset); 392 } 393 394 // ------------------------------------------------------------------ 395 // ciInstanceKlass::get_field_by_offset 396 ciField* ciInstanceKlass::get_field_by_offset(int field_offset, bool is_static) { 397 if (!is_static) { 398 for (int i = 0, len = nof_nonstatic_fields(); i < len; i++) { 399 ciField* field = _nonstatic_fields->at(i); 400 int field_off = field->offset_in_bytes(); 401 if (field_off == field_offset) 402 return field; 403 if (field_off > field_offset) 404 break; 405 // could do binary search or check bins, but probably not worth it 406 } 407 return nullptr; 408 } 409 VM_ENTRY_MARK; 410 InstanceKlass* k = get_instanceKlass(); 411 fieldDescriptor fd; 412 if (!k->find_field_from_offset(field_offset, is_static, &fd)) { 413 return nullptr; 414 } 415 ciField* field = new (CURRENT_THREAD_ENV->arena()) ciField(&fd); 416 return field; 417 } 418 419 // ------------------------------------------------------------------ 420 // ciInstanceKlass::get_field_by_name 421 ciField* ciInstanceKlass::get_field_by_name(ciSymbol* name, ciSymbol* signature, bool is_static) { 422 VM_ENTRY_MARK; 423 InstanceKlass* k = get_instanceKlass(); 424 fieldDescriptor fd; 425 Klass* def = k->find_field(name->get_symbol(), signature->get_symbol(), is_static, &fd); 426 if (def == nullptr) { 427 return nullptr; 428 } 429 ciField* field = new (CURRENT_THREAD_ENV->arena()) ciField(&fd); 430 return field; 431 } 432 433 434 static int sort_field_by_offset(ciField** a, ciField** b) { 435 return (*a)->offset_in_bytes() - (*b)->offset_in_bytes(); 436 // (no worries about 32-bit overflow...) 437 } 438 439 // ------------------------------------------------------------------ 440 // ciInstanceKlass::compute_nonstatic_fields 441 int ciInstanceKlass::compute_nonstatic_fields() { 442 assert(is_loaded(), "must be loaded"); 443 444 if (_nonstatic_fields != nullptr) 445 return _nonstatic_fields->length(); 446 447 if (!has_nonstatic_fields()) { 448 Arena* arena = CURRENT_ENV->arena(); 449 _nonstatic_fields = new (arena) GrowableArray<ciField*>(arena, 0, 0, nullptr); 450 return 0; 451 } 452 assert(!is_java_lang_Object(), "bootstrap OK"); 453 454 ciInstanceKlass* super = this->super(); 455 GrowableArray<ciField*>* super_fields = nullptr; 456 if (super != nullptr && super->has_nonstatic_fields()) { 457 int super_flen = super->nof_nonstatic_fields(); 458 super_fields = super->_nonstatic_fields; 459 assert(super_flen == 0 || super_fields != nullptr, "first get nof_fields"); 460 } 461 462 GrowableArray<ciField*>* fields = nullptr; 463 GUARDED_VM_ENTRY({ 464 fields = compute_nonstatic_fields_impl(super_fields); 465 }); 466 467 if (fields == nullptr) { 468 // This can happen if this class (java.lang.Class) has invisible fields. 469 if (super_fields != nullptr) { 470 _nonstatic_fields = super_fields; 471 return super_fields->length(); 472 } else { 473 return 0; 474 } 475 } 476 477 int flen = fields->length(); 478 479 // Now sort them by offset, ascending. 480 // (In principle, they could mix with superclass fields.) 481 fields->sort(sort_field_by_offset); 482 _nonstatic_fields = fields; 483 return flen; 484 } 485 486 GrowableArray<ciField*>* 487 ciInstanceKlass::compute_nonstatic_fields_impl(GrowableArray<ciField*>* 488 super_fields) { 489 ASSERT_IN_VM; 490 Arena* arena = CURRENT_ENV->arena(); 491 int flen = 0; 492 GrowableArray<ciField*>* fields = nullptr; 493 InstanceKlass* k = get_instanceKlass(); 494 for (JavaFieldStream fs(k); !fs.done(); fs.next()) { 495 if (fs.access_flags().is_static()) continue; 496 flen += 1; 497 } 498 499 // allocate the array: 500 if (flen == 0) { 501 return nullptr; // return nothing if none are locally declared 502 } 503 if (super_fields != nullptr) { 504 flen += super_fields->length(); 505 } 506 fields = new (arena) GrowableArray<ciField*>(arena, flen, 0, nullptr); 507 if (super_fields != nullptr) { 508 fields->appendAll(super_fields); 509 } 510 511 for (JavaFieldStream fs(k); !fs.done(); fs.next()) { 512 if (fs.access_flags().is_static()) continue; 513 fieldDescriptor& fd = fs.field_descriptor(); 514 ciField* field = new (arena) ciField(&fd); 515 fields->append(field); 516 } 517 assert(fields->length() == flen, "sanity"); 518 return fields; 519 } 520 521 bool ciInstanceKlass::compute_injected_fields_helper() { 522 ASSERT_IN_VM; 523 InstanceKlass* k = get_instanceKlass(); 524 525 for (InternalFieldStream fs(k); !fs.done(); fs.next()) { 526 if (fs.access_flags().is_static()) continue; 527 return true; 528 } 529 return false; 530 } 531 532 void ciInstanceKlass::compute_injected_fields() { 533 assert(is_loaded(), "must be loaded"); 534 535 int has_injected_fields = 0; 536 if (super() != nullptr && super()->has_injected_fields()) { 537 has_injected_fields = 1; 538 } else { 539 GUARDED_VM_ENTRY({ 540 has_injected_fields = compute_injected_fields_helper() ? 1 : 0; 541 }); 542 } 543 // may be concurrently initialized for shared ciInstanceKlass objects 544 assert(_has_injected_fields == -1 || _has_injected_fields == has_injected_fields, "broken concurrent initialization"); 545 _has_injected_fields = has_injected_fields; 546 } 547 548 bool ciInstanceKlass::has_object_fields() const { 549 GUARDED_VM_ENTRY( 550 return get_instanceKlass()->nonstatic_oop_map_size() > 0; 551 ); 552 } 553 554 bool ciInstanceKlass::compute_has_trusted_loader() { 555 ASSERT_IN_VM; 556 oop loader_oop = loader(); 557 if (loader_oop == nullptr) { 558 return true; // bootstrap class loader 559 } 560 return java_lang_ClassLoader::is_trusted_loader(loader_oop); 561 } 562 563 // ------------------------------------------------------------------ 564 // ciInstanceKlass::find_method 565 // 566 // Find a method in this klass. 567 ciMethod* ciInstanceKlass::find_method(ciSymbol* name, ciSymbol* signature) { 568 VM_ENTRY_MARK; 569 InstanceKlass* k = get_instanceKlass(); 570 Symbol* name_sym = name->get_symbol(); 571 Symbol* sig_sym= signature->get_symbol(); 572 573 Method* m = k->find_method(name_sym, sig_sym); 574 if (m == nullptr) return nullptr; 575 576 return CURRENT_THREAD_ENV->get_method(m); 577 } 578 579 // ------------------------------------------------------------------ 580 // ciInstanceKlass::is_leaf_type 581 bool ciInstanceKlass::is_leaf_type() { 582 assert(is_loaded(), "must be loaded"); 583 if (is_shared()) { 584 return is_final(); // approximately correct 585 } else { 586 return !has_subklass() && (nof_implementors() == 0); 587 } 588 } 589 590 // ------------------------------------------------------------------ 591 // ciInstanceKlass::implementor 592 // 593 // Report an implementor of this interface. 594 // Note that there are various races here, since my copy 595 // of _nof_implementors might be out of date with respect 596 // to results returned by InstanceKlass::implementor. 597 // This is OK, since any dependencies we decide to assert 598 // will be checked later under the Compile_lock. 599 ciInstanceKlass* ciInstanceKlass::implementor() { 600 ciInstanceKlass* impl = _implementor; 601 if (impl == nullptr) { 602 if (is_shared()) { 603 impl = this; // assume a well-known interface never has a unique implementor 604 } else { 605 // Go into the VM to fetch the implementor. 606 VM_ENTRY_MARK; 607 InstanceKlass* ik = get_instanceKlass(); 608 Klass* implk = ik->implementor(); 609 if (implk != nullptr) { 610 if (implk == ik) { 611 // More than one implementors. Use 'this' in this case. 612 impl = this; 613 } else { 614 impl = CURRENT_THREAD_ENV->get_instance_klass(implk); 615 } 616 } 617 } 618 // Memoize this result. 619 _implementor = impl; 620 } 621 return impl; 622 } 623 624 // Utility class for printing of the contents of the static fields for 625 // use by compilation replay. It only prints out the information that 626 // could be consumed by the compiler, so for primitive types it prints 627 // out the actual value. For Strings it's the actual string value. 628 // For array types it it's first level array size since that's the 629 // only value which statically unchangeable. For all other reference 630 // types it simply prints out the dynamic type. 631 632 class StaticFinalFieldPrinter : public FieldClosure { 633 outputStream* _out; 634 const char* _holder; 635 public: 636 StaticFinalFieldPrinter(outputStream* out, const char* holder) : 637 _out(out), 638 _holder(holder) { 639 } 640 void do_field(fieldDescriptor* fd) { 641 if (fd->is_final() && !fd->has_initial_value()) { 642 ResourceMark rm; 643 oop mirror = fd->field_holder()->java_mirror(); 644 _out->print("staticfield %s %s %s ", _holder, fd->name()->as_quoted_ascii(), fd->signature()->as_quoted_ascii()); 645 BasicType field_type = fd->field_type(); 646 switch (field_type) { 647 case T_BYTE: _out->print_cr("%d", mirror->byte_field(fd->offset())); break; 648 case T_BOOLEAN: _out->print_cr("%d", mirror->bool_field(fd->offset())); break; 649 case T_SHORT: _out->print_cr("%d", mirror->short_field(fd->offset())); break; 650 case T_CHAR: _out->print_cr("%d", mirror->char_field(fd->offset())); break; 651 case T_INT: _out->print_cr("%d", mirror->int_field(fd->offset())); break; 652 case T_LONG: _out->print_cr(INT64_FORMAT, (int64_t)(mirror->long_field(fd->offset()))); break; 653 case T_FLOAT: { 654 float f = mirror->float_field(fd->offset()); 655 _out->print_cr("%d", *(int*)&f); 656 break; 657 } 658 case T_DOUBLE: { 659 double d = mirror->double_field(fd->offset()); 660 _out->print_cr(INT64_FORMAT, *(int64_t*)&d); 661 break; 662 } 663 case T_ARRAY: // fall-through 664 case T_OBJECT: { 665 oop value = mirror->obj_field_acquire(fd->offset()); 666 if (value == nullptr) { 667 if (field_type == T_ARRAY) { 668 _out->print("%d", -1); 669 } 670 _out->cr(); 671 } else if (value->is_instance()) { 672 assert(field_type == T_OBJECT, ""); 673 if (value->is_a(vmClasses::String_klass())) { 674 const char* ascii_value = java_lang_String::as_quoted_ascii(value); 675 _out->print_cr("\"%s\"", (ascii_value != nullptr) ? ascii_value : ""); 676 } else { 677 const char* klass_name = value->klass()->name()->as_quoted_ascii(); 678 _out->print_cr("%s", klass_name); 679 } 680 } else if (value->is_array()) { 681 typeArrayOop ta = (typeArrayOop)value; 682 _out->print("%d", ta->length()); 683 if (value->is_objArray()) { 684 objArrayOop oa = (objArrayOop)value; 685 const char* klass_name = value->klass()->name()->as_quoted_ascii(); 686 _out->print(" %s", klass_name); 687 } 688 _out->cr(); 689 } else { 690 ShouldNotReachHere(); 691 } 692 break; 693 } 694 default: 695 ShouldNotReachHere(); 696 } 697 } 698 } 699 }; 700 701 const char *ciInstanceKlass::replay_name() const { 702 return CURRENT_ENV->replay_name(get_instanceKlass()); 703 } 704 705 void ciInstanceKlass::dump_replay_instanceKlass(outputStream* out, InstanceKlass* ik) { 706 if (ik->is_hidden()) { 707 const char *name = CURRENT_ENV->dyno_name(ik); 708 if (name != nullptr) { 709 out->print_cr("instanceKlass %s # %s", name, ik->name()->as_quoted_ascii()); 710 } else { 711 out->print_cr("# instanceKlass %s", ik->name()->as_quoted_ascii()); 712 } 713 } else { 714 out->print_cr("instanceKlass %s", ik->name()->as_quoted_ascii()); 715 } 716 } 717 718 GrowableArray<ciInstanceKlass*>* ciInstanceKlass::transitive_interfaces() const{ 719 if (_transitive_interfaces == nullptr) { 720 const_cast<ciInstanceKlass*>(this)->compute_transitive_interfaces(); 721 } 722 return _transitive_interfaces; 723 } 724 725 void ciInstanceKlass::compute_transitive_interfaces() { 726 GUARDED_VM_ENTRY( 727 InstanceKlass* ik = get_instanceKlass(); 728 Array<InstanceKlass*>* interfaces = ik->transitive_interfaces(); 729 int orig_length = interfaces->length(); 730 Arena* arena = CURRENT_ENV->arena(); 731 int transitive_interfaces_len = orig_length + (is_interface() ? 1 : 0); 732 GrowableArray<ciInstanceKlass*>* transitive_interfaces = new(arena)GrowableArray<ciInstanceKlass*>(arena, transitive_interfaces_len, 733 0, nullptr); 734 for (int i = 0; i < orig_length; i++) { 735 transitive_interfaces->append(CURRENT_ENV->get_instance_klass(interfaces->at(i))); 736 } 737 if (is_interface()) { 738 transitive_interfaces->append(this); 739 } 740 _transitive_interfaces = transitive_interfaces; 741 ); 742 } 743 744 void ciInstanceKlass::dump_replay_data(outputStream* out) { 745 ResourceMark rm; 746 747 InstanceKlass* ik = get_instanceKlass(); 748 ConstantPool* cp = ik->constants(); 749 750 // Try to record related loaded classes 751 Klass* sub = ik->subklass(); 752 while (sub != nullptr) { 753 if (sub->is_instance_klass()) { 754 InstanceKlass *isub = InstanceKlass::cast(sub); 755 dump_replay_instanceKlass(out, isub); 756 } 757 sub = sub->next_sibling(); 758 } 759 760 // Dump out the state of the constant pool tags. During replay the 761 // tags will be validated for things which shouldn't change and 762 // classes will be resolved if the tags indicate that they were 763 // resolved at compile time. 764 const char *name = replay_name(); 765 out->print("ciInstanceKlass %s %d %d %d", name, 766 is_linked(), is_initialized(), cp->length()); 767 for (int index = 1; index < cp->length(); index++) { 768 out->print(" %d", cp->tags()->at(index)); 769 } 770 out->cr(); 771 if (is_initialized()) { 772 // Dump out the static final fields in case the compilation relies 773 // on their value for correct replay. 774 StaticFinalFieldPrinter sffp(out, name); 775 ik->do_local_static_fields(&sffp); 776 } 777 } 778 779 #ifdef ASSERT 780 bool ciInstanceKlass::debug_final_field_at(int offset) { 781 GUARDED_VM_ENTRY( 782 InstanceKlass* ik = get_instanceKlass(); 783 fieldDescriptor fd; 784 if (ik->find_field_from_offset(offset, false, &fd)) { 785 return fd.is_final(); 786 } 787 ); 788 return false; 789 } 790 791 bool ciInstanceKlass::debug_stable_field_at(int offset) { 792 GUARDED_VM_ENTRY( 793 InstanceKlass* ik = get_instanceKlass(); 794 fieldDescriptor fd; 795 if (ik->find_field_from_offset(offset, false, &fd)) { 796 return fd.is_stable(); 797 } 798 ); 799 return false; 800 } 801 #endif