< prev index next >

src/hotspot/share/memory/heapShared.cpp

Print this page

        

*** 27,45 **** #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/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" #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; --- 27,46 ---- #include "classfile/symbolTable.hpp" #include "classfile/vmSymbols.hpp" #include "logging/log.hpp" #include "logging/logMessage.hpp" #include "logging/logStream.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,79 **** --- 71,83 ---- 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,328 **** 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))); m->obj_field_put(field_offset, v); i += 2; } } --- 322,332 ---- 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( ! entry_field_records->at(i+1)); m->obj_field_put(field_offset, v); i += 2; } }
*** 599,604 **** --- 603,700 ---- 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 >