< prev index next >

src/hotspot/share/oops/klass.cpp

Print this page
rev 58565 : 8238358: Implementation of JEP 371: Hidden Classes
Reviewed-by: duke
Contributed-by: mandy.chung@oracle.com, lois.foltan@oracle.com, david.holmes@oracle.com, harold.seigel@oracle.com, serguei.spitsyn@oracle.com, alex.buckley@oracle.com, jamsheed.c.m@oracle.com


 591     log_debug(cds, mirror)("%s has raw archived mirror", external_name());
 592     if (HeapShared::open_archive_heap_region_mapped()) {
 593       bool present = java_lang_Class::restore_archived_mirror(this, loader, module_handle,
 594                                                               protection_domain,
 595                                                               CHECK);
 596       if (present) {
 597         return;
 598       }
 599     }
 600 
 601     // No archived mirror data
 602     log_debug(cds, mirror)("No archived mirror data for %s", external_name());
 603     _java_mirror = NULL;
 604     this->clear_has_raw_archived_mirror();
 605   }
 606 
 607   // Only recreate it if not present.  A previous attempt to restore may have
 608   // gotten an OOM later but keep the mirror if it was created.
 609   if (java_mirror() == NULL) {
 610     log_trace(cds, mirror)("Recreate mirror for %s", external_name());
 611     java_lang_Class::create_mirror(this, loader, module_handle, protection_domain, CHECK);
 612   }
 613 }
 614 
 615 #if INCLUDE_CDS_JAVA_HEAP
 616 // Used at CDS dump time to access the archived mirror. No GC barrier.
 617 oop Klass::archived_java_mirror_raw() {
 618   assert(has_raw_archived_mirror(), "must have raw archived mirror");
 619   return CompressedOops::decode(_archived_mirror);
 620 }
 621 
 622 narrowOop Klass::archived_java_mirror_raw_narrow() {
 623   assert(has_raw_archived_mirror(), "must have raw archived mirror");
 624   return _archived_mirror;
 625 }
 626 
 627 // No GC barrier
 628 void Klass::set_archived_java_mirror_raw(oop m) {
 629   assert(DumpSharedSpaces, "called only during runtime");
 630   _archived_mirror = CompressedOops::encode(m);
 631 }


 655 
 656 Klass* Klass::array_klass_impl(bool or_null, TRAPS) {
 657   fatal("array_klass should be dispatched to InstanceKlass, ObjArrayKlass or TypeArrayKlass");
 658   return NULL;
 659 }
 660 
 661 void Klass::check_array_allocation_length(int length, int max_length, TRAPS) {
 662   if (length > max_length) {
 663     if (!THREAD->in_retryable_allocation()) {
 664       report_java_out_of_memory("Requested array size exceeds VM limit");
 665       JvmtiExport::post_array_size_exhausted();
 666       THROW_OOP(Universe::out_of_memory_error_array_size());
 667     } else {
 668       THROW_OOP(Universe::out_of_memory_error_retry());
 669     }
 670   } else if (length < 0) {
 671     THROW_MSG(vmSymbols::java_lang_NegativeArraySizeException(), err_msg("%d", length));
 672   }
 673 }
 674 














 675 // In product mode, this function doesn't have virtual function calls so
 676 // there might be some performance advantage to handling InstanceKlass here.
 677 const char* Klass::external_name() const {
 678   if (is_instance_klass()) {
 679     const InstanceKlass* ik = static_cast<const InstanceKlass*>(this);
 680     if (ik->is_unsafe_anonymous()) {
 681       char addr_buf[20];
 682       jio_snprintf(addr_buf, 20, "/" INTPTR_FORMAT, p2i(ik));
 683       size_t addr_len = strlen(addr_buf);
 684       size_t name_len = name()->utf8_length();
 685       char*  result   = NEW_RESOURCE_ARRAY(char, name_len + addr_len + 1);
 686       name()->as_klass_external_name(result, (int) name_len + 1);
 687       assert(strlen(result) == name_len, "");
 688       strcpy(result + name_len, addr_buf);
 689       assert(strlen(result) == name_len + addr_len, "");
 690       return result;




 691     }



 692   }
 693   if (name() == NULL)  return "<unknown>";
 694   return name()->as_klass_external_name();
 695 }
 696 
 697 const char* Klass::signature_name() const {
 698   if (name() == NULL)  return "<unknown>";












 699   return name()->as_C_string();
 700 }
 701 
 702 const char* Klass::external_kind() const {
 703   if (is_interface()) return "interface";
 704   if (is_abstract()) return "abstract class";
 705   return "class";
 706 }
 707 
 708 // Unless overridden, modifier_flags is 0.
 709 jint Klass::compute_modifier_flags(TRAPS) const {
 710   return 0;
 711 }
 712 
 713 int Klass::atomic_incr_biased_lock_revocation_count() {
 714   return (int) Atomic::add(&_biased_lock_revocation_count, 1);
 715 }
 716 
 717 // Unless overridden, jvmti_class_status has no flags set.
 718 jint Klass::jvmti_class_status() const {




 591     log_debug(cds, mirror)("%s has raw archived mirror", external_name());
 592     if (HeapShared::open_archive_heap_region_mapped()) {
 593       bool present = java_lang_Class::restore_archived_mirror(this, loader, module_handle,
 594                                                               protection_domain,
 595                                                               CHECK);
 596       if (present) {
 597         return;
 598       }
 599     }
 600 
 601     // No archived mirror data
 602     log_debug(cds, mirror)("No archived mirror data for %s", external_name());
 603     _java_mirror = NULL;
 604     this->clear_has_raw_archived_mirror();
 605   }
 606 
 607   // Only recreate it if not present.  A previous attempt to restore may have
 608   // gotten an OOM later but keep the mirror if it was created.
 609   if (java_mirror() == NULL) {
 610     log_trace(cds, mirror)("Recreate mirror for %s", external_name());
 611     java_lang_Class::create_mirror(this, loader, module_handle, protection_domain, Handle(), CHECK);
 612   }
 613 }
 614 
 615 #if INCLUDE_CDS_JAVA_HEAP
 616 // Used at CDS dump time to access the archived mirror. No GC barrier.
 617 oop Klass::archived_java_mirror_raw() {
 618   assert(has_raw_archived_mirror(), "must have raw archived mirror");
 619   return CompressedOops::decode(_archived_mirror);
 620 }
 621 
 622 narrowOop Klass::archived_java_mirror_raw_narrow() {
 623   assert(has_raw_archived_mirror(), "must have raw archived mirror");
 624   return _archived_mirror;
 625 }
 626 
 627 // No GC barrier
 628 void Klass::set_archived_java_mirror_raw(oop m) {
 629   assert(DumpSharedSpaces, "called only during runtime");
 630   _archived_mirror = CompressedOops::encode(m);
 631 }


 655 
 656 Klass* Klass::array_klass_impl(bool or_null, TRAPS) {
 657   fatal("array_klass should be dispatched to InstanceKlass, ObjArrayKlass or TypeArrayKlass");
 658   return NULL;
 659 }
 660 
 661 void Klass::check_array_allocation_length(int length, int max_length, TRAPS) {
 662   if (length > max_length) {
 663     if (!THREAD->in_retryable_allocation()) {
 664       report_java_out_of_memory("Requested array size exceeds VM limit");
 665       JvmtiExport::post_array_size_exhausted();
 666       THROW_OOP(Universe::out_of_memory_error_array_size());
 667     } else {
 668       THROW_OOP(Universe::out_of_memory_error_retry());
 669     }
 670   } else if (length < 0) {
 671     THROW_MSG(vmSymbols::java_lang_NegativeArraySizeException(), err_msg("%d", length));
 672   }
 673 }
 674 
 675 // Replace the last '+' char with '/'.
 676 static char* convert_hidden_name_to_java(Symbol* name) {
 677   size_t name_len = name->utf8_length();
 678   char* result = NEW_RESOURCE_ARRAY(char, name_len + 1);
 679   name->as_klass_external_name(result, (int)name_len + 1);
 680   for (int index = (int)name_len; index > 0; index--) {
 681     if (result[index] == '+') {
 682       result[index] = JVM_SIGNATURE_SLASH;
 683       break;
 684     }
 685   }
 686   return result;
 687 }
 688 
 689 // In product mode, this function doesn't have virtual function calls so
 690 // there might be some performance advantage to handling InstanceKlass here.
 691 const char* Klass::external_name() const {
 692   if (is_instance_klass()) {
 693     const InstanceKlass* ik = static_cast<const InstanceKlass*>(this);
 694     if (ik->is_unsafe_anonymous()) {
 695       char addr_buf[20];
 696       jio_snprintf(addr_buf, 20, "/" INTPTR_FORMAT, p2i(ik));
 697       size_t addr_len = strlen(addr_buf);
 698       size_t name_len = name()->utf8_length();
 699       char*  result   = NEW_RESOURCE_ARRAY(char, name_len + addr_len + 1);
 700       name()->as_klass_external_name(result, (int) name_len + 1);
 701       assert(strlen(result) == name_len, "");
 702       strcpy(result + name_len, addr_buf);
 703       assert(strlen(result) == name_len + addr_len, "");
 704       return result;
 705 
 706     } else if (ik->is_hidden()) {
 707       char* result = convert_hidden_name_to_java(name());
 708       return result;
 709     }
 710   } else if (is_objArray_klass() && ObjArrayKlass::cast(this)->bottom_klass()->is_hidden()) {
 711     char* result = convert_hidden_name_to_java(name());
 712     return result;
 713   }
 714   if (name() == NULL)  return "<unknown>";
 715   return name()->as_klass_external_name();
 716 }
 717 
 718 const char* Klass::signature_name() const {
 719   if (name() == NULL)  return "<unknown>";
 720   if (is_objArray_klass() && ObjArrayKlass::cast(this)->bottom_klass()->is_hidden()) {
 721     size_t name_len = name()->utf8_length();
 722     char* result = NEW_RESOURCE_ARRAY(char, name_len + 1);
 723     name()->as_C_string(result, (int)name_len + 1);
 724     for (int index = (int)name_len; index > 0; index--) {
 725       if (result[index] == '+') {
 726         result[index] = JVM_SIGNATURE_DOT;
 727         break;
 728       }
 729     }
 730     return result;
 731   }
 732   return name()->as_C_string();
 733 }
 734 
 735 const char* Klass::external_kind() const {
 736   if (is_interface()) return "interface";
 737   if (is_abstract()) return "abstract class";
 738   return "class";
 739 }
 740 
 741 // Unless overridden, modifier_flags is 0.
 742 jint Klass::compute_modifier_flags(TRAPS) const {
 743   return 0;
 744 }
 745 
 746 int Klass::atomic_incr_biased_lock_revocation_count() {
 747   return (int) Atomic::add(&_biased_lock_revocation_count, 1);
 748 }
 749 
 750 // Unless overridden, jvmti_class_status has no flags set.
 751 jint Klass::jvmti_class_status() const {


< prev index next >