654 if (obj->is_array()) {
655 guarantee(klass->is_cloneable(), "all arrays are cloneable");
656 } else {
657 guarantee(obj->is_instance(), "should be instanceOop");
658 bool cloneable = klass->is_subtype_of(vmClasses::Cloneable_klass());
659 guarantee(cloneable == klass->is_cloneable(), "incorrect cloneable flag");
660 }
661 #endif
662
663 // Check if class of obj supports the Cloneable interface.
664 // All arrays are considered to be cloneable (See JLS 20.1.5).
665 // All j.l.r.Reference classes are considered non-cloneable.
666 if (!klass->is_cloneable() ||
667 (klass->is_instance_klass() &&
668 InstanceKlass::cast(klass)->reference_type() != REF_NONE)) {
669 ResourceMark rm(THREAD);
670 THROW_MSG_NULL(vmSymbols::java_lang_CloneNotSupportedException(), klass->external_name());
671 }
672
673 // Make shallow object copy
674 const size_t size = obj->size();
675 oop new_obj_oop = nullptr;
676 if (obj->is_array()) {
677 const int length = ((arrayOop)obj())->length();
678 new_obj_oop = Universe::heap()->array_allocate(klass, size, length,
679 /* do_zero */ true, CHECK_NULL);
680 } else {
681 new_obj_oop = Universe::heap()->obj_allocate(klass, size, CHECK_NULL);
682 }
683
684 HeapAccess<>::clone(obj(), new_obj_oop, size);
685
686 Handle new_obj(THREAD, new_obj_oop);
687 // Caution: this involves a java upcall, so the clone should be
688 // "gc-robust" by this stage.
689 if (klass->has_finalizer()) {
690 assert(obj->is_instance(), "should be instanceOop");
691 new_obj_oop = InstanceKlass::register_finalizer(instanceOop(new_obj()), CHECK_NULL);
692 new_obj = Handle(THREAD, new_obj_oop);
693 }
694
|
654 if (obj->is_array()) {
655 guarantee(klass->is_cloneable(), "all arrays are cloneable");
656 } else {
657 guarantee(obj->is_instance(), "should be instanceOop");
658 bool cloneable = klass->is_subtype_of(vmClasses::Cloneable_klass());
659 guarantee(cloneable == klass->is_cloneable(), "incorrect cloneable flag");
660 }
661 #endif
662
663 // Check if class of obj supports the Cloneable interface.
664 // All arrays are considered to be cloneable (See JLS 20.1.5).
665 // All j.l.r.Reference classes are considered non-cloneable.
666 if (!klass->is_cloneable() ||
667 (klass->is_instance_klass() &&
668 InstanceKlass::cast(klass)->reference_type() != REF_NONE)) {
669 ResourceMark rm(THREAD);
670 THROW_MSG_NULL(vmSymbols::java_lang_CloneNotSupportedException(), klass->external_name());
671 }
672
673 // Make shallow object copy
674 // With compact object headers, the original might have been expanded by GC
675 // for the identity hash. The clone must be allocated at the base size, since
676 // it will get a fresh (not-hashed, not-expanded) mark word.
677 const size_t size = UseCompactObjectHeaders
678 ? obj->base_size_given_klass(obj->mark(), klass)
679 : obj->size();
680 oop new_obj_oop = nullptr;
681 if (obj->is_array()) {
682 const int length = ((arrayOop)obj())->length();
683 new_obj_oop = Universe::heap()->array_allocate(klass, size, length,
684 /* do_zero */ true, CHECK_NULL);
685 } else {
686 new_obj_oop = Universe::heap()->obj_allocate(klass, size, CHECK_NULL);
687 }
688
689 HeapAccess<>::clone(obj(), new_obj_oop, size);
690
691 Handle new_obj(THREAD, new_obj_oop);
692 // Caution: this involves a java upcall, so the clone should be
693 // "gc-robust" by this stage.
694 if (klass->has_finalizer()) {
695 assert(obj->is_instance(), "should be instanceOop");
696 new_obj_oop = InstanceKlass::register_finalizer(instanceOop(new_obj()), CHECK_NULL);
697 new_obj = Handle(THREAD, new_obj_oop);
698 }
699
|