< prev index next >

src/hotspot/share/cds/heapShared.cpp

Print this page
@@ -805,18 +805,38 @@
      intptr_t src_hash = orig_mirror->identity_hash();
      if (UseCompactObjectHeaders) {
        narrowKlass nk = CompressedKlassPointers::encode(orig_mirror->klass());
        scratch_m->set_mark(markWord::prototype().set_narrow_klass(nk).copy_set_hash(src_hash));
      } else {
+       // For valhalla, the prototype header is the same as markWord::prototype();
        scratch_m->set_mark(markWord::prototype().copy_set_hash(src_hash));
      }
      assert(scratch_m->mark().is_unlocked(), "sanity");
  
      DEBUG_ONLY(intptr_t archived_hash = scratch_m->identity_hash());
      assert(src_hash == archived_hash, "Different hash codes: original " INTPTR_FORMAT ", archived " INTPTR_FORMAT, src_hash, archived_hash);
    }
  
+   Klass* k = java_lang_Class::as_Klass(orig_mirror);
+   if (k != nullptr && k->is_instance_klass()) {
+     InstanceKlass* ik = InstanceKlass::cast(k);
+ 
+     if (ik->is_inline_klass() && ik->is_initialized()) {
+       // Only concrete value classes need the null_reset field
+       InlineKlass* ilk = InlineKlass::cast(k);
+       if (ilk->supports_nullable_layouts()) {
+         scratch_m->obj_field_put(ilk->null_reset_value_offset(), ilk->null_reset_value());
+       }
+     }
+ 
+     if (ik->has_acmp_maps_offset()) {
+       int maps_offset = ik->acmp_maps_offset();
+       oop maps = orig_mirror->obj_field(maps_offset);
+       scratch_m->obj_field_put(maps_offset, maps);
+     }
+   }
+ 
    if (CDSConfig::is_dumping_aot_linked_classes()) {
      java_lang_Class::set_module(scratch_m, java_lang_Class::module(orig_mirror));
      java_lang_Class::set_protection_domain(scratch_m, java_lang_Class::protection_domain(orig_mirror));
    }
  }

@@ -1512,11 +1532,15 @@
  
  void HeapShared::resolve_or_init(Klass* k, bool do_init, TRAPS) {
    if (!do_init) {
      if (k->class_loader_data() == nullptr) {
        Klass* resolved_k = SystemDictionary::resolve_or_null(k->name(), CHECK);
-       assert(resolved_k == k, "classes used by archived heap must not be replaced by JVMTI ClassFileLoadHook");
+       if (resolved_k->is_array_klass()) {
+         assert(resolved_k == k || resolved_k == k->super(), "classes used by archived heap must not be replaced by JVMTI ClassFileLoadHook");
+       } else {
+         assert(resolved_k == k, "classes used by archived heap must not be replaced by JVMTI ClassFileLoadHook");
+       }
      }
    } else {
      assert(k->class_loader_data() != nullptr, "must have been resolved by HeapShared::resolve_classes");
      if (k->is_instance_klass()) {
        InstanceKlass* ik = InstanceKlass::cast(k);

@@ -1974,11 +1998,12 @@
      GrowableArray<Klass*>* klasses = _dump_time_special_subgraph->subgraph_object_klasses();
      int num = klasses->length();
      for (int i = 0; i < num; i++) {
        Klass* subgraph_k = klasses->at(i);
        Symbol* name = subgraph_k->name();
-       if (subgraph_k->is_instance_klass() &&
+ 
+       if (subgraph_k->is_identity_class() &&
            name != vmSymbols::java_lang_Class() &&
            name != vmSymbols::java_lang_String() &&
            name != vmSymbols::java_lang_ArithmeticException() &&
            name != vmSymbols::java_lang_ArrayIndexOutOfBoundsException() &&
            name != vmSymbols::java_lang_ArrayStoreException() &&

@@ -2266,10 +2291,11 @@
    //     At runtime, these classes are initialized before X's archived fields
    //     are restored by HeapShared::initialize_from_archived_subgraph().
    for (int i = 0; fields[i].valid(); ) {
      ArchivableStaticFieldInfo* info = &fields[i];
      const char* klass_name = info->klass_name;
+ 
      start_recording_subgraph(info->klass, klass_name, is_full_module_graph);
  
      // If you have specified consecutive fields of the same klass in
      // fields[], these will be archived in the same
      // {start_recording_subgraph ... done_recording_subgraph} pass to
< prev index next >