< prev index next >

src/hotspot/share/cds/aotMapLogger.cpp

Print this page

 519 #undef _LOG_PREFIX
 520 
 521 // Log all the data [base...top). Pretend that the base address
 522 // will be mapped to requested_base at run-time.
 523 void AOTMapLogger::log_as_hex(address base, address top, address requested_base, bool is_heap) {
 524   assert(top >= base, "must be");
 525 
 526   LogStreamHandle(Trace, aot, map) lsh;
 527   if (lsh.is_enabled()) {
 528     int unitsize = sizeof(address);
 529     if (is_heap && UseCompressedOops) {
 530       // This makes the compressed oop pointers easier to read, but
 531       // longs and doubles will be split into two words.
 532       unitsize = sizeof(narrowOop);
 533     }
 534     os::print_hex_dump(&lsh, base, top, unitsize, /* print_ascii=*/true, /* bytes_per_line=*/32, requested_base);
 535   }
 536 }
 537 
 538 #if INCLUDE_CDS_JAVA_HEAP
 539 // FakeOop (and subclasses FakeMirror, FakeString, FakeObjArray, FakeTypeArray) are used to traverse
 540 // and print the (image of) heap objects stored in the AOT cache. These objects are different than regular oops:
 541 // - They do not reside inside the range of the heap.
 542 // - For +UseCompressedOops: pointers may use a different narrowOop encoding: see FakeOop::read_oop_at(narrowOop*)
 543 // - For -UseCompressedOops: pointers are not direct: see FakeOop::read_oop_at(oop*)
 544 //
 545 // Hence, in general, we cannot use regular oop API (such as oopDesc::obj_field()) on these objects. There
 546 // are a few rare case where regular oop API work, but these are all guarded with the raw_oop() method and
 547 // should be used with care.
 548 //
 549 // Each AOT heap reader and writer has its own oop_iterator() API that retrieves all the data required to build
 550 // fake oops for logging.
 551 class AOTMapLogger::FakeOop {
 552   OopDataIterator* _iter;
 553   OopData _data;
 554 
 555   address* buffered_field_addr(int field_offset) {
 556     return (address*)(buffered_addr() + field_offset);
 557   }
 558 
 559 public:
 560   RequestedMetadataAddr metadata_field(int field_offset) {
 561     return RequestedMetadataAddr(*(address*)(buffered_field_addr(field_offset)));
 562   }
 563 
 564   address buffered_addr() {
 565     return _data._buffered_addr;
 566   }
 567 
 568   // Return an "oop" pointer so we can use APIs that accept regular oops. This
 569   // must be used with care, as only a limited number of APIs can work with oops that
 570   // live outside of the range of the heap.
 571   oop raw_oop() { return _data._raw_oop; }
 572 
 573   FakeOop() : _data() {}
 574   FakeOop(OopDataIterator* iter, OopData data) : _iter(iter), _data(data) {}
 575 
 576   FakeMirror as_mirror();
 577   FakeObjArray as_obj_array();

 578   FakeString as_string();
 579   FakeTypeArray as_type_array();
 580 
 581   RequestedMetadataAddr klass() {
 582     address rk = (address)real_klass();
 583     if (_is_runtime_logging) {
 584       return RequestedMetadataAddr(rk - _requested_to_mapped_metadata_delta);
 585     } else {
 586       ArchiveBuilder* builder = ArchiveBuilder::current();
 587       return builder->to_requested(builder->get_buffered_addr(rk));
 588     }
 589   }
 590 
 591   Klass* real_klass() {
 592     return _data._klass;
 593   }
 594 
 595   // in heap words
 596   size_t size() {
 597     return _data._size;

 644     fd->print_on_for(st, raw_oop());
 645   }
 646 }; // AOTMapLogger::FakeOop
 647 
 648 class AOTMapLogger::FakeMirror : public AOTMapLogger::FakeOop {
 649 public:
 650   FakeMirror(OopDataIterator* iter, OopData data) : FakeOop(iter, data) {}
 651 
 652   void print_class_signature_on(outputStream* st);
 653 
 654   Klass* real_mirrored_klass() {
 655     RequestedMetadataAddr mirrored_klass = metadata_field(java_lang_Class::klass_offset());
 656     return mirrored_klass.to_real_klass();
 657   }
 658 
 659   int static_oop_field_count() {
 660     return java_lang_Class::static_oop_field_count(raw_oop());
 661   }
 662 }; // AOTMapLogger::FakeMirror
 663 
 664 class AOTMapLogger::FakeObjArray : public AOTMapLogger::FakeOop {
 665   objArrayOop raw_objArrayOop() {
 666     return (objArrayOop)raw_oop();
 667   }
 668 
 669 public:
 670   FakeObjArray(OopDataIterator* iter, OopData data) : FakeOop(iter, data) {}
 671 
 672   int length() {
 673     return raw_objArrayOop()->length();
 674   }
 675   FakeOop obj_at(int i) {
 676     if (UseCompressedOops) {
 677       return read_oop_at(raw_objArrayOop()->obj_at_addr<narrowOop>(i));
 678     } else {
 679       return read_oop_at(raw_objArrayOop()->obj_at_addr<oop>(i));
 680     }
 681   }
 682 }; // AOTMapLogger::FakeObjArray

















 683 
 684 class AOTMapLogger::FakeString : public AOTMapLogger::FakeOop {
 685 public:
 686   FakeString(OopDataIterator* iter, OopData data) : FakeOop(iter, data) {}
 687 
 688   bool is_latin1() {
 689     jbyte coder = raw_oop()->byte_field(java_lang_String::coder_offset());
 690     assert(CompactStrings || coder == java_lang_String::CODER_UTF16, "Must be UTF16 without CompactStrings");
 691     return coder == java_lang_String::CODER_LATIN1;
 692   }
 693 
 694   FakeTypeArray value();
 695 
 696   int length();
 697   void print_on(outputStream* st, int max_length = MaxStringPrintSize);
 698 }; // AOTMapLogger::FakeString
 699 
 700 class AOTMapLogger::FakeTypeArray : public AOTMapLogger::FakeOop {
 701   typeArrayOop raw_typeArrayOop() {
 702     return (typeArrayOop)raw_oop();
 703   }
 704 
 705 public:
 706   FakeTypeArray(OopDataIterator* iter, OopData data) : FakeOop(iter, data) {}
 707 
 708   void print_elements_on(outputStream* st) {
 709     TypeArrayKlass::cast(real_klass())->oop_print_elements_on(raw_typeArrayOop(), st);
 710   }
 711 
 712   int length() { return raw_typeArrayOop()->length(); }
 713   jbyte byte_at(int i) { return raw_typeArrayOop()->byte_at(i); }
 714   jchar char_at(int i) { return raw_typeArrayOop()->char_at(i); }
 715 }; // AOTMapLogger::FakeTypeArray
 716 
 717 AOTMapLogger::FakeMirror AOTMapLogger::FakeOop::as_mirror() {
 718   precond(real_klass() == vmClasses::Class_klass());
 719   return FakeMirror(_iter, _data);
 720 }
 721 
 722 AOTMapLogger::FakeObjArray AOTMapLogger::FakeOop::as_obj_array() {
 723   precond(real_klass()->is_objArray_klass());
 724   return FakeObjArray(_iter, _data);





 725 }
 726 
 727 AOTMapLogger::FakeTypeArray AOTMapLogger::FakeOop::as_type_array() {
 728   precond(real_klass()->is_typeArray_klass());
 729   return FakeTypeArray(_iter, _data);
 730 }
 731 
 732 AOTMapLogger::FakeString AOTMapLogger::FakeOop::as_string() {
 733   precond(real_klass() == vmClasses::String_klass());
 734   return FakeString(_iter, _data);
 735 }
 736 
 737 void AOTMapLogger::FakeMirror::print_class_signature_on(outputStream* st) {
 738   ResourceMark rm;
 739   RequestedMetadataAddr requested_klass = metadata_field(java_lang_Class::klass_offset());
 740   Klass* real_klass = requested_klass.to_real_klass();
 741 
 742   if (real_klass == nullptr) {
 743     // This is a primitive mirror (Java expressions of int.class, long.class, void.class, etc);
 744     RequestedMetadataAddr requested_array_klass = metadata_field(java_lang_Class::array_klass_offset());

 949       } else if (real_klass == vmClasses::Class_klass()) {
 950         fake_oop.as_mirror().print_class_signature_on(st);
 951       }
 952 
 953       st->cr();
 954     }
 955   }
 956 }
 957 
 958 // Print the fields of instanceOops, or the elements of arrayOops
 959 void AOTMapLogger::print_oop_details(FakeOop fake_oop, outputStream* st) {
 960   Klass* real_klass = fake_oop.real_klass();
 961 
 962   st->print(" - klass: ");
 963   real_klass->print_value_on(st);
 964   st->print(" " PTR_FORMAT, p2i(fake_oop.klass().raw_addr()));
 965   st->cr();
 966 
 967   if (real_klass->is_typeArray_klass()) {
 968     fake_oop.as_type_array().print_elements_on(st);
 969   } else if (real_klass->is_objArray_klass()) {
 970     FakeObjArray fake_obj_array = fake_oop.as_obj_array();




 971     bool is_logging_root_segment = fake_oop.is_root_segment();
 972 
 973     for (int i = 0; i < fake_obj_array.length(); i++) {
 974       FakeOop elm = fake_obj_array.obj_at(i);
 975       if (is_logging_root_segment) {
 976         st->print(" root[%4d]: ", _roots->length());
 977         _roots->append(elm);
 978       } else {
 979         st->print(" -%4d: ", i);
 980       }
 981       print_oop_info_cr(st, elm);
 982     }
 983   } else {
 984     st->print_cr(" - fields (%zu words):", fake_oop.size());
 985 
 986     ArchivedFieldPrinter print_field(fake_oop, st);
 987     InstanceKlass::cast(real_klass)->print_nonstatic_fields(&print_field);
 988 
 989     if (real_klass == vmClasses::Class_klass()) {
 990       FakeMirror fake_mirror = fake_oop.as_mirror();

 519 #undef _LOG_PREFIX
 520 
 521 // Log all the data [base...top). Pretend that the base address
 522 // will be mapped to requested_base at run-time.
 523 void AOTMapLogger::log_as_hex(address base, address top, address requested_base, bool is_heap) {
 524   assert(top >= base, "must be");
 525 
 526   LogStreamHandle(Trace, aot, map) lsh;
 527   if (lsh.is_enabled()) {
 528     int unitsize = sizeof(address);
 529     if (is_heap && UseCompressedOops) {
 530       // This makes the compressed oop pointers easier to read, but
 531       // longs and doubles will be split into two words.
 532       unitsize = sizeof(narrowOop);
 533     }
 534     os::print_hex_dump(&lsh, base, top, unitsize, /* print_ascii=*/true, /* bytes_per_line=*/32, requested_base);
 535   }
 536 }
 537 
 538 #if INCLUDE_CDS_JAVA_HEAP
 539 // FakeOop (and subclasses FakeMirror, FakeString, FakeRefArray, FakeFlatArray, FakeTypeArray) are used to traverse
 540 // and print the (image of) heap objects stored in the AOT cache. These objects are different than regular oops:
 541 // - They do not reside inside the range of the heap.
 542 // - For +UseCompressedOops: pointers may use a different narrowOop encoding: see FakeOop::read_oop_at(narrowOop*)
 543 // - For -UseCompressedOops: pointers are not direct: see FakeOop::read_oop_at(oop*)
 544 //
 545 // Hence, in general, we cannot use regular oop API (such as oopDesc::obj_field()) on these objects. There
 546 // are a few rare case where regular oop API work, but these are all guarded with the raw_oop() method and
 547 // should be used with care.
 548 //
 549 // Each AOT heap reader and writer has its own oop_iterator() API that retrieves all the data required to build
 550 // fake oops for logging.
 551 class AOTMapLogger::FakeOop {
 552   OopDataIterator* _iter;
 553   OopData _data;
 554 
 555   address* buffered_field_addr(int field_offset) {
 556     return (address*)(buffered_addr() + field_offset);
 557   }
 558 
 559 public:
 560   RequestedMetadataAddr metadata_field(int field_offset) {
 561     return RequestedMetadataAddr(*(address*)(buffered_field_addr(field_offset)));
 562   }
 563 
 564   address buffered_addr() {
 565     return _data._buffered_addr;
 566   }
 567 
 568   // Return an "oop" pointer so we can use APIs that accept regular oops. This
 569   // must be used with care, as only a limited number of APIs can work with oops that
 570   // live outside of the range of the heap.
 571   oop raw_oop() { return _data._raw_oop; }
 572 
 573   FakeOop() : _data() {}
 574   FakeOop(OopDataIterator* iter, OopData data) : _iter(iter), _data(data) {}
 575 
 576   FakeMirror as_mirror();
 577   FakeRefArray as_ref_array();
 578   FakeFlatArray as_flat_array();
 579   FakeString as_string();
 580   FakeTypeArray as_type_array();
 581 
 582   RequestedMetadataAddr klass() {
 583     address rk = (address)real_klass();
 584     if (_is_runtime_logging) {
 585       return RequestedMetadataAddr(rk - _requested_to_mapped_metadata_delta);
 586     } else {
 587       ArchiveBuilder* builder = ArchiveBuilder::current();
 588       return builder->to_requested(builder->get_buffered_addr(rk));
 589     }
 590   }
 591 
 592   Klass* real_klass() {
 593     return _data._klass;
 594   }
 595 
 596   // in heap words
 597   size_t size() {
 598     return _data._size;

 645     fd->print_on_for(st, raw_oop());
 646   }
 647 }; // AOTMapLogger::FakeOop
 648 
 649 class AOTMapLogger::FakeMirror : public AOTMapLogger::FakeOop {
 650 public:
 651   FakeMirror(OopDataIterator* iter, OopData data) : FakeOop(iter, data) {}
 652 
 653   void print_class_signature_on(outputStream* st);
 654 
 655   Klass* real_mirrored_klass() {
 656     RequestedMetadataAddr mirrored_klass = metadata_field(java_lang_Class::klass_offset());
 657     return mirrored_klass.to_real_klass();
 658   }
 659 
 660   int static_oop_field_count() {
 661     return java_lang_Class::static_oop_field_count(raw_oop());
 662   }
 663 }; // AOTMapLogger::FakeMirror
 664 
 665 class AOTMapLogger::FakeRefArray : public AOTMapLogger::FakeOop {
 666   refArrayOop raw_refArrayOop() {
 667     return (refArrayOop)raw_oop();
 668   }
 669 
 670 public:
 671   FakeRefArray(OopDataIterator* iter, OopData data) : FakeOop(iter, data) {}
 672 
 673   int length() {
 674     return raw_refArrayOop()->length();
 675   }
 676   FakeOop obj_at(int i) {
 677     if (UseCompressedOops) {
 678       return read_oop_at(raw_refArrayOop()->obj_at_addr<narrowOop>(i));
 679     } else {
 680       return read_oop_at(raw_refArrayOop()->obj_at_addr<oop>(i));
 681     }
 682   }
 683 }; // AOTMapLogger::FakeRefArray
 684 
 685 class AOTMapLogger::FakeFlatArray : public AOTMapLogger::FakeOop {
 686   flatArrayOop raw_flatArrayOop() {
 687     return (flatArrayOop)raw_oop();
 688   }
 689 
 690 public:
 691   FakeFlatArray(OopDataIterator* iter, OopData data) : FakeOop(iter, data) {}
 692 
 693   int length() {
 694     return raw_flatArrayOop()->length();
 695   }
 696   void print_elements_on(outputStream* st) {
 697     FlatArrayKlass::cast(real_klass())->oop_print_elements_on(raw_flatArrayOop(), st);
 698   }
 699 
 700 }; // AOTMapLogger::FakeRefArray
 701 
 702 class AOTMapLogger::FakeString : public AOTMapLogger::FakeOop {
 703 public:
 704   FakeString(OopDataIterator* iter, OopData data) : FakeOop(iter, data) {}
 705 
 706   bool is_latin1() {
 707     jbyte coder = raw_oop()->byte_field(java_lang_String::coder_offset());
 708     assert(CompactStrings || coder == java_lang_String::CODER_UTF16, "Must be UTF16 without CompactStrings");
 709     return coder == java_lang_String::CODER_LATIN1;
 710   }
 711 
 712   FakeTypeArray value();
 713 
 714   int length();
 715   void print_on(outputStream* st, int max_length = MaxStringPrintSize);
 716 }; // AOTMapLogger::FakeString
 717 
 718 class AOTMapLogger::FakeTypeArray : public AOTMapLogger::FakeOop {
 719   typeArrayOop raw_typeArrayOop() {
 720     return (typeArrayOop)raw_oop();
 721   }
 722 
 723 public:
 724   FakeTypeArray(OopDataIterator* iter, OopData data) : FakeOop(iter, data) {}
 725 
 726   void print_elements_on(outputStream* st) {
 727     TypeArrayKlass::cast(real_klass())->oop_print_elements_on(raw_typeArrayOop(), st);
 728   }
 729 
 730   int length() { return raw_typeArrayOop()->length(); }
 731   jbyte byte_at(int i) { return raw_typeArrayOop()->byte_at(i); }
 732   jchar char_at(int i) { return raw_typeArrayOop()->char_at(i); }
 733 }; // AOTMapLogger::FakeTypeArray
 734 
 735 AOTMapLogger::FakeMirror AOTMapLogger::FakeOop::as_mirror() {
 736   precond(real_klass() == vmClasses::Class_klass());
 737   return FakeMirror(_iter, _data);
 738 }
 739 
 740 AOTMapLogger::FakeRefArray AOTMapLogger::FakeOop::as_ref_array() {
 741   precond(real_klass()->is_refArray_klass());
 742   return FakeRefArray(_iter, _data);
 743 }
 744 
 745 AOTMapLogger::FakeFlatArray AOTMapLogger::FakeOop::as_flat_array() {
 746   precond(real_klass()->is_flatArray_klass());
 747   return FakeFlatArray(_iter, _data);
 748 }
 749 
 750 AOTMapLogger::FakeTypeArray AOTMapLogger::FakeOop::as_type_array() {
 751   precond(real_klass()->is_typeArray_klass());
 752   return FakeTypeArray(_iter, _data);
 753 }
 754 
 755 AOTMapLogger::FakeString AOTMapLogger::FakeOop::as_string() {
 756   precond(real_klass() == vmClasses::String_klass());
 757   return FakeString(_iter, _data);
 758 }
 759 
 760 void AOTMapLogger::FakeMirror::print_class_signature_on(outputStream* st) {
 761   ResourceMark rm;
 762   RequestedMetadataAddr requested_klass = metadata_field(java_lang_Class::klass_offset());
 763   Klass* real_klass = requested_klass.to_real_klass();
 764 
 765   if (real_klass == nullptr) {
 766     // This is a primitive mirror (Java expressions of int.class, long.class, void.class, etc);
 767     RequestedMetadataAddr requested_array_klass = metadata_field(java_lang_Class::array_klass_offset());

 972       } else if (real_klass == vmClasses::Class_klass()) {
 973         fake_oop.as_mirror().print_class_signature_on(st);
 974       }
 975 
 976       st->cr();
 977     }
 978   }
 979 }
 980 
 981 // Print the fields of instanceOops, or the elements of arrayOops
 982 void AOTMapLogger::print_oop_details(FakeOop fake_oop, outputStream* st) {
 983   Klass* real_klass = fake_oop.real_klass();
 984 
 985   st->print(" - klass: ");
 986   real_klass->print_value_on(st);
 987   st->print(" " PTR_FORMAT, p2i(fake_oop.klass().raw_addr()));
 988   st->cr();
 989 
 990   if (real_klass->is_typeArray_klass()) {
 991     fake_oop.as_type_array().print_elements_on(st);
 992   } else if (real_klass->is_flatArray_klass()) {
 993     // Archiving FlatArrayOop with embedded oops is not supported.
 994     // TODO: add restriction.
 995     fake_oop.as_flat_array().print_elements_on(st);
 996   } else if (real_klass->is_refArray_klass()) {
 997     FakeRefArray fake_obj_array = fake_oop.as_ref_array();
 998     bool is_logging_root_segment = fake_oop.is_root_segment();
 999 
1000     for (int i = 0; i < fake_obj_array.length(); i++) {
1001       FakeOop elm = fake_obj_array.obj_at(i);
1002       if (is_logging_root_segment) {
1003         st->print(" root[%4d]: ", _roots->length());
1004         _roots->append(elm);
1005       } else {
1006         st->print(" -%4d: ", i);
1007       }
1008       print_oop_info_cr(st, elm);
1009     }
1010   } else {
1011     st->print_cr(" - fields (%zu words):", fake_oop.size());
1012 
1013     ArchivedFieldPrinter print_field(fake_oop, st);
1014     InstanceKlass::cast(real_klass)->print_nonstatic_fields(&print_field);
1015 
1016     if (real_klass == vmClasses::Class_klass()) {
1017       FakeMirror fake_mirror = fake_oop.as_mirror();
< prev index next >