< prev index next >

src/hotspot/share/memory/heapShared.cpp

Print this page

        

@@ -27,19 +27,20 @@
 #include "classfile/symbolTable.hpp"
 #include "classfile/vmSymbols.hpp"
 #include "logging/log.hpp"
 #include "logging/logMessage.hpp"
 #include "logging/logStream.hpp"
-#include "memory/heapShared.hpp"
+#include "memory/heapShared.inline.hpp"
 #include "memory/iterator.inline.hpp"
 #include "memory/metadataFactory.hpp"
 #include "memory/metaspaceClosure.hpp"
 #include "memory/metaspaceShared.hpp"
 #include "memory/resourceArea.hpp"
 #include "oops/compressedOops.inline.hpp"
 #include "oops/oop.inline.hpp"
 #include "runtime/fieldDescriptor.inline.hpp"
+#include "utilities/bitMap.inline.hpp"
 
 #if INCLUDE_CDS_JAVA_HEAP
 KlassSubGraphInfo* HeapShared::_subgraph_info_list = NULL;
 int HeapShared::_num_archived_subgraph_info_records = 0;
 Array<ArchivedKlassSubGraphInfoRecord>* HeapShared::_archived_subgraph_info_records = NULL;

@@ -70,10 +71,13 @@
   info = new KlassSubGraphInfo(relocated_k, _subgraph_info_list);
   _subgraph_info_list = info;
   return info;
 }
 
+address   HeapShared::_narrow_oop_base;
+int       HeapShared::_narrow_oop_shift;
+
 int HeapShared::num_of_subgraph_infos() {
   int num = 0;
   KlassSubGraphInfo* info = _subgraph_info_list;
   while (info != NULL) {
     num ++;

@@ -318,11 +322,11 @@
           int field_offset = entry_field_records->at(i);
           // The object refereced by the field becomes 'known' by GC from this
           // point. All objects in the subgraph reachable from the object are
           // also 'known' by GC.
           oop v = MetaspaceShared::materialize_archived_object(
-            CompressedOops::decode(entry_field_records->at(i+1)));
+            entry_field_records->at(i+1));
           m->obj_field_put(field_offset, v);
           i += 2;
         }
       }
 

@@ -599,6 +603,98 @@
   for (int i = 0; i < num_archivable_static_fields; i++) {
     ArchivableStaticFieldInfo* info = &archivable_static_fields[i];
     archive_reachable_objects_from_static_field(info->klass, info->offset, info->type, CHECK);
   }
 }
+
+// At dump-time, find the location of all the non-null oop pointers in an archived heap
+// region. This way we can quickly relocate all the pointers without using
+// BasicOopIterateClosure at runtime.
+class FindEmbeddedNonNullPointers: public BasicOopIterateClosure {
+  narrowOop* _start;
+  BitMap *_oopmap;
+  int _num_total_oops;
+  int _num_null_oops;
+ public:
+  FindEmbeddedNonNullPointers(narrowOop* start, BitMap* oopmap)
+    : _start(start), _oopmap(oopmap), _num_total_oops(0),  _num_null_oops(0) {}
+
+  virtual bool should_verify_oops(void) {
+    return false;
+  }
+  virtual void do_oop(narrowOop* p) {
+    _num_total_oops ++;
+    narrowOop v = *p;
+    if (!CompressedOops::is_null(v)) {
+      size_t idx = p - _start;
+      _oopmap->set_bit(idx);
+    } else {
+      _num_null_oops ++;
+    }
+  }
+  virtual void do_oop(oop *p) {
+    ShouldNotReachHere();
+  }
+  int num_total_oops() const { return _num_total_oops; }
+  int num_null_oops()  const { return _num_null_oops; }
+};
+
+ResourceBitMap HeapShared::calculate_oopmap(MemRegion region) {
+  assert(UseCompressedOops, "must be");
+  size_t num_bits = region.byte_size() / sizeof(narrowOop);
+  ResourceBitMap oopmap(num_bits);
+
+  HeapWord* p   = region.start();
+  HeapWord* end = region.end();
+  FindEmbeddedNonNullPointers finder((narrowOop*)p, &oopmap);
+
+  int num_objs = 0;
+  while (p < end) {
+    oop o = (oop)p;
+    o->oop_iterate(&finder);
+    p += o->size();
+    ++ num_objs;
+  }
+
+  log_info(cds, heap)("calculate_oopmap: objects = %6d, embedded oops = %7d, nulls = %7d",
+                      num_objs, finder.num_total_oops(), finder.num_null_oops());
+  return oopmap;
+}
+
+void HeapShared::init_narrow_oop_decoding(address base, int shift) {
+  _narrow_oop_base = base;
+  _narrow_oop_shift = shift;
+}
+
+// Patch all the embedded oop pointers inside an archived heap region,
+// to be consistent with the runtime oop encoding.
+class PatchEmbeddedPointers: public BitMapClosure {
+  narrowOop* _start;
+
+ public:
+  PatchEmbeddedPointers(narrowOop* start) : _start(start) {}
+
+  bool do_bit(size_t offset) {
+    narrowOop* p = _start + offset;
+    narrowOop v = *p;
+    assert(!CompressedOops::is_null(v), "null oops should have been filtered out at dump time");
+    oop o = HeapShared::decode_with_archived_oop_encoding_mode(v);
+    RawAccess<IS_NOT_NULL>::oop_store(p, o);
+    return true;
+  }
+};
+
+void HeapShared::patch_archived_heap_embedded_pointers(MemRegion region, address oopmap,
+                                                       size_t oopmap_size_in_bits) {
+  BitMapView bm((BitMap::bm_word_t*)oopmap, oopmap_size_in_bits);
+
+#ifndef PRODUCT
+  ResourceMark rm;
+  ResourceBitMap checkBm = calculate_oopmap(region);
+  assert(bm.is_same(checkBm), "sanity");
+#endif
+
+  PatchEmbeddedPointers patcher((narrowOop*)region.start());
+  bm.iterate(&patcher);
+}
+
 #endif // INCLUDE_CDS_JAVA_HEAP
< prev index next >