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