--- old/src/hotspot/share/memory/heapShared.cpp 2020-01-21 14:54:29.501129231 -0800 +++ new/src/hotspot/share/memory/heapShared.cpp 2020-01-21 14:54:29.161122563 -0800 @@ -29,7 +29,7 @@ #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" @@ -38,6 +38,7 @@ #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; @@ -72,6 +73,9 @@ 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; @@ -320,7 +324,7 @@ // 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; } @@ -601,4 +605,96 @@ 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::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