< prev index next >

src/hotspot/share/cds/aotMapLogger.cpp

Print this page

 475 #undef _LOG_PREFIX
 476 
 477 // Log all the data [base...top). Pretend that the base address
 478 // will be mapped to requested_base at run-time.
 479 void AOTMapLogger::log_as_hex(address base, address top, address requested_base, bool is_heap) {
 480   assert(top >= base, "must be");
 481 
 482   LogStreamHandle(Trace, aot, map) lsh;
 483   if (lsh.is_enabled()) {
 484     int unitsize = sizeof(address);
 485     if (is_heap && UseCompressedOops) {
 486       // This makes the compressed oop pointers easier to read, but
 487       // longs and doubles will be split into two words.
 488       unitsize = sizeof(narrowOop);
 489     }
 490     os::print_hex_dump(&lsh, base, top, unitsize, /* print_ascii=*/true, /* bytes_per_line=*/32, requested_base);
 491   }
 492 }
 493 
 494 #if INCLUDE_CDS_JAVA_HEAP
 495 // FakeOop (and subclasses FakeMirror, FakeString, FakeObjArray, FakeTypeArray) are used to traverse
 496 // and print the (image of) heap objects stored in the AOT cache. These objects are different than regular oops:
 497 // - They do not reside inside the range of the heap.
 498 // - For +UseCompressedOops: pointers may use a different narrowOop encoding: see FakeOop::read_oop_at(narrowOop*)
 499 // - For -UseCompressedOops: pointers are not direct: see FakeOop::read_oop_at(oop*)
 500 //
 501 // Hence, in general, we cannot use regular oop API (such as oopDesc::obj_field()) on these objects. There
 502 // are a few rare case where regular oop API work, but these are all guarded with the raw_oop() method and
 503 // should be used with care.
 504 //
 505 // Each AOT heap reader and writer has its own oop_iterator() API that retrieves all the data required to build
 506 // fake oops for logging.
 507 class AOTMapLogger::FakeOop {
 508   OopDataIterator* _iter;
 509   OopData _data;
 510 
 511   address* buffered_field_addr(int field_offset) {
 512     return (address*)(buffered_addr() + field_offset);
 513   }
 514 
 515 public:
 516   RequestedMetadataAddr metadata_field(int field_offset) {
 517     return RequestedMetadataAddr(*(address*)(buffered_field_addr(field_offset)));
 518   }
 519 
 520   address buffered_addr() {
 521     return _data._buffered_addr;
 522   }
 523 
 524   // Return an "oop" pointer so we can use APIs that accept regular oops. This
 525   // must be used with care, as only a limited number of APIs can work with oops that
 526   // live outside of the range of the heap.
 527   oop raw_oop() { return _data._raw_oop; }
 528 
 529   FakeOop() : _data() {}
 530   FakeOop(OopDataIterator* iter, OopData data) : _iter(iter), _data(data) {}
 531 
 532   FakeMirror as_mirror();
 533   FakeObjArray as_obj_array();

 534   FakeString as_string();
 535   FakeTypeArray as_type_array();
 536 
 537   RequestedMetadataAddr klass() {
 538     address rk = (address)real_klass();
 539     if (_is_runtime_logging) {
 540       return RequestedMetadataAddr(rk - _requested_to_mapped_metadata_delta);
 541     } else {
 542       ArchiveBuilder* builder = ArchiveBuilder::current();
 543       return builder->to_requested(builder->get_buffered_addr(rk));
 544     }
 545   }
 546 
 547   Klass* real_klass() {
 548     assert(UseCompressedClassPointers, "heap archiving requires UseCompressedClassPointers");
 549     return _data._klass;
 550   }
 551 
 552   // in heap words
 553   size_t size() {

 601     fd->print_on_for(st, raw_oop());
 602   }
 603 }; // AOTMapLogger::FakeOop
 604 
 605 class AOTMapLogger::FakeMirror : public AOTMapLogger::FakeOop {
 606 public:
 607   FakeMirror(OopDataIterator* iter, OopData data) : FakeOop(iter, data) {}
 608 
 609   void print_class_signature_on(outputStream* st);
 610 
 611   Klass* real_mirrored_klass() {
 612     RequestedMetadataAddr mirrored_klass = metadata_field(java_lang_Class::klass_offset());
 613     return mirrored_klass.to_real_klass();
 614   }
 615 
 616   int static_oop_field_count() {
 617     return java_lang_Class::static_oop_field_count(raw_oop());
 618   }
 619 }; // AOTMapLogger::FakeMirror
 620 
 621 class AOTMapLogger::FakeObjArray : public AOTMapLogger::FakeOop {
 622   objArrayOop raw_objArrayOop() {
 623     return (objArrayOop)raw_oop();
 624   }
 625 
 626 public:
 627   FakeObjArray(OopDataIterator* iter, OopData data) : FakeOop(iter, data) {}
 628 
 629   int length() {
 630     return raw_objArrayOop()->length();
 631   }
 632   FakeOop obj_at(int i) {
 633     if (UseCompressedOops) {
 634       return read_oop_at(raw_objArrayOop()->obj_at_addr<narrowOop>(i));
 635     } else {
 636       return read_oop_at(raw_objArrayOop()->obj_at_addr<oop>(i));
 637     }
 638   }
 639 }; // AOTMapLogger::FakeObjArray

















 640 
 641 class AOTMapLogger::FakeString : public AOTMapLogger::FakeOop {
 642 public:
 643   FakeString(OopDataIterator* iter, OopData data) : FakeOop(iter, data) {}
 644 
 645   bool is_latin1() {
 646     jbyte coder = raw_oop()->byte_field(java_lang_String::coder_offset());
 647     assert(CompactStrings || coder == java_lang_String::CODER_UTF16, "Must be UTF16 without CompactStrings");
 648     return coder == java_lang_String::CODER_LATIN1;
 649   }
 650 
 651   FakeTypeArray value();
 652 
 653   int length();
 654   void print_on(outputStream* st, int max_length = MaxStringPrintSize);
 655 }; // AOTMapLogger::FakeString
 656 
 657 class AOTMapLogger::FakeTypeArray : public AOTMapLogger::FakeOop {
 658   typeArrayOop raw_typeArrayOop() {
 659     return (typeArrayOop)raw_oop();
 660   }
 661 
 662 public:
 663   FakeTypeArray(OopDataIterator* iter, OopData data) : FakeOop(iter, data) {}
 664 
 665   void print_elements_on(outputStream* st) {
 666     TypeArrayKlass::cast(real_klass())->oop_print_elements_on(raw_typeArrayOop(), st);
 667   }
 668 
 669   int length() { return raw_typeArrayOop()->length(); }
 670   jbyte byte_at(int i) { return raw_typeArrayOop()->byte_at(i); }
 671   jchar char_at(int i) { return raw_typeArrayOop()->char_at(i); }
 672 }; // AOTMapLogger::FakeTypeArray
 673 
 674 AOTMapLogger::FakeMirror AOTMapLogger::FakeOop::as_mirror() {
 675   precond(real_klass() == vmClasses::Class_klass());
 676   return FakeMirror(_iter, _data);
 677 }
 678 
 679 AOTMapLogger::FakeObjArray AOTMapLogger::FakeOop::as_obj_array() {
 680   precond(real_klass()->is_objArray_klass());
 681   return FakeObjArray(_iter, _data);





 682 }
 683 
 684 AOTMapLogger::FakeTypeArray AOTMapLogger::FakeOop::as_type_array() {
 685   precond(real_klass()->is_typeArray_klass());
 686   return FakeTypeArray(_iter, _data);
 687 }
 688 
 689 AOTMapLogger::FakeString AOTMapLogger::FakeOop::as_string() {
 690   precond(real_klass() == vmClasses::String_klass());
 691   return FakeString(_iter, _data);
 692 }
 693 
 694 void AOTMapLogger::FakeMirror::print_class_signature_on(outputStream* st) {
 695   ResourceMark rm;
 696   RequestedMetadataAddr requested_klass = metadata_field(java_lang_Class::klass_offset());
 697   Klass* real_klass = requested_klass.to_real_klass();
 698 
 699   if (real_klass == nullptr) {
 700     // This is a primitive mirror (Java expressions of int.class, long.class, void.class, etc);
 701     RequestedMetadataAddr requested_array_klass = metadata_field(java_lang_Class::array_klass_offset());

 906       } else if (real_klass == vmClasses::Class_klass()) {
 907         fake_oop.as_mirror().print_class_signature_on(st);
 908       }
 909 
 910       st->cr();
 911     }
 912   }
 913 }
 914 
 915 // Print the fields of instanceOops, or the elements of arrayOops
 916 void AOTMapLogger::print_oop_details(FakeOop fake_oop, outputStream* st) {
 917   Klass* real_klass = fake_oop.real_klass();
 918 
 919   st->print(" - klass: ");
 920   real_klass->print_value_on(st);
 921   st->print(" " PTR_FORMAT, p2i(fake_oop.klass().raw_addr()));
 922   st->cr();
 923 
 924   if (real_klass->is_typeArray_klass()) {
 925     fake_oop.as_type_array().print_elements_on(st);
 926   } else if (real_klass->is_objArray_klass()) {
 927     FakeObjArray fake_obj_array = fake_oop.as_obj_array();




 928     bool is_logging_root_segment = fake_oop.is_root_segment();
 929 
 930     for (int i = 0; i < fake_obj_array.length(); i++) {
 931       FakeOop elm = fake_obj_array.obj_at(i);
 932       if (is_logging_root_segment) {
 933         st->print(" root[%4d]: ", _roots->length());
 934         _roots->append(elm);
 935       } else {
 936         st->print(" -%4d: ", i);
 937       }
 938       print_oop_info_cr(st, elm);
 939     }
 940   } else {
 941     st->print_cr(" - fields (%zu words):", fake_oop.size());
 942 
 943     ArchivedFieldPrinter print_field(fake_oop, st);
 944     InstanceKlass::cast(real_klass)->print_nonstatic_fields(&print_field);
 945 
 946     if (real_klass == vmClasses::Class_klass()) {
 947       FakeMirror fake_mirror = fake_oop.as_mirror();

 475 #undef _LOG_PREFIX
 476 
 477 // Log all the data [base...top). Pretend that the base address
 478 // will be mapped to requested_base at run-time.
 479 void AOTMapLogger::log_as_hex(address base, address top, address requested_base, bool is_heap) {
 480   assert(top >= base, "must be");
 481 
 482   LogStreamHandle(Trace, aot, map) lsh;
 483   if (lsh.is_enabled()) {
 484     int unitsize = sizeof(address);
 485     if (is_heap && UseCompressedOops) {
 486       // This makes the compressed oop pointers easier to read, but
 487       // longs and doubles will be split into two words.
 488       unitsize = sizeof(narrowOop);
 489     }
 490     os::print_hex_dump(&lsh, base, top, unitsize, /* print_ascii=*/true, /* bytes_per_line=*/32, requested_base);
 491   }
 492 }
 493 
 494 #if INCLUDE_CDS_JAVA_HEAP
 495 // FakeOop (and subclasses FakeMirror, FakeString, FakeRefArray, FakeFlatArray, FakeTypeArray) are used to traverse
 496 // and print the (image of) heap objects stored in the AOT cache. These objects are different than regular oops:
 497 // - They do not reside inside the range of the heap.
 498 // - For +UseCompressedOops: pointers may use a different narrowOop encoding: see FakeOop::read_oop_at(narrowOop*)
 499 // - For -UseCompressedOops: pointers are not direct: see FakeOop::read_oop_at(oop*)
 500 //
 501 // Hence, in general, we cannot use regular oop API (such as oopDesc::obj_field()) on these objects. There
 502 // are a few rare case where regular oop API work, but these are all guarded with the raw_oop() method and
 503 // should be used with care.
 504 //
 505 // Each AOT heap reader and writer has its own oop_iterator() API that retrieves all the data required to build
 506 // fake oops for logging.
 507 class AOTMapLogger::FakeOop {
 508   OopDataIterator* _iter;
 509   OopData _data;
 510 
 511   address* buffered_field_addr(int field_offset) {
 512     return (address*)(buffered_addr() + field_offset);
 513   }
 514 
 515 public:
 516   RequestedMetadataAddr metadata_field(int field_offset) {
 517     return RequestedMetadataAddr(*(address*)(buffered_field_addr(field_offset)));
 518   }
 519 
 520   address buffered_addr() {
 521     return _data._buffered_addr;
 522   }
 523 
 524   // Return an "oop" pointer so we can use APIs that accept regular oops. This
 525   // must be used with care, as only a limited number of APIs can work with oops that
 526   // live outside of the range of the heap.
 527   oop raw_oop() { return _data._raw_oop; }
 528 
 529   FakeOop() : _data() {}
 530   FakeOop(OopDataIterator* iter, OopData data) : _iter(iter), _data(data) {}
 531 
 532   FakeMirror as_mirror();
 533   FakeRefArray as_ref_array();
 534   FakeFlatArray as_flat_array();
 535   FakeString as_string();
 536   FakeTypeArray as_type_array();
 537 
 538   RequestedMetadataAddr klass() {
 539     address rk = (address)real_klass();
 540     if (_is_runtime_logging) {
 541       return RequestedMetadataAddr(rk - _requested_to_mapped_metadata_delta);
 542     } else {
 543       ArchiveBuilder* builder = ArchiveBuilder::current();
 544       return builder->to_requested(builder->get_buffered_addr(rk));
 545     }
 546   }
 547 
 548   Klass* real_klass() {
 549     assert(UseCompressedClassPointers, "heap archiving requires UseCompressedClassPointers");
 550     return _data._klass;
 551   }
 552 
 553   // in heap words
 554   size_t size() {

 602     fd->print_on_for(st, raw_oop());
 603   }
 604 }; // AOTMapLogger::FakeOop
 605 
 606 class AOTMapLogger::FakeMirror : public AOTMapLogger::FakeOop {
 607 public:
 608   FakeMirror(OopDataIterator* iter, OopData data) : FakeOop(iter, data) {}
 609 
 610   void print_class_signature_on(outputStream* st);
 611 
 612   Klass* real_mirrored_klass() {
 613     RequestedMetadataAddr mirrored_klass = metadata_field(java_lang_Class::klass_offset());
 614     return mirrored_klass.to_real_klass();
 615   }
 616 
 617   int static_oop_field_count() {
 618     return java_lang_Class::static_oop_field_count(raw_oop());
 619   }
 620 }; // AOTMapLogger::FakeMirror
 621 
 622 class AOTMapLogger::FakeRefArray : public AOTMapLogger::FakeOop {
 623   refArrayOop raw_refArrayOop() {
 624     return (refArrayOop)raw_oop();
 625   }
 626 
 627 public:
 628   FakeRefArray(OopDataIterator* iter, OopData data) : FakeOop(iter, data) {}
 629 
 630   int length() {
 631     return raw_refArrayOop()->length();
 632   }
 633   FakeOop obj_at(int i) {
 634     if (UseCompressedOops) {
 635       return read_oop_at(raw_refArrayOop()->obj_at_addr<narrowOop>(i));
 636     } else {
 637       return read_oop_at(raw_refArrayOop()->obj_at_addr<oop>(i));
 638     }
 639   }
 640 }; // AOTMapLogger::FakeRefArray
 641 
 642 class AOTMapLogger::FakeFlatArray : public AOTMapLogger::FakeOop {
 643   flatArrayOop raw_flatArrayOop() {
 644     return (flatArrayOop)raw_oop();
 645   }
 646 
 647 public:
 648   FakeFlatArray(OopDataIterator* iter, OopData data) : FakeOop(iter, data) {}
 649 
 650   int length() {
 651     return raw_flatArrayOop()->length();
 652   }
 653   void print_elements_on(outputStream* st) {
 654     FlatArrayKlass::cast(real_klass())->oop_print_elements_on(raw_flatArrayOop(), st);
 655   }
 656 
 657 }; // AOTMapLogger::FakeRefArray
 658 
 659 class AOTMapLogger::FakeString : public AOTMapLogger::FakeOop {
 660 public:
 661   FakeString(OopDataIterator* iter, OopData data) : FakeOop(iter, data) {}
 662 
 663   bool is_latin1() {
 664     jbyte coder = raw_oop()->byte_field(java_lang_String::coder_offset());
 665     assert(CompactStrings || coder == java_lang_String::CODER_UTF16, "Must be UTF16 without CompactStrings");
 666     return coder == java_lang_String::CODER_LATIN1;
 667   }
 668 
 669   FakeTypeArray value();
 670 
 671   int length();
 672   void print_on(outputStream* st, int max_length = MaxStringPrintSize);
 673 }; // AOTMapLogger::FakeString
 674 
 675 class AOTMapLogger::FakeTypeArray : public AOTMapLogger::FakeOop {
 676   typeArrayOop raw_typeArrayOop() {
 677     return (typeArrayOop)raw_oop();
 678   }
 679 
 680 public:
 681   FakeTypeArray(OopDataIterator* iter, OopData data) : FakeOop(iter, data) {}
 682 
 683   void print_elements_on(outputStream* st) {
 684     TypeArrayKlass::cast(real_klass())->oop_print_elements_on(raw_typeArrayOop(), st);
 685   }
 686 
 687   int length() { return raw_typeArrayOop()->length(); }
 688   jbyte byte_at(int i) { return raw_typeArrayOop()->byte_at(i); }
 689   jchar char_at(int i) { return raw_typeArrayOop()->char_at(i); }
 690 }; // AOTMapLogger::FakeTypeArray
 691 
 692 AOTMapLogger::FakeMirror AOTMapLogger::FakeOop::as_mirror() {
 693   precond(real_klass() == vmClasses::Class_klass());
 694   return FakeMirror(_iter, _data);
 695 }
 696 
 697 AOTMapLogger::FakeRefArray AOTMapLogger::FakeOop::as_ref_array() {
 698   precond(real_klass()->is_refArray_klass());
 699   return FakeRefArray(_iter, _data);
 700 }
 701 
 702 AOTMapLogger::FakeFlatArray AOTMapLogger::FakeOop::as_flat_array() {
 703   precond(real_klass()->is_flatArray_klass());
 704   return FakeFlatArray(_iter, _data);
 705 }
 706 
 707 AOTMapLogger::FakeTypeArray AOTMapLogger::FakeOop::as_type_array() {
 708   precond(real_klass()->is_typeArray_klass());
 709   return FakeTypeArray(_iter, _data);
 710 }
 711 
 712 AOTMapLogger::FakeString AOTMapLogger::FakeOop::as_string() {
 713   precond(real_klass() == vmClasses::String_klass());
 714   return FakeString(_iter, _data);
 715 }
 716 
 717 void AOTMapLogger::FakeMirror::print_class_signature_on(outputStream* st) {
 718   ResourceMark rm;
 719   RequestedMetadataAddr requested_klass = metadata_field(java_lang_Class::klass_offset());
 720   Klass* real_klass = requested_klass.to_real_klass();
 721 
 722   if (real_klass == nullptr) {
 723     // This is a primitive mirror (Java expressions of int.class, long.class, void.class, etc);
 724     RequestedMetadataAddr requested_array_klass = metadata_field(java_lang_Class::array_klass_offset());

 929       } else if (real_klass == vmClasses::Class_klass()) {
 930         fake_oop.as_mirror().print_class_signature_on(st);
 931       }
 932 
 933       st->cr();
 934     }
 935   }
 936 }
 937 
 938 // Print the fields of instanceOops, or the elements of arrayOops
 939 void AOTMapLogger::print_oop_details(FakeOop fake_oop, outputStream* st) {
 940   Klass* real_klass = fake_oop.real_klass();
 941 
 942   st->print(" - klass: ");
 943   real_klass->print_value_on(st);
 944   st->print(" " PTR_FORMAT, p2i(fake_oop.klass().raw_addr()));
 945   st->cr();
 946 
 947   if (real_klass->is_typeArray_klass()) {
 948     fake_oop.as_type_array().print_elements_on(st);
 949   } else if (real_klass->is_flatArray_klass()) {
 950     // Archiving FlatArrayOop with embedded oops is not supported.
 951     // TODO: add restriction.
 952     fake_oop.as_flat_array().print_elements_on(st);
 953   } else if (real_klass->is_refArray_klass()) {
 954     FakeRefArray fake_obj_array = fake_oop.as_ref_array();
 955     bool is_logging_root_segment = fake_oop.is_root_segment();
 956 
 957     for (int i = 0; i < fake_obj_array.length(); i++) {
 958       FakeOop elm = fake_obj_array.obj_at(i);
 959       if (is_logging_root_segment) {
 960         st->print(" root[%4d]: ", _roots->length());
 961         _roots->append(elm);
 962       } else {
 963         st->print(" -%4d: ", i);
 964       }
 965       print_oop_info_cr(st, elm);
 966     }
 967   } else {
 968     st->print_cr(" - fields (%zu words):", fake_oop.size());
 969 
 970     ArchivedFieldPrinter print_field(fake_oop, st);
 971     InstanceKlass::cast(real_klass)->print_nonstatic_fields(&print_field);
 972 
 973     if (real_klass == vmClasses::Class_klass()) {
 974       FakeMirror fake_mirror = fake_oop.as_mirror();
< prev index next >