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