< prev index next >

src/hotspot/share/memory/heapShared.cpp

Print this page

*** 183,194 **** for (int i = 0; i < num_subgraphs_klasses; i++) { Klass* subgraph_k = subgraph_klasses->at(i); if (log_is_enabled(Info, cds, heap)) { ResourceMark rm; log_info(cds, heap)( ! "Archived object klass (%d): %s in %s sub-graphs", ! i, subgraph_k->external_name(), _k->external_name()); } _subgraph_klasses->at_put(i, subgraph_k); } } } --- 183,194 ---- for (int i = 0; i < num_subgraphs_klasses; i++) { Klass* subgraph_k = subgraph_klasses->at(i); if (log_is_enabled(Info, cds, heap)) { ResourceMark rm; log_info(cds, heap)( ! "Archived object klass %s (%2d) => %s", ! _k->external_name(), i, subgraph_k->external_name()); } _subgraph_klasses->at_put(i, subgraph_k); } } }
*** 346,439 **** class WalkOopAndArchiveClosure: public BasicOopIterateClosure { int _level; oop _orig_referencing_obj; oop _archived_referencing_obj; public: WalkOopAndArchiveClosure(int level, ! oop orig, oop archived) : _level(level), _orig_referencing_obj(orig), ! _archived_referencing_obj(archived) {} void do_oop(narrowOop *p) { WalkOopAndArchiveClosure::do_oop_work(p); } void do_oop( oop *p) { WalkOopAndArchiveClosure::do_oop_work(p); } protected: template <class T> void do_oop_work(T *p) { oop obj = RawAccess<>::oop_load(p); if (!CompressedOops::is_null(obj)) { // A java.lang.Class instance cannot be included in an archived // object sub-graph. if (java_lang_Class::is_instance(obj)) { ! log_error(cds, heap)("Unknown java.lang.Class object is in the archived sub-graph"); vm_exit(1); } if (log_is_enabled(Debug, cds, heap)) { - LogTarget(Debug, cds, heap) log; - LogStream ls(log); - outputStream* out = &ls; ResourceMark rm; ! log.print("(%d) %s <--- referenced from: %s", ! _level, obj->klass()->external_name(), ! CompressedOops::is_null(_orig_referencing_obj) ? ! "" : _orig_referencing_obj->klass()->external_name()); ! obj->print_on(out); } - assert(!MetaspaceShared::is_archive_object(obj), - "original objects must not directly point to archived object"); - - size_t field_delta = pointer_delta( - p, _orig_referencing_obj, sizeof(char)); - T* new_p = (T*)(address(_archived_referencing_obj) + field_delta); oop archived = MetaspaceShared::find_archived_heap_object(obj); ! if (archived != NULL) { ! // There is an archived copy existing, update reference to point ! // to the archived copy RawAccess<IS_NOT_NULL>::oop_store(new_p, archived); - log_debug(cds, heap)("--- found existing archived copy, store archived " PTR_FORMAT " in " PTR_FORMAT, - p2i(archived), p2i(new_p)); - return; } ! Thread* THREAD = Thread::current(); ! // Archive the current oop before iterating through its references ! archived = MetaspaceShared::archive_heap_object(obj, THREAD); ! if (archived == NULL) { ResourceMark rm; ! LogTarget(Error, cds, heap) log_err; ! LogStream ls_err(log_err); ! outputStream* out_err = &ls_err; ! log_err.print("Failed to archive %s object (" ! PTR_FORMAT "), size[" SIZE_FORMAT "] in sub-graph", ! obj->klass()->external_name(), p2i(obj), (size_t)obj->size()); ! obj->print_on(out_err); vm_exit(1); } - assert(MetaspaceShared::is_archive_object(archived), "must be archived"); - log_debug(cds, heap)("=== archiving oop " PTR_FORMAT " ==> " PTR_FORMAT, - p2i(obj), p2i(archived)); - - // Following the references in the current oop and archive any - // encountered objects during the process - WalkOopAndArchiveClosure walker(_level + 1, obj, archived); - obj->oop_iterate(&walker); - - // Update the reference in the archived copy of the referencing object - RawAccess<IS_NOT_NULL>::oop_store(new_p, archived); - log_debug(cds,heap)("=== store archived " PTR_FORMAT " in " PTR_FORMAT, - p2i(archived), p2i(new_p)); } ! } ! }; // // Start from the given static field in a java mirror and archive the // complete sub-graph of java heap objects that are reached directly // or indirectly from the starting object by following references. ! // Currently, only ArchivedModuleGraph class instance (mirror) has archived ! // object subgraphs. Sub-graph archiving restrictions (current): // // - All classes of objects in the archived sub-graph (including the // entry class) must be boot class only. // - No java.lang.Class instance (java mirror) can be included inside // an archived sub-graph. Mirror can only be the sub-graph entry object. --- 346,442 ---- class WalkOopAndArchiveClosure: public BasicOopIterateClosure { int _level; oop _orig_referencing_obj; oop _archived_referencing_obj; + Thread* _thread; public: WalkOopAndArchiveClosure(int level, ! oop orig, oop archived, TRAPS) : _level(level), _orig_referencing_obj(orig), ! _archived_referencing_obj(archived), ! _thread(THREAD) {} void do_oop(narrowOop *p) { WalkOopAndArchiveClosure::do_oop_work(p); } void do_oop( oop *p) { WalkOopAndArchiveClosure::do_oop_work(p); } protected: template <class T> void do_oop_work(T *p) { oop obj = RawAccess<>::oop_load(p); if (!CompressedOops::is_null(obj)) { + assert(!MetaspaceShared::is_archive_object(obj), + "original objects must not directly point to archived object"); + size_t field_delta = pointer_delta(p, _orig_referencing_obj, sizeof(char)); + T* new_p = (T*)(address(_archived_referencing_obj) + field_delta); + // A java.lang.Class instance cannot be included in an archived // object sub-graph. if (java_lang_Class::is_instance(obj)) { ! log_error(cds, heap)("(%d) Unknown java.lang.Class object is in the archived sub-graph", _level); vm_exit(1); } if (log_is_enabled(Debug, cds, heap)) { ResourceMark rm; ! log_debug(cds, heap)("(%d) %s[" SIZE_FORMAT "] ==> " PTR_FORMAT " size %d %s", _level, ! _orig_referencing_obj->klass()->external_name(), field_delta, ! p2i(obj), obj->size() * HeapWordSize, obj->klass()->external_name()); ! LogTarget(Trace, cds, heap) log; ! LogStream out(log); ! obj->print_on(&out); } oop archived = MetaspaceShared::find_archived_heap_object(obj); ! if (archived == NULL) { ! Thread* THREAD = _thread; ! archived = HeapShared::archive_reachable_objects_from(_level + 1, obj, THREAD); ! assert(archived != NULL, "VM should have exited"); ! } ! assert(MetaspaceShared::is_archive_object(archived), "must be"); ! ! // Update the reference in the archived copy of the referencing object. ! log_debug(cds, heap)("(%d) archiving oop @[" PTR_FORMAT "] " PTR_FORMAT " ==> " PTR_FORMAT, ! _level, p2i(new_p), p2i(obj), p2i(archived)); RawAccess<IS_NOT_NULL>::oop_store(new_p, archived); } + } + }; ! oop HeapShared::archive_reachable_objects_from(int level, oop orig_obj, TRAPS) { ! assert(orig_obj != NULL, "must be"); ! assert(!MetaspaceShared::is_archive_object(orig_obj), "sanity"); ! ! // get the archived copy of the field referenced object ! oop archived_obj = MetaspaceShared::archive_heap_object(orig_obj, THREAD); ! if (archived_obj == NULL) { ! // Skip archiving the sub-graph referenced from the current entry field. ResourceMark rm; ! log_error(cds, heap)( ! "Cannot archive the sub-graph referenced from %s object (" ! PTR_FORMAT ") size %d, skipped.", ! orig_obj->klass()->external_name(), p2i(orig_obj), orig_obj->size() * HeapWordSize); ! if (level == 1) { ! // See runtime/appcds/cacheObject/ArchivedIntegerCacheTest.java ! return NULL; ! } else { ! // We don't know how to handle an object that has been archived, but some of its reachable ! // objects cannot be archived. Bail out for now. We might need to fix this in the future if ! // we have a real use case. vm_exit(1); } } ! ! WalkOopAndArchiveClosure walker(level, orig_obj, archived_obj, THREAD); ! orig_obj->oop_iterate(&walker); ! assert(archived_obj != NULL, "must be"); ! return archived_obj; ! } // // Start from the given static field in a java mirror and archive the // complete sub-graph of java heap objects that are reached directly // or indirectly from the starting object by following references. ! // Sub-graph archiving restrictions (current): // // - All classes of objects in the archived sub-graph (including the // entry class) must be boot class only. // - No java.lang.Class instance (java mirror) can be included inside // an archived sub-graph. Mirror can only be the sub-graph entry object.
*** 468,521 **** oop archived_m = MetaspaceShared::find_archived_heap_object(m); if (CompressedOops::is_null(archived_m)) { return; } - // obtain k's subGraph Info KlassSubGraphInfo* subgraph_info = get_subgraph_info(k); - - // get the object referenced by the field oop f = m->obj_field(field_offset); ! if (log_is_enabled(Debug, cds, heap)) { ! LogTarget(Debug, cds, heap) log; ! LogStream ls(log); ! outputStream* out = &ls; ! log.print("Start archiving from: %s::%s ", klass_name, field_name); ! if (!CompressedOops::is_null(f)) { ! f->print_on(out); ! } else { ! log.print("null"); ! } } if (!CompressedOops::is_null(f)) { ! // get the archived copy of the field referenced object ! oop af = MetaspaceShared::archive_heap_object(f, THREAD); if (af == NULL) { ! // Skip archiving the sub-graph referenced from the current entry field. ! ResourceMark rm; ! log_info(cds, heap)( ! "Cannot archive the sub-graph referenced from %s object (" ! PTR_FORMAT ") size[" SIZE_FORMAT "], skipped.", ! f->klass()->external_name(), p2i(f), (size_t)f->size()); ! return; ! } ! if (!MetaspaceShared::is_archive_object(f)) { ! WalkOopAndArchiveClosure walker(1, f, af); ! f->oop_iterate(&walker); ! } ! ! // The field value is not preserved in the archived mirror. // Record the field as a new subGraph entry point. The recorded // information is restored from the archive at runtime. subgraph_info->add_subgraph_entry_field(field_offset, af); ! if (log_is_enabled(Info, cds, heap)) { ! ResourceMark rm; ! log_info(cds, heap)( ! "Archived the sub-graph referenced from %s object " PTR_FORMAT, ! f->klass()->external_name(), p2i(f)); } } else { // The field contains null, we still need to record the entry point, // so it can be restored at runtime. subgraph_info->add_subgraph_entry_field(field_offset, NULL); --- 471,501 ---- oop archived_m = MetaspaceShared::find_archived_heap_object(m); if (CompressedOops::is_null(archived_m)) { return; } KlassSubGraphInfo* subgraph_info = get_subgraph_info(k); oop f = m->obj_field(field_offset); ! log_debug(cds, heap)("Start archiving from: %s::%s ", klass_name, field_name); ! if (log_is_enabled(Trace, cds, heap) && !CompressedOops::is_null(f)) { ! LogTarget(Trace, cds, heap) log; ! LogStream out(log); ! f->print_on(&out); } if (!CompressedOops::is_null(f)) { ! oop af = archive_reachable_objects_from(1, f, CHECK); if (af == NULL) { ! log_error(cds, heap)("Archiving failed %s::%s (some reachable objects cannot be archived)", ! klass_name, field_name); ! } else { ! // Note: the field value is not preserved in the archived mirror. // Record the field as a new subGraph entry point. The recorded // information is restored from the archive at runtime. subgraph_info->add_subgraph_entry_field(field_offset, af); ! log_info(cds, heap)("Archived field %s::%s => " PTR_FORMAT, klass_name, field_name, p2i(af)); } } else { // The field contains null, we still need to record the entry point, // so it can be restored at runtime. subgraph_info->add_subgraph_entry_field(field_offset, NULL);
*** 549,564 **** int field_offset, const char* field_name) { assert(DumpSharedSpaces, "dump time only"); assert(k->is_shared_boot_class(), "must be boot class"); ! if (log_is_enabled(Debug, cds, heap)) { ! LogTarget(Debug, cds, heap) log; ! LogStream ls(log); ! outputStream* out = &ls; ! log.print("Start recording from: %s::%s", klass_name, field_name); ! } oop m = k->java_mirror(); oop f = m->obj_field(field_offset); record_subgraph_klasses_for(get_subgraph_info(k), f); } --- 529,539 ---- int field_offset, const char* field_name) { assert(DumpSharedSpaces, "dump time only"); assert(k->is_shared_boot_class(), "must be boot class"); ! log_debug(cds, heap)("Start recording from: %s::%s", klass_name, field_name); oop m = k->java_mirror(); oop f = m->obj_field(field_offset); record_subgraph_klasses_for(get_subgraph_info(k), f); }
< prev index next >