< prev index next >

src/hotspot/share/oops/cpCache.cpp

Print this page
*** 23,10 ***
--- 23,11 ---
   */
  
  #include "precompiled.hpp"
  #include "cds/archiveBuilder.hpp"
  #include "cds/cdsConfig.hpp"
+ #include "cds/classPrelinker.hpp"
  #include "cds/heapShared.hpp"
  #include "classfile/resolutionErrors.hpp"
  #include "classfile/systemDictionary.hpp"
  #include "classfile/systemDictionaryShared.hpp"
  #include "classfile/vmClasses.hpp"

*** 171,11 ***
          method->name() != vmSymbols::object_initializer_name()) {
        do_resolve = false;
      }
      if (invoke_code == Bytecodes::_invokestatic) {
        assert(method->method_holder()->is_initialized() ||
!              method->method_holder()->is_init_thread(JavaThread::current()),
               "invalid class initialization state for invoke_static");
  
        if (!VM_Version::supports_fast_class_init_checks() && method->needs_clinit_barrier()) {
          // Don't mark invokestatic to method as resolved if the holder class has not yet completed
          // initialization. An invokestatic must only proceed if the class is initialized, but if
--- 172,12 ---
          method->name() != vmSymbols::object_initializer_name()) {
        do_resolve = false;
      }
      if (invoke_code == Bytecodes::_invokestatic) {
        assert(method->method_holder()->is_initialized() ||
!              method->method_holder()->is_init_thread(JavaThread::current()) ||
+              (CDSConfig::is_dumping_archive() && VM_Version::supports_fast_class_init_checks()),
               "invalid class initialization state for invoke_static");
  
        if (!VM_Version::supports_fast_class_init_checks() && method->needs_clinit_barrier()) {
          // Don't mark invokestatic to method as resolved if the holder class has not yet completed
          // initialization. An invokestatic must only proceed if the class is initialized, but if

*** 358,10 ***
--- 360,22 ---
          return klass->method_at_vtable(method_entry->table_index());
        }
      }
    }
    return nullptr;
+ #if 0
+  else {
+     assert(is_field_entry(), "must be a field entry");
+     st->print_cr(" - F1:  [   " PTR_FORMAT "]", (intptr_t)_f1);
+     st->print_cr(" - F2:  [   " PTR_FORMAT "]", (intptr_t)_f2);
+     st->print_cr(" - flag values: [%02x|0|1|0|0|0|%01x|%01x|0|0|%04x]",
+                  flag_state(), is_final(), is_volatile(), field_index());
+     st->print_cr(" - tos: %s\n - final: %d\n - volatile: %d\n - field index: %04x",
+                  type2name(as_BasicType(flag_state())), is_final(), is_volatile(), field_index());
+   }
+   st->print_cr("                 -------------");
+ #endif
  }
  
  ConstantPoolCache* ConstantPoolCache::allocate(ClassLoaderData* loader_data,
                                       const intStack& invokedynamic_map,
                                       const GrowableArray<ResolvedIndyEntry> indy_entries,

*** 386,26 ***
  }
  
  #if INCLUDE_CDS
  void ConstantPoolCache::remove_unshareable_info() {
    assert(CDSConfig::is_dumping_archive(), "sanity");
!   // <this> is the copy to be written into the archive. It's in the ArchiveBuilder's "buffer space".
!   // However, this->_initial_entries was not copied/relocated by the ArchiveBuilder, so it's
!   // still pointing to the array allocated inside save_for_archive().
    if (_resolved_indy_entries != nullptr) {
      for (int i = 0; i < _resolved_indy_entries->length(); i++) {
!       resolved_indy_entry_at(i)->remove_unshareable_info();
      }
    }
    if (_resolved_field_entries != nullptr) {
      for (int i = 0; i < _resolved_field_entries->length(); i++) {
!       resolved_field_entry_at(i)->remove_unshareable_info();
      }
    }
    if (_resolved_method_entries != nullptr) {
      for (int i = 0; i < _resolved_method_entries->length(); i++) {
!       resolved_method_entry_at(i)->remove_unshareable_info();
      }
    }
  }
  #endif // INCLUDE_CDS
  
--- 400,79 ---
  }
  
  #if INCLUDE_CDS
  void ConstantPoolCache::remove_unshareable_info() {
    assert(CDSConfig::is_dumping_archive(), "sanity");
!   ConstantPool* cp = constant_pool();
!   ConstantPool* src_cp =  ArchiveBuilder::current()->get_source_addr(cp);
! 
    if (_resolved_indy_entries != nullptr) {
      for (int i = 0; i < _resolved_indy_entries->length(); i++) {
!       ResolvedIndyEntry *rei = resolved_indy_entry_at(i);
+       int cp_index = rei->constant_pool_index();
+       bool archived = false;
+       if (rei->is_resolved() && ClassPrelinker::is_indy_archivable(src_cp, cp_index)) {
+         if (log_is_enabled(Debug, cds, resolve)) {
+           ResourceMark rm;
+           int bsm = cp->bootstrap_method_ref_index_at(cp_index);
+           int bsm_ref = cp->method_handle_index_at(bsm);
+           Symbol* bsm_name = cp->uncached_name_ref_at(bsm_ref);
+           Symbol* bsm_signature = cp->uncached_signature_ref_at(bsm_ref);
+           Symbol* bsm_klass = cp->klass_name_at(cp->uncached_klass_ref_index_at(bsm_ref));
+           log_debug(cds, resolve)("archived indy   CP entry [%3d]: %s (%d) => %s.%s:%s", cp_index,
+                                   cp->pool_holder()->name()->as_C_string(), i,
+                                   bsm_klass->as_C_string(), bsm_name->as_C_string(), bsm_signature->as_C_string());
+         }
+         rei->mark_and_relocate();
+         archived = true;
+       } else {
+         rei->remove_unshareable_info();
+       }
+       ArchiveBuilder::alloc_stats()->record_indy_cp_entry(archived);
      }
    }
+ 
    if (_resolved_field_entries != nullptr) {
      for (int i = 0; i < _resolved_field_entries->length(); i++) {
!       ResolvedFieldEntry *rfi = resolved_field_entry_at(i);
+       int cp_index = rfi->constant_pool_index();
+       bool archived = false;
+       if ((rfi->is_resolved(Bytecodes::_getstatic) ||
+            rfi->is_resolved(Bytecodes::_putstatic) ||
+            rfi->is_resolved(Bytecodes::_putfield) ||
+            rfi->is_resolved(Bytecodes::_putfield)) &&
+           ClassPrelinker::can_archive_resolved_field(src_cp, cp_index)) {
+         if (log_is_enabled(Debug, cds, resolve)) {
+           ResourceMark rm;
+           int klass_cp_index = cp->uncached_klass_ref_index_at(cp_index);
+           Symbol* klass_name = cp->klass_name_at(klass_cp_index);
+           Symbol* name = cp->uncached_name_ref_at(cp_index);
+           Symbol* signature = cp->uncached_signature_ref_at(cp_index);
+           log_debug(cds, resolve)("archived field  CP entry [%3d]: %s => %s.%s:%s", cp_index,
+                                   cp->pool_holder()->name()->as_C_string(), klass_name->as_C_string(),
+                                   name->as_C_string(), signature->as_C_string());
+         }
+         rfi->mark_and_relocate();
+         archived = true;
+       } else {
+         rfi->remove_unshareable_info();
+       }
+       ArchiveBuilder::alloc_stats()->record_field_cp_entry(archived);
      }
    }
+ 
    if (_resolved_method_entries != nullptr) {
      for (int i = 0; i < _resolved_method_entries->length(); i++) {
!       ResolvedMethodEntry *rme = resolved_method_entry_at(i);
+       bool archived = false;
+       if (cp->can_archive_resolved_method(rme)) {
+         rme->mark_and_relocate(src_cp);
+         archived = true;
+       } else {
+         rme->remove_unshareable_info();
+       }
+       ArchiveBuilder::alloc_stats()->record_method_cp_entry(archived);
      }
    }
  }
  #endif // INCLUDE_CDS
  
< prev index next >