403
404 int num_klasses = _klasses->length();
405 for (i = 0; i < num_klasses; i++) {
406 it->push(_klasses->adr_at(i));
407 }
408
409 iterate_roots(it, is_relocating_pointers);
410 }
411
412 class GatherSortedSourceObjs : public MetaspaceClosure {
413 ArchiveBuilder* _builder;
414
415 public:
416 GatherSortedSourceObjs(ArchiveBuilder* builder) : _builder(builder) {}
417
418 virtual bool do_ref(Ref* ref, bool read_only) {
419 return _builder->gather_one_source_obj(enclosing_ref(), ref, read_only);
420 }
421
422 virtual void push_special(SpecialRef type, Ref* ref, intptr_t* p) {
423 assert(type == _method_entry_ref, "only special type allowed for now");
424 address src_obj = ref->obj();
425 size_t field_offset = pointer_delta(p, src_obj, sizeof(u1));
426 _builder->add_special_ref(type, src_obj, field_offset);
427 };
428
429 virtual void do_pending_ref(Ref* ref) {
430 if (ref->obj() != NULL) {
431 _builder->remember_embedded_pointer_in_copied_obj(enclosing_ref(), ref);
432 }
433 }
434 };
435
436 bool ArchiveBuilder::gather_one_source_obj(MetaspaceClosure::Ref* enclosing_ref,
437 MetaspaceClosure::Ref* ref, bool read_only) {
438 address src_obj = ref->obj();
439 if (src_obj == NULL) {
440 return false;
441 }
442 ref->set_keep_after_pushing();
443 remember_embedded_pointer_in_copied_obj(enclosing_ref, ref);
444
445 FollowMode follow_mode = get_follow_mode(ref);
446 SourceObjInfo src_info(ref, read_only, follow_mode);
450 if (_src_obj_table.maybe_grow()) {
451 log_info(cds, hashtables)("Expanded _src_obj_table table to %d", _src_obj_table.table_size());
452 }
453 }
454
455 assert(p->read_only() == src_info.read_only(), "must be");
456
457 if (created && src_info.should_copy()) {
458 ref->set_user_data((void*)p);
459 if (read_only) {
460 _ro_src_objs.append(enclosing_ref, p);
461 } else {
462 _rw_src_objs.append(enclosing_ref, p);
463 }
464 return true; // Need to recurse into this ref only if we are copying it
465 } else {
466 return false;
467 }
468 }
469
470 void ArchiveBuilder::add_special_ref(MetaspaceClosure::SpecialRef type, address src_obj, size_t field_offset) {
471 _special_refs->append(SpecialRefInfo(type, src_obj, field_offset));
472 }
473
474 void ArchiveBuilder::remember_embedded_pointer_in_copied_obj(MetaspaceClosure::Ref* enclosing_ref,
475 MetaspaceClosure::Ref* ref) {
476 assert(ref->obj() != NULL, "should have checked");
477
478 if (enclosing_ref != NULL) {
479 SourceObjInfo* src_info = (SourceObjInfo*)enclosing_ref->user_data();
480 if (src_info == NULL) {
481 // source objects of point_to_it/set_to_null types are not copied
482 // so we don't need to remember their pointers.
483 } else {
484 if (src_info->read_only()) {
485 _ro_src_objs.remember_embedded_pointer(src_info, ref);
486 } else {
487 _rw_src_objs.remember_embedded_pointer(src_info, ref);
488 }
489 }
490 }
491 }
492
493 void ArchiveBuilder::gather_source_objs() {
645 SourceObjInfo* p = _src_obj_table.get(src_obj);
646 assert(p != NULL, "must be");
647
648 return p->dumped_addr();
649 }
650
651 void ArchiveBuilder::relocate_embedded_pointers(ArchiveBuilder::SourceObjList* src_objs) {
652 for (int i = 0; i < src_objs->objs()->length(); i++) {
653 src_objs->relocate(i, this);
654 }
655 }
656
657 void ArchiveBuilder::update_special_refs() {
658 for (int i = 0; i < _special_refs->length(); i++) {
659 SpecialRefInfo s = _special_refs->at(i);
660 size_t field_offset = s.field_offset();
661 address src_obj = s.src_obj();
662 address dst_obj = get_dumped_addr(src_obj);
663 intptr_t* src_p = (intptr_t*)(src_obj + field_offset);
664 intptr_t* dst_p = (intptr_t*)(dst_obj + field_offset);
665 assert(s.type() == MetaspaceClosure::_method_entry_ref, "only special type allowed for now");
666
667 assert(*src_p == *dst_p, "must be a copy");
668 ArchivePtrMarker::mark_pointer((address*)dst_p);
669 }
670 }
671
672 class RefRelocator: public MetaspaceClosure {
673 ArchiveBuilder* _builder;
674
675 public:
676 RefRelocator(ArchiveBuilder* builder) : _builder(builder) {}
677
678 virtual bool do_ref(Ref* ref, bool read_only) {
679 if (ref->not_null()) {
680 ref->update(_builder->get_dumped_addr(ref->obj()));
681 ArchivePtrMarker::mark_pointer(ref->addr());
682 }
683 return false; // Do not recurse.
684 }
685 };
686
687 void ArchiveBuilder::relocate_roots() {
|
403
404 int num_klasses = _klasses->length();
405 for (i = 0; i < num_klasses; i++) {
406 it->push(_klasses->adr_at(i));
407 }
408
409 iterate_roots(it, is_relocating_pointers);
410 }
411
412 class GatherSortedSourceObjs : public MetaspaceClosure {
413 ArchiveBuilder* _builder;
414
415 public:
416 GatherSortedSourceObjs(ArchiveBuilder* builder) : _builder(builder) {}
417
418 virtual bool do_ref(Ref* ref, bool read_only) {
419 return _builder->gather_one_source_obj(enclosing_ref(), ref, read_only);
420 }
421
422 virtual void push_special(SpecialRef type, Ref* ref, intptr_t* p) {
423 address src_obj = ref->obj();
424 size_t field_offset = pointer_delta(p, src_obj, sizeof(u1));
425 _builder->add_special_ref(type, src_obj, field_offset, ref->size() * BytesPerWord);
426 };
427
428 virtual void do_pending_ref(Ref* ref) {
429 if (ref->obj() != NULL) {
430 _builder->remember_embedded_pointer_in_copied_obj(enclosing_ref(), ref);
431 }
432 }
433 };
434
435 bool ArchiveBuilder::gather_one_source_obj(MetaspaceClosure::Ref* enclosing_ref,
436 MetaspaceClosure::Ref* ref, bool read_only) {
437 address src_obj = ref->obj();
438 if (src_obj == NULL) {
439 return false;
440 }
441 ref->set_keep_after_pushing();
442 remember_embedded_pointer_in_copied_obj(enclosing_ref, ref);
443
444 FollowMode follow_mode = get_follow_mode(ref);
445 SourceObjInfo src_info(ref, read_only, follow_mode);
449 if (_src_obj_table.maybe_grow()) {
450 log_info(cds, hashtables)("Expanded _src_obj_table table to %d", _src_obj_table.table_size());
451 }
452 }
453
454 assert(p->read_only() == src_info.read_only(), "must be");
455
456 if (created && src_info.should_copy()) {
457 ref->set_user_data((void*)p);
458 if (read_only) {
459 _ro_src_objs.append(enclosing_ref, p);
460 } else {
461 _rw_src_objs.append(enclosing_ref, p);
462 }
463 return true; // Need to recurse into this ref only if we are copying it
464 } else {
465 return false;
466 }
467 }
468
469 void ArchiveBuilder::remember_embedded_pointer_in_copied_obj(MetaspaceClosure::Ref* enclosing_ref,
470 MetaspaceClosure::Ref* ref) {
471 assert(ref->obj() != NULL, "should have checked");
472
473 if (enclosing_ref != NULL) {
474 SourceObjInfo* src_info = (SourceObjInfo*)enclosing_ref->user_data();
475 if (src_info == NULL) {
476 // source objects of point_to_it/set_to_null types are not copied
477 // so we don't need to remember their pointers.
478 } else {
479 if (src_info->read_only()) {
480 _ro_src_objs.remember_embedded_pointer(src_info, ref);
481 } else {
482 _rw_src_objs.remember_embedded_pointer(src_info, ref);
483 }
484 }
485 }
486 }
487
488 void ArchiveBuilder::gather_source_objs() {
640 SourceObjInfo* p = _src_obj_table.get(src_obj);
641 assert(p != NULL, "must be");
642
643 return p->dumped_addr();
644 }
645
646 void ArchiveBuilder::relocate_embedded_pointers(ArchiveBuilder::SourceObjList* src_objs) {
647 for (int i = 0; i < src_objs->objs()->length(); i++) {
648 src_objs->relocate(i, this);
649 }
650 }
651
652 void ArchiveBuilder::update_special_refs() {
653 for (int i = 0; i < _special_refs->length(); i++) {
654 SpecialRefInfo s = _special_refs->at(i);
655 size_t field_offset = s.field_offset();
656 address src_obj = s.src_obj();
657 address dst_obj = get_dumped_addr(src_obj);
658 intptr_t* src_p = (intptr_t*)(src_obj + field_offset);
659 intptr_t* dst_p = (intptr_t*)(dst_obj + field_offset);
660
661
662 MetaspaceClosure::assert_valid(s.type());
663 switch (s.type()) {
664 case MetaspaceClosure::_method_entry_ref:
665 assert(*src_p == *dst_p, "must be a copy");
666 break;
667 case MetaspaceClosure::_internal_pointer_ref:
668 {
669 // *src_p points to a location inside src_obj. Let's make *dst_p point to
670 // the same location inside dst_obj.
671 size_t off = pointer_delta(*((address*)src_p), src_obj, sizeof(u1));
672 assert(off < s.src_obj_size_in_bytes(), "must point to internal address");
673 *((address*)dst_p) = dst_obj + off;
674 }
675 break;
676 default:
677 ShouldNotReachHere();
678 }
679 ArchivePtrMarker::mark_pointer((address*)dst_p);
680 }
681 }
682
683 class RefRelocator: public MetaspaceClosure {
684 ArchiveBuilder* _builder;
685
686 public:
687 RefRelocator(ArchiveBuilder* builder) : _builder(builder) {}
688
689 virtual bool do_ref(Ref* ref, bool read_only) {
690 if (ref->not_null()) {
691 ref->update(_builder->get_dumped_addr(ref->obj()));
692 ArchivePtrMarker::mark_pointer(ref->addr());
693 }
694 return false; // Do not recurse.
695 }
696 };
697
698 void ArchiveBuilder::relocate_roots() {
|