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