< prev index next >

src/hotspot/share/cds/aotMapLogger.cpp

Print this page

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

 566   FakeString as_string();
 567   FakeTypeArray as_type_array();
 568 
 569   RequestedMetadataAddr klass() {
 570     address rk = (address)real_klass();
 571     if (_is_runtime_logging) {
 572       return RequestedMetadataAddr(rk - _requested_to_mapped_metadata_delta);
 573     } else {
 574       ArchiveBuilder* builder = ArchiveBuilder::current();
 575       return builder->to_requested(builder->get_buffered_addr(rk));
 576     }
 577   }
 578 
 579   Klass* real_klass() {
 580     assert(UseCompressedClassPointers, "heap archiving requires UseCompressedClassPointers");
 581     return _data._klass;
 582   }
 583 
 584   // in heap words
 585   size_t size() {

 633     fd->print_on_for(st, raw_oop());
 634   }
 635 }; // AOTMapLogger::FakeOop
 636 
 637 class AOTMapLogger::FakeMirror : public AOTMapLogger::FakeOop {
 638 public:
 639   FakeMirror(OopDataIterator* iter, OopData data) : FakeOop(iter, data) {}
 640 
 641   void print_class_signature_on(outputStream* st);
 642 
 643   Klass* real_mirrored_klass() {
 644     RequestedMetadataAddr mirrored_klass = metadata_field(java_lang_Class::klass_offset());
 645     return mirrored_klass.to_real_klass();
 646   }
 647 
 648   int static_oop_field_count() {
 649     return java_lang_Class::static_oop_field_count(raw_oop());
 650   }
 651 }; // AOTMapLogger::FakeMirror
 652 
 653 class AOTMapLogger::FakeObjArray : public AOTMapLogger::FakeOop {
 654   objArrayOop raw_objArrayOop() {
 655     return (objArrayOop)raw_oop();
 656   }
 657 
 658 public:
 659   FakeObjArray(OopDataIterator* iter, OopData data) : FakeOop(iter, data) {}
 660 
 661   int length() {
 662     return raw_objArrayOop()->length();
 663   }
 664   FakeOop obj_at(int i) {
 665     if (UseCompressedOops) {
 666       return read_oop_at(raw_objArrayOop()->obj_at_addr<narrowOop>(i));
 667     } else {
 668       return read_oop_at(raw_objArrayOop()->obj_at_addr<oop>(i));
 669     }
 670   }
 671 }; // AOTMapLogger::FakeObjArray

















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





 714 }
 715 
 716 AOTMapLogger::FakeTypeArray AOTMapLogger::FakeOop::as_type_array() {
 717   precond(real_klass()->is_typeArray_klass());
 718   return FakeTypeArray(_iter, _data);
 719 }
 720 
 721 AOTMapLogger::FakeString AOTMapLogger::FakeOop::as_string() {
 722   precond(real_klass() == vmClasses::String_klass());
 723   return FakeString(_iter, _data);
 724 }
 725 
 726 void AOTMapLogger::FakeMirror::print_class_signature_on(outputStream* st) {
 727   ResourceMark rm;
 728   RequestedMetadataAddr requested_klass = metadata_field(java_lang_Class::klass_offset());
 729   Klass* real_klass = requested_klass.to_real_klass();
 730 
 731   if (real_klass == nullptr) {
 732     // This is a primitive mirror (Java expressions of int.class, long.class, void.class, etc);
 733     RequestedMetadataAddr requested_array_klass = metadata_field(java_lang_Class::array_klass_offset());

 938       } else if (real_klass == vmClasses::Class_klass()) {
 939         fake_oop.as_mirror().print_class_signature_on(st);
 940       }
 941 
 942       st->cr();
 943     }
 944   }
 945 }
 946 
 947 // Print the fields of instanceOops, or the elements of arrayOops
 948 void AOTMapLogger::print_oop_details(FakeOop fake_oop, outputStream* st) {
 949   Klass* real_klass = fake_oop.real_klass();
 950 
 951   st->print(" - klass: ");
 952   real_klass->print_value_on(st);
 953   st->print(" " PTR_FORMAT, p2i(fake_oop.klass().raw_addr()));
 954   st->cr();
 955 
 956   if (real_klass->is_typeArray_klass()) {
 957     fake_oop.as_type_array().print_elements_on(st);
 958   } else if (real_klass->is_objArray_klass()) {
 959     FakeObjArray fake_obj_array = fake_oop.as_obj_array();




 960     bool is_logging_root_segment = fake_oop.is_root_segment();
 961 
 962     for (int i = 0; i < fake_obj_array.length(); i++) {
 963       FakeOop elm = fake_obj_array.obj_at(i);
 964       if (is_logging_root_segment) {
 965         st->print(" root[%4d]: ", _roots->length());
 966         _roots->append(elm);
 967       } else {
 968         st->print(" -%4d: ", i);
 969       }
 970       print_oop_info_cr(st, elm);
 971     }
 972   } else {
 973     st->print_cr(" - fields (%zu words):", fake_oop.size());
 974 
 975     ArchivedFieldPrinter print_field(fake_oop, st);
 976     InstanceKlass::cast(real_klass)->print_nonstatic_fields(&print_field);
 977 
 978     if (real_klass == vmClasses::Class_klass()) {
 979       FakeMirror fake_mirror = fake_oop.as_mirror();

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

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

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